diff options
author | Anas Nashif <anas.nashif@intel.com> | 2013-01-15 08:32:18 -0800 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-01-15 08:32:18 -0800 |
commit | 689b9dbb8d7f88ab91e7741932ed000b6e49be9a (patch) | |
tree | 463f5a1df8b2d35644c260e7bf6c8e0a26198af1 | |
parent | 59749d048d9e452f049f9151735b5256756919c3 (diff) | |
download | ltrace-689b9dbb8d7f88ab91e7741932ed000b6e49be9a.tar.gz ltrace-689b9dbb8d7f88ab91e7741932ed000b6e49be9a.tar.bz2 ltrace-689b9dbb8d7f88ab91e7741932ed000b6e49be9a.zip |
Imported Upstream version 0.7.2upstream/0.7.2
303 files changed, 76470 insertions, 7086 deletions
@@ -1,6 +0,0 @@ -* Manual page is not accurate (config files...) -* Doesn't do inter-library calls (BP is in the executable's PLT) -* It lacks support for several Linux archs, and many operating systems -* 2008-12-29: this line in config file does not work (2nd argument not used): - string setlocale(enum(LC_ALL=6), string); -* 2009-04-07 doesn't work with threads (processes sharing memory) @@ -0,0 +1,127 @@ + This is at least a partial credits-file of people that have + contributed to the Ltrace project. It is sorted by name and + formatted to allow easy grepping and beautification by + scripts. The fields are: name (N), email (E), web-address + (W), PGP key ID and fingerprint (P), description (D), and + snail-mail address (S). +---------- + +N: Pat Beirne +E: pbeirne@home.com +D: ARM port + +N: Anton Blanchard +E: anton@samba.org +D: PowerPC port + +N: Jakub Bogusz +E: qboosh@pld-linux.org +D: Alpha port + +N: Paul Buerger +E: pbuerger@avetec.org +D: Fix measuring time spent in a syscall + +N: Silvio Cesare +E: silvio@big.net.au +D: ELF hacking + +N: Juan Cespedes +W: http://cespedes.org/ +E: cespedes@debian.org +D: All development up to 0.5.3 + +N: Joe Damato +E: ice799@gmail.com +D: libdl support +D: libunwind support +D: Release 0.6 + +N: Sedat Dilek +E: sedat.dilek@gmail.com +D: Fixes and testing for MIPS arch + +N: Michael K. Edwards +E: m.k.edwards@gmail.com +D: Fixes + +N: Morten Eriksen +E: mortene@sim.no +D: Fixes + +N: Timothy Fesig +E: slate@us.ibm.com +D: s390 port + +N: Roman Hodek +E: Roman.Hodek@informatik.uni-erlangen.de +D: m68k port + +N: Edgar E. Iglesias +E: edgar.iglesias@gmail.com +D: CRIS port +D: MIPSel port + +N: Andreas Jaeger +E: aj@suse.de +D: x86-64 port + +N: Jakub Jelinek +E: jakub@redhat.com +D: SPARC port +D: x86-64 fixes +D: libelf support +D: Fixes + +N: Michal Ludvig +E: mludvig@suse.cz +D: x86-64 fixes +D: Support for Elf64 binaries + +N: Petr Machata +E: pmachata@redhat.com +D: Tracing multi-threaded processes +D: Tracing inter-library calls +D: Tracing PIE binaries +D: Fetch backend, ABI fixes for various arches +D: PowerPC fixes +D: Manual pages +D: Release 0.7 + +N: Santiago Romero +E: santiago.romero@imdea.org + +N: Andreas Schwab +E: schwab@linux-m68k.org +D: m68k fixes, fetch backend + +N: César Sánchez +E: cesar.sanchez@imdea.org + +N: Eric Vaitl +E: evaitl@cisco.com +D: MIPSel port + +N: Ian Wienand +E: ianw@gelato.unsw.edu.au +D: ia64 port + +N: Andrey Zonov +E: zont@FreeBSD.org +D: Portability fixes + + +# This file is part of ltrace. +# +# ltrace is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# ltrace is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 49b785f..0000000 --- a/ChangeLog +++ /dev/null @@ -1,539 +0,0 @@ -2009-07-25 Juan Cespedes <cespedes@debian.org> - - * New release 0.5.3 - * Created "libltrace.a" and a simple main program that calls it - * Added support for callbacks to libltrace - * Got rid of GNU's Autoconf stuff - * Make it work again in sparc with new kernel headers - -2009-05-21 Juan Cespedes <cespedes@debian.org> - - * Release version 0.5.2 - * new fork() and clone() approach: - + used PTRACE_O_TRACE{FORK,VFORK,CLONE} to trace newly created - processes instead of figuring it out whether a given syscall - would create another process or not - That way, new processes are always traced from the very beginning - * Use PTRACE_O_TRACEEXEC to check if a process has called exec() - -2009-05-07 Juan Cespedes <cespedes@debian.org> - - * clean-up of structs Process, Breakpoint, Function and Event - -2009-04-07 Juan Cespedes <cespedes@debian.org> - - * Improved documentation - * Cleaning up of "struct options" - * wait_for_something -> sysdeps/linux/events.c:next_event() - * wait for new children to stop instead of assuming they have stopped - -2009-02-11 Juan Cespedes <cespedes@debian.org> - - * Fixed bug present since the first version (!) of ltrace, - which caused many programs to segfault when a signal is received: - + When a breakpoint is hit, and we need to continue with it, we: - 1) remove the breakpoint - 2) order a SINGLESTEP - 3) when control comes back, set the breakpoint again - 4) let the process continue - + The problem came when a signal is received in the middle - of all this (specifically, between 2) and 3)). - If this is so, we treat the signal "in the usual way", - it is, at the end we issue a "CONTINUE" instead of the - needed SINGLESTEP. - -2008-12-10 Juan Cespedes <cespedes@debian.org> - - * summary.c: Fix "ltrace -o -c" - * mkdist: rm -rf autom4te.cache - * debian/control.ini: re-added armel and armeb - -2008-12-10 Juan Cespedes <cespedes@debian.org> - - * Release version 0.5.1 - -2008-12-10 Juan Cespedes <cespedes@debian.org> - - * Patches from Anderson Lizardo and Riku Voipio: - + Add generic support for arm targets - + Save funtion arguments on arm - + Add thumb instruction support - + Add basic arm/eabi support - + fix exec() testcase cleanup - + fix memory corruption in clone() test - + fix tracing child with "-p" option - -2008-02-27 Luis Machado <luisgpm@br.ibm.com> - - * sysdeps/linux-gnu/ppc/trace.c (arch_umovelong): New function. - * sysdeps/linux-gnu/ppc/regs.c (get_instruction): New function. - (get_count_register): New function. - * sysdeps/linux-gnu/ppc/arch.h (ARCH_HAVE_UMOVELONG): New define. - * sysdeps/linux-gnu/trace.c (umovelong): Create arch-specific - variant. - * ltrace.h (umovelong): Change prototype. - * process_event.c (process_breakpoint): Handle specifics of ppc32 PLT. - * display_args.c: Call umovelong with info parameter. - -2007-09-04 Juan Cespedes <cespedes@debian.org> - - * ltrace.h: Take arg_num out of arg_type_info - * linux-gnu/*/trace.c: gimme_arg(): Add arg_num as argument - * ltrace.c: check for existence of $HOME before using it - * General: Small fixes (indentation) - -2007-08-31 Juan Cespedes <cespedes@debian.org> - - * General: Small fixes (indentation, typos, clean-up of code) - * ltrace.c: Close output file on exit - * ltrace.c: use getenv("HOME") instead of getpwuid(geteuid())->pw_dir - * read_config_file.c, display_args.c: remove "ignore" argtype; - that's what "void" is for - * packaging/debian/: misc fixes, sync with version 0.5-2 - * etc/ltrace.conf: added more system calls - * testsuite/ltrace.minor/trace-clone.c: sleep(1) to avoid earlier - termination of process - * sysdeps/linux-gnu/trace.c: trace_pid(): reverted Petr's patch - to wait for child to stop, as it stopped following clone() - * process_event.c: Disable breakpoints before doing fork() (again!), - to make children work as expected - -2007-05-10 Petr Machata <pmachata@redhat.com> - - * Based on work of Supriya Kannery <supriyak@in.ibm.com> - * wait_for_something.c, process_event.c: Tracing across exec. - * sysdeps/linux-gnu/trace.c, ltrace.h: New interface was_exec. - * testsuite/ltrace.minor/trace-exec.c, - testsuite/ltrace.minor/trace-exec.exp, - testsuite/ltrace.minor/trace-exec1.c: Testcase for same. - -2007-05-09 Petr Machata <pmachata@redhat.com> - - * wait_for_something.c (wait_for_something): Interpret SIGILL, - SIGEMT and SIGSEGV as valid breakpoint signals, if instruction - pointer referes to breakpoint. - * testsuite/ltrace.torture/ia64-sigill.s, - * testsuite/ltrace.torture/ia64-sigill.exp: Testcase for same. - IA64-centric, because the only reproducer is there. - -2007-01-19 Petr Machata <pmachata@redhat.com> - - * sysdeps/linux-gnu/trace.c (trace_pid): wait for child to stop, - as indicated by ptrace documentation. - * proc.c (open_pid): start the traced child again, it will have - been stopped after trace_pid. Fixes tracing with -p. - * breakpoints.c: initialize proc->breakpoints always, don't wait - untill it might be needed. This renders a check in insert_breakpoint - superfluous. Fixes a sigsegvs experienced with -L. - -2006-12-28 Eric Vaitl <evaitl@cisco.com> - - * sysdeps/linux-gnu/mipsel/* Added mipsel support - * debug.h Added printf format attribute to debug_ - * elf.h Added mips relocation data to struct ltelf - * elf.c (do_init_elf) Read mips relocation data - * elf.c (read_elf) On the mips loop through mips_gotsym - instead of relplt_count. - * process_event.c (process_breakpoint) For the mips, - conditionally add a new breakpoint if the address of the - function changes because of lazy relocation. - * breakpoints.c (enable_all_breakpoints) For the mips, - reinsert breakpoints after the child has been started. - - -2006-11-30 Petr Machata <pmachata@redhat.com> - - * elf.c (elf_gnu_hash): renamed to private_elf_gnu_hash to avoid - conflicts with non-static version from libelf. - -2006-11-30 Petr Machata <pmachata@redhat.com> - - * elf.c (in_load_libraries): removed unused variables - bitmask_idxbits and shift. - * elf.c (do_init_elf, opd2addr): use ARCH_SUPPORTS_OPD to - determine whether to load/use .opd section - * sysdeps/linux-gnu/*/arch.h: define ARCH_SUPPORTS_OPD accordingly - * breakpoints.c (insert_breakpoint): rewrite loop to canonical for - -2006-10-13 Olaf Hering <olh@suse.de> - - * options.c: fix up typo for config file - -2006-09-25 Olaf Hering <olh@suse.de> - - * elf.c, elf.h : remove confilict with glibc SHT_GNU_HASH, include - elf_gnu_hash() directly, remove special casing and fix up output - specifier. - -2006-09-18 Steve Fink <sphink@gmail.com> - - * display_args.c: store arg_num in arg_type_info - * display_args.c: support 'double' parameters - * display_args.c: fix implementation of float,double params for ia64 - * output.c, process_event.c: store arg_num in arg_type_info - * read_config_file.c: support 'double' parameters - * read_config_file.c: store arg_num in arg_type_info, and as a result, - stop using singleton objects for any of the arg_type_info's. - * read_config_file.c: improve support for struct field alignments - * read_config_file.c: count floating-point parameters to support ia64 - float parameter passing - * sysdeps/README, sysdeps/linux-gnu/*/trace.c: pass in the full - arg_type_info to gimme_arg rather than just the arg_num (necessary - for float params on some architectures) - * sysdeps/linux-gnu/ia64/trace.c: accommodate register renaming when - fetching the parameters of a function after it has returned - * sysdeps/linux-gnu/ia64/trace.c: support floating point parameters - -2006-09-15 Olaf Hering <olh@suse.de> - - * Makefile.in : allow installation as non-root user, print out - some debugging information before running test suite. - * summary.c : allow compilation without USE_DEMANGLE - * sysdeps/linux-gnu/ppc/plt.c : fix warning in sym2addr - * sysdeps/linux-gnu/ia64/regs.c : fix warning when finding - instruction slot - * elf.c : fix up error created in 2006-07-26 refactor - -2006-08-14 Steve Fink <sphink@gmail.com> - - * demangle.c: remove my_demagle_dict_clear(), remove atexit() call - for same. Avoid potential segfault as demangling uses the - dictionary. - -2006-08-07 Steve Fink <sphink@gmail.com> - - * display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c, - testsuite/ltrace.main/parameters-lib.c, - testsuite/ltrace.main/parameters.c, - testsuite/ltrace.main/parameters.conf, - testsuite/ltrace.main/parameters.exp: Allow parameters to be - pointers to structs, which themselves can contain - (nearly) any other type, including other structs or pointers to - structs. - - -2006-08-07 Steve Fink <sphink@gmail.com> - - * defs.h, display_args.c, etc/ltrace.conf, ltrace.1, ltrace.h, - options.c, options.h, read_config_file.c, - testsuite/ltrace.main/parameters-lib.c, - testsuite/ltrace.main/parameters.c, - testsuite/ltrace.main/parameters.conf, - testsuite/ltrace.main/parameters.exp: array arguments - -2006-08-07 Steve Fink <sphink@gmail.com> - - * etc/ltrace.conf, read_config_file.c, - testsuite/ltrace.main/parameters-lib.c, - testsuite/ltrace.main/parameters.c, - testsuite/ltrace.main/parameters.conf, - testsuite/ltrace.main/parameters.exp: add ability to typedef - -2006-08-07 Steve Fink <sphink@gmail.com> - - * display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c, - testsuite/ltrace.main/parameters-lib.c, - testsuite/ltrace.main/parameters.c, - testsuite/ltrace.main/parameters.conf, - testsuite/ltrace.main/parameters.exp: short, ushort and float types - -2006-08-07 Steve Fink <sphink@gmail.com> - - * display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c, - testsuite/ltrace.main/parameters-lib.c, - testsuite/ltrace.main/parameters.c, - testsuite/ltrace.main/parameters.conf, - testsuite/ltrace.main/parameters.exp: implement enumerated parameters - -2006-08-07 Steve Fink <sphink@gmail.com> - - * testsuite/ltrace.main/Makefile.in : update testsuite for - new parameters - * testsuite/ltrace.main/parameters-lib.c : added - * testsuite/ltrace.main/parameters.c : added - * testsuite/ltrace.main/parameters.conf : added - * testsuite/ltrace.main/parameters.exp : added - -2006-08-07 Steve Fink <sphink@gmail.com> - - * display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c, - sysdeps/README, sysdeps/linux-gnu-trace.c : switch to passing - around values rather than argument numbers that need to be fetched - (needed for pointer params) - -2006-08-07 Steve Fink <sphink@gmail.com> - - * display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c: - implement ignored arguments - -2006-08-07 Steve Fink <sphink@gmail.com> - - * display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c: - implement string[argN] and string[N] parameter descriptors - -2006-08-07 Steve Fink <sphink@gmail.com> - - * ltrace.h, output.c, read_config_file.c : use arg_type_info in - place of arg_type in order to eventually be able to record - properties along with types. - -2006-07-20 Steve Fink <sphink@gmail.com> - - * testsuite/lib/ltrace.exp: better quoting and error detection for - ltrace_verify_output's call to grep - -2006-08-07 Steve Fink <sphink@gmail.com> - - * ltrace.1: update bug email addr - -2006-07-26 Ian Wienand <ianw@debian.org> - - * elf.c: refactor opd2addr to not pass void* (fix warnings) - -2006-07-18 Petr Machata <pmachata@redhat.com> - - * elf.c: replace nonexistant elf_plt2addr with opd2addr, fix - typo, and fix WEAK symbol detection - * sysdeps/linux-gnu/ppc/arch.h: define breakpoint instruction, - its length, etc., also on ppc32 - -2006-07-18 Petr Machata <pmachata@redhat.com> - - * elf.c: support .gnu.hash ELF entry - * elf.h: likewise - -2006-07-18 Petr Machata <pmachata@redhat.com> - - * options.c: don't hardcode version number - -2006-07-18 Justin Pryzby <justinpryzby@users.sourceforge.net> - - * ltrace.1: make demagle clearer - -2006-07-16 Steve Fink <sphink@gmail.com> - - * options.c: implement -F flag for alternate config file(s) - * ltrace.c: load SYSCONFDIR/ltrace.conf and ~/.ltrace.conf by default - -2006-06-19 Ian Wienand <ianw@ieee.org> - - * sysdeps/linux-gnu/mksyscallent: update, fix for ia64 - * sysdeps/linux-gnu/i386/syscallent.h: regenerate to 2.6.17 - * sysdeps/linux-gnu/i386/signalent.h: likewise - * sysdeps/linux-gnu/arm/syscallent.h: likewise - * sysdeps/linux-gnu/arm/signalent.h: likewise - * sysdeps/linux-gnu/m68k/syscallent.h: likewise - * sysdeps/linux-gnu/m68k/signalent.h: likewise - * sysdeps/linux-gnu/ia64/syscallent.h: likewise - * sysdeps/linux-gnu/ia64/signalent.h: likewise - -2006-06-19 Heiko Carstens <heiko.carstens@de.ibm.com> - - * sysdeps/linux-gnu/s390/syscalls31.h: update to 2.6.17 - * sysdeps/linux-gnu/s390/syscalls64.h: ditto - -2006-06-16 Justin Pryzby <justinpryzby@users.sourceforge.net> - - * ltrace.1: spelling fix - * TODO: spelling fix - -2006-06-14 Ian Wienand <ianw@gelato.unsw.edu.au> - - * configure.ac: Bump version to 0.5 for Paull Gillam's PPC64 - non-exec PLT patch (as merged below). - * breakpoints.c: merge - * elf.c: merge - * elf.h: merge - * ltrace.h: merge - * output.c: merge - * process_event.c: merge - * sysdeps/linux-gnu/alpha/plt.c: merge - * sysdeps/linux-gnu/arm/plt.c: merge - * sysdeps/linux-gnu/breakpoint.c: merge - * sysdeps/linux-gnu/i386/plt.c: merge - * sysdeps/linux-gnu/ia64/plt.c: merge - * sysdeps/linux-gnu/m68k/plt.c: merge - * sysdeps/linux-gnu/ppc/arch.h: merge - * sysdeps/linux-gnu/ppc/arch.h.rej: merge - * sysdeps/linux-gnu/ppc/plt.c: merge - * sysdeps/linux-gnu/s390/plt.c: merge - * sysdeps/linux-gnu/sparc/plt.c: merge - * sysdeps/linux-gnu/x86_64/plt.c: merge - - -2006-05-11 Heiko Carstens <heiko.carstens@de.ibm.com> - - * sysdeps/linux-gnu/mksyscallent_s390: add - * sysdeps/linux-gnu/s390/syscalls31.h: update to 2.6.16 - * sysdeps/linux-gnu/s390/syscalls64.h: ditto - -2006-04-24 Paul Gilliam <pgilliam@us.ibm.com> - - * elf.c: Use PLT_REINITALISATION_BP for those architectures that need - to re-initialize breakpoints after the dynamic linker has run. Also, - use value of "e_entry" for address of PLT_REINITALISATION_BP if the - target program has been stripped. - * ltrace.1: Note that fact that "-X" is only available on architectures - that need it. - * options.c: Use PLT_REINITALISATION_BP for those architectures that - need to re-initialize breakpoints after the dynamic linker has run. - * process_event.c: ditto. - * sysdeps/linux-gnu/ppc/arch.h: This is the only such architecture. - * sysdeps/linux-gnu/arm/arch.h: Delete use of PLT_REINITALISATION_BP. - * sysdeps/linux-gnu/m68k/arch.h: ditto. - * sysdeps/linux-gnu/alpha/arch.h: ditto. - * sysdeps/linux-gnu/i386/arch.h: ditto. - * sysdeps/linux-gnu/x86_64/arch.h: ditto. - * sysdeps/linux-gnu/s390/arch.h: ditto. - * sysdeps/linux-gnu/ia64/arch.h: ditto. - * sysdeps/linux-gnu/sparc/arch.h: ditto. - -2006-04-24 Paul Gilliam <pgilliam@us.ibm.com> - - * elf.c: Adds some casts to keep a more picky version of GCC happy. - * sysdeps/linux-gnu/trace.c: ditto. - * sysdeps/linux-gnu/breakpoint.c: ditto. - * ltrace.h: ditto. - -2006-04-24 Paul Gilliam <pgilliam@us.ibm.com> - - * summery.c: Correct a typo prevented the inclusion of "demangle.h". - -2006-03-16 Ian Wienand <ianw@gelato.unsw.edu.au> - - * testsuite/ltrace.minor/trace-clone.c: use __clone2() for IA64 - clone test - -2006-03=13 Paul Gilliam <pgilliam@us.ibm.com> - - * Makefile.in: Add targets to support testsuite, including 'check'. - * confiure.ac: Add testsuite Makefile's to AC_OUTPUT. - * testsuite: Add dejagnu base testsuite. - * testsuite/config/: Add - * testsuite/config/unix.exp: Add - * testsuite/lib/: Add - * testsuite/lib/compiler.c: Add - * testsuite/lib/compiler.cc: Add - * testsuite/lib/ltrace.exp: Add - * testsuite/ltrace.main/: Add - * testsuite/ltrace.main/main.c: Add - * testsuite/ltrace.main/main.exp: Add - * testsuite/ltrace.main/main-internal-1.c: Add - * testsuite/ltrace.main/main-internal.c: Add - * testsuite/ltrace.main/main-internal.exp: Add - * testsuite/ltrace.main/main-lib.c: Add - * testsuite/ltrace.main/Makefile.in: Add - * testsuite/ltrace.main/signals.c: Add - * testsuite/ltrace.main/signals.exp: Add - * testsuite/ltrace.main/system_calls.c: Add - * testsuite/ltrace.main/system_calls.exp: Add - * testsuite/ltrace.minor/: Add - * testsuite/ltrace.minor/attach-process.c: Add - * testsuite/ltrace.minor/attach-process.exp: Add - * testsuite/ltrace.minor/count-record.c: Add - * testsuite/ltrace.minor/count-record.exp: Add - * testsuite/ltrace.minor/demangle.cpp: Add - * testsuite/ltrace.minor/demangle.exp: Add - * testsuite/ltrace.minor/demangle.h: Add - * testsuite/ltrace.minor/demangle-lib.cpp: Add - * testsuite/ltrace.minor/Makefile.in: Add - * testsuite/ltrace.minor/print-instruction-pointer.c: Add - * testsuite/ltrace.minor/print-instruction-pointer.exp: Add - * testsuite/ltrace.minor/time-record.c: Add - * testsuite/ltrace.minor/time-record-T.exp: Add - * testsuite/ltrace.minor/time-record-tt.exp: Add - * testsuite/ltrace.minor/time-record-ttt.exp: Add - * testsuite/ltrace.minor/trace-clone.c: Add - * testsuite/ltrace.minor/trace-clone.exp: Add - * testsuite/ltrace.minor/trace-fork.c: Add - * testsuite/ltrace.minor/trace-fork.exp: Add - * testsuite/ltrace.torture/: Add - * testsuite/ltrace.torture/Makefile.in: Add - * testsuite/ltrace.torture/signals.c: Add - * testsuite/ltrace.torture/signals.exp: Add - * testsuite/Makefile.in: Add - * testsuite/README: Add - * testsuite/run-my-tests.sh: Add - * testsuite/so_test1/: Add - * testsuite/so_test2/: Add - -2006-03-13 Paul Gilliam <pgilliam@us.ibm.com> - - * options.h: New structure for opt_x list elements, now with 'found'. - * options.c: Use new opt_x_t structure, initializing 'found' to 0. - * elf.c: Use new 'found' field for better error checking. - -2006-03-06 Ian Wienand <ianw@ieee.org> - - * Makefile.in: remove unneeded dirs from make dist; use rm - directly. - -2006-02-22 Ian Wienand <ianw@ieee.org> - - * COPYING: update from FSF to update address - * Makefile.in: check for SVN checkout with make dist. - -2006-02-21 Ian Wienand <ianw@ieee.org> - - * README: update to point to Alioth list - -2006-02-21 Ian Wienand <ianw@ieee.org> - - * lots!: Rebase from RedHat 0.3.36-4.2 package. Forward port most - of the below changes that weren't already there. Bump version to - 0.4 as there are two added architectures and internal API changes. - All changes from this point on should be reflected in this file. - -2006-02-17 Ian Wienand <ianw@ieee.org> - - * sysdeps/linux-gnu/ia64/arch.h: add ia64 support - * sysdeps/linux-gnu/ia64/breakpoint.c: add - * sysdeps/linux-gnu/ia64/Makefile: add - * sysdeps/linux-gnu/ia64/plt.c: add - * sysdeps/linux-gnu/ia64/ptrace.h: add - * sysdeps/linux-gnu/ia64/regs.c: add - * sysdeps/linux-gnu/ia64/signalent.h: add - * sysdeps/linux-gnu/ia64/syscallent.h: add - * sysdeps/linux-gnu/ia64/trace.c: add - * elf.h: add extra field for PLT size - * elf.c: put in PLT size - * sysdeps/linux-gnu/breakpoint.c: add arch breakpoint override - * sysdeps/linux-gnu/trace.c: don't single step after breakpoint for - ia64 - - * configure.ac: add version to AC_INIT, bump version to 0.3.38 - * options.c: use PACKAGE_VERSION - -2006-02-16 Ian Wienand <ianw@ieee.org> - - * Makefile.in: install documentation into share/doc, make dist - target from SVN export. - -2006-02-16 Rajeev V. Pillai <rajeevvp@yahoo.com> - - * Makefile.in: pass through CPP and LD FLAGS - -2006-02-16 Ian Wienand <ianw@ieee.org> - - * read_config_file.c: initialise pt stack argument to stop warning - * summary.c: make show_summary() obey -C for demangaling function names - -2006-02-16 Bernd Zeimetz <bernd@zeimetz.de> - - * ltrace.1: reference reportbug - -2006-02-16 Colin S. Miller <csmiller@iname.com> - - * ltrace.1: fix debug typo - -2006-02-16 Andrew Stribblehill <ads@debian.org> - - * etc/ltrace.conf: fix putenv typo - -2006-02-16 Ian Wienand <ianw@ieee.org> - - * README: update - * Makefile.in: remove obsolete -I- for -iquote, add TAGS target - * debug.c, debug.h: __PRETTY_FUNCTION__ is const; change specifier - to stop warnings. - * ltrace.1: add a note about not tracing dlopen()ed libraries @@ -1,19 +1,365 @@ -How to build ltrace from source -------------------------------- +Installation Instructions +************************* -To get the latest version from GIT: +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. - git clone git://git.debian.org/git/collab-maint/ltrace.git + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. -To create a distribution (ltrace-<version>.tar.gz): +Basic Installation +================== - ./mkdist + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. -To compile: + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). - ./configure - make + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. -To build debian/control (to create Debian package): + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `<wchar.h>' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. - debian/rules debian/control DEB_AUTO_UPDATE_DEBIAN_CONTROL:=yes diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..6e46949 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,157 @@ +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# Copyright (C) 2010 Zachary T Welch, CodeSourcery +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +ACLOCAL_AMFLAGS = -I config/m4 + +SUBDIRS = \ + sysdeps \ + . \ + testsuite + +AM_CPPFLAGS += \ + $(libelf_CFLAGS) \ + -DSYSCONFDIR=\"$(sysconfdir)\" + +noinst_LTLIBRARIES = \ + libltrace.la + +libltrace_la_SOURCES = \ + breakpoints.c \ + debug.c \ + demangle.c \ + dict.c \ + ltrace-elf.c \ + execute_program.c \ + handle_event.c \ + libltrace.c \ + options.c \ + output.c \ + proc.c \ + read_config_file.c \ + summary.c \ + library.c \ + filter.c \ + glob.c \ + type.c \ + value.c \ + value_dict.c \ + expr.c \ + fetch.c \ + vect.c \ + param.c \ + printf.c \ + zero.c \ + lens.c \ + lens_default.c \ + lens_enum.c + +libltrace_la_LIBADD = \ + $(libelf_LIBS) \ + $(liberty_LIBS) \ + $(libsupcxx_LIBS) \ + $(libstdcxx_LIBS) \ + $(libunwind_LIBS) \ + sysdeps/libos.la + + +bin_PROGRAMS = \ + ltrace + +ltrace_SOURCES = \ + main.c + +ltrace_LDADD = \ + libltrace.la + + +noinst_HEADERS = \ + backend.h \ + breakpoint.h \ + common.h \ + debug.h \ + defs.h \ + demangle.h \ + dict.h \ + forward.h \ + ltrace-elf.h \ + ltrace.h \ + options.h \ + output.h \ + proc.h \ + read_config_file.h \ + library.h \ + filter.h \ + glob.h \ + vect.h \ + type.h \ + value.h \ + value_dict.h \ + callback.h \ + expr.h \ + fetch.h \ + vect.h \ + param.h \ + printf.h \ + zero.h \ + lens.h \ + lens_default.h \ + lens_enum.h + +dist_man1_MANS = ltrace.1 +dist_man5_MANS = ltrace.conf.5 + +dist_doc_DATA = COPYING CREDITS INSTALL README TODO + +dist_sysconf_DATA = \ + etc/ltrace.conf + +EXTRA_DIST = \ + ltrace.spec \ + debian/changelog \ + debian/compat \ + debian/control \ + debian/copyright \ + debian/rules + +MAINTAINERCLEANFILES = \ + configure \ + Makefile.in \ + aclocal.m4 \ + config.h.in \ + config.h.in~ \ + config/autoconf/compile \ + config/autoconf/config.guess \ + config/autoconf/config.sub \ + config/autoconf/depcomp \ + config/autoconf/install-sh \ + config/autoconf/ltmain.sh \ + config/autoconf/mdate-sh \ + config/autoconf/missing \ + config/autoconf/texinfo.tex \ + libtool.m4 \ + ltoptions.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + lt~obsolete.m4 \ + $(DIST_ARCHIVES) + +maintainer-clean-local: + -chmod -R a+rw $(distdir) + -rm -fr $(distdir) diff --git a/Makefile.in b/Makefile.in index 1e8adcd..ebf0884 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,74 +1,1203 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# Copyright (C) 2010 Zachary T Welch, CodeSourcery +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. # -# ltrace's Makefile.in +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = ltrace$(EXEEXT) +subdir = . +DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \ + $(dist_man1_MANS) $(dist_man5_MANS) $(dist_sysconf_DATA) \ + $(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in $(top_srcdir)/configure COPYING INSTALL \ + NEWS TODO config/autoconf/config.guess \ + config/autoconf/config.sub config/autoconf/depcomp \ + config/autoconf/install-sh config/autoconf/ltmain.sh \ + config/autoconf/missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libltrace_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) sysdeps/libos.la +am_libltrace_la_OBJECTS = breakpoints.lo debug.lo demangle.lo dict.lo \ + ltrace-elf.lo execute_program.lo handle_event.lo libltrace.lo \ + options.lo output.lo proc.lo read_config_file.lo summary.lo \ + library.lo filter.lo glob.lo type.lo value.lo value_dict.lo \ + expr.lo fetch.lo vect.lo param.lo printf.lo zero.lo lens.lo \ + lens_default.lo lens_enum.lo +libltrace_la_OBJECTS = $(am_libltrace_la_OBJECTS) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(sysconfdir)" +PROGRAMS = $(bin_PROGRAMS) +am_ltrace_OBJECTS = main.$(OBJEXT) +ltrace_OBJECTS = $(am_ltrace_OBJECTS) +ltrace_DEPENDENCIES = libltrace.la +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libltrace_la_SOURCES) $(ltrace_SOURCES) +DIST_SOURCES = $(libltrace_la_SOURCES) $(ltrace_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +man1dir = $(mandir)/man1 +man5dir = $(mandir)/man5 +NROFF = nroff +MANS = $(dist_man1_MANS) $(dist_man5_MANS) +DATA = $(dist_doc_DATA) $(dist_sysconf_DATA) +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ $(libelf_CFLAGS) \ + -DSYSCONFDIR=\"$(sysconfdir)\" +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I config/m4 +SUBDIRS = \ + sysdeps \ + . \ + testsuite + +noinst_LTLIBRARIES = \ + libltrace.la + +libltrace_la_SOURCES = \ + breakpoints.c \ + debug.c \ + demangle.c \ + dict.c \ + ltrace-elf.c \ + execute_program.c \ + handle_event.c \ + libltrace.c \ + options.c \ + output.c \ + proc.c \ + read_config_file.c \ + summary.c \ + library.c \ + filter.c \ + glob.c \ + type.c \ + value.c \ + value_dict.c \ + expr.c \ + fetch.c \ + vect.c \ + param.c \ + printf.c \ + zero.c \ + lens.c \ + lens_default.c \ + lens_enum.c + +libltrace_la_LIBADD = \ + $(libelf_LIBS) \ + $(liberty_LIBS) \ + $(libsupcxx_LIBS) \ + $(libstdcxx_LIBS) \ + $(libunwind_LIBS) \ + sysdeps/libos.la + +ltrace_SOURCES = \ + main.c + +ltrace_LDADD = \ + libltrace.la + +noinst_HEADERS = \ + backend.h \ + breakpoint.h \ + common.h \ + debug.h \ + defs.h \ + demangle.h \ + dict.h \ + forward.h \ + ltrace-elf.h \ + ltrace.h \ + options.h \ + output.h \ + proc.h \ + read_config_file.h \ + library.h \ + filter.h \ + glob.h \ + vect.h \ + type.h \ + value.h \ + value_dict.h \ + callback.h \ + expr.h \ + fetch.h \ + vect.h \ + param.h \ + printf.h \ + zero.h \ + lens.h \ + lens_default.h \ + lens_enum.h + +dist_man1_MANS = ltrace.1 +dist_man5_MANS = ltrace.conf.5 +dist_doc_DATA = COPYING CREDITS INSTALL README TODO +dist_sysconf_DATA = \ + etc/ltrace.conf + +EXTRA_DIST = \ + ltrace.spec \ + debian/changelog \ + debian/compat \ + debian/control \ + debian/copyright \ + debian/rules + +MAINTAINERCLEANFILES = \ + configure \ + Makefile.in \ + aclocal.m4 \ + config.h.in \ + config.h.in~ \ + config/autoconf/compile \ + config/autoconf/config.guess \ + config/autoconf/config.sub \ + config/autoconf/depcomp \ + config/autoconf/install-sh \ + config/autoconf/ltmain.sh \ + config/autoconf/mdate-sh \ + config/autoconf/missing \ + config/autoconf/texinfo.tex \ + libtool.m4 \ + ltoptions.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + lt~obsolete.m4 \ + $(DIST_ARCHIVES) + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libltrace.la: $(libltrace_la_OBJECTS) $(libltrace_la_DEPENDENCIES) + $(LINK) $(libltrace_la_OBJECTS) $(libltrace_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +ltrace$(EXEEXT): $(ltrace_OBJECTS) $(ltrace_DEPENDENCIES) + @rm -f ltrace$(EXEEXT) + $(LINK) $(ltrace_OBJECTS) $(ltrace_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoints.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demangle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute_program.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glob.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/handle_event.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lens.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lens_default.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lens_enum.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libltrace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/library.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ltrace-elf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/param.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read_config_file.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/summary.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/type.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/value.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/value_dict.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vect.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zero.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-man1: $(dist_man1_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" + @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } +install-man5: $(dist_man5_MANS) + @$(NORMAL_INSTALL) + test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" + @list='$(dist_man5_MANS)'; test -n "$(man5dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list='$(dist_man5_MANS)'; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(docdir)" && rm -f $$files +install-dist_sysconfDATA: $(dist_sysconf_DATA) + @$(NORMAL_INSTALL) + test -z "$(sysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" + @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysconfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \ + done + +uninstall-dist_sysconfDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sysconfdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sysconfdir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) \ + config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(sysconfdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-dist_docDATA install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-dist_sysconfDATA + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: -#OS := $(shell uname -s) -OS := @HOST_OS@ +install-man: install-man1 install-man5 -TOPDIR = $(shell pwd) +install-pdf: install-pdf-recursive -prefix = @prefix@ -sysconfdir = @sysconfdir@ -bindir = $(prefix)/bin -mandir = @mandir@ -docdir = $(prefix)/share/doc/ltrace +install-pdf-am: -CC = @CC@ -CFLAGS = -Wall @CFLAGS@ -CPPFLAGS = -iquote $(TOPDIR) -iquote $(TOPDIR)/sysdeps/$(OS) -DSYSCONFDIR=\"$(sysconfdir)\" @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ +install-ps: install-ps-recursive -INSTALL = @INSTALL@ -INSTALL_FILE = $(INSTALL) -p -m 644 -INSTALL_PROGRAM = $(INSTALL) -p -m 755 -INSTALL_SCRIPT = $(INSTALL) -p -m 755 -INSTALL_DIR = $(INSTALL) -p -d -m 755 +install-ps-am: -OBJ = libltrace.o options.o elf.o output.o read_config_file.o \ - execute_program.o handle_event.o display_args.o \ - breakpoints.o proc.o demangle.o dict.o debug.o summary.o +installcheck-am: -VERSION = @PACKAGE_VERSION@ +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local -all: ltrace +mostlyclean: mostlyclean-recursive -ltrace: main.o libltrace.a - $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool -libltrace.a: sysdeps/sysdep.o $(OBJ) - $(AR) rcv $@ $^ +pdf: pdf-recursive -sysdeps/sysdep.o: dummy - $(MAKE) -C sysdeps/$(OS) +pdf-am: -clean-deja: - $(RM) testrun.log testrun.sum - cd testsuite; make clean +ps: ps-recursive -clean: clean-deja - $(MAKE) -C sysdeps/$(OS) clean - rm -f ltrace main.o libltrace.a $(OBJ) - rm -f *~ *.bak a.out core +ps-am: -distclean: clean - rm -f config.h Makefile +uninstall-am: uninstall-binPROGRAMS uninstall-dist_docDATA \ + uninstall-dist_sysconfDATA uninstall-man -realclean: distclean +uninstall-man: uninstall-man1 uninstall-man5 -install: ltrace - $(INSTALL_DIR) $(DESTDIR)$(bindir) $(DESTDIR)$(docdir) $(DESTDIR)$(mandir)/man1 - $(INSTALL_DIR) $(DESTDIR)$(sysconfdir) - $(INSTALL_PROGRAM) ltrace $(DESTDIR)$(bindir) - $(INSTALL_FILE) etc/ltrace.conf $(DESTDIR)$(sysconfdir) - $(INSTALL_FILE) COPYING README TODO BUGS ChangeLog $(DESTDIR)$(docdir) - $(INSTALL_FILE) ltrace.1 $(DESTDIR)$(mandir)/man1 +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive -check: - cd testsuite;cat /proc/version;uptime;free -m;$(MAKE) check +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-noinstLTLIBRARIES ctags \ + ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-lzma \ + dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-dist_docDATA install-dist_sysconfDATA \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-man1 install-man5 install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-local mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-dist_docDATA \ + uninstall-dist_sysconfDATA uninstall-man uninstall-man1 \ + uninstall-man5 -dummy: -.PHONY: all clean distclean dist install dummy +maintainer-clean-local: + -chmod -R a+rw $(distdir) + -rm -fr $(distdir) -.EXPORT_ALL_VARIABLES: +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: @@ -0,0 +1,303 @@ +-*-org-*- +* Version 0.7.2 [2012-12-07 Fri] +** Bugfixes +*** (Again) detect VDSO entry in r_debug linkmap with non-empty name + This bug caused messages like: + | Couldn't determine base address of linux-vdso32.so.1 + | Couldn't load ELF object linux-vdso32.so.1: No such file or directory +*** Fix building with libunwind 1.1 +*** Fix prototype lookup for -x symbols from shared libraries + Ltrace was unable to find prototypes of static symbols in shared + libraries. It changed the symbol name internally to the form + name@libfoo.so. Thus mangled, symbols were not found in config + files. + +* Version 0.7.1 [2012-11-29 Thu] +** Bugfixes +*** ltrace.conf.5 is now installed to man5 as it should be +*** [PowerPC] A header file necessary for building is now shipped +*** [MIPS] Work around duplicate symbol request bug + This fixes the ltrace abort: + | ./ltrace: proc.c: 755: breakpoint_for_symbol: Assertion `bp->libsym == ((void *)0)' failed. + +*** Detect VDSO entry in r_debug linkmap with non-empty name + This bug caused messages like: + | Couldn't determine base address of linux-vdso32.so.1 + | Couldn't load ELF object linux-vdso32.so.1: No such file or directory + +*** Temporary files are wiped properly after the test suite has been run +*** Parsing typedefs with common prefix now works as it should + More exactly, if there were typedefs X and XY (in this order), and + a reference was made to X, ltrace would match XY instead. + +** Cofiguration Files +*** The following prototypes in ltrace.conf were added or updated + __ctype_get_mb_cur_max, __endmntent, __getmntent_r, __setmntent, + a64l, abort, abs, addmntent, getmntent_r, hasmntopt, inet_addr, + inet_aton, inet_lnaof, inet_makeaddr, inet_netof, inet_network, + inet_ntoa, kill, l64a, labs, memcpy, memmove, setlocale, + sigaction, sigaddset, sigandset, sigdelset, sigemptyset, + sigfillset, sigisemptyset, sigismember, signal, sigorset, + sigpending, sigprocmask, sigsuspend. + +*** Duplicate typedefs are now guarded against +*** It's now possible to define recursive structures + Please read ltrace.conf(5) man page, chapter "recursive + structures", to learn about this new feature. + +*** New lens "bitvec" is available + This allows displaying various data types as bit vectors. Please + read ltrace.conf(5) to learn more. + +*** Octal lens renamed to "oct" + For reasons of consistency with "hex". "octal" is still valid and + will be for forseeable future. + +*** The hex lens can now format floating point arguments + +* Version 0.7.0 [2012-11-09 Fri] +** Tracing +*** Full support for tracing multi-threaded processes + + Ltrace now understands thread groups, and it stops all threads + before manipulating breakpoints. The downside is that performance + of multi-threaded processes is rather bad, because handling any + event implies stopping the whole job. The upside is that + individual threads don't get random SIGILL's and SIGSEGV's and + events are not missed. + +*** Support for tracing inter-library calls + + -e and -x were extended to allow library selectors. See the man + page for details. + +*** Better support for parameter passing ("fetch backend") + + This version brings more complete support for parameter passing, + including passing structures in registers, passing double on i386, + and other edge cases that were not handled correctly before. The + following architectures now have implementation of fetch backend: + i386, x86_64, ppc, ppc64, ia64, s390, s390x, m68k. + +*** Awareness of deny_ptrace SELinux boolean + + The deny_ptrace boolean denies all processes from being able to + use ptrace to manipulate other processes. Ltrace now understands + that this boolean exists, and recommends turning it off, if it is + on and ltrace fails to attach to a process. + +*** Limited support for tracing returns from tail call functions +*** -e, -x and -l selectors now allow using globs and regular expressions + + See the man page for details of the selector syntax. This changes + the way -x and -l behave with respect to tracing libraries opened + by dlopen: + + - In 0.6.0, only those -x symbols that were unmatched in main + binary were used to search through symbol table of libraries + opened with dlopen. In 0.7.0, -x and -e are applied uniformly + to each mapped binary: the main binary, dependent DSO's, and any + dlopened libraries. + + - In 0.6.0, -l argument was a filename to open and inspect. In + 0.7.0, -l is a glob expression matched against each mapped + binary. + +*** -g command line option dropped + + This option was introduced in 0.6.0 with the meaning identical to + -L, which should be used instead. + +*** Test suite can now be run under valgrind + + Use --enable-valgrind to turn this on. + +*** [ppc] Support both BSS and secure PLTs for 32-bit processes +*** [mips] Implement software singlestepping +*** [mips] Add support for CPIC main programs +*** Support tracing PIE binaries + +** Configuration Files + +*** New abstraction: parameter pack + + Parameter packs describe zero or more of actual arguments, whose + type can be determined in runtime. The only parameter pack + currently implemented is "format" for decoding printf-style format + strings. + + In future, it should be relatively straightforward to add more + parameter packs for functions like execl, and others. + +*** New expression: zero + + When used in array length expressions, it means "this array ends + at the first element with zero value". C strings are essentially + array(char, zero)*. + +*** Lenses: change the way that underlying type is rendered + + Lenses are used similarly to parametrized types, e.g.: + | void func(lens(int)); | + +**** octal + + "octal", which used to be a separate type, is now lens, which can + be used to render any underlying type in base 8. Plain "octal" + is still valid and means the same thing as "octal(int)". + +**** hex, hide, bool + + Similarly, "hex" lens was introduced to format as base 16. + "hide" was introduced to conceal given argument. "bool" lens was + added to format objects as either true, or false. + +**** enum + + "enum" became lens as well. Because enum already uses + parentheses to denote the list of enumeration values, the + underlying type is selected by square brackets: + + | void func(enum[short](RED,GREEN,BLUE)); | + +**** string + + "string" was also turned to lens. The argument can be either a + char*, or pointer to array of char, or array of char. The latter + is useful in cases like the following: + + | void func_struct_2(struct(string(array(char, 6)))); | + +*** Misspelling of "int" as "itn" temporarily accepted, but deprecated + + Pre-0.7 ltrace shipped a buggy version of ltrace.conf that + contained the following prototype: + + | itn acl_valid(addr); | + + To support extant versions of ltrace.conf, that use is now + considered valid, and "itn" is a synonym of "int". It is however + deprecated, and will produce a warning in future. + +*** Using void as top-level function argument now deprecated + + Functions that take no arguments shouldn't pretend to take one + parameter of void type. For example the following: + + | int fork(void); | + + ... should be declared like this: + + | int fork(); | + + To support extant versions of ltrace.conf, that use is now + considered valid. It is however deprecated, and will produce a + warning in future. + +*** Using void to hide one argument is now obsolete + + Ltrace needs to know the exact underlying type to decide what the + calling convention is. The use of void to mean "hide this + argument", such as the following example, is therefore obsolete: + + | void func(void, array(int, arg1)); | + + Instead, rewrite the prototype depending on the exact underlying + type: + + | void func(hide(int), array(int, arg1)); | + | void func(hide(long), array(int, arg1)); | + + To support extant versions of ltrace.conf, this use is still + accepted, and "void" is taken to mean "hide(int)". It is however + obsolete, produces a warning, and will be removed in future. + +** Documentation + +*** New manual page ltrace.conf(5) +*** README, INSTALL brought up to date +*** New file CREDITS with a list of contributors + +** Bugfixes + +*** Fix detaching from a process + + Earlier, a process that ltrace detached from would sometimes die + of SIGSEGV, SIGTRAP, or SIGILL. These were caused by ltrace + detaching from the process just after that process hit a + breakpoint. Program counter would thus be left pointing + mid-instruction, or signals would be left pending. + +*** Argument to -n is now checked for validity +*** Fix tracing across exec in a stripped binary +*** [x86] ORIG_RAX/ORIG_EAX may not contain original syscall number + + In cases where the system call shouldn't be restarted, these are + set to -1. In that case assume that the return is from the + topmost syscall. This gets rid of some "unexpected breakpoint" + messages on x86_64 and i386. + +*** [ppc] Fix races in tracing -e events in 64-bit processes + + On ppc, the contents of PLT table change after the first call. + Ltrace used to handle this by reinserting the (now overwritten) + breakpoint after the function returns. This introduced a window + where calls to the same function from the same binary (either a + recursive calls, or calls from another thread) weren't traced. + This is fixed as of 0.7.0. + + As a side effect, events requested via -e now only hit when a PLT + call is made, which is consistent with other architectures. + +*** [ppc] Allow stepping over lwarx instruction + +** Known bugs + +*** [arm] Tracing is not supported at all on ARM + + ltrace might work on older kernels, but no attempt was made to + fully support it. Newer kernels don't support PTRACE_SINGLESTEP, + which ltrace depends on. Before singlestepping is implemented in + software, ARM is considered unsupported. + +* Version 0.6.0 [2011-01-06 Thu] + +** General Features + +*** Use autotools for building +*** New option -b: disables output of signals received by the tracee +*** New option -w: print stack trace of events + + Pass --with-libunwind to configure to enable the feature. This + requires libunwind. + +*** Support tracing of symbols from libraries opened with dlopen + + These symbols are selected by -x. + +** Architecture-specific Changes + +*** Various fixes for MIPS and PowerPC +*** Support for ARM Thumb mode +*** Implement fetching of 5th and further function arguments on s390 +*** Support fork/exec syscalls on 31-bit s390 +*** Support for float and double arguments on x86_64 +*** Fixes for return arguments (after '+') in nested calls on x86_64 + +* License +------------------------------------------------------------------------------- +Copyright (C) 2012 Petr Machata <pmachata@redhat.com> +This file is part of ltrace. + +ltrace is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +ltrace is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -1,92 +1,101 @@ - ltrace +This directory contains sources of ltrace. See the file configure.ac +to see what version this is. - A Dynamic Library Tracer +Ltrace is a debugging program which runs a specified command until the +command exits. While the command is executing, ltrace intercepts and +records both the dynamic library calls called by the executed process +and the signals received by the executed process. Ltrace can also +intercept and print system calls executed by the process. - Copyright 1997-2009 Juan Cespedes <cespedes@debian.org> +For general building and installation instructions, see the file INSTALL. +For list of authors and contributors, see the file CREDITS. -Contents --------- - 0. Authors - 1. Introduction - 2. Where can I find it - 3. How does it work - 4. Where does it work - 5. Bugs - 6. License +ltrace is free software. See the file COPYING for license. +Some documentation on ltrace usage is given in the manual page, which +is in the file ltrace.1. -0. Authors ----------- -ltrace has been developed mainly by Juan Cespedes <cespedes@debian.org>, -but he has received many contributions from other people. The following -people have contributed significantly to this project: +Supported Targets +----------------- -* César Sánchez <cesar.sanchez@imdea.org> -* Santiago Romero <santiago.romero@imdea.org> -* Pat Beirne <pbeirne@home.com> (ARM port) -* Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> (m68k port) -* Morten Eriksen <mortene@sim.no> (misc fixes) -* Silvio Cesare <silvio@big.net.au> (ELF hacking) -* Timothy Fesig <slate@us.ibm.com> (S390 port) -* Anton Blanchard <anton@samba.org> (Powerpc port) -* Jakub Jelinek <jakub@redhat.com> (SPARC port, support for libelf, many fixes) -* Jakub Bogusz <qboosh@pld-linux.org> (alpha port) -* SuSE (amd64 port) -* Ian Wienand <ianw@gelato.unsw.edu.au> (IA64 port) -* Eric Vaitl <evaitl@cisco.com> (mipsel port) -* Petr Machata <pmachata@redhat.com> (misc fixes) +The following targets are currently (at least somewhat) supported. +Some of them may be more or less broken in reality, it is not feasible +to test each release comprehensively on each target. -1. Introduction ---------------- + i[4567]86-*-linux-gnu + ia64-*-linux-gnu + m68k-*-linux-gnu + mips-*-linux-gnu + powerpc-*-linux-gnu + powerpc64-*-linux-gnu + s390-*-linux-gnu + s390x-*-linux-gnu + x86_64-*-linux-gnu -ltrace is a debugging tool, similar to strace, but it traces library -calls instead of system calls. +The following systems were supported at some point in past, but +current status is unknown: -2. Where can I find it ----------------------- + sparc*-*-linux-gnu + sparc64*-*-linux-gnu + alpha*-*-linux-gnu -http://www.ltrace.org +Support of the following systems is known to be broken and requires +fixing: -3. How does it work -------------------- + arm-*-linux-gnueabi -Using software breakpoints, just like gdb. -4. Where does it work ---------------------- +Bug Reports +----------- -It works with ELF based Linux systems running on i386, m68k, S/390, -ARM, PowerPC, PowerPC64, IA64, AMD64, SPARC and Alpha processors. +You can send bug reports to <ltrace-devel@lists.alioth.debian.org>. +User requests can also be directed to that address. -It is part of at least Debian GNU/Linux, RedHat, SuSE, Mandrake... +If the ltrace package that you are using came with your operating +system, please be sure to reproduce the problem in unmodified upstream +version of ltrace before reporting a bug. -5. Bugs -------- -Too many to list here :). If you like to submit a bug report, or a -feature request, either do that against the Debian `ltrace' package, -or mail ltrace-devel@lists.alioth.debian.org. +Development +----------- -This file is very incomplete and out-of-date. +ltrace development is hosted by Alioth.Debian.org: -6. License ----------- + https://alioth.debian.org/projects/ltrace/ - Copyright (C) 1997-2009 Juan Cespedes <cespedes@debian.org> +Release tarballs can be downloaded here: - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + https://alioth.debian.org/frs/?group_id=30892 - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +Anonymous GIT access is available via: - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + git://git.debian.org/git/collab-maint/ltrace.git +If you have anything to contribute, please send an e-mail to +<ltrace-devel@lists.alioth.debian.org>, and attach your patches +formatted with git format-patch. This makes them easy to apply after +review, and such patches also preserve authorship. + +If you intend to work on a feature (essentially anything beyond a +quick one-liner), it is advisable to send an e-mail beforehand. + + +------------------------------------------------------------------------------- +Copyright (C) 2012 Petr Machata <pmachata@redhat.com> +Copyright (C) 1997-2009 Juan Cespedes <cespedes@debian.org> +This file is part of ltrace. + +ltrace is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +ltrace is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -1,36 +1,138 @@ -* BFD: - + New executable formats - + Read list of libraries needed - + Read list of undefined symbols in executables - + Read list of exported symbols in libraries - + Read debugging info from executables/libraries -* Automatically update list of syscalls? -* Improve documentation -* Improve -e/-x options (regexp?) -* Improve -l option -* Improve C++ name demangling -* Display different argument types -* Update /etc/ltrace.conf -* More architectures, cleaner way to port -* More operating systems (solaris?) -* Option -I (inter-library calls) -* Modify ARGTYPE_STRING[0-5] types so that they don't stop displaying chars when '\0' is seen -* Get rid of EVENT_ARCH_SYSCALL and EVENT_ARCH_SYSRET -* Cleaner way to use breakpoints: - + BP is placed in the PLT - + When control hits there: - - write down return address - - change return address with another one (handled by ltrace) - - get arguments... - - change the process' PC to be in the correct place, - without removing breakpoint - + When control hits one of our return addresses: - - get return value... - - change PC to the right place -* To be able to work with processes sharing memory, we must: - + ptrace() every single thread - + place breakpoints only in places where the process control can continue - without having to remove it -* List source dependencies in Makefile -* Create different ltrace processes to trace different children -* After a clone(), syscalls may be seen as sysrets in s390 (see trace.c:syscall_p()) +-*-org-*- +* TODO +** Automatic prototype discovery: +*** Use debuginfo if available + Alternatively, use debuginfo to generate configure file. +*** Demangled identifiers contain partial prototypes themselves +** Automatically update list of syscalls? +** Update /etc/ltrace.conf + In particular, we could use a config directory, where packages + would install their ltrace config scripts. The config file could + be named after SONAME, and automatically read when corresponding + library is mapped. +** More operating systems (solaris?) +** Get rid of EVENT_ARCH_SYSCALL and EVENT_ARCH_SYSRET +** Implement displaced tracing + A technique used in GDB (and in uprobes, I believe), whereby the + instruction under breakpoint is moved somewhere else, and followed + by a jump back to original place. When the breakpoint hits, the IP + is moved to the displaced instruction, and the process is + continued. We avoid all the fuss with singlestepping and + reenablement. +** Create different ltrace processes to trace different children +** Config file syntax +*** named arguments + This would be useful for replacing the arg1, emt2 etc. + +*** parameter pack improvements + The above format tweaks require that packs that expand to no types + at all be supported. If this works, then it should be relatively + painless to implement conditionals: + + | void ptrace(REQ=enum(PTRACE_TRACEME=0,...), + | if[REQ==0](pack(),pack(pid_t, void*, void *))) + + This is of course dangerously close to a programming language, and + I think ltrace should be careful to stay as simple as possible. + (We can hook into Lua, or TinyScheme, or some such if we want more + general scripting capabilities. Implementing something ad-hoc is + undesirable.) But the above can be nicely expressed by pattern + matching: + + | void ptrace(REQ=enum[int](...)): + | [REQ==0] => () + | [REQ==1 or REQ==2] => (pid_t, void*) + | [true] => (pid_t, void*, void*); + + Or: + + | int open(string, FLAGS=flags[int](O_RDONLY=00,...,O_CREAT=0100,...)): + | [(FLAGS & 0100) != 0] => (flags[int](S_IRWXU,...)) + + This would still require pretty complete expression evaluation. + _Including_ pointer dereferences and such. And e.g. in accept, we + need subtraction: + + | int accept(int, +struct(short, +array(hex(char), X-2))*, (X=uint)*); + + Perhaps we should hook to something after all. + +*** errno tracking + Some calls result in setting errno. Somehow mark those, and on + failure, show errno. + +*** second conversions? + This definitely calls for some general scripting. The goal is to + have seconds in adjtimex calls show as e.g. 10s, 1m15s or some + such. + +*** format should take arguments like string does + Format should take value argument describing the value that should + be analyzed. The following overwriting rules would then apply: + + | format | format(array(char, zero)*) | + | format(LENS) | X=LENS, format[X] | + + The latter expanded form would be canonical. + + This depends on named arguments and parameter pack improvements + (we need to be able to construct parameter packs that expand to + nothing). + +*** More fine-tuned control of right arguments + Combination of named arguments and some extensions could take care + of that: + + | void func(X=hide(int*), long*, +pack(X)); | + + This would show long* as input argument (i.e. the function could + mangle it), and later show the pre-fetched X. The "pack" syntax is + utterly undeveloped as of now. The general idea is to produce + arguments that expand to some mix of types and values. But maybe + all we need is something like + + | void func(out int*, long*); | + + ltrace would know that out/inout/in arguments are given in the + right order, but left pass should display in and inout arguments + only, and right pass then out and inout. + would be + backward-compatible syntactic sugar, expanded like so: + + | void func(int*, int*, +long*, long*); | + | void func(in int*, in int*, out long*, out long*); | + + But sometimes we may want to see a different type on the way in and + on the way out. E.g. in asprintf, what's interesting on the way in + is the address, but on the way out we want to see buffer contents. + Does something like the following make sense? + + | void func(X=void*, long*, out string(X)); | + +** Support for functions that never return + This would be useful for __cxa_throw, presumably also for longjmp + (do we handle that at all?) and perhaps a handful of others. + +** Support flag fields + enum-like syntax, except disjunction of several values is assumed. +** Support long long + We currently can't define time_t on 32bit machines. That mean we + can't describe a range of time-related functions. + +** Support signed char, unsigned char, char + Also, don't format it as characted by default, string lens can do + it. Perhaps introduce byte and ubyte and leave 'char' as alias of + one of those with string lens applied by default. + +** Support fixed-width types + Really we should keep everything as {u,}int{8,16,32,64} internally, + and have long, short and others be translated to one of those + according to architecture rules. Maybe this could be achieved by a + per-arch config file with typedefs such as: + + | typedef ulong = uint8_t | + +** Some more functions in vect might be made to take const* + Or even marked __attribute__((pure)). + +* BUGS +** After a clone(), syscalls may be seen as sysrets in s390 (see trace.c:syscall_p()) diff --git a/VERSION b/VERSION deleted file mode 100644 index be14282..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.5.3 @@ -1,833 +1,996 @@ -dnl aclocal.m4t generated automatically by aclocal 1.4-p6 - -dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without -dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A -dnl PARTICULAR PURPOSE. - -# lib-prefix.m4 serial 3 (gettext-0.13) -dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break fi fi - fi -]) + done -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi ]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) -# lib-link.m4 serial 4 (gettext-0.12) -dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and -dnl augments the CPPFLAGS variable. -AC_DEFUN([AC_LIB_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - ac_cv_lib[]Name[]_libs="$LIB[]NAME" - ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" - ac_cv_lib[]Name[]_cppflags="$INC[]NAME" - ]) - LIB[]NAME="$ac_cv_lib[]Name[]_libs" - LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" - INC[]NAME="$ac_cv_lib[]Name[]_cppflags" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the - dnl results of this search when this library appears as a dependency. - HAVE_LIB[]NAME=yes - undefine([Name]) - undefine([NAME]) -]) -dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) -dnl searches for libname and the libraries corresponding to explicit and -dnl implicit dependencies, together with the specified include files and -dnl the ability to compile and link the specified testcode. If found, it -dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and -dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. -AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - - dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - - dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, - dnl because if the user has installed lib[]Name and not disabled its use - dnl via --without-lib[]Name-prefix, he wants to use it. - ac_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - - AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIB[]NAME" - AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) - LIBS="$ac_save_LIBS" - ]) - if test "$ac_cv_lib[]Name" = yes; then - HAVE_LIB[]NAME=yes - AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) - AC_MSG_CHECKING([how to link with lib[]$1]) - AC_MSG_RESULT([$LIB[]NAME]) - else - HAVE_LIB[]NAME=no - dnl If $LIB[]NAME didn't lead to a usable library, we don't need - dnl $INC[]NAME either. - CPPFLAGS="$ac_save_CPPFLAGS" - LIB[]NAME= - LTLIB[]NAME= - fi - AC_SUBST([HAVE_LIB]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - undefine([Name]) - undefine([NAME]) +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) -dnl Determine the platform dependent parameters needed to use rpath: -dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, -dnl hardcode_direct, hardcode_minus_L. -AC_DEFUN([AC_LIB_RPATH], -[ - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - libext="$acl_cv_libext" - shlibext="$acl_cv_shlibext" - hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - hardcode_direct="$acl_cv_hardcode_direct" - hardcode_minus_L="$acl_cv_hardcode_minus_L" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE(rpath, - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib$1-prefix], -[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib - --without-lib$1-prefix don't search for lib$1 in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi + continue fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" done done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi -]) +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) -# lib-ld.m4 serial 3 (gettext-0.13) -dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl Subroutines of libtool.m4, -dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision -dnl with libtool.m4. - -dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - acl_cv_prog_gnu_ld=yes ;; -*) - acl_cv_prog_gnu_ld=no ;; -esac]) -with_gnu_ld=$acl_cv_prog_gnu_ld +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) -dnl From libtool-1.4. Sets the variable LD. -AC_DEFUN([AC_LIB_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' else - PATH_SEPARATOR=: + CYGPATH_W=echo fi - rm -f conf$$.sh fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; + install_sh="\${SHELL} $am_aux_dir/install-sh" esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) fi -AC_CACHE_VAL(acl_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break ;; - *) - test "$with_gnu_ld" != yes && break ;; - esac - fi - done - IFS="$ac_save_ifs" +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " else - AC_MSG_RESULT(no) + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_LIB_PROG_LD_GNU ]) +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([config/m4/libtool.m4]) +m4_include([config/m4/ltoptions.m4]) +m4_include([config/m4/ltsugar.m4]) +m4_include([config/m4/ltversion.m4]) +m4_include([config/m4/lt~obsolete.m4]) diff --git a/backend.h b/backend.h new file mode 100644 index 0000000..89c05c3 --- /dev/null +++ b/backend.h @@ -0,0 +1,343 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef BACKEND_H +#define BACKEND_H + +#include "forward.h" +#include "sysdep.h" + +#include <gelf.h> + +enum process_status { + ps_invalid, /* Failure. */ + ps_stop, /* Job-control stop. */ + ps_tracing_stop, + ps_sleeping, + ps_zombie, + ps_other, /* Necessary other states can be added as needed. */ +}; + +/* + * This file contains documentation of back end interface. Some of + * these may be implemented on an OS level (i.e. they are the same + * e.g. on all Linux architectures), some may differ per architecture + * on the same OS (e.g. a way to insert a breakpoint into the process + * image is a likely candidate). + */ + +/* Convert a PID to a path to the corresponding binary. */ +char *pid2name(pid_t pid); + +/* Given a PID, find a leader of thread group. */ +pid_t process_leader(pid_t pid); + +/* Given a PID of leader thread, fill in PIDs of all the tasks. The + * function will initialize the pointer *RET_TASKS to a + * newly-allocated array, and will store number of elements in that + * array to *RET_N. You have to free that buffer when you don't need + * it anymore. */ +int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n); + +/* Answer whether the process PID is stopped. Returns 0 when not + * stopped, 1 when stopped, or -1 when there was an error. */ +int process_stopped(pid_t pid); + +/* Answer a status of the task PID. See enum process_status. */ +enum process_status process_status(pid_t pid); + +/* Wait for PID to be ready for tracing. */ +int wait_for_proc(pid_t pid); + +/* Send a signal SIG to the task PID. */ +int task_kill(pid_t pid, int sig); + +/* Called after PID is attached, but before it is continued. */ +void trace_set_options(struct Process *proc); + +/* Called after ltrace forks. Should attach the newly created child, + * in whose context this function is called. */ +void trace_me(void); + +/* Called when ltrace needs to attach to PID, such as when it attaches + * to a running process, whose PID is given on the command line. */ +int trace_pid(pid_t pid); + +/* Stop tracing PID. */ +void untrace_pid(pid_t pid); + +/* The back end may need to store arbitrary data to a process. This + * is a place where it can initialize PROC->arch_dep. XXX this should + * be dropped in favor of arhc_process_init on pmachata/libs. */ +void get_arch_dep(struct Process *proc); + +/* Return current instruction pointer of PROC. + * + * XXX note that the IP must fit into an arch pointer. This prevents + * us to use 32-bit ltrace to trace 64-bit process, even on arches + * that would otherwise support this. Above we have a definition of + * arch_addr_t. This should be converted to an integral type and + * used for target addresses throughout. */ +void *get_instruction_pointer(struct Process *proc); + +/* Set instruction pointer of PROC to ADDR. XXX see above. */ +void set_instruction_pointer(struct Process *proc, void *addr); + +/* Return current stack pointer of PROC. XXX see above. */ +void *get_stack_pointer(struct Process *proc); + +/* Find and return caller address, i.e. the address where the current + * function returns. */ +void *get_return_addr(struct Process *proc, void *stack_pointer); + +/* Adjust PROC so that when the current function returns, it returns + * to ADDR. */ +void set_return_addr(struct Process *proc, void *addr); + +/* Enable breakpoint SBP in process PROC. */ +void enable_breakpoint(struct Process *proc, struct breakpoint *sbp); + +/* Disable breakpoint SBP in process PROC. */ +void disable_breakpoint(struct Process *proc, struct breakpoint *sbp); + +/* Determine whether the event that we have just seen (and that is + * recorded in STATUS) was a syscall. If it was, return 1. If it was + * a return from syscall, return 2. In both cases, set *SYSNUM to the + * number of said syscall. If it wasn't a syscall, return 0. If + * there was an error, return -1. */ +int syscall_p(struct Process *proc, int status, int *sysnum); + +/* Continue execution of the process with given PID. */ +void continue_process(pid_t pid); + +/* Called after we received a signal SIGNUM. Should do whatever + * book-keeping is necessary and continue the process if + * necessary. */ +void continue_after_signal(pid_t pid, int signum); + +/* Called after we received a system call SYSNUM. RET_P is 0 if this + * is system call, otherwise it's return from a system call. The + * callback should do whatever book-keeping is necessary and continue + * the process if necessary. */ +void continue_after_syscall(struct Process *proc, int sysnum, int ret_p); + +/* Called after we hit a breakpoint SBP. Should do whatever + * book-keeping is necessary and then continue the process. */ +void continue_after_breakpoint(struct Process *proc, struct breakpoint *sbp); + +/* Called after we received a vfork. Should do whatever book-keeping + * is necessary and continue the process if necessary. N.B. right + * now, with Linux/GNU the only back end, this is not necessary. I + * imagine other systems may be different. */ +void continue_after_vfork(struct Process *proc); + +/* Called when trace_me or primary trace_pid fail. This may plug in + * any platform-specific knowledge of why it could be so. */ +void trace_fail_warning(pid_t pid); + +/* A pair of functions called to initiate a detachment request when + * ltrace is about to exit. Their job is to undo any effects that + * tracing had and eventually detach process, perhaps by way of + * installing a process handler. + * + * OS_LTRACE_EXITING_SIGHANDLER is called from a signal handler + * context right after the signal was captured. It returns 1 if the + * request was handled or 0 if it wasn't. + * + * If the call to OS_LTRACE_EXITING_SIGHANDLER didn't handle the + * request, OS_LTRACE_EXITING is called when the next event is + * generated. Therefore it's called in "safe" context, without + * re-entrancy concerns, but it's only called after an even is + * generated. */ +int os_ltrace_exiting_sighandler(void); +void os_ltrace_exiting(void); + +/* Should copy COUNT bytes from address ADDR of process PROC to local + * buffer BUF. */ +size_t umovebytes (struct Process *proc, void *addr, void *buf, size_t count); + +/* Find out an address of symbol SYM in process PROC, and return. + * Returning NULL delays breakpoint insertion and enables heaps of + * arch-specific black magic that we should clean up some day. + * + * XXX the same points as for get_instruction_pointer apply. */ +void *sym2addr(struct Process *proc, struct library_symbol *sym); + +/* Obtain address of PLT entry corresponding to relocation RELA in + * file LTE. This is NDX-th PLT entry in the file. + * + * XXX should this return arch_addr_t? */ +GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela); + +/* Called at some point after we have attached to PROC. This callback + * should insert an introspection breakpoint for handling dynamic + * linker library loads. */ +int linkmap_init(struct Process *proc, arch_addr_t dyn_addr); + +/* This should produce and return the next event of one of the traced + * processes. The returned pointer will not be freed by the core and + * should be either statically allocated, or the management should be + * done some other way. */ +struct Event *next_event(void); + +/* Called when process PROC was removed. */ +void process_removed(struct Process *proc); + +/* This should extract entry point address and interpreter (dynamic + * linker) bias if possible. Returns 0 if there were no errors, -1 + * otherwise. Sets *ENTRYP and *INTERP_BIASP to non-zero values if + * the corresponding value is known, or zero otherwise; this is not + * done for pointers that are NULL. */ +int process_get_entry(struct Process *proc, + arch_addr_t *entryp, + arch_addr_t *interp_biasp); + + +/* Optional callbacks + * + * Some callbacks are only available if backend (arch.h) has a certain + * define. If such a define is not present, default implementation + * (most often doing nothing at all) us used instead. This is used + * for gradual extensions of ltrace, so that backends that are not + * fully up to date, or that don't need certain functionality, keep + * working, while other backends take advantage of the optional + * features. */ + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_LTELF_DATA. Those are used to init and destroy + * LTE->arch. arch_elf_init returns 0 on success or a negative value + * on failure. */ +int arch_elf_init(struct ltelf *lte, struct library *lib); +void arch_elf_destroy(struct ltelf *lte); + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_BREAKPOINT_DATA. Those are used to init, + * destroy, and clone SBP->arch. arch_breakpoint_init and + * arch_breakpoint_clone return 0 on success or a negative value on + * failure. */ +int arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp); +void arch_breakpoint_destroy(struct breakpoint *sbp); +int arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp); + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_LIBRARY_DATA. Those are used to init, destroy + * and clone LIB->arch. */ +void arch_library_init(struct library *lib); +void arch_library_destroy(struct library *lib); +void arch_library_clone(struct library *retp, struct library *lib); + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_LIBRARY_SYMBOL_DATA. Those are used to init, + * destroy and clone LIBSYM->arch. arch_library_symbol_init and + * arch_library_symbol_clone return 0 on success or a negative value + * on failure. */ +int arch_library_symbol_init(struct library_symbol *libsym); +void arch_library_symbol_destroy(struct library_symbol *libsym); +int arch_library_symbol_clone(struct library_symbol *retp, + struct library_symbol *libsym); + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_PROCESS_DATA. Those are used to init, destroy + * and clone PROC->arch. arch_process_exec is called to update + * PROC->arch in case that PROC underwent an exec. See notes at + * process_init, process_destroy, process_clone and process_exec in + * proc.h. */ +int arch_process_init(struct Process *proc); +void arch_process_destroy(struct Process *proc); +int arch_process_clone(struct Process *retp, struct Process *proc); +int arch_process_exec(struct Process *proc); + +/* The following callbacks have to be implemented in OS backend if + * os.h defines OS_HAVE_PROCESS_DATA. The protocol is same as for, + * respectively, arch_process_init, arch_process_destroy, + * arch_process_clone and arch_process_exec. */ +int os_process_init(struct Process *proc); +void os_process_destroy(struct Process *proc); +int os_process_clone(struct Process *retp, struct Process *proc); +int os_process_exec(struct Process *proc); + +/* The following callback has to be implemented in backend if arch.h + * defines ARCH_HAVE_GET_SYM_INFO. + * + * This is called for every PLT relocation R in ELF file LTE, that + * ltrace is about to add to it's internal representation of the + * program under trace. + * The corresponding PLT entry is for SYM_INDEX-th relocation in the file. + * + * The callback is responsible for initializing RELA and SYM. + * + * Return 0 if OK. + * Return a negative value if this symbol (SYM_INDEX) should be ignored. */ +int arch_get_sym_info(struct ltelf *lte, const char *filename, + size_t sym_index, GElf_Rela *rela, GElf_Sym *sym); + +enum plt_status { + plt_fail, + plt_ok, + plt_default, +}; + +/* The following callback has to be implemented in backend if arch.h + * defines ARCH_HAVE_ADD_PLT_ENTRY. + * + * This is called for every PLT relocation R in ELF file LTE, that + * ltrace is about to add to a library constructed in process PROC. + * The corresponding PLT entry is for symbol called NAME, and it's + * I-th relocation in the file. + * + * If this function returns plt_default, PLT address is obtained by + * calling arch_plt_sym_val, and symbol is allocated. If plt_ok or + * plt_default are returned, the chain of symbols passed back in RET + * is added to library under construction. */ +enum plt_status arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *name, GElf_Rela *rela, + size_t i, struct library_symbol **ret); + +/* This callback needs to be implemented if arch.h defines + * ARCH_HAVE_DYNLINK_DONE. It is called after the dynamic linker is + * done with the process startup. */ +void arch_dynlink_done(struct Process *proc); + +/* This callback needs to be implemented if arch.h defines + * ARCH_HAVE_SYMBOL_RET. It is called after a traced call returns. */ +void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym); + + +/* This callback needs to be implemented if arch.h defines + * ARCH_HAVE_FIND_DL_DEBUG. + * It is called by generic code to find the address of the dynamic + * linkers debug structure. + * DYN_ADDR holds the address of the dynamic section. + * If the debug area is found, return 0 and fill in the address in *RET. + * If the debug area is not found, return a negative value. */ +int arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr, + arch_addr_t *ret); + +/* If arch.h defines ARCH_HAVE_FETCH_ARG, the following callbacks have + * to be implemented: arch_fetch_arg_init, arch_fetch_arg_clone, + * arch_fetch_arg_done, arch_fetch_arg_next and arch_fetch_retval. + * See fetch.h for details. */ + +/* If arch.h defines both ARCH_HAVE_FETCH_ARG and + * ARCH_HAVE_FETCH_PACK, the following callbacks have to be + * implemented: arch_fetch_param_pack_start, + * arch_fetch_param_pack_end. See fetch.h for details. */ + +#endif /* BACKEND_H */ diff --git a/breakpoint.h b/breakpoint.h new file mode 100644 index 0000000..7cd914e --- /dev/null +++ b/breakpoint.h @@ -0,0 +1,138 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef BREAKPOINT_H +#define BREAKPOINT_H + +/* XXX This is currently a very weak abstraction. We would like to + * much expand this to allow things like breakpoints on SDT probes and + * such. + * + * In particular, we would like to add a tracepoint abstraction. + * Tracepoint is a traceable feature--e.g. an exact address, a DWARF + * symbol, an ELF symbol, a PLT entry, or an SDT probe. Tracepoints + * are named and the user can configure which of them he wants to + * enable. Realized tracepoints enable breakpoints, which are a + * low-level realization of high-level tracepoint. + * + * Service breakpoints like the handling of dlopen would be a + * low-level breakpoint, likely without tracepoint attached. + * + * So that's for sometimes. + */ + +#include "sysdep.h" +#include "library.h" + +struct Process; +struct breakpoint; + +struct bp_callbacks { + void (*on_hit)(struct breakpoint *bp, struct Process *proc); + void (*on_continue)(struct breakpoint *bp, struct Process *proc); + void (*on_retract)(struct breakpoint *bp, struct Process *proc); +}; + +struct breakpoint { + struct bp_callbacks *cbs; + struct library_symbol *libsym; + void *addr; + unsigned char orig_value[BREAKPOINT_LENGTH]; + int enabled; + struct arch_breakpoint_data arch; +}; + +/* Call on-hit handler of BP, if any is set. */ +void breakpoint_on_hit(struct breakpoint *bp, struct Process *proc); + +/* Call on-continue handler of BP. If none is set, call + * continue_after_breakpoint. */ +void breakpoint_on_continue(struct breakpoint *bp, struct Process *proc); + +/* Call on-retract handler of BP, if any is set. This should be + * called before the breakpoints are destroyed. The reason for a + * separate interface is that breakpoint_destroy has to be callable + * without PROC. ON_DISABLE might be useful as well, but that would + * be called every time we disable the breakpoint, which is too often + * (a breakpoint has to be disabled every time that we need to execute + * the instruction underneath it). */ +void breakpoint_on_retract(struct breakpoint *bp, struct Process *proc); + +/* Initialize a breakpoint structure. That doesn't actually realize + * the breakpoint. The breakpoint is initially assumed to be + * disabled. orig_value has to be set separately. CBS may be + * NULL. */ +int breakpoint_init(struct breakpoint *bp, struct Process *proc, + arch_addr_t addr, struct library_symbol *libsym); + +/* Make a clone of breakpoint BP into the area of memory pointed to by + * RETP. The original breakpoint was assigned to process OLD_PROC, + * the cloned breakpoint will be attached to process NEW_PROC. + * Returns 0 on success or a negative value on failure. */ +int breakpoint_clone(struct breakpoint *retp, struct Process *new_proc, + struct breakpoint *bp, struct Process *old_proc); + +/* Set callbacks. If CBS is non-NULL, then BP->cbs shall be NULL. */ +void breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs); + +/* Destroy a breakpoint structure. */ +void breakpoint_destroy(struct breakpoint *bp); + +/* Call enable_breakpoint the first time it's called. Returns 0 on + * success and a negative value on failure. */ +int breakpoint_turn_on(struct breakpoint *bp, struct Process *proc); + +/* Call disable_breakpoint when turned off the same number of times + * that it was turned on. Returns 0 on success and a negative value + * on failure. */ +int breakpoint_turn_off(struct breakpoint *bp, struct Process *proc); + +/* Utility function that does what typically needs to be done when a + * breakpoint is to be inserted. It checks whether there is another + * breakpoint in PROC->LEADER for given ADDR. If not, it allocates + * memory for a new breakpoint on the heap, initializes it, and calls + * PROC_ADD_BREAKPOINT to add the newly-created breakpoint. For newly + * added as well as preexisting breakpoints, it then calls + * BREAKPOINT_TURN_ON. If anything fails, it cleans up and returns + * NULL. Otherwise it returns the breakpoint for ADDR. */ +struct breakpoint *insert_breakpoint(struct Process *proc, void *addr, + struct library_symbol *libsym); + +/* Name of a symbol associated with BP. May be NULL. */ +const char *breakpoint_name(const struct breakpoint *bp); + +/* A library that this breakpoint comes from. May be NULL. */ +struct library *breakpoint_library(const struct breakpoint *bp); + +/* Again, this seems to be several interfaces rolled into one: + * - breakpoint_disable + * - proc_remove_breakpoint + * - breakpoint_destroy + * XXX */ +void delete_breakpoint(struct Process *proc, void *addr); + +/* XXX some of the following belongs to proc.h/proc.c. */ +struct breakpoint *address2bpstruct(struct Process *proc, void *addr); +void enable_all_breakpoints(struct Process *proc); +void disable_all_breakpoints(struct Process *proc); +int breakpoints_init(struct Process *proc); + +#endif /* BREAKPOINT_H */ diff --git a/breakpoints.c b/breakpoints.c index ba3b060..258be93 100644 --- a/breakpoints.c +++ b/breakpoints.c @@ -1,230 +1,420 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006,2007,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2009 Juan Cespedes + * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" +#include <assert.h> +#include <errno.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <assert.h> #ifdef __powerpc__ #include <sys/ptrace.h> #endif -#include "common.h" +#include "backend.h" +#include "breakpoint.h" +#include "debug.h" +#include "library.h" +#include "ltrace-elf.h" +#include "proc.h" + +#ifndef ARCH_HAVE_TRANSLATE_ADDRESS +int +arch_translate_address_dyn(struct Process *proc, + arch_addr_t addr, arch_addr_t *ret) +{ + *ret = addr; + return 0; +} + +struct ltelf; +int +arch_translate_address(struct ltelf *lte, + arch_addr_t addr, arch_addr_t *ret) +{ + *ret = addr; + return 0; +} +#endif + +void +breakpoint_on_hit(struct breakpoint *bp, struct Process *proc) +{ + assert(bp != NULL); + if (bp->cbs != NULL && bp->cbs->on_hit != NULL) + (bp->cbs->on_hit)(bp, proc); +} + +void +breakpoint_on_continue(struct breakpoint *bp, struct Process *proc) +{ + assert(bp != NULL); + if (bp->cbs != NULL && bp->cbs->on_continue != NULL) + (bp->cbs->on_continue)(bp, proc); + else + continue_after_breakpoint(proc, bp); +} + +void +breakpoint_on_retract(struct breakpoint *bp, struct Process *proc) +{ + assert(bp != NULL); + if (bp->cbs != NULL && bp->cbs->on_retract != NULL) + (bp->cbs->on_retract)(bp, proc); +} /*****************************************************************************/ -Breakpoint * -address2bpstruct(Process *proc, void *addr) { +struct breakpoint * +address2bpstruct(Process *proc, void *addr) +{ + assert(proc != NULL); + assert(proc->breakpoints != NULL); + assert(proc->leader == proc); debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); return dict_find_entry(proc->breakpoints, addr); } +#ifndef ARCH_HAVE_BREAKPOINT_DATA +int +arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp) +{ + return 0; +} + void -insert_breakpoint(Process *proc, void *addr, - struct library_symbol *libsym) { - Breakpoint *sbp; +arch_breakpoint_destroy(struct breakpoint *sbp) +{ +} - debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", proc->pid, addr, libsym ? libsym->name : "NULL"); - debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr); +int +arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) +{ + return 0; +} +#endif - if (!addr) +static void +breakpoint_init_base(struct breakpoint *bp, struct Process *proc, + arch_addr_t addr, struct library_symbol *libsym) +{ + bp->cbs = NULL; + bp->addr = addr; + memset(bp->orig_value, 0, sizeof(bp->orig_value)); + bp->enabled = 0; + bp->libsym = libsym; +} + +/* On second thought, I don't think we need PROC. All the translation + * (arch_translate_address in particular) should be doable using + * static lookups of various sections in the ELF file. We shouldn't + * need process for anything. */ +int +breakpoint_init(struct breakpoint *bp, struct Process *proc, + arch_addr_t addr, struct library_symbol *libsym) +{ + breakpoint_init_base(bp, proc, addr, libsym); + return arch_breakpoint_init(proc, bp); +} + +void +breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs) +{ + if (bp->cbs != NULL) + assert(bp->cbs == NULL); + bp->cbs = cbs; +} + +void +breakpoint_destroy(struct breakpoint *bp) +{ + if (bp == NULL) return; + arch_breakpoint_destroy(bp); +} + +int +breakpoint_clone(struct breakpoint *retp, struct Process *new_proc, + struct breakpoint *bp, struct Process *old_proc) +{ + struct library_symbol *libsym = NULL; + if (bp->libsym != NULL) { + int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym); + assert(rc == 0); + } - if (libsym) - libsym->needs_init = 0; + breakpoint_init_base(retp, new_proc, bp->addr, libsym); + memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value)); + retp->enabled = bp->enabled; + if (arch_breakpoint_clone(retp, bp) < 0) + return -1; + breakpoint_set_callbacks(retp, bp->cbs); + return 0; +} + +int +breakpoint_turn_on(struct breakpoint *bp, struct Process *proc) +{ + bp->enabled++; + if (bp->enabled == 1) { + assert(proc->pid != 0); + enable_breakpoint(proc, bp); + } + return 0; +} + +int +breakpoint_turn_off(struct breakpoint *bp, struct Process *proc) +{ + bp->enabled--; + if (bp->enabled == 0) + disable_breakpoint(proc, bp); + assert(bp->enabled >= 0); + return 0; +} - sbp = dict_find_entry(proc->breakpoints, addr); - if (!sbp) { - sbp = calloc(1, sizeof(Breakpoint)); - if (!sbp) { - return; /* TODO FIXME XXX: error_mem */ +struct breakpoint * +insert_breakpoint(struct Process *proc, void *addr, + struct library_symbol *libsym) +{ + Process *leader = proc->leader; + + /* Only the group leader should be getting the breakpoints and + * thus have ->breakpoint initialized. */ + assert(leader != NULL); + assert(leader->breakpoints != NULL); + + debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", + proc->pid, addr, libsym ? libsym->name : "NULL"); + + assert(addr != 0); + + /* XXX what we need to do instead is have a list of + * breakpoints that are enabled at this address. The + * following works if every breakpoint is the same and there's + * no extra data, but that doesn't hold anymore. For now it + * will suffice, about the only realistic case where we need + * to have more than one breakpoint per address is return from + * a recursive library call. */ + struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr); + if (sbp == NULL) { + sbp = malloc(sizeof(*sbp)); + if (sbp == NULL + || breakpoint_init(sbp, proc, addr, libsym) < 0) { + free(sbp); + return NULL; + } + if (proc_add_breakpoint(leader, sbp) < 0) { + fail: + breakpoint_destroy(sbp); + free(sbp); + return NULL; } - dict_enter(proc->breakpoints, addr, sbp); - sbp->addr = addr; - sbp->libsym = libsym; } -#ifdef __arm__ - sbp->thumb_mode = proc->thumb_mode; - proc->thumb_mode = 0; -#endif - sbp->enabled++; - if (sbp->enabled == 1 && proc->pid) - enable_breakpoint(proc->pid, sbp); + + if (breakpoint_turn_on(sbp, proc) < 0) { + proc_remove_breakpoint(leader, sbp); + goto fail; + } + + return sbp; } void -delete_breakpoint(Process *proc, void *addr) { - Breakpoint *sbp; - +delete_breakpoint(Process *proc, void *addr) +{ debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); - sbp = dict_find_entry(proc->breakpoints, addr); - assert(sbp); /* FIXME: remove after debugging has been done. */ + Process * leader = proc->leader; + assert(leader != NULL); + + struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr); + assert(sbp != NULL); /* This should only happen on out-of-memory conditions. */ if (sbp == NULL) return; - sbp->enabled--; - if (sbp->enabled == 0) - disable_breakpoint(proc->pid, sbp); - assert(sbp->enabled >= 0); + if (breakpoint_turn_off(sbp, proc) < 0) { + fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n", + breakpoint_name(sbp), sbp->addr); + return; + } + if (sbp->enabled == 0) { + proc_remove_breakpoint(leader, sbp); + breakpoint_destroy(sbp); + free(sbp); + } +} + +const char * +breakpoint_name(const struct breakpoint *bp) +{ + assert(bp != NULL); + return bp->libsym != NULL ? bp->libsym->name : NULL; +} + +struct library * +breakpoint_library(const struct breakpoint *bp) +{ + assert(bp != NULL); + return bp->libsym != NULL ? bp->libsym->lib : NULL; } static void -enable_bp_cb(void *addr, void *sbp, void *proc) { +enable_bp_cb(void *addr, void *sbp, void *proc) +{ debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid); - if (((Breakpoint *)sbp)->enabled) { - enable_breakpoint(((Process *)proc)->pid, sbp); - } + if (((struct breakpoint *)sbp)->enabled) + enable_breakpoint(proc, sbp); } void -enable_all_breakpoints(Process *proc) { +enable_all_breakpoints(Process *proc) +{ debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); - if (proc->breakpoints_enabled <= 0) { -#ifdef __powerpc__ - unsigned long a; - - /* - * PPC HACK! (XXX FIXME TODO) - * If the dynamic linker hasn't populated the PLT then - * dont enable the breakpoints - */ - if (options.libcalls) { - a = ptrace(PTRACE_PEEKTEXT, proc->pid, - sym2addr(proc, proc->list_of_symbols), - 0); - if (a == 0x0) - return; - } -#endif - debug(1, "Enabling breakpoints for pid %u...", proc->pid); - if (proc->breakpoints) { - dict_apply_to_all(proc->breakpoints, enable_bp_cb, - proc); - } -#ifdef __mips__ - { - /* - * I'm sure there is a nicer way to do this. We need to - * insert breakpoints _after_ the child has been started. - */ - struct library_symbol *sym; - struct library_symbol *new_sym; - sym=proc->list_of_symbols; - while(sym){ - void *addr= sym2addr(proc,sym); - if(!addr){ - sym=sym->next; - continue; - } - if(dict_find_entry(proc->breakpoints,addr)){ - sym=sym->next; - continue; - } - debug(2,"inserting bp %p %s",addr,sym->name); - new_sym=malloc(sizeof(*new_sym)); - memcpy(new_sym,sym,sizeof(*new_sym)); - new_sym->next=proc->list_of_symbols; - proc->list_of_symbols=new_sym; - insert_breakpoint(proc, addr, new_sym); - sym=sym->next; - } - } -#endif + debug(1, "Enabling breakpoints for pid %u...", proc->pid); + if (proc->breakpoints) { + dict_apply_to_all(proc->breakpoints, enable_bp_cb, + proc); } - proc->breakpoints_enabled = 1; } static void -disable_bp_cb(void *addr, void *sbp, void *proc) { +disable_bp_cb(void *addr, void *sbp, void *proc) +{ debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid); - if (((Breakpoint *)sbp)->enabled) { - disable_breakpoint(((Process *)proc)->pid, sbp); - } + if (((struct breakpoint *)sbp)->enabled) + disable_breakpoint(proc, sbp); } void disable_all_breakpoints(Process *proc) { debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); - if (proc->breakpoints_enabled) { - debug(1, "Disabling breakpoints for pid %u...", proc->pid); - dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); - } - proc->breakpoints_enabled = 0; + assert(proc->leader == proc); + dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); } +/* XXX This is not currently properly supported. On clone, this is + * just sliced. Hopefully at the point that clone is done, this + * breakpoint is not necessary anymore. If this use case ends up + * being important, we need to add a clone and destroy callbacks to + * breakpoints, and we should also probably drop arch_breakpoint_data + * so that we don't end up with two different customization mechanisms + * for one structure. */ +struct entry_breakpoint { + struct breakpoint super; + arch_addr_t dyn_addr; +}; + static void -free_bp_cb(void *addr, void *sbp, void *data) { - debug(DEBUG_FUNCTION, "free_bp_cb(sbp=%p)", sbp); - assert(sbp); - free(sbp); +entry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc) +{ + struct entry_breakpoint *bp = (void *)a; + if (proc == NULL || proc->leader == NULL) + return; + arch_addr_t dyn_addr = bp->dyn_addr; + delete_breakpoint(proc, bp->super.addr); + linkmap_init(proc, dyn_addr); + arch_dynlink_done(proc); } -void -breakpoints_init(Process *proc) { - struct library_symbol *sym; +int +entry_breakpoint_init(struct Process *proc, + struct entry_breakpoint *bp, arch_addr_t addr, + struct library *lib) +{ + assert(addr != 0); + int err = breakpoint_init(&bp->super, proc, addr, NULL); + if (err < 0) + return err; + static struct bp_callbacks entry_callbacks = { + .on_hit = entry_breakpoint_on_hit, + }; + bp->super.cbs = &entry_callbacks; + bp->dyn_addr = lib->dyn_addr; + return 0; +} + +int +breakpoints_init(Process *proc) +{ debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); - if (proc->breakpoints) { /* let's remove that struct */ - dict_apply_to_all(proc->breakpoints, free_bp_cb, NULL); - dict_clear(proc->breakpoints); - proc->breakpoints = NULL; - } - proc->breakpoints = dict_init(dict_key2hash_int, dict_key_cmp_int); - - if (options.libcalls && proc->filename) { - /* FIXME: memory leak when called by exec(): */ - proc->list_of_symbols = read_elf(proc); - if (opt_e) { - struct library_symbol **tmp1 = &(proc->list_of_symbols); - while (*tmp1) { - struct opt_e_t *tmp2 = opt_e; - int keep = !opt_e_enable; - - while (tmp2) { - if (!strcmp((*tmp1)->name, tmp2->name)) { - keep = opt_e_enable; - } - tmp2 = tmp2->next; - } - if (!keep) { - *tmp1 = (*tmp1)->next; - } else { - tmp1 = &((*tmp1)->next); - } - } + + /* XXX breakpoint dictionary should be initialized + * outside. Here we just put in breakpoints. */ + assert(proc->breakpoints != NULL); + + /* Only the thread group leader should hold the breakpoints. */ + assert(proc->leader == proc); + + /* N.B. the following used to be conditional on this, and + * maybe it still needs to be. */ + assert(proc->filename != NULL); + + struct library *lib = ltelf_read_main_binary(proc, proc->filename); + struct entry_breakpoint *entry_bp = NULL; + int bp_state = 0; + int result = -1; + switch (lib != NULL) { + fail: + switch (bp_state) { + case 2: + proc_remove_library(proc, lib); + proc_remove_breakpoint(proc, &entry_bp->super); + case 1: + breakpoint_destroy(&entry_bp->super); } - } else { - proc->list_of_symbols = NULL; + library_destroy(lib); + free(entry_bp); + case 0: + return result; } - for (sym = proc->list_of_symbols; sym; sym = sym->next) { - /* proc->pid==0 delays enabling. */ - insert_breakpoint(proc, sym2addr(proc, sym), sym); - } - proc->callstack_depth = 0; - proc->breakpoints_enabled = -1; -} -void -reinitialize_breakpoints(Process *proc) { - struct library_symbol *sym; - - debug(DEBUG_FUNCTION, "reinitialize_breakpoints(pid=%d)", proc->pid); - - sym = proc->list_of_symbols; - - while (sym) { - if (sym->needs_init) { - insert_breakpoint(proc, sym2addr(proc, sym), - sym); - if (sym->needs_init && !sym->is_weak) { - fprintf(stderr, - "could not re-initialize breakpoint for \"%s\" in file \"%s\"\n", - sym->name, proc->filename); - exit(1); - } - } - sym = sym->next; + entry_bp = malloc(sizeof(*entry_bp)); + if (entry_bp == NULL + || (entry_breakpoint_init(proc, entry_bp, + lib->entry, lib)) < 0) { + fprintf(stderr, + "Couldn't initialize entry breakpoint for PID %d.\n" + "Some tracing events may be missed.\n", proc->pid); + free(entry_bp); + + } else { + ++bp_state; + + if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0) + goto fail; + ++bp_state; + + if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0) + goto fail; } + proc_add_library(proc, lib); + + proc->callstack_depth = 0; + return 0; } diff --git a/callback.h b/callback.h new file mode 100644 index 0000000..31e5c8f --- /dev/null +++ b/callback.h @@ -0,0 +1,50 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _CALLBACK_H_ +#define _CALLBACK_H_ + +/* Notes on the iteration interface used across ltrace. Typically the + * iteration function looks something like this: + * + * foo *each_foo(foo *start_after, + * enum callback_status (*cb)(foo *f, void *data), + * void *data); + * + * The iteration starts after the element designated by START_AFTER, + * or at the first element if START_AFTER is NULL. CB is then called + * for each element of the collection. DATA is passed verbatim to CB. + * If CB returns CBS_STOP, the iteration stops and the current element + * is returned. That element can then be passed as START_AFTER to + * restart the iteration. NULL is returned when iteration ends. + * + * CBS_FAIL is not currently handled, and essentially means the same + * thing as CBS_STOP. There's no provision for returning error + * states. Errors need to be signaled to the caller via DATA, + * together with any other data that the callback needs. + */ +enum callback_status { + CBS_STOP, /* The iteration should stop. */ + CBS_CONT, /* The iteration should continue. */ + CBS_FAIL, /* There was an error. The iteration should stop + * and return error. */ +}; + +#endif /* _CALLBACK_H_ */ @@ -1,3 +1,30 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Joe Damato + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef COMMON_H +#define COMMON_H + +#include <config.h> + #include <sys/types.h> #include <sys/time.h> #include <stdio.h> @@ -7,10 +34,15 @@ #include "dict.h" #include "sysdep.h" #include "debug.h" -#include "elf.h" +#include "ltrace-elf.h" #include "read_config_file.h" +#include "proc.h" +#include "forward.h" -#if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__ +#if defined HAVE_LIBSUPC__ || defined HAVE_LIBSTDC__ +# define USE_CXA_DEMANGLE +#endif +#if defined HAVE_LIBIBERTY || defined USE_CXA_DEMANGLE # define USE_DEMANGLE #endif @@ -18,177 +50,19 @@ extern char * command; extern int exiting; /* =1 if we have to exit ASAP */ -typedef struct Breakpoint Breakpoint; -struct Breakpoint { - void * addr; - unsigned char orig_value[BREAKPOINT_LENGTH]; - int enabled; - struct library_symbol * libsym; -#ifdef __arm__ - int thumb_mode; -#endif -}; - -enum arg_type { - ARGTYPE_UNKNOWN = -1, - ARGTYPE_VOID, - ARGTYPE_INT, - ARGTYPE_UINT, - ARGTYPE_LONG, - ARGTYPE_ULONG, - ARGTYPE_OCTAL, - ARGTYPE_CHAR, - ARGTYPE_SHORT, - ARGTYPE_USHORT, - ARGTYPE_FLOAT, /* float value, may require index */ - ARGTYPE_DOUBLE, /* double value, may require index */ - ARGTYPE_ADDR, - ARGTYPE_FILE, - ARGTYPE_FORMAT, /* printf-like format */ - ARGTYPE_STRING, /* NUL-terminated string */ - ARGTYPE_STRING_N, /* String of known maxlen */ - ARGTYPE_ARRAY, /* Series of values in memory */ - ARGTYPE_ENUM, /* Enumeration */ - ARGTYPE_STRUCT, /* Structure of values */ - ARGTYPE_POINTER, /* Pointer to some other type */ - ARGTYPE_COUNT /* number of ARGTYPE_* values */ -}; - -typedef struct arg_type_info_t { - enum arg_type type; - union { - /* ARGTYPE_ENUM */ - struct { - size_t entries; - char ** keys; - int * values; - } enum_info; - - /* ARGTYPE_ARRAY */ - struct { - struct arg_type_info_t * elt_type; - size_t elt_size; - int len_spec; - } array_info; - - /* ARGTYPE_STRING_N */ - struct { - int size_spec; - } string_n_info; - - /* ARGTYPE_STRUCT */ - struct { - struct arg_type_info_t ** fields; /* NULL-terminated */ - size_t * offset; - size_t size; - } struct_info; - - /* ARGTYPE_POINTER */ - struct { - struct arg_type_info_t * info; - } ptr_info; - - /* ARGTYPE_FLOAT */ - struct { - size_t float_index; - } float_info; - - /* ARGTYPE_DOUBLE */ - struct { - size_t float_index; - } double_info; - } u; -} arg_type_info; - -enum tof { - LT_TOF_NONE = 0, - LT_TOF_FUNCTION, /* A real library function */ - LT_TOF_FUNCTIONR, /* Return from a real library function */ - LT_TOF_SYSCALL, /* A syscall */ - LT_TOF_SYSCALLR, /* Return from a syscall */ - LT_TOF_STRUCT /* Not a function; read args from struct */ -}; - typedef struct Function Function; struct Function { const char * name; - arg_type_info * return_info; - int num_params; - arg_type_info * arg_info[MAX_ARGS]; - int params_right; + struct param *params; + struct arg_type_info *return_info; + int own_return_info; + size_t num_params; Function * next; }; -enum toplt { - LS_TOPLT_NONE = 0, /* PLT not used for this symbol. */ - LS_TOPLT_EXEC, /* PLT for this symbol is executable. */ - LS_TOPLT_POINT /* PLT for this symbol is a non-executable. */ -}; - extern Function * list_of_functions; extern char *PLTs_initialized_by_here; -struct library_symbol { - char * name; - void * enter_addr; - char needs_init; - enum toplt plt_type; - char is_weak; - struct library_symbol * next; -}; - -struct callstack_element { - union { - int syscall; - struct library_symbol * libfunc; - } c_un; - int is_syscall; - void * return_addr; - struct timeval time_spent; -}; - -#define MAX_CALLDEPTH 64 - -typedef enum Process_State Process_State; -enum Process_State { - STATE_ATTACHED = 0, - STATE_BEING_CREATED, - STATE_IGNORED /* ignore this process (it's a fork and no -f was used) */ -}; - -struct Process { - Process_State state; - Process * parent; /* needed by STATE_BEING_CREATED */ - char * filename; - pid_t pid; - Dict * breakpoints; - int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */ - int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */ - unsigned int personality; - int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */ - - int callstack_depth; - struct callstack_element callstack[MAX_CALLDEPTH]; - struct library_symbol * list_of_symbols; - - /* Arch-dependent: */ - void * instruction_pointer; - void * stack_pointer; /* To get return addr, args... */ - void * return_addr; - Breakpoint * breakpoint_being_enabled; - void * arch_ptr; - short e_machine; - short need_to_reinitialize_breakpoints; -#ifdef __arm__ - int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */ -#endif - - /* output: */ - enum tof type_being_displayed; - - Process * next; -}; - struct opt_c_struct { int count; struct timeval tv; @@ -202,52 +76,22 @@ struct opt_c_struct { extern Dict * dict_opt_c; -extern Process * list_of_processes; - +/* Events */ extern Event * next_event(void); -extern Process * pid2proc(pid_t pid); extern void handle_event(Event * event); -extern void execute_program(Process *, char **); -extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info); -extern Breakpoint * address2bpstruct(Process * proc, void * addr); -extern void breakpoints_init(Process * proc); -extern void insert_breakpoint(Process * proc, void * addr, struct library_symbol * libsym); -extern void delete_breakpoint(Process * proc, void * addr); -extern void enable_all_breakpoints(Process * proc); -extern void disable_all_breakpoints(Process * proc); -extern void reinitialize_breakpoints(Process *); - -extern Process * open_program(char * filename, pid_t pid); -extern void open_pid(pid_t pid); + +extern pid_t execute_program(const char * command, char ** argv); + extern void show_summary(void); -extern arg_type_info * lookup_prototype(enum arg_type at); - -/* Arch-dependent stuff: */ -extern char * pid2name(pid_t pid); -extern void trace_set_options(Process * proc, pid_t pid); -extern void trace_me(void); -extern int trace_pid(pid_t pid); -extern void untrace_pid(pid_t pid); -extern void get_arch_dep(Process * proc); -extern void * get_instruction_pointer(Process * proc); -extern void set_instruction_pointer(Process * proc, void * addr); -extern void * get_stack_pointer(Process * proc); -extern void * get_return_addr(Process * proc, void * stack_pointer); -extern void set_return_addr(Process * proc, void * addr); -extern void enable_breakpoint(pid_t pid, Breakpoint * sbp); -extern void disable_breakpoint(pid_t pid, const Breakpoint * sbp); -extern int syscall_p(Process * proc, int status, int * sysnum); -extern void continue_process(pid_t pid); -extern void continue_after_signal(pid_t pid, int signum); -extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp); -extern void continue_enabling_breakpoint(pid_t pid, Breakpoint * sbp); -extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info); -extern void save_register_args(enum tof type, Process * proc); -extern int umovestr(Process * proc, void * addr, int len, void * laddr); -extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info); -extern int ffcheck(void * maddr); -extern void * sym2addr(Process *, struct library_symbol *); - -#if 0 /* not yet */ -extern int umoven(Process * proc, void * addr, int len, void * laddr); + +struct breakpoint; +struct library_symbol; + +/* Format VALUE into STREAM. The dictionary of all arguments is given + * for purposes of evaluating array lengths and other dynamic + * expressions. Returns number of characters outputted, -1 in case of + * failure. */ +int format_argument(FILE *stream, struct value *value, + struct value_dict *arguments); + #endif diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..0625d9c --- /dev/null +++ b/config.h.in @@ -0,0 +1,197 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* debugging */ +#undef DEBUG + +/* elf_hash() takes char* (as opposed to unsigned char *) */ +#undef ELF_HASH_TAKES_CHARP + +/* Define to 1 if you have the `alarm' function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the `atexit' function. */ +#undef HAVE_ATEXIT + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* we have read mmap support */ +#undef HAVE_ELF_C_READ_MMAP + +/* Define to 1 if you have the <elf.h> header file. */ +#undef HAVE_ELF_H + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the <gelf.h> header file. */ +#undef HAVE_GELF_H + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `elf' library (-lelf). */ +#undef HAVE_LIBELF + +/* we have libiberty */ +#undef HAVE_LIBIBERTY + +/* Define to 1 if you have the `selinux' library (-lselinux). */ +#undef HAVE_LIBSELINUX + +/* we have libstdc++ */ +#undef HAVE_LIBSTDC__ + +/* we have libsupc++ */ +#undef HAVE_LIBSUPC__ + +/* we have libunwind */ +#undef HAVE_LIBUNWIND + +/* Define to 1 if you have the <libunwind.h> header file. */ +#undef HAVE_LIBUNWIND_H + +/* Define to 1 if you have the <libunwind-ptrace.h> header file. */ +#undef HAVE_LIBUNWIND_PTRACE_H + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the `mkdir' function. */ +#undef HAVE_MKDIR + +/* Define to 1 if you have the `rmdir' function. */ +#undef HAVE_RMDIR + +/* Define to 1 if you have the <selinux/selinux.h> header file. */ +#undef HAVE_SELINUX_SELINUX_H + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if you have the <sys/ioctl.h> header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the <vfork.h> header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef gid_t + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `int' if <sys/types.h> does not define. */ +#undef pid_t + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to `int' if <sys/types.h> doesn't define. */ +#undef uid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/config/autoconf/config.guess b/config/autoconf/config.guess new file mode 100755 index 0000000..dc84c68 --- /dev/null +++ b/config/autoconf/config.guess @@ -0,0 +1,1501 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to <config-patches@gnu.org> and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/autoconf/config.sub b/config/autoconf/config.sub new file mode 100755 index 0000000..2a55a50 --- /dev/null +++ b/config/autoconf/config.sub @@ -0,0 +1,1705 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/autoconf/depcomp b/config/autoconf/depcomp new file mode 100755 index 0000000..df8eea7 --- /dev/null +++ b/config/autoconf/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/autoconf/install-sh b/config/autoconf/install-sh new file mode 100755 index 0000000..6781b98 --- /dev/null +++ b/config/autoconf/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/autoconf/ltmain.sh b/config/autoconf/ltmain.sh new file mode 100755 index 0000000..78cf017 --- /dev/null +++ b/config/autoconf/ltmain.sh @@ -0,0 +1,9636 @@ + +# libtool (GNU libtool) 2.4 +# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to <bug-libtool@gnu.org>. +# GNU libtool home page: <http://www.gnu.org/software/libtool/>. +# General help using GNU software: <http://www.gnu.org/gethelp/>. + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4 +TIMESTAMP="" +package_revision=1.3293 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${EGREP="/bin/grep -E"} +: ${FGREP="/bin/grep -F"} +: ${GREP="/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/bin/sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <<EOF +# $write_libobj - a libtool object file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object=$write_lobj + +# Name of the non-PIC object +non_pic_object=$write_oldobj + +EOF + $MV "${write_libobj}T" "${write_libobj}" + } +} + + +################################################## +# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # +################################################## + +# func_convert_core_file_wine_to_w32 ARG +# Helper function used by file name conversion functions when $build is *nix, +# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. +# +# ARG is the $build file name to be converted to w32 format. +# Result is available in $func_convert_core_file_wine_to_w32_result, and will +# be empty on error (or when ARG is empty) +func_convert_core_file_wine_to_w32 () +{ + $opt_debug + func_convert_core_file_wine_to_w32_result="$1" + if test -n "$1"; then + # Unfortunately, winepath does not exit with a non-zero error code, so we + # are forced to check the contents of stdout. On the other hand, if the + # command is not found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both error code of + # zero AND non-empty stdout, which explains the odd construction: + func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen <import library>. + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. +*/ +EOF + cat <<"EOF" +#ifdef _MSC_VER +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef _MSC_VER +# include <direct.h> +# include <process.h> +# include <io.h> +#else +# include <unistd.h> +# include <stdint.h> +# ifdef __CYGWIN__ +# include <io.h> +# endif +#endif +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <<EOF +volatile const char * MAGIC_EXE = "$magic_exe"; +const char * LIB_PATH_VARNAME = "$shlibpath_var"; +EOF + + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + func_to_host_path "$temp_rpath" + cat <<EOF +const char * LIB_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * LIB_PATH_VALUE = ""; +EOF + fi + + if test -n "$dllsearchpath"; then + func_to_host_path "$dllsearchpath:" + cat <<EOF +const char * EXE_PATH_VARNAME = "PATH"; +const char * EXE_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * EXE_PATH_VARNAME = ""; +const char * EXE_PATH_VALUE = ""; +EOF + fi + + if test "$fast_install" = yes; then + cat <<EOF +const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ +EOF + else + cat <<EOF +const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ +EOF + fi + + + cat <<"EOF" + +#define LTWRAPPER_OPTION_PREFIX "--lt-" + +static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; +static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; +static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; + +int +main (int argc, char *argv[]) +{ + char **newargz; + int newargc; + char *tmp_pathspec; + char *actual_cwrapper_path; + char *actual_cwrapper_name; + char *target_name; + char *lt_argv_zero; + intptr_t rval = 127; + + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + newargz = XMALLOC (char *, argc + 1); + + /* very simple arg parsing; don't want to rely on getopt + * also, copy all non cwrapper options to newargz, except + * argz[0], which is handled differently + */ + newargc=0; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], dumpscript_opt) == 0) + { +EOF + case "$host" in + *mingw* | *cygwin* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; + esac + + cat <<"EOF" + lt_dump_script (stdout); + return 0; + } + if (strcmp (argv[i], debug_opt) == 0) + { + lt_debug = 1; + continue; + } + if (strcmp (argv[i], ltwrapper_option_prefix) == 0) + { + /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX + namespace, but it is not one of the ones we know about and + have already dealt with, above (inluding dump-script), then + report an error. Otherwise, targets might begin to believe + they are allowed to use options in the LTWRAPPER_OPTION_PREFIX + namespace. The first time any user complains about this, we'll + need to make LTWRAPPER_OPTION_PREFIX a configure-time option + or a configure.ac-settable value. + */ + lt_fatal (__FILE__, __LINE__, + "unrecognized %s option: '%s'", + ltwrapper_option_prefix, argv[i]); + } + /* otherwise ... */ + newargz[++newargc] = xstrdup (argv[i]); + } + newargz[++newargc] = NULL; + +EOF + cat <<EOF + /* The GNU banner must be the first non-error debug message */ + lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n"); +EOF + cat <<"EOF" + lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); + lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); + + tmp_pathspec = find_executable (argv[0]); + if (tmp_pathspec == NULL) + lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (before symlink chase) at: %s\n", + tmp_pathspec); + + actual_cwrapper_path = chase_symlinks (tmp_pathspec); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (after symlink chase) at: %s\n", + actual_cwrapper_path); + XFREE (tmp_pathspec); + + actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); + strendzap (actual_cwrapper_path, actual_cwrapper_name); + + /* wrapper name transforms */ + strendzap (actual_cwrapper_name, ".exe"); + tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); + XFREE (actual_cwrapper_name); + actual_cwrapper_name = tmp_pathspec; + tmp_pathspec = 0; + + /* target_name transforms -- use actual target program name; might have lt- prefix */ + target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); + strendzap (target_name, ".exe"); + tmp_pathspec = lt_extend_str (target_name, ".exe", 1); + XFREE (target_name); + target_name = tmp_pathspec; + tmp_pathspec = 0; + + lt_debugprintf (__FILE__, __LINE__, + "(main) libtool target name: %s\n", + target_name); +EOF + + cat <<EOF + newargz[0] = + XMALLOC (char, (strlen (actual_cwrapper_path) + + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); + strcpy (newargz[0], actual_cwrapper_path); + strcat (newargz[0], "$objdir"); + strcat (newargz[0], "/"); +EOF + + cat <<"EOF" + /* stop here, and copy so we don't have to do this twice */ + tmp_pathspec = xstrdup (newargz[0]); + + /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ + strcat (newargz[0], actual_cwrapper_name); + + /* DO want the lt- prefix here if it exists, so use target_name */ + lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); + XFREE (tmp_pathspec); + tmp_pathspec = NULL; +EOF + + case $host_os in + mingw*) + cat <<"EOF" + { + char* p; + while ((p = strchr (newargz[0], '\\')) != NULL) + { + *p = '/'; + } + while ((p = strchr (lt_argv_zero, '\\')) != NULL) + { + *p = '/'; + } + } +EOF + ;; + esac + + cat <<"EOF" + XFREE (target_name); + XFREE (actual_cwrapper_path); + XFREE (actual_cwrapper_name); + + lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ + lt_setenv ("DUALCASE", "1"); /* for MSK sh */ + /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must + be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) + because on Windows, both *_VARNAMEs are PATH but uninstalled + libraries must come first. */ + lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); + lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); + + lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", + nonnull (lt_argv_zero)); + for (i = 0; i < newargc; i++) + { + lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", + i, nonnull (newargz[i])); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + newargz = prepare_spawn (newargz); + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + lt_debugprintf (__FILE__, __LINE__, + "(main) failed to launch target \"%s\": %s\n", + lt_argv_zero, nonnull (strerror (errno))); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal (__FILE__, __LINE__, "memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' + + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + echo + $ECHO "*** Warning! Library $i is needed by this library but I was not able to" + echo "*** make it link in! You will probably need to install it or some" + echo "*** library that it depends on before this library will be fully" + echo "*** functional. Installing it before continuing would be even better." + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method; shift + file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + if test -n "$file_magic_glob"; then + libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` + else + libnameglob=$libname + fi + test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + if test "$want_nocaseglob" = yes; then + shopt -s nocaseglob + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/config/autoconf/missing b/config/autoconf/missing new file mode 100755 index 0000000..28055d2 --- /dev/null +++ b/config/autoconf/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/m4/libtool.m4 b/config/m4/libtool.m4 new file mode 100644 index 0000000..88de383 --- /dev/null +++ b/config/m4/libtool.m4 @@ -0,0 +1,7835 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/config/m4/ltoptions.m4 b/config/m4/ltoptions.m4 new file mode 100644 index 0000000..17cfd51 --- /dev/null +++ b/config/m4/ltoptions.m4 @@ -0,0 +1,369 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/config/m4/ltsugar.m4 b/config/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/config/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/config/m4/ltversion.m4 b/config/m4/ltversion.m4 new file mode 100644 index 0000000..9c7b5d4 --- /dev/null +++ b/config/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3293 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4]) +m4_define([LT_PACKAGE_REVISION], [1.3293]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4' +macro_revision='1.3293' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/config/m4/lt~obsolete.m4 b/config/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c573da9 --- /dev/null +++ b/config/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) @@ -1,157 +1,15032 @@ -#!/bin/sh +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for ltrace 0.7.2. +# +# Report bugs to <ltrace-devel@lists.alioth.debian.org>. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## -if [ ! -f libltrace.c ] -then - echo "configure: error: cannot find sources (libltrace.c)" 1>&2 +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: ltrace-devel@lists.alioth.debian.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi exit 1 fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status -echo -n "checking package name... " +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. PACKAGE_NAME='ltrace' -echo $PACKAGE_NAME +PACKAGE_TARNAME='ltrace' +PACKAGE_VERSION='0.7.2' +PACKAGE_STRING='ltrace 0.7.2' +PACKAGE_BUGREPORT='ltrace-devel@lists.alioth.debian.org' +PACKAGE_URL='' + +ac_unique_file="libltrace.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +libunwind_LD_LIBRARY_PATH +libelf_LD_LIBRARY_PATH +AM_LDFLAGS +AM_CFLAGS +AM_CPPFLAGS +USE_VALGRIND_FALSE +USE_VALGRIND_TRUE +HAVE_VALGRIND +LIBOBJS +libunwind_LIBS +libstdcxx_LIBS +libsupcxx_LIBS +liberty_LIBS +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +AWK +RANLIB +STRIP +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +HOST_CPU +HOST_OS +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_dependency_tracking +enable_maintainer_mode +with_libelf +with_libunwind +enable_debug +enable_werror +enable_valgrind +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ltrace 0.7.2 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ltrace] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ltrace 0.7.2:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --enable-debug enable debugging [default=no] + --disable-werror disable use of -Werror + --enable-valgrind run all tests under valgrind + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-libelf Prefix of libelf headers/library + --with-libunwind Use libunwind frame unwinding support + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <ltrace-devel@lists.alioth.debian.org>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ltrace configure 0.7.2 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------------------- ## +## Report this to ltrace-devel@lists.alioth.debian.org ## +## --------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ltrace $as_me 0.7.2, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers config.h" + + + +ac_aux_dir= +for ac_dir in config/autoconf "$srcdir"/config/autoconf; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config/autoconf \"$srcdir\"/config/autoconf" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +case "${host_os}" in + linux-gnu*) HOST_OS="linux-gnu" ;; + *) as_fn_error $? "unkown host-os ${host_os}" "$LINENO" 5 ;; +esac + + +case "${host_cpu}" in + arm*|sa110) HOST_CPU="arm" ;; + cris*) HOST_CPU="cris" ;; + mips*el) HOST_CPU="mipsel" ;; + mips*) HOST_CPU="mips" ;; + powerpc|powerpc64) HOST_CPU="ppc" ;; + sun4u|sparc64) HOST_CPU="sparc" ;; + s390x) HOST_CPU="s390" ;; + i?86|x86_64) HOST_CPU="x86" ;; + *) HOST_CPU="${host_cpu}" ;; +esac + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4' +macro_revision='1.3293' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" -echo -n "checking $PACKAGE_NAME version... " -PACKAGE_VERSION=$( cat VERSION ) -echo $PACKAGE_VERSION +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' -echo -n "checking HOST_OS... " -HOST_OS=$( uname -s ) -if [ "$HOST_OS" = "Linux" ] + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +# libtool-2: LT_INIT() +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) then - HOST_OS="linux-gnu" + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + fi -echo $HOST_OS +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='ltrace' + VERSION='0.7.2' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + +# Check whether --with-libelf was given. +if test "${with_libelf+set}" = set; then : + withval=$with_libelf; case "${withval}" in + (no) + as_fn_error $? "*** libelf is a required dependency" "$LINENO" 5 + ;; + (yes) + as_fn_error $? "*** --with-libelf requires you to specify a path" "$LINENO" 5 + ;; + (*) + AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include" + AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib" + libelf_LD_LIBRARY_PATH="${withval}/lib" + ;; +esac +fi + + +# Checks for libraries. + +saved_CPPFLAGS="${CPPFLAGS}" +saved_LDFLAGS="${LDFLAGS}" +CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}" +LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}" +# libelf +for ac_header in elf.h gelf.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + as_fn_error $? "*** libelf.h or gelf.h not found on your system" "$LINENO" 5 + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for elf_begin in -lelf" >&5 +$as_echo_n "checking for elf_begin in -lelf... " >&6; } +if ${ac_cv_lib_elf_elf_begin+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char elf_begin (); +int +main () +{ +return elf_begin (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_elf_elf_begin=yes +else + ac_cv_lib_elf_elf_begin=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_elf_elf_begin" >&5 +$as_echo "$ac_cv_lib_elf_elf_begin" >&6; } +if test "x$ac_cv_lib_elf_elf_begin" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBELF 1 +_ACEOF + + LIBS="-lelf $LIBS" + +else + as_fn_error $? "*** libelf not found on your system" "$LINENO" 5 + +fi + +CPPFLAGS="${saved_CPPFLAGS}" +LDFLAGS="${saved_LDFLAGS}" + # HAVE_LIBIBERTY -echo -n "checking for cplus_demangle in -liberty... " -cat > conftest.c << EOF -char cplus_demangle(); -int main () { - return cplus_demangle(); +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cplus_demangle in -liberty" >&5 +$as_echo_n "checking for cplus_demangle in -liberty... " >&6; } +if ${ac_cv_lib_iberty_cplus_demangle+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-liberty $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char cplus_demangle (); +int +main () +{ +return cplus_demangle (); + ; + return 0; } -EOF -if gcc conftest.c -liberty 2>/dev/null -then - HAVE_LIBIBERTY=1 - echo "yes" +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_iberty_cplus_demangle=yes +else + ac_cv_lib_iberty_cplus_demangle=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iberty_cplus_demangle" >&5 +$as_echo "$ac_cv_lib_iberty_cplus_demangle" >&6; } +if test "x$ac_cv_lib_iberty_cplus_demangle" = xyes; then : + + +$as_echo "#define HAVE_LIBIBERTY 1" >>confdefs.h + + liberty_LIBS="-liberty" else - unset HAVE_LIBIBERTY - echo "no" + + liberty_LIBS="" fi -rm -f conftest.c a.out + + + # HAVE_LIBSUPC__ -echo -n "checking for __cxa_demangle in -lsupc++... " -cat > conftest.c << EOF -char __cxa_demangle(); -int main () { - return __cxa_demangle(); +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cxa_demangle in -lsupc++" >&5 +$as_echo_n "checking for __cxa_demangle in -lsupc++... " >&6; } +if ${ac_cv_lib_supcpp___cxa_demangle+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsupc++ $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __cxa_demangle (); +int +main () +{ +return __cxa_demangle (); + ; + return 0; } -EOF -if gcc conftest.c -lsupc++ 2>/dev/null -then - HAVE_LIBSUPC__=1 - echo "yes" +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_supcpp___cxa_demangle=yes else - unset HAVE_LIBSUPC__ - echo "no" + ac_cv_lib_supcpp___cxa_demangle=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_supcpp___cxa_demangle" >&5 +$as_echo "$ac_cv_lib_supcpp___cxa_demangle" >&6; } +if test "x$ac_cv_lib_supcpp___cxa_demangle" = xyes; then : + + +$as_echo "#define HAVE_LIBSUPC__ 1" >>confdefs.h + + libsupcxx_LIBS="-lsupc++" +else + + libsupcxx_LIBS="" fi -rm -f conftest.c a.out + + + +# HAVE_LIBSTDC__ +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cxa_demangle in -lstdc++" >&5 +$as_echo_n "checking for __cxa_demangle in -lstdc++... " >&6; } +if ${ac_cv_lib_stdcpp___cxa_demangle+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lstdc++ $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __cxa_demangle (); +int +main () +{ +return __cxa_demangle (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_stdcpp___cxa_demangle=yes +else + ac_cv_lib_stdcpp___cxa_demangle=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_stdcpp___cxa_demangle" >&5 +$as_echo "$ac_cv_lib_stdcpp___cxa_demangle" >&6; } +if test "x$ac_cv_lib_stdcpp___cxa_demangle" = xyes; then : + + +$as_echo "#define HAVE_LIBSTDC__ 1" >>confdefs.h + + libstdcxx_LIBS="-lstdc++" +else + + libstdcxx_LIBS="" +fi + + + + +for ac_header in selinux/selinux.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" +if test "x$ac_cv_header_selinux_selinux_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SELINUX_SELINUX_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5 +$as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; } +if ${ac_cv_lib_selinux_security_get_boolean_active+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char security_get_boolean_active (); +int +main () +{ +return security_get_boolean_active (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_selinux_security_get_boolean_active=yes +else + ac_cv_lib_selinux_security_get_boolean_active=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_security_get_boolean_active" >&5 +$as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; } +if test "x$ac_cv_lib_selinux_security_get_boolean_active" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSELINUX 1 +_ACEOF + + LIBS="-lselinux $LIBS" + +fi + + + +# HAVE_LIBUNWIND + +# Check whether --with-libunwind was given. +if test "${with_libunwind+set}" = set; then : + withval=$with_libunwind; case "${withval}" in + (yes|no) enable_libunwind=$withval;; + (*) enable_libunwind=yes + AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include" + AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib" + libunwind_LD_LIBRARY_PATH="${withval}/lib" + ;; +esac +else + enable_libunwind=maybe +fi + + +saved_CPPFLAGS="${CPPFLAGS}" +CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}" +for ac_header in libunwind.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libunwind.h" "ac_cv_header_libunwind_h" "$ac_includes_default" +if test "x$ac_cv_header_libunwind_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUNWIND_H 1 +_ACEOF + have_libunwind_h=yes +fi + +done + +for ac_header in libunwind-ptrace.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libunwind-ptrace.h" "ac_cv_header_libunwind_ptrace_h" "$ac_includes_default" +if test "x$ac_cv_header_libunwind_ptrace_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUNWIND_PTRACE_H 1 +_ACEOF + have_libunwind_ptrace_h=yes +fi + +done + +CPPFLAGS="${saved_CPPFLAGS}" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libunwind support" >&5 +$as_echo_n "checking whether to use libunwind support... " >&6; } +case "${enable_libunwind}" in +(yes|maybe) + if test x$have_libunwind_h = xyes -o x$have_libunwind_ptrace_h = xyes; then + enable_libunwind=yes + elif test $enable_libunwind = maybe; then + enable_libunwind=no + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_libunwind" >&5 +$as_echo "$enable_libunwind" >&6; } + as_fn_error $? "libunwind.h or libunwind-ptrace.h cannot be found" "$LINENO" 5 + fi + ;; +(*) ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_libunwind" >&5 +$as_echo "$enable_libunwind" >&6; } + +if test x"$enable_libunwind" = xyes; then + case "${host_cpu}" in + arm*|sa110) UNWIND_ARCH="arm" ;; + i?86) UNWIND_ARCH="x86" ;; + powerpc) UNWIND_ARCH="ppc32" ;; + powerpc64) UNWIND_ARCH="ppc64" ;; + mips*) UNWIND_ARCH="mips" ;; + *) UNWIND_ARCH="${host_cpu}" ;; + esac + + saved_LDFLAGS="${LDFLAGS}" + LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for backtrace in -lunwind" >&5 +$as_echo_n "checking for backtrace in -lunwind... " >&6; } +if ${ac_cv_lib_unwind_backtrace+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lunwind $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char backtrace (); +int +main () +{ +return backtrace (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_unwind_backtrace=yes +else + ac_cv_lib_unwind_backtrace=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unwind_backtrace" >&5 +$as_echo "$ac_cv_lib_unwind_backtrace" >&6; } +if test "x$ac_cv_lib_unwind_backtrace" = xyes; then : + libunwind_LIBS=-lunwind +else + as_fn_error $? "Couldn't find or use libunwind." "$LINENO" 5 +fi + + + as_ac_Lib=`$as_echo "ac_cv_lib_unwind-${UNWIND_ARCH}''__U${UNWIND_ARCH}_init_remote" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _U${UNWIND_ARCH}_init_remote in -lunwind-${UNWIND_ARCH}" >&5 +$as_echo_n "checking for _U${UNWIND_ARCH}_init_remote in -lunwind-${UNWIND_ARCH}... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lunwind-${UNWIND_ARCH} $libunwind_LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _U${UNWIND_ARCH}_init_remote (); +int +main () +{ +return _U${UNWIND_ARCH}_init_remote (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + libunwind_LIBS="-lunwind-${UNWIND_ARCH} $libunwind_LIBS" +else + as_fn_error $? "Couldn't find or use libunwind-${UNWIND_ARCH}." "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _UPT_create in -lunwind-ptrace" >&5 +$as_echo_n "checking for _UPT_create in -lunwind-ptrace... " >&6; } +if ${ac_cv_lib_unwind_ptrace__UPT_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lunwind-ptrace $libunwind_LIBS $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _UPT_create (); +int +main () +{ +return _UPT_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_unwind_ptrace__UPT_create=yes +else + ac_cv_lib_unwind_ptrace__UPT_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unwind_ptrace__UPT_create" >&5 +$as_echo "$ac_cv_lib_unwind_ptrace__UPT_create" >&6; } +if test "x$ac_cv_lib_unwind_ptrace__UPT_create" = xyes; then : + libunwind_LIBS="-lunwind-ptrace $libunwind_LIBS" +else + as_fn_error $? "Couldn't find or use libunwind-ptrace." "$LINENO" 5 +fi + + + + +$as_echo "#define HAVE_LIBUNWIND 1" >>confdefs.h + + LDFLAGS="${saved_LDFLAGS}" +fi + + +saved_CPPFLAGS="${CPPFLAGS}" +saved_LDFLAGS="${LDFLAGS}" +CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}" +LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}" # HAVE_ELF_C_READ_MMAP -echo -n "checking whether elf_begin accepts ELF_C_READ_MMAP... " -cat > conftest.c << EOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether elf_begin accepts ELF_C_READ_MMAP" >&5 +$as_echo_n "checking whether elf_begin accepts ELF_C_READ_MMAP... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ #include <gelf.h> +int +main () +{ + int main () { - Elf *elf = elf_begin (4, ELF_C_READ_MMAP, 0); + Elf *elf = elf_begin(4, ELF_C_READ_MMAP, 0); + return 0; +} + + ; return 0; } -EOF -if gcc conftest.c 2>/dev/null -then - HAVE_ELF_C_READ_MMAP=1 - echo "yes" +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + +$as_echo "#define HAVE_ELF_C_READ_MMAP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } else - unset HAVE_ELF_C_READ_MMAP - echo "no" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -rm -f conftest.c a.out +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -CC=gcc -CPPFLAGS=' -I /usr/include/libelf' -CFLAGS='-g -O2' -LIBS='-lelf -lsupc++ -liberty ' -INSTALL='/usr/bin/install -c' -iquote='-iquote ' -iquoteend='' +saved_CFLAGS="${CFLAGS}" +CFLAGS="${CFLAGS} -Wall -Werror" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether elf_hash takes a char* argument" >&5 +$as_echo_n "checking whether elf_hash takes a char* argument... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <libelf.h> +int +main () +{ -prefix=/usr/local -sysconfdir='${prefix}/etc' -bindir='${prefix}/bin' -mandir='${prefix}/share/man' -docdir='${prefix}/share/doc/ltrace' -for x_option -do - if test -n "$x_prev"; then - eval $x_prev=\$x_option - x_prev= - continue - fi - case $x_option in - --*=* | *=*) - x_var=`echo $x_option | sed 's/^--//' | sed 's/=.*//'` - x_val=`echo $x_option | sed 's/^.*=//'` - eval $x_var=$x_val + (void) elf_hash("name"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define ELF_HASH_TAKES_CHARP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="${saved_CFLAGS}" +CPPFLAGS="${saved_CPPFLAGS}" +LDFLAGS="${saved_LDFLAGS}" + +AM_CPPFLAGS=" \ + ${AM_CPPFLAGS} \ + -I\$(top_srcdir)/sysdeps/${HOST_OS}/${HOST_CPU} \ + -I\$(top_srcdir)/sysdeps/${HOST_OS} \ + -I\$(top_srcdir)/sysdeps \ + -I\$(top_srcdir) \ +" + +# Checks for header files. +for ac_header in \ + fcntl.h \ + limits.h \ + stddef.h \ + stdint.h \ + stdlib.h \ + string.h \ + sys/ioctl.h \ + sys/param.h \ + sys/time.h \ + unistd.h \ + +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + + +# Checks for library functions. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5 +$as_echo_n "checking for error_at_line... " >&6; } +if ${ac_cv_lib_error_at_line+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <error.h> +int +main () +{ +error_at_line (0, 0, "", 0, "an error occurred"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_error_at_line=yes +else + ac_cv_lib_error_at_line=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5 +$as_echo "$ac_cv_lib_error_at_line" >&6; } +if test $ac_cv_lib_error_at_line = no; then + case " $LIBOBJS " in + *" error.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS error.$ac_objext" + ;; +esac + +fi + +for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no ;; - --*) - x_prev=`echo $x_option | sed 's/^--//'` + *) + ac_cv_func_fork_works=yes ;; esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + +for ac_func in \ + alarm \ + atexit \ + getcwd \ + gettimeofday \ + memset \ + mkdir \ + rmdir \ + strchr \ + strdup \ + strerror \ + strtol \ + strtoul \ + +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi done -echo "configure: creating Makefile" + + # -# Makefile.in -> Makefile +# Debugging # -x_subst_vars='PACKAGE_VERSION HOST_OS INSTALL CC CPPFLAGS CFLAGS LDFLAGS LIBS iquote iquoteend prefix sysconfdir mandir docdir' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 +$as_echo_n "checking whether to enable debugging... " >&6; } +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; case "$enableval" in + y | yes) CONFIG_DEBUG=yes ;; + *) CONFIG_DEBUG=no ;; + esac +else + CONFIG_DEBUG=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CONFIG_DEBUG}" >&5 +$as_echo "${CONFIG_DEBUG}" >&6; } +if test "${CONFIG_DEBUG}" = "yes"; then + +$as_echo "#define DEBUG 1" >>confdefs.h + +fi + +# Ignore the compiler's warnings at your own risk. +AM_CFLAGS="${AM_CFLAGS} -Wall -Wsign-compare -Wfloat-equal -Wformat-security" +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; enable_werror=$enableval +else + enable_werror=yes +fi + +if test x$enable_werror = xyes; then + AM_CFLAGS="${AM_CFLAGS} -Werror" +fi -for i in $x_subst_vars +# Check whether --enable-valgrind was given. +if test "${enable_valgrind+set}" = set; then : + enableval=$enable_valgrind; use_valgrind=$enableval +else + use_valgrind=no +fi + +if test x$use_valgrind = xyes; then + # Extract the first word of "valgrind", so it can be a program name with args. +set dummy valgrind; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_VALGRIND+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_VALGRIND"; then + ac_cv_prog_HAVE_VALGRIND="$HAVE_VALGRIND" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH do - x_val=`eval echo \\"\\$$i\\"` - x_sed="$x_sed -s&@$i@&$x_val&g" + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_HAVE_VALGRIND="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_VALGRIND" && ac_cv_prog_HAVE_VALGRIND="no" +fi +fi +HAVE_VALGRIND=$ac_cv_prog_HAVE_VALGRIND +if test -n "$HAVE_VALGRIND"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_VALGRIND" >&5 +$as_echo "$HAVE_VALGRIND" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x$HAVE_VALGRIND = xno; then + as_fn_error $? "valgrind not found" "$LINENO" 5 + fi +fi + if test "$use_valgrind" = yes; then + USE_VALGRIND_TRUE= + USE_VALGRIND_FALSE='#' +else + USE_VALGRIND_TRUE='#' + USE_VALGRIND_FALSE= +fi + + + + + -sed "$x_sed" Makefile.in > Makefile -echo "configure: creating config.h" + +ac_config_files="$ac_config_files Makefile sysdeps/Makefile sysdeps/linux-gnu/Makefile sysdeps/linux-gnu/alpha/Makefile sysdeps/linux-gnu/arm/Makefile sysdeps/linux-gnu/cris/Makefile sysdeps/linux-gnu/ia64/Makefile sysdeps/linux-gnu/m68k/Makefile sysdeps/linux-gnu/mipsel/Makefile sysdeps/linux-gnu/ppc/Makefile sysdeps/linux-gnu/s390/Makefile sysdeps/linux-gnu/sparc/Makefile sysdeps/linux-gnu/x86/Makefile testsuite/Makefile testsuite/ltrace.main/Makefile testsuite/ltrace.minor/Makefile testsuite/ltrace.torture/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. # -# config.h +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. # -exec > config.h +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. -echo '#define PACKAGE_NAME "ltrace"' -echo '#define PACKAGE_VERSION "'$PACKAGE_VERSION'"' +_ACEOF -if [ "$HAVE_LIBIBERTY" ] -then - echo '#define HAVE_LIBIBERTY 1' +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' else - echo '#undef HAVE_LIBIBERTY' + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= fi -if [ "$HAVE_LIBSUPC__" ] -then - echo '#define HAVE_LIBSUPC__ 1' +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_VALGRIND_TRUE}" && test -z "${USE_VALGRIND_FALSE}"; then + as_fn_error $? "conditional \"USE_VALGRIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST else - echo '#undef HAVE_LIBSUPC__' + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac fi -if [ "$HAVE_ELF_C_READ_MMAP" ] -then - echo '#define HAVE_ELF_C_READ_MMAP 1' + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' else - echo '#undef HAVE_ELF_C_READ_MMAP' + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ltrace $as_me 0.7.2, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <ltrace-devel@lists.alioth.debian.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ltrace config.status 0.7.2 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "sysdeps/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/Makefile" ;; + "sysdeps/linux-gnu/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/Makefile" ;; + "sysdeps/linux-gnu/alpha/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/alpha/Makefile" ;; + "sysdeps/linux-gnu/arm/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/arm/Makefile" ;; + "sysdeps/linux-gnu/cris/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/cris/Makefile" ;; + "sysdeps/linux-gnu/ia64/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/ia64/Makefile" ;; + "sysdeps/linux-gnu/m68k/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/m68k/Makefile" ;; + "sysdeps/linux-gnu/mipsel/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/mipsel/Makefile" ;; + "sysdeps/linux-gnu/ppc/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/ppc/Makefile" ;; + "sysdeps/linux-gnu/s390/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/s390/Makefile" ;; + "sysdeps/linux-gnu/sparc/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/sparc/Makefile" ;; + "sysdeps/linux-gnu/x86/Makefile") CONFIG_FILES="$CONFIG_FILES sysdeps/linux-gnu/x86/Makefile" ;; + "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; + "testsuite/ltrace.main/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/ltrace.main/Makefile" ;; + "testsuite/ltrace.minor/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/ltrace.minor/Makefile" ;; + "testsuite/ltrace.torture/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/ltrace.torture/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi -exit 0 diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..20c84f4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,327 @@ +# -*- Autoconf -*- +# This file is part of ltrace. +# Copyright (C) 2010,2012 Petr Machata, Red Hat Inc. +# Copyright (C) 2010,2011 Joe Damato +# Copyright (C) 2010 Marc Kleine-Budde +# Copyright (C) 2010 Zachary T Welch +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +# Process this file with autoconf to produce a configure script. +AC_PREREQ(2.65) + +AC_INIT([ltrace],[0.7.2],[ltrace-devel@lists.alioth.debian.org]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_SRCDIR(libltrace.c) +AC_CONFIG_MACRO_DIR([config/m4]) +AC_CONFIG_AUX_DIR([config/autoconf]) +AC_CANONICAL_BUILD +AC_CANONICAL_HOST + +case "${host_os}" in + linux-gnu*) HOST_OS="linux-gnu" ;; + *) AC_MSG_ERROR([unkown host-os ${host_os}]) ;; +esac +AC_SUBST(HOST_OS) + +case "${host_cpu}" in + arm*|sa110) HOST_CPU="arm" ;; + cris*) HOST_CPU="cris" ;; + mips*el) HOST_CPU="mipsel" ;; + mips*) HOST_CPU="mips" ;; + powerpc|powerpc64) HOST_CPU="ppc" ;; + sun4u|sparc64) HOST_CPU="sparc" ;; + s390x) HOST_CPU="s390" ;; + i?86|x86_64) HOST_CPU="x86" ;; + *) HOST_CPU="${host_cpu}" ;; +esac +AC_SUBST(HOST_CPU) + +# Checks for programs. +AC_PROG_CC +LT_INIT +# libtool-2: LT_INIT() +AM_INIT_AUTOMAKE([foreign no-exeext dist-bzip2]) +AM_MAINTAINER_MODE + +AC_ARG_WITH([libelf], + AS_HELP_STRING([--with-libelf], [Prefix of libelf headers/library]), + [case "${withval}" in + (no) + AC_MSG_ERROR([*** libelf is a required dependency]) + ;; + (yes) + AC_MSG_ERROR([*** --with-libelf requires you to specify a path]) + ;; + (*) + AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include" + AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib" + libelf_LD_LIBRARY_PATH="${withval}/lib" + ;; +esac],[]) + +# Checks for libraries. + +saved_CPPFLAGS="${CPPFLAGS}" +saved_LDFLAGS="${LDFLAGS}" +CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}" +LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}" +# libelf +AC_CHECK_HEADERS([elf.h gelf.h],, + [AC_MSG_ERROR([*** libelf.h or gelf.h not found on your system])] +) +AC_CHECK_LIB([elf], [elf_begin],, + [AC_MSG_ERROR([*** libelf not found on your system])] +) +CPPFLAGS="${saved_CPPFLAGS}" +LDFLAGS="${saved_LDFLAGS}" + + +# HAVE_LIBIBERTY +AC_CHECK_LIB([iberty], [cplus_demangle], [ + AC_DEFINE([HAVE_LIBIBERTY], [1], [we have libiberty]) + liberty_LIBS="-liberty"], [ + liberty_LIBS=""]) +AC_SUBST(liberty_LIBS) + + +# HAVE_LIBSUPC__ +AC_CHECK_LIB([supc++], [__cxa_demangle], [ + AC_DEFINE([HAVE_LIBSUPC__], [1], [we have libsupc++]) + libsupcxx_LIBS="-lsupc++"], [ + libsupcxx_LIBS=""]) +AC_SUBST(libsupcxx_LIBS) + + +# HAVE_LIBSTDC__ +AC_CHECK_LIB([stdc++], [__cxa_demangle], [ + AC_DEFINE([HAVE_LIBSTDC__], [1], [we have libstdc++]) + libstdcxx_LIBS="-lstdc++"], [ + libstdcxx_LIBS=""]) +AC_SUBST(libstdcxx_LIBS) + + +dnl Check security_get_boolean_active availability. +AC_CHECK_HEADERS(selinux/selinux.h) +AC_CHECK_LIB(selinux, security_get_boolean_active) + + +# HAVE_LIBUNWIND +AC_ARG_WITH(libunwind, + AS_HELP_STRING([--with-libunwind], [Use libunwind frame unwinding support]), + [case "${withval}" in + (yes|no) enable_libunwind=$withval;; + (*) enable_libunwind=yes + AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include" + AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib" + libunwind_LD_LIBRARY_PATH="${withval}/lib" + ;; +esac],[enable_libunwind=maybe]) + +saved_CPPFLAGS="${CPPFLAGS}" +CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}" +AC_CHECK_HEADERS([libunwind.h], [have_libunwind_h=yes]) +AC_CHECK_HEADERS([libunwind-ptrace.h], [have_libunwind_ptrace_h=yes]) +CPPFLAGS="${saved_CPPFLAGS}" + +AC_MSG_CHECKING([whether to use libunwind support]) +case "${enable_libunwind}" in +(yes|maybe) + if test x$have_libunwind_h = xyes -o x$have_libunwind_ptrace_h = xyes; then + enable_libunwind=yes + elif test $enable_libunwind = maybe; then + enable_libunwind=no + else + AC_MSG_RESULT([$enable_libunwind]) + AC_MSG_ERROR([libunwind.h or libunwind-ptrace.h cannot be found]) + fi + ;; +(*) ;; +esac +AC_MSG_RESULT([$enable_libunwind]) + +if test x"$enable_libunwind" = xyes; then + case "${host_cpu}" in + arm*|sa110) UNWIND_ARCH="arm" ;; + i?86) UNWIND_ARCH="x86" ;; + powerpc) UNWIND_ARCH="ppc32" ;; + powerpc64) UNWIND_ARCH="ppc64" ;; + mips*) UNWIND_ARCH="mips" ;; + *) UNWIND_ARCH="${host_cpu}" ;; + esac + + saved_LDFLAGS="${LDFLAGS}" + LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}" + AC_CHECK_LIB([unwind], [backtrace], [libunwind_LIBS=-lunwind], + [AC_MSG_ERROR([Couldn't find or use libunwind.])]) + + AC_CHECK_LIB([unwind-${UNWIND_ARCH}], [_U${UNWIND_ARCH}_init_remote], + [libunwind_LIBS="-lunwind-${UNWIND_ARCH} $libunwind_LIBS"], + [AC_MSG_ERROR([Couldn't find or use libunwind-${UNWIND_ARCH}.])], + [$libunwind_LIBS]) + + AC_CHECK_LIB([unwind-ptrace], [_UPT_create], + [libunwind_LIBS="-lunwind-ptrace $libunwind_LIBS"], + [AC_MSG_ERROR([Couldn't find or use libunwind-ptrace.])], + [$libunwind_LIBS]) + + AC_SUBST(libunwind_LIBS) + AC_DEFINE([HAVE_LIBUNWIND], [1], [we have libunwind]) + LDFLAGS="${saved_LDFLAGS}" +fi + + +saved_CPPFLAGS="${CPPFLAGS}" +saved_LDFLAGS="${LDFLAGS}" +CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}" +LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}" +# HAVE_ELF_C_READ_MMAP +AC_MSG_CHECKING([whether elf_begin accepts ELF_C_READ_MMAP]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <gelf.h>]], [[ +int main () { + Elf *elf = elf_begin(4, ELF_C_READ_MMAP, 0); + return 0; +} + ]])],[ + AC_DEFINE([HAVE_ELF_C_READ_MMAP], [1], [we have read mmap support]) + AC_MSG_RESULT([yes])],[ + AC_MSG_RESULT([no])]) + +saved_CFLAGS="${CFLAGS}" +CFLAGS="${CFLAGS} -Wall -Werror" +AC_MSG_CHECKING([whether elf_hash takes a char* argument]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libelf.h>]], [[ + (void) elf_hash("name"); + ]])], + [AC_DEFINE([ELF_HASH_TAKES_CHARP], [1], + [elf_hash() takes char* (as opposed to unsigned char *)]) + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])]) +CFLAGS="${saved_CFLAGS}" +CPPFLAGS="${saved_CPPFLAGS}" +LDFLAGS="${saved_LDFLAGS}" + +AM_CPPFLAGS=" \ + ${AM_CPPFLAGS} \ + -I\$(top_srcdir)/sysdeps/${HOST_OS}/${HOST_CPU} \ + -I\$(top_srcdir)/sysdeps/${HOST_OS} \ + -I\$(top_srcdir)/sysdeps \ + -I\$(top_srcdir) \ +" + +# Checks for header files. +AC_CHECK_HEADERS([ \ + fcntl.h \ + limits.h \ + stddef.h \ + stdint.h \ + stdlib.h \ + string.h \ + sys/ioctl.h \ + sys/param.h \ + sys/time.h \ + unistd.h \ +]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_UID_T +AC_C_INLINE +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_CHECK_SIZEOF([long]) + + +# Checks for library functions. +AC_FUNC_ERROR_AT_LINE +AC_FUNC_FORK +AC_CHECK_FUNCS([ \ + alarm \ + atexit \ + getcwd \ + gettimeofday \ + memset \ + mkdir \ + rmdir \ + strchr \ + strdup \ + strerror \ + strtol \ + strtoul \ +]) + + +# +# Debugging +# +AC_MSG_CHECKING([whether to enable debugging]) +AC_ARG_ENABLE(debug, + AS_HELP_STRING([--enable-debug], [enable debugging @<:@default=no@:>@]), + [case "$enableval" in + y | yes) CONFIG_DEBUG=yes ;; + *) CONFIG_DEBUG=no ;; + esac], + [CONFIG_DEBUG=no]) +AC_MSG_RESULT([${CONFIG_DEBUG}]) +if test "${CONFIG_DEBUG}" = "yes"; then + AC_DEFINE(DEBUG, 1, [debugging]) +fi + +# Ignore the compiler's warnings at your own risk. +AM_CFLAGS="${AM_CFLAGS} -Wall -Wsign-compare -Wfloat-equal -Wformat-security" +AC_ARG_ENABLE([werror], + AS_HELP_STRING([--disable-werror], [disable use of -Werror]), + [enable_werror=$enableval], [enable_werror=yes]) +if test x$enable_werror = xyes; then + AM_CFLAGS="${AM_CFLAGS} -Werror" +fi + +AC_ARG_ENABLE([valgrind], + AS_HELP_STRING([--enable-valgrind],[run all tests under valgrind]), + [use_valgrind=$enableval], [use_valgrind=no]) +if test x$use_valgrind = xyes; then + AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no) + if test x$HAVE_VALGRIND = xno; then + AC_MSG_ERROR([valgrind not found]) + fi +fi +AM_CONDITIONAL(USE_VALGRIND, test "$use_valgrind" = yes) + +AC_SUBST(AM_CPPFLAGS) +AC_SUBST(AM_CFLAGS) +AC_SUBST(AM_LDFLAGS) +AC_SUBST(libelf_LD_LIBRARY_PATH) +AC_SUBST(libunwind_LD_LIBRARY_PATH) + +AC_CONFIG_FILES([ + Makefile + sysdeps/Makefile + sysdeps/linux-gnu/Makefile + sysdeps/linux-gnu/alpha/Makefile + sysdeps/linux-gnu/arm/Makefile + sysdeps/linux-gnu/cris/Makefile + sysdeps/linux-gnu/ia64/Makefile + sysdeps/linux-gnu/m68k/Makefile + sysdeps/linux-gnu/mipsel/Makefile + sysdeps/linux-gnu/ppc/Makefile + sysdeps/linux-gnu/s390/Makefile + sysdeps/linux-gnu/sparc/Makefile + sysdeps/linux-gnu/x86/Makefile + testsuite/Makefile + testsuite/ltrace.main/Makefile + testsuite/ltrace.minor/Makefile + testsuite/ltrace.torture/Makefile +]) +AC_OUTPUT diff --git a/debian/changelog b/debian/changelog index f97cb8f..3547080 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +ltrace (0.6-1) unstable; urgency=low + + * New upstream release + * Support for cris added + * Numerous bugfixes for MIPS, ARM, and PPC + * Support for libunwind and libdl + + -- Joe Damato <ice799@gmail.com> Fri, 10 Dec 2010 00:41:20 -0800 + +ltrace (0.5.3-2) unstable; urgency=low + + * Fixed compilation problems in armel, ia64 and powerpc (closes: Bug#538441) + + -- Juan Cespedes <cespedes@debian.org> Sun, 26 Jul 2009 13:24:44 +0200 + ltrace (0.5.3-1) unstable; urgency=low * New upstream release diff --git a/debian/control.in b/debian/control index aff5316..75a177c 100644 --- a/debian/control.in +++ b/debian/control @@ -3,10 +3,10 @@ Section: utils Priority: optional Maintainer: Juan Cespedes <cespedes@debian.org> Standards-Version: 3.8.2 -Build-Depends: @cdbs@, binutils-dev, libelfg0-dev +Build-Depends: cdbs, debhelper (>= 7), dh-autoreconf, binutils-dev, libelfg0-dev, libunwind7-dev [i386 amd64 ia64] Package: ltrace -Architecture: i386 arm armeb armel m68k s390 powerpc sparc alpha amd64 ia64 ppc64 +Architecture: i386 arm armeb armel s390 powerpc sparc alpha amd64 ia64 ppc64 Depends: ${shlibs:Depends}, ${misc:Depends} Description: Tracks runtime library calls in dynamically linked programs ltrace is a debugging program which runs a specified command until it diff --git a/debian/rules b/debian/rules index 4105eb7..5d9c499 100755 --- a/debian/rules +++ b/debian/rules @@ -2,6 +2,7 @@ include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk +include /usr/share/cdbs/1/rules/autoreconf.mk install/ltrace:: rm -f debian/ltrace/usr/share/doc/ltrace/* @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2003,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <stdio.h> #include <stdarg.h> @@ -16,6 +37,7 @@ debug_(int level, const char *file, int line, const char *fmt, ...) { va_end(args); output_line(NULL, "DEBUG: %s:%d: %s", file, line, buf); + fflush(options.output); } /* @@ -101,7 +123,7 @@ xinfdump(long pid, void *ptr, int len) { addr = ((addr + sizeof(long) - 1) / sizeof(long)) * sizeof(long); for (i = 0; i < wrdcnt; ++i) { - infwords[i] = ptrace(PTRACE_PEEKTEXT, pid, addr); + infwords[i] = ptrace(PTRACE_PEEKTEXT, pid, (void *)addr, NULL); addr += sizeof(long); } @@ -1,4 +1,25 @@ -#include <features.h> +/* + * This file is part of ltrace. + * Copyright (C) 2003,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _DEBUG_H +#define _DEBUG_H /* debug levels: */ @@ -15,3 +36,4 @@ int xinfdump(long, void *, int); # define debug(level, expr...) debug_(level, __FILE__, __LINE__, expr) +#endif @@ -1,12 +1,29 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2008 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2006 Steve Fink + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #ifndef DEFAULT_ALIGN #define DEFAULT_ALIGN 50 /* default alignment column for results */ #endif /* (-a switch) */ -#ifndef MAX_ARGS -#define MAX_ARGS 32 /* maximum number of args for a function */ -#endif - #ifndef DEFAULT_STRLEN #define DEFAULT_STRLEN 32 /* default maximum # of bytes printed in */ #endif /* strings (-s switch) */ @@ -14,5 +31,3 @@ #ifndef DEFAULT_ARRAYLEN #define DEFAULT_ARRAYLEN 4 /* default maximum # array elements */ #endif /* (-A switch) */ - -#define MAX_LIBRARIES 30 @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,1999,2003,2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <string.h> @@ -15,9 +36,8 @@ static Dict *d = NULL; const char * my_demangle(const char *function_name) { const char *tmp, *fn_copy; -#if !defined HAVE_LIBIBERTY && defined HAVE_LIBSUPC__ +#ifdef USE_CXA_DEMANGLE extern char *__cxa_demangle(const char *, char *, size_t *, int *); - int status = 0; #endif debug(DEBUG_FUNCTION, "my_demangle(name=%s)", function_name); @@ -30,7 +50,8 @@ my_demangle(const char *function_name) { fn_copy = strdup(function_name); #ifdef HAVE_LIBIBERTY tmp = cplus_demangle(function_name, DMGL_ANSI | DMGL_PARAMS); -#elif defined HAVE_LIBSUPC__ +#elif defined USE_CXA_DEMANGLE + int status = 0; tmp = __cxa_demangle(function_name, NULL, NULL, &status); #endif if (!tmp) @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" extern char *cplus_demangle(const char *mangled, int options); @@ -1,3 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata + * Copyright (C) 2003,2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -6,8 +28,8 @@ #include "common.h" /* - Dictionary based on code by Morten Eriksen <mortene@sim.no>. -*/ + * Dictionary based on code by Morten Eriksen <mortene@sim.no>. + */ struct dict_entry { unsigned int hash; @@ -24,13 +46,14 @@ struct dict_entry { struct dict { struct dict_entry *buckets[DICTTABLESIZE]; - unsigned int (*key2hash) (void *); - int (*key_cmp) (void *, void *); + unsigned int (*key2hash) (const void *); + int (*key_cmp) (const void *, const void *); }; Dict * -dict_init(unsigned int (*key2hash) (void *), - int (*key_cmp) (void *, void *)) { +dict_init(unsigned int (*key2hash) (const void *), + int (*key_cmp) (const void *, const void *)) +{ Dict *d; int i; @@ -103,7 +126,33 @@ dict_enter(Dict *d, void *key, void *value) { } void * -dict_find_entry(Dict *d, void *key) { +dict_remove(Dict *d, void *key) +{ + assert(d != NULL); + debug(DEBUG_FUNCTION, "dict_remove(%p)", key); + + unsigned int hash = d->key2hash(key); + unsigned int bucketpos = hash % DICTTABLESIZE; + + struct dict_entry **entryp; + for (entryp = &d->buckets[bucketpos]; (*entryp) != NULL; + entryp = &(*entryp)->next) { + struct dict_entry *entry = *entryp; + if (hash != entry->hash) + continue; + if (d->key_cmp(key, entry->key) == 0) { + *entryp = entry->next; + void *value = entry->value; + free(entry); + return value; + } + } + return NULL; +} + +void * +dict_find_entry(Dict *d, const void *key) +{ unsigned int hash; unsigned int bucketpos; struct dict_entry *entry; @@ -147,7 +196,8 @@ dict_apply_to_all(Dict *d, /*****************************************************************************/ unsigned int -dict_key2hash_string(void *key) { +dict_key2hash_string(const void *key) +{ const char *s = (const char *)key; unsigned int total = 0, shift = 0; @@ -163,24 +213,29 @@ dict_key2hash_string(void *key) { } int -dict_key_cmp_string(void *key1, void *key2) { +dict_key_cmp_string(const void *key1, const void *key2) +{ assert(key1); assert(key2); return strcmp((const char *)key1, (const char *)key2); } unsigned int -dict_key2hash_int(void *key) { +dict_key2hash_int(const void *key) +{ return (unsigned long)key; } int -dict_key_cmp_int(void *key1, void *key2) { +dict_key_cmp_int(const void *key1, const void *key2) +{ return key1 - key2; } Dict * -dict_clone(Dict *old, void * (*key_clone)(void*), void * (*value_clone)(void*)) { +dict_clone2(Dict * old, void * (*key_clone)(void *, void *), + void * (*value_clone)(void *, void *), void * data) +{ Dict *d; int i; @@ -199,17 +254,64 @@ dict_clone(Dict *old, void * (*key_clone)(void*), void * (*value_clone)(void*)) de_old = old->buckets[i]; de_new = &d->buckets[i]; while (de_old) { + void * nkey, * nval; *de_new = malloc(sizeof(struct dict_entry)); if (!*de_new) { perror("malloc()"); exit(1); } memcpy(*de_new, de_old, sizeof(struct dict_entry)); - (*de_new)->key = key_clone(de_old->key); - (*de_new)->value = value_clone(de_old->value); + + /* The error detection is rather weak :-/ */ + nkey = key_clone(de_old->key, data); + if (nkey == NULL && de_old->key != NULL) { + perror("key_clone"); + err: + /* XXX Will this actually work? We + * simply memcpy the old dictionary + * over up there. */ + dict_clear(d); + free(de_new); + return NULL; + } + + nval = value_clone(de_old->value, data); + if (nval == NULL && de_old->value != NULL) { + perror("value_clone"); + goto err; + } + + (*de_new)->key = nkey; + (*de_new)->value = nval; de_new = &(*de_new)->next; de_old = de_old->next; } } return d; } + +struct wrap_clone_cb +{ + void * (*key_clone)(void *); + void * (*value_clone)(void *); +}; + +static void * +value_clone_1(void * arg, void * data) +{ + return ((struct wrap_clone_cb *)data)->value_clone(arg); +} + +static void * +key_clone_1(void * arg, void * data) +{ + return ((struct wrap_clone_cb *)data)->key_clone(arg); +} + +Dict * +dict_clone(Dict * old, void * (*key_clone)(void *), + void * (*value_clone)(void *)) +{ + struct wrap_clone_cb cb = { key_clone, value_clone }; + return dict_clone2(old, &key_clone_1, &value_clone_1, &cb); +} @@ -1,20 +1,55 @@ /* - Dictionary based on code by Morten Eriksen <mortene@sim.no>. -*/ + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata + * Copyright (C) 2003,2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) ???? Morten Eriksen <mortene@sim.no> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _DICT_H_ +#define _DICT_H_ + +/* + * Dictionary based on code by Morten Eriksen <mortene@sim.no>. + */ typedef struct dict Dict; -extern Dict *dict_init(unsigned int (*key2hash) (void *), - int (*key_cmp) (void *, void *)); +extern Dict *dict_init(unsigned int (*key2hash) (const void *), + int (*key_cmp) (const void *, const void *)); extern void dict_clear(Dict *d); extern int dict_enter(Dict *d, void *key, void *value); -extern void *dict_find_entry(Dict *d, void *key); +extern void *dict_remove(Dict *d, void *key); +extern void *dict_find_entry(Dict *d, const void *key); extern void dict_apply_to_all(Dict *d, void (*func) (void *key, void *value, void *data), void *data); -extern unsigned int dict_key2hash_string(void *key); -extern int dict_key_cmp_string(void *key1, void *key2); -extern unsigned int dict_key2hash_int(void *key); -extern int dict_key_cmp_int(void *key1, void *key2); +extern unsigned int dict_key2hash_string(const void *key); +extern int dict_key_cmp_string(const void *key1, const void *key2); + +extern unsigned int dict_key2hash_int(const void *key); +extern int dict_key_cmp_int(const void *key1, const void *key2); + extern Dict * dict_clone(Dict *old, void * (*key_clone)(void*), void * (*value_clone)(void*)); +extern Dict * dict_clone2(Dict * old, + void * (* key_clone)(void * key, void * data), + void * (* value_clone)(void * value, void * data), + void * data); + +#endif /* _DICT_H_ */ diff --git a/display_args.c b/display_args.c deleted file mode 100644 index 993a808..0000000 --- a/display_args.c +++ /dev/null @@ -1,460 +0,0 @@ -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#include "common.h" - -static int display_char(int what); -static int display_string(enum tof type, Process *proc, - void* addr, size_t maxlen); -static int display_value(enum tof type, Process *proc, - long value, arg_type_info *info, - void *st, arg_type_info* st_info); -static int display_unknown(enum tof type, Process *proc, long value); -static int display_format(enum tof type, Process *proc, int arg_num); - -static int string_maxlength = INT_MAX; -static int array_maxlength = INT_MAX; - -static long -get_length(enum tof type, Process *proc, int len_spec, - void *st, arg_type_info* st_info) { - long len; - arg_type_info info; - - if (len_spec > 0) - return len_spec; - if (type == LT_TOF_STRUCT) { - umovelong (proc, st + st_info->u.struct_info.offset[-len_spec-1], - &len, st_info->u.struct_info.fields[-len_spec-1]); - return len; - } - - info.type = ARGTYPE_INT; - return gimme_arg(type, proc, -len_spec-1, &info); -} - -static int -display_ptrto(enum tof type, Process *proc, long item, - arg_type_info * info, - void *st, arg_type_info* st_info) { - arg_type_info temp; - temp.type = ARGTYPE_POINTER; - temp.u.ptr_info.info = info; - return display_value(type, proc, item, &temp, st, st_info); -} - -/* - * addr - A pointer to the first element of the array - * - * The function name is used to indicate that we're not actually - * looking at an 'array', which is a contiguous region of memory - * containing a sequence of elements of some type; instead, we have a - * pointer to that region of memory. - */ -static int -display_arrayptr(enum tof type, Process *proc, - void *addr, arg_type_info * info, - void *st, arg_type_info* st_info) { - int len = 0; - int i; - int array_len; - - if (addr == NULL) - return fprintf(options.output, "NULL"); - - array_len = get_length(type, proc, info->u.array_info.len_spec, - st, st_info); - len += fprintf(options.output, "[ "); - for (i = 0; i < options.arraylen && i < array_maxlength && i < array_len; i++) { - arg_type_info *elt_type = info->u.array_info.elt_type; - size_t elt_size = info->u.array_info.elt_size; - if (i != 0) - len += fprintf(options.output, ", "); - if (options.debug) - len += fprintf(options.output, "%p=", addr); - len += - display_ptrto(type, proc, (long) addr, elt_type, st, st_info); - addr += elt_size; - } - if (i < array_len) - len += fprintf(options.output, "..."); - len += fprintf(options.output, " ]"); - return len; -} - -/* addr - A pointer to the beginning of the memory region occupied by - * the struct (aka a pointer to the struct) - */ -static int -display_structptr(enum tof type, Process *proc, - void *addr, arg_type_info * info) { - int i; - arg_type_info *field; - int len = 0; - - if (addr == NULL) - return fprintf(options.output, "NULL"); - - len += fprintf(options.output, "{ "); - for (i = 0; (field = info->u.struct_info.fields[i]) != NULL; i++) { - if (i != 0) - len += fprintf(options.output, ", "); - if (options.debug) - len += - fprintf(options.output, "%p=", - addr + info->u.struct_info.offset[i]); - len += - display_ptrto(LT_TOF_STRUCT, proc, - (long) addr + info->u.struct_info.offset[i], - field, addr, info); - } - len += fprintf(options.output, " }"); - - return len; -} - -static int -display_pointer(enum tof type, Process *proc, long value, - arg_type_info * info, - void *st, arg_type_info* st_info) { - long pointed_to; - arg_type_info *inner = info->u.ptr_info.info; - - if (inner->type == ARGTYPE_ARRAY) { - return display_arrayptr(type, proc, (void*) value, inner, - st, st_info); - } else if (inner->type == ARGTYPE_STRUCT) { - return display_structptr(type, proc, (void *) value, inner); - } else { - if (value == 0) - return fprintf(options.output, "NULL"); - else if (umovelong (proc, (void *) value, &pointed_to, - info->u.ptr_info.info) < 0) - return fprintf(options.output, "?"); - else - return display_value(type, proc, pointed_to, inner, - st, st_info); - } -} - -static int -display_enum(enum tof type, Process *proc, - arg_type_info* info, long value) { - int ii; - for (ii = 0; ii < info->u.enum_info.entries; ++ii) { - if (info->u.enum_info.values[ii] == value) - return fprintf(options.output, "%s", info->u.enum_info.keys[ii]); - } - - return display_unknown(type, proc, value); -} - -/* Args: - type - syscall or shared library function or memory - proc - information about the traced process - value - the value to display - info - the description of the type to display - st - if the current value is a struct member, the address of the struct - st_info - type of the above struct - - Those last two parameters are used for structs containing arrays or - strings whose length is given by another structure element. -*/ -int -display_value(enum tof type, Process *proc, - long value, arg_type_info *info, - void *st, arg_type_info* st_info) { - int tmp; - - switch (info->type) { - case ARGTYPE_VOID: - return 0; - case ARGTYPE_INT: - return fprintf(options.output, "%d", (int) value); - case ARGTYPE_UINT: - return fprintf(options.output, "%u", (unsigned) value); - case ARGTYPE_LONG: - if (proc->mask_32bit) - return fprintf(options.output, "%d", (int) value); - else - return fprintf(options.output, "%ld", value); - case ARGTYPE_ULONG: - if (proc->mask_32bit) - return fprintf(options.output, "%u", (unsigned) value); - else - return fprintf(options.output, "%lu", (unsigned long) value); - case ARGTYPE_OCTAL: - return fprintf(options.output, "0%o", (unsigned) value); - case ARGTYPE_CHAR: - tmp = fprintf(options.output, "'"); - tmp += display_char(value == -1 ? value : (char) value); - tmp += fprintf(options.output, "'"); - return tmp; - case ARGTYPE_SHORT: - return fprintf(options.output, "%hd", (short) value); - case ARGTYPE_USHORT: - return fprintf(options.output, "%hu", (unsigned short) value); - case ARGTYPE_FLOAT: { - union { long l; float f; double d; } cvt; - cvt.l = value; - return fprintf(options.output, "%f", cvt.f); - } - case ARGTYPE_DOUBLE: { - union { long l; float f; double d; } cvt; - cvt.l = value; - return fprintf(options.output, "%lf", cvt.d); - } - case ARGTYPE_ADDR: - if (!value) - return fprintf(options.output, "NULL"); - else - return fprintf(options.output, "0x%08lx", value); - case ARGTYPE_FORMAT: - fprintf(stderr, "Should never encounter a format anywhere but at the top level (for now?)\n"); - exit(1); - case ARGTYPE_STRING: - return display_string(type, proc, (void*) value, - string_maxlength); - case ARGTYPE_STRING_N: - return display_string(type, proc, (void*) value, - get_length(type, proc, - info->u.string_n_info.size_spec, st, st_info)); - case ARGTYPE_ARRAY: - return fprintf(options.output, "<array without address>"); - case ARGTYPE_ENUM: - return display_enum(type, proc, info, value); - case ARGTYPE_STRUCT: - return fprintf(options.output, "<struct without address>"); - case ARGTYPE_POINTER: - return display_pointer(type, proc, value, info, - st, st_info); - case ARGTYPE_UNKNOWN: - default: - return display_unknown(type, proc, value); - } -} - -int -display_arg(enum tof type, Process *proc, int arg_num, arg_type_info * info) { - long arg; - - if (info->type == ARGTYPE_VOID) { - return 0; - } else if (info->type == ARGTYPE_FORMAT) { - return display_format(type, proc, arg_num); - } else { - arg = gimme_arg(type, proc, arg_num, info); - return display_value(type, proc, arg, info, NULL, NULL); - } -} - -static int -display_char(int what) { - switch (what) { - case -1: - return fprintf(options.output, "EOF"); - case '\r': - return fprintf(options.output, "\\r"); - case '\n': - return fprintf(options.output, "\\n"); - case '\t': - return fprintf(options.output, "\\t"); - case '\b': - return fprintf(options.output, "\\b"); - case '\\': - return fprintf(options.output, "\\\\"); - default: - if (isprint(what)) { - return fprintf(options.output, "%c", what); - } else { - return fprintf(options.output, "\\%03o", (unsigned char)what); - } - } -} - -#define MIN(a,b) (((a)<(b)) ? (a) : (b)) - -static int -display_string(enum tof type, Process *proc, void *addr, - size_t maxlength) { - unsigned char *str1; - int i; - int len = 0; - - if (!addr) { - return fprintf(options.output, "NULL"); - } - - str1 = malloc(MIN(options.strlen, maxlength) + 3); - if (!str1) { - return fprintf(options.output, "???"); - } - umovestr(proc, addr, MIN(options.strlen, maxlength) + 1, str1); - len = fprintf(options.output, "\""); - for (i = 0; i < MIN(options.strlen, maxlength); i++) { - if (str1[i]) { - len += display_char(str1[i]); - } else { - break; - } - } - len += fprintf(options.output, "\""); - if (str1[i] && (options.strlen <= maxlength)) { - len += fprintf(options.output, "..."); - } - free(str1); - return len; -} - -static int -display_unknown(enum tof type, Process *proc, long value) { - if (proc->mask_32bit) { - if ((int)value < 1000000 && (int)value > -1000000) - return fprintf(options.output, "%d", (int)value); - else - return fprintf(options.output, "%p", (void *)value); - } else if (value < 1000000 && value > -1000000) { - return fprintf(options.output, "%ld", value); - } else { - return fprintf(options.output, "%p", (void *)value); - } -} - -static int -display_format(enum tof type, Process *proc, int arg_num) { - void *addr; - unsigned char *str1; - int i; - int len = 0; - arg_type_info info; - - info.type = ARGTYPE_POINTER; - addr = (void *)gimme_arg(type, proc, arg_num, &info); - if (!addr) { - return fprintf(options.output, "NULL"); - } - - str1 = malloc(MIN(options.strlen, string_maxlength) + 3); - if (!str1) { - return fprintf(options.output, "???"); - } - umovestr(proc, addr, MIN(options.strlen, string_maxlength) + 1, str1); - len = fprintf(options.output, "\""); - for (i = 0; len < MIN(options.strlen, string_maxlength) + 1; i++) { - if (str1[i]) { - len += display_char(str1[i]); - } else { - break; - } - } - len += fprintf(options.output, "\""); - if (str1[i] && (options.strlen <= string_maxlength)) { - len += fprintf(options.output, "..."); - } - for (i = 0; str1[i]; i++) { - if (str1[i] == '%') { - int is_long = 0; - while (1) { - unsigned char c = str1[++i]; - if (c == '%') { - break; - } else if (!c) { - break; - } else if (strchr("lzZtj", c)) { - is_long++; - if (c == 'j') - is_long++; - if (is_long > 1 - && (sizeof(long) < sizeof(long long) - || proc->mask_32bit)) { - len += fprintf(options.output, ", ..."); - str1[i + 1] = '\0'; - break; - } - } else if (c == 'd' || c == 'i') { - info.type = ARGTYPE_LONG; - if (!is_long || proc->mask_32bit) - len += - fprintf(options.output, ", %d", - (int)gimme_arg(type, proc, ++arg_num, &info)); - else - len += - fprintf(options.output, ", %ld", - gimme_arg(type, proc, ++arg_num, &info)); - break; - } else if (c == 'u') { - info.type = ARGTYPE_LONG; - if (!is_long || proc->mask_32bit) - len += - fprintf(options.output, ", %u", - (int)gimme_arg(type, proc, ++arg_num, &info)); - else - len += - fprintf(options.output, ", %lu", - gimme_arg(type, proc, ++arg_num, &info)); - break; - } else if (c == 'o') { - info.type = ARGTYPE_LONG; - if (!is_long || proc->mask_32bit) - len += - fprintf(options.output, ", 0%o", - (int)gimme_arg(type, proc, ++arg_num, &info)); - else - len += - fprintf(options.output, ", 0%lo", - gimme_arg(type, proc, ++arg_num, &info)); - break; - } else if (c == 'x' || c == 'X') { - info.type = ARGTYPE_LONG; - if (!is_long || proc->mask_32bit) - len += - fprintf(options.output, ", %#x", - (int)gimme_arg(type, proc, ++arg_num, &info)); - else - len += - fprintf(options.output, ", %#lx", - gimme_arg(type, proc, ++arg_num, &info)); - break; - } else if (strchr("eEfFgGaACS", c) - || (is_long - && (c == 'c' || c == 's'))) { - len += fprintf(options.output, ", ..."); - str1[i + 1] = '\0'; - break; - } else if (c == 'c') { - info.type = ARGTYPE_LONG; - len += fprintf(options.output, ", '"); - len += - display_char((int) - gimme_arg(type, proc, ++arg_num, &info)); - len += fprintf(options.output, "'"); - break; - } else if (c == 's') { - info.type = ARGTYPE_POINTER; - len += fprintf(options.output, ", "); - len += - display_string(type, proc, - (void *)gimme_arg(type, proc, ++arg_num, &info), - string_maxlength); - break; - } else if (c == 'p' || c == 'n') { - info.type = ARGTYPE_POINTER; - len += - fprintf(options.output, ", %p", - (void *)gimme_arg(type, proc, ++arg_num, &info)); - break; - } else if (c == '*') { - info.type = ARGTYPE_LONG; - len += - fprintf(options.output, ", %d", - (int)gimme_arg(type, proc, ++arg_num, &info)); - } - } - } - } - free(str1); - return len; -} @@ -1,619 +0,0 @@ -# include "config.h" - -#include <endian.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <gelf.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "common.h" - -static void do_init_elf(struct ltelf *lte, const char *filename); -static void do_close_elf(struct ltelf *lte); -static void add_library_symbol(GElf_Addr addr, const char *name, - struct library_symbol **library_symbolspp, - enum toplt type_of_plt, int is_weak); -static int in_load_libraries(const char *name, struct ltelf *lte); -static GElf_Addr opd2addr(struct ltelf *ltc, GElf_Addr addr); - -#ifdef PLT_REINITALISATION_BP -extern char *PLTs_initialized_by_here; -#endif - -static void -do_init_elf(struct ltelf *lte, const char *filename) { - int i; - GElf_Addr relplt_addr = 0; - size_t relplt_size = 0; - - debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename); - debug(1, "Reading ELF from %s...", filename); - - memset(lte, 0, sizeof(*lte)); - lte->fd = open(filename, O_RDONLY); - if (lte->fd == -1) - error(EXIT_FAILURE, errno, "Can't open \"%s\"", filename); - -#ifdef HAVE_ELF_C_READ_MMAP - lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); -#else - lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); -#endif - - if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) - error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename); - - if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) - error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"", - filename); - - if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) - error(EXIT_FAILURE, 0, - "\"%s\" is not an ELF executable nor shared library", - filename); - - if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS - || lte->ehdr.e_machine != LT_ELF_MACHINE) -#ifdef LT_ELF_MACHINE2 - && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 - || lte->ehdr.e_machine != LT_ELF_MACHINE2) -#endif -#ifdef LT_ELF_MACHINE3 - && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 - || lte->ehdr.e_machine != LT_ELF_MACHINE3) -#endif - ) - error(EXIT_FAILURE, 0, - "\"%s\" is ELF from incompatible architecture", filename); - - for (i = 1; i < lte->ehdr.e_shnum; ++i) { - Elf_Scn *scn; - GElf_Shdr shdr; - const char *name; - - scn = elf_getscn(lte->elf, i); - if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get section header from \"%s\"", - filename); - - name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); - if (name == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get section header from \"%s\"", - filename); - - if (shdr.sh_type == SHT_SYMTAB) { - Elf_Data *data; - - lte->symtab = elf_getdata(scn, NULL); - lte->symtab_count = shdr.sh_size / shdr.sh_entsize; - if ((lte->symtab == NULL - || elf_getdata(scn, lte->symtab) != NULL) - && opt_x != NULL) - error(EXIT_FAILURE, 0, - "Couldn't get .symtab data from \"%s\"", - filename); - - scn = elf_getscn(lte->elf, shdr.sh_link); - if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get section header from \"%s\"", - filename); - - data = elf_getdata(scn, NULL); - if (data == NULL || elf_getdata(scn, data) != NULL - || shdr.sh_size != data->d_size || data->d_off) - error(EXIT_FAILURE, 0, - "Couldn't get .strtab data from \"%s\"", - filename); - - lte->strtab = data->d_buf; - } else if (shdr.sh_type == SHT_DYNSYM) { - Elf_Data *data; - - lte->dynsym = elf_getdata(scn, NULL); - lte->dynsym_count = shdr.sh_size / shdr.sh_entsize; - if (lte->dynsym == NULL - || elf_getdata(scn, lte->dynsym) != NULL) - error(EXIT_FAILURE, 0, - "Couldn't get .dynsym data from \"%s\"", - filename); - - scn = elf_getscn(lte->elf, shdr.sh_link); - if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get section header from \"%s\"", - filename); - - data = elf_getdata(scn, NULL); - if (data == NULL || elf_getdata(scn, data) != NULL - || shdr.sh_size != data->d_size || data->d_off) - error(EXIT_FAILURE, 0, - "Couldn't get .dynstr data from \"%s\"", - filename); - - lte->dynstr = data->d_buf; - } else if (shdr.sh_type == SHT_DYNAMIC) { - Elf_Data *data; - size_t j; - - data = elf_getdata(scn, NULL); - if (data == NULL || elf_getdata(scn, data) != NULL) - error(EXIT_FAILURE, 0, - "Couldn't get .dynamic data from \"%s\"", - filename); - - for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { - GElf_Dyn dyn; - - if (gelf_getdyn(data, j, &dyn) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get .dynamic data from \"%s\"", - filename); -#ifdef __mips__ -/** - MIPS ABI Supplement: - - DT_PLTGOT This member holds the address of the .got section. - - DT_MIPS_SYMTABNO This member holds the number of entries in the - .dynsym section. - - DT_MIPS_LOCAL_GOTNO This member holds the number of local global - offset table entries. - - DT_MIPS_GOTSYM This member holds the index of the first dyamic - symbol table entry that corresponds to an entry in the gobal offset - table. - - */ - if(dyn.d_tag==DT_PLTGOT){ - lte->pltgot_addr=dyn.d_un.d_ptr; - } - if(dyn.d_tag==DT_MIPS_LOCAL_GOTNO){ - lte->mips_local_gotno=dyn.d_un.d_val; - } - if(dyn.d_tag==DT_MIPS_GOTSYM){ - lte->mips_gotsym=dyn.d_un.d_val; - } -#endif // __mips__ - if (dyn.d_tag == DT_JMPREL) - relplt_addr = dyn.d_un.d_ptr; - else if (dyn.d_tag == DT_PLTRELSZ) - relplt_size = dyn.d_un.d_val; - } - } else if (shdr.sh_type == SHT_HASH) { - Elf_Data *data; - size_t j; - - lte->hash_type = SHT_HASH; - - data = elf_getdata(scn, NULL); - if (data == NULL || elf_getdata(scn, data) != NULL - || data->d_off || data->d_size != shdr.sh_size) - error(EXIT_FAILURE, 0, - "Couldn't get .hash data from \"%s\"", - filename); - - if (shdr.sh_entsize == 4) { - /* Standard conforming ELF. */ - if (data->d_type != ELF_T_WORD) - error(EXIT_FAILURE, 0, - "Couldn't get .hash data from \"%s\"", - filename); - lte->hash = (Elf32_Word *) data->d_buf; - } else if (shdr.sh_entsize == 8) { - /* Alpha or s390x. */ - Elf32_Word *dst, *src; - size_t hash_count = data->d_size / 8; - - lte->hash = (Elf32_Word *) - malloc(hash_count * sizeof(Elf32_Word)); - if (lte->hash == NULL) - error(EXIT_FAILURE, 0, - "Couldn't convert .hash section from \"%s\"", - filename); - lte->lte_flags |= LTE_HASH_MALLOCED; - dst = lte->hash; - src = (Elf32_Word *) data->d_buf; - if ((data->d_type == ELF_T_WORD - && __BYTE_ORDER == __BIG_ENDIAN) - || (data->d_type == ELF_T_XWORD - && lte->ehdr.e_ident[EI_DATA] == - ELFDATA2MSB)) - ++src; - for (j = 0; j < hash_count; ++j, src += 2) - *dst++ = *src; - } else - error(EXIT_FAILURE, 0, - "Unknown .hash sh_entsize in \"%s\"", - filename); - } else if (shdr.sh_type == SHT_GNU_HASH - && lte->hash == NULL) { - Elf_Data *data; - - lte->hash_type = SHT_GNU_HASH; - - if (shdr.sh_entsize != 0 - && shdr.sh_entsize != 4) { - error(EXIT_FAILURE, 0, - ".gnu.hash sh_entsize in \"%s\" should be 4, but is %llu", - filename, shdr.sh_entsize); - } - - data = elf_getdata(scn, NULL); - if (data == NULL || elf_getdata(scn, data) != NULL - || data->d_off || data->d_size != shdr.sh_size) - error(EXIT_FAILURE, 0, - "Couldn't get .gnu.hash data from \"%s\"", - filename); - - lte->hash = (Elf32_Word *) data->d_buf; - } else if (shdr.sh_type == SHT_PROGBITS - || shdr.sh_type == SHT_NOBITS) { - if (strcmp(name, ".plt") == 0) { - lte->plt_addr = shdr.sh_addr; - lte->plt_size = shdr.sh_size; - if (shdr.sh_flags & SHF_EXECINSTR) { - lte->lte_flags |= LTE_PLT_EXECUTABLE; - } - } -#ifdef ARCH_SUPPORTS_OPD - else if (strcmp(name, ".opd") == 0) { - lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; - lte->opd_size = shdr.sh_size; - lte->opd = elf_rawdata(scn, NULL); - } -#endif - } - } - - if (lte->dynsym == NULL || lte->dynstr == NULL) - error(EXIT_FAILURE, 0, - "Couldn't find .dynsym or .dynstr in \"%s\"", filename); - - if (!relplt_addr || !lte->plt_addr) { - debug(1, "%s has no PLT relocations", filename); - lte->relplt = NULL; - lte->relplt_count = 0; - } else { - for (i = 1; i < lte->ehdr.e_shnum; ++i) { - Elf_Scn *scn; - GElf_Shdr shdr; - - scn = elf_getscn(lte->elf, i); - if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get section header from \"%s\"", - filename); - if (shdr.sh_addr == relplt_addr - && shdr.sh_size == relplt_size) { - lte->relplt = elf_getdata(scn, NULL); - lte->relplt_count = - shdr.sh_size / shdr.sh_entsize; - if (lte->relplt == NULL - || elf_getdata(scn, lte->relplt) != NULL) - error(EXIT_FAILURE, 0, - "Couldn't get .rel*.plt data from \"%s\"", - filename); - break; - } - } - - if (i == lte->ehdr.e_shnum) - error(EXIT_FAILURE, 0, - "Couldn't find .rel*.plt section in \"%s\"", - filename); - - debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); - } -} - -static void -do_close_elf(struct ltelf *lte) { - debug(DEBUG_FUNCTION, "do_close_elf()"); - if (lte->lte_flags & LTE_HASH_MALLOCED) - free((char *)lte->hash); - elf_end(lte->elf); - close(lte->fd); -} - -static void -add_library_symbol(GElf_Addr addr, const char *name, - struct library_symbol **library_symbolspp, - enum toplt type_of_plt, int is_weak) { - struct library_symbol *s; - - debug(DEBUG_FUNCTION, "add_library_symbol()"); - - s = malloc(sizeof(struct library_symbol) + strlen(name) + 1); - if (s == NULL) - error(EXIT_FAILURE, errno, "add_library_symbol failed"); - - s->needs_init = 1; - s->is_weak = is_weak; - s->plt_type = type_of_plt; - s->next = *library_symbolspp; - s->enter_addr = (void *)(uintptr_t) addr; - s->name = (char *)(s + 1); - strcpy(s->name, name); - *library_symbolspp = s; - - debug(2, "addr: %p, symbol: \"%s\"", (void *)(uintptr_t) addr, name); -} - -/* stolen from elfutils-0.123 */ -static unsigned long -private_elf_gnu_hash(const char *name) { - unsigned long h = 5381; - const unsigned char *string = (const unsigned char *)name; - unsigned char c; - for (c = *string; c; c = *++string) - h = h * 33 + c; - return h & 0xffffffff; -} - -static int -in_load_libraries(const char *name, struct ltelf *lte) { - size_t i; - unsigned long hash; - unsigned long gnu_hash; - - if (!library_num) - return 1; - - hash = elf_hash((const unsigned char *)name); - gnu_hash = private_elf_gnu_hash(name); - for (i = 1; i <= library_num; ++i) { - if (lte[i].hash == NULL) - continue; - - if (lte[i].hash_type == SHT_GNU_HASH) { - Elf32_Word * hashbase = lte[i].hash; - Elf32_Word nbuckets = *hashbase++; - Elf32_Word symbias = *hashbase++; - Elf32_Word bitmask_nwords = *hashbase++; - Elf32_Word * buckets; - Elf32_Word * chain_zero; - Elf32_Word bucket; - - // +1 for skipped `shift' - hashbase += lte[i].ehdr.e_ident[EI_CLASS] * bitmask_nwords + 1; - buckets = hashbase; - hashbase += nbuckets; - chain_zero = hashbase - symbias; - bucket = buckets[gnu_hash % nbuckets]; - - if (bucket != 0) { - const Elf32_Word *hasharr = &chain_zero[bucket]; - do - if ((*hasharr & ~1u) == (gnu_hash & ~1u)) { - int symidx = hasharr - chain_zero; - GElf_Sym sym; - - if (gelf_getsym(lte[i].dynsym, symidx, &sym) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get symbol from .dynsym"); - - if (sym.st_value != 0 - && sym.st_shndx != SHN_UNDEF - && strcmp(name, lte[i].dynstr + sym.st_name) == 0) - return 1; - } - while ((*hasharr++ & 1u) == 0); - } - } else { - Elf32_Word nbuckets, symndx; - Elf32_Word *buckets, *chain; - nbuckets = lte[i].hash[0]; - buckets = <e[i].hash[2]; - chain = <e[i].hash[2 + nbuckets]; - - for (symndx = buckets[hash % nbuckets]; - symndx != STN_UNDEF; symndx = chain[symndx]) { - GElf_Sym sym; - - if (gelf_getsym(lte[i].dynsym, symndx, &sym) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get symbol from .dynsym"); - - if (sym.st_value != 0 - && sym.st_shndx != SHN_UNDEF - && strcmp(name, lte[i].dynstr + sym.st_name) == 0) - return 1; - } - } - } - return 0; -} - -static GElf_Addr -opd2addr(struct ltelf *lte, GElf_Addr addr) { -#ifdef ARCH_SUPPORTS_OPD - unsigned long base, offset; - - if (!lte->opd) - return addr; - - base = (unsigned long)lte->opd->d_buf; - offset = (unsigned long)addr - (unsigned long)lte->opd_addr; - if (offset > lte->opd_size) - error(EXIT_FAILURE, 0, "static plt not in .opd"); - - return *(GElf_Addr*)(base + offset); -#else //!ARCH_SUPPORTS_OPD - return addr; -#endif -} - -struct library_symbol * -read_elf(Process *proc) { - struct library_symbol *library_symbols = NULL; - struct ltelf lte[MAX_LIBRARIES + 1]; - size_t i; - struct opt_x_t *xptr; - struct library_symbol **lib_tail = NULL; - int exit_out = 0; - - debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename); - - elf_version(EV_CURRENT); - - do_init_elf(lte, proc->filename); - proc->e_machine = lte->ehdr.e_machine; - for (i = 0; i < library_num; ++i) - do_init_elf(<e[i + 1], library[i]); -#ifdef __mips__ - // MIPS doesn't use the PLT and the GOT entries get changed - // on startup. - proc->need_to_reinitialize_breakpoints = 1; - for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){ - GElf_Sym sym; - const char *name; - GElf_Addr addr = arch_plt_sym_val(lte, i, 0); - if (gelf_getsym(lte->dynsym, i, &sym) == NULL){ - error(EXIT_FAILURE, 0, - "Couldn't get relocation from \"%s\"", - proc->filename); - } - name=lte->dynstr+sym.st_name; - if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){ - debug(2,"sym %s not a function",name); - continue; - } - add_library_symbol(addr, name, &library_symbols, 0, - ELF64_ST_BIND(sym.st_info) != 0); - if (!lib_tail) - lib_tail = &(library_symbols->next); - } -#else - for (i = 0; i < lte->relplt_count; ++i) { - GElf_Rel rel; - GElf_Rela rela; - GElf_Sym sym; - GElf_Addr addr; - void *ret; - const char *name; - - if (lte->relplt->d_type == ELF_T_REL) { - ret = gelf_getrel(lte->relplt, i, &rel); - rela.r_offset = rel.r_offset; - rela.r_info = rel.r_info; - rela.r_addend = 0; - } else - ret = gelf_getrela(lte->relplt, i, &rela); - - if (ret == NULL - || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count - || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info), - &sym) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get relocation from \"%s\"", - proc->filename); - -#ifdef PLT_REINITALISATION_BP - if (!sym.st_value && PLTs_initialized_by_here) - proc->need_to_reinitialize_breakpoints = 1; -#endif - - name = lte->dynstr + sym.st_name; - if (in_load_libraries(name, lte)) { - addr = arch_plt_sym_val(lte, i, &rela); - add_library_symbol(addr, name, &library_symbols, - (PLTS_ARE_EXECUTABLE(lte) - ? LS_TOPLT_EXEC : LS_TOPLT_POINT), - ELF64_ST_BIND(sym.st_info) == STB_WEAK); - if (!lib_tail) - lib_tail = &(library_symbols->next); - } - } -#endif // !__mips__ -#ifdef PLT_REINITALISATION_BP - struct opt_x_t *main_cheat; - - if (proc->need_to_reinitialize_breakpoints) { - /* Add "PLTs_initialized_by_here" to opt_x list, if not - already there. */ - main_cheat = (struct opt_x_t *)malloc(sizeof(struct opt_x_t)); - if (main_cheat == NULL) - error(EXIT_FAILURE, 0, "Couldn't allocate memory"); - main_cheat->next = opt_x; - main_cheat->found = 0; - main_cheat->name = PLTs_initialized_by_here; - - for (xptr = opt_x; xptr; xptr = xptr->next) - if (strcmp(xptr->name, PLTs_initialized_by_here) == 0 - && main_cheat) { - free(main_cheat); - main_cheat = NULL; - break; - } - if (main_cheat) - opt_x = main_cheat; - } -#endif - - for (i = 0; i < lte->symtab_count; ++i) { - GElf_Sym sym; - GElf_Addr addr; - const char *name; - - if (gelf_getsym(lte->symtab, i, &sym) == NULL) - error(EXIT_FAILURE, 0, - "Couldn't get symbol from \"%s\"", - proc->filename); - - name = lte->strtab + sym.st_name; - addr = sym.st_value; - if (!addr) - continue; - - for (xptr = opt_x; xptr; xptr = xptr->next) - if (xptr->name && strcmp(xptr->name, name) == 0) { - /* FIXME: Should be able to use &library_symbols as above. But - when you do, none of the real library symbols cause breaks. */ - add_library_symbol(opd2addr(lte, addr), - name, lib_tail, LS_TOPLT_NONE, 0); - xptr->found = 1; - break; - } - } - for (xptr = opt_x; xptr; xptr = xptr->next) - if ( ! xptr->found) { - char *badthing = "WARNING"; -#ifdef PLT_REINITALISATION_BP - if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) { - if (lte->ehdr.e_entry) { - add_library_symbol ( - opd2addr (lte, lte->ehdr.e_entry), - PLTs_initialized_by_here, - lib_tail, 1, 0); - fprintf (stderr, "WARNING: Using e_ent" - "ry from elf header (%p) for " - "address of \"%s\"\n", (void*) - (long) lte->ehdr.e_entry, - PLTs_initialized_by_here); - continue; - } - badthing = "ERROR"; - exit_out = 1; - } -#endif - fprintf (stderr, - "%s: Couldn't find symbol \"%s\" in file \"%s" - "\"\n", badthing, xptr->name, proc->filename); - } - if (exit_out) { - exit (1); - } - - for (i = 0; i < library_num + 1; ++i) - do_close_elf(<e[i]); - - return library_symbols; -} @@ -1,49 +0,0 @@ -#ifndef LTRACE_ELF_H -#define LTRACE_ELF_H - -#include <gelf.h> -#include <stdlib.h> - -struct ltelf { - int fd; - Elf *elf; - GElf_Ehdr ehdr; - Elf_Data *dynsym; - size_t dynsym_count; - const char *dynstr; - GElf_Addr plt_addr; - size_t plt_size; - Elf_Data *relplt; - size_t relplt_count; - Elf_Data *symtab; - const char *strtab; - size_t symtab_count; - Elf_Data *opd; - GElf_Addr *opd_addr; - size_t opd_size; - Elf32_Word *hash; - int hash_type; - int lte_flags; -#ifdef __mips__ - size_t pltgot_addr; - size_t mips_local_gotno; - size_t mips_gotsym; -#endif // __mips__ -}; - -#define LTE_HASH_MALLOCED 1 -#define LTE_PLT_EXECUTABLE 2 - -#define PLTS_ARE_EXECUTABLE(lte) ((lte->lte_flags & LTE_PLT_EXECUTABLE) != 0) - -extern int library_num; -extern char *library[MAX_LIBRARIES]; - -extern struct library_symbol *read_elf(Process *); - -extern GElf_Addr arch_plt_sym_val(struct ltelf *, size_t, GElf_Rela *); - -#ifndef SHT_GNU_HASH -#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -#endif -#endif diff --git a/etc/ltrace.conf b/etc/ltrace.conf index ed4fc5a..8f83986 100644 --- a/etc/ltrace.conf +++ b/etc/ltrace.conf @@ -4,104 +4,21 @@ ; used to suppress the automatic inclusion of both this file and ; ~/.ltrace.conf, and load a different config file or config files ; instead. - -; Argument types: -; + == May vary (ie, is a returned value) (prefix) -; void -; int -; uint == (unsigned int) -; long -; ulong == (unsigned long) -; octal == (unsigned) [written in octal] -; char -; short == (short) -; ushort == (unsigned short) -; addr == (void *) [unsigned, written in hexa] -; file == (FILE *) [TODO] -; format == ((const char *), ...) [printf() like] [TODO] -; string == (char *) -; string[argN] == (char *) [N>0] [show only up to (arg N) bytes] -; string[eltN] == (char *) [N>0] [show only up to (elt N) bytes] -; string[retval] == (char *) [show only up to (return val) bytes] -; string[arg0] == (char *) [same as string[retval]] -; string[N] == (char *) [N>0] [show only up to N bytes] -; type* == (type *) [pointer to any other type] -; enum (key=value,key=value,...) [enumeration, see below] -; array(type,argN) -; == (type[SIZE]) [array of (arg N) elements] -; array(type,eltN) -; == (type[SIZE]) [array of (struct element N) elements] -; array(type,N) == (type[N]) [array of N elements] -; struct(type,type,...) -; == (struct {...}) [struct of several types] ; -; Backwards-compatibility: -; string0 == (char *) [same as string[retval]] -; stringN == (char *) [N>0] [same as string[argN]] - - - -; Typedefs -; -; To make it easier to specify argument lists, you can use 'typedef' -; directives to avoid repeating complex parameter descriptors: -; -; typedef color = enum(RED=1,BLUE=2,GREEN=3) -; void draw_line(color,int,int,int,int) -; void draw_square(color,int,int,int,int) -; -; Enumerations -; -; The syntax is a parenthesized list of key=value assignments, like so: -; enum (F_DUPFD=0,F_GETFD=1,F_SETFD=2) -; an example usage might look like -; int fcntl(int,enum (F_DUPFD=0,F_GETFD=1,F_SETFD=2)) -; -; Arrays -; -; NOTE: Uses of array(...) alone are very rare. You almost always -; want array(...)*. The exceptions are when you have a fixed-size -; array. -; -; Structs -; -; NOTE: Uses of struct(...) alone are very rare. You almost always -; want struct(...)* (a pointer to a struct) anyway. Most compilers -; pass structs as pointers anyway, and those that don't are not yet -; supported. The one time when you want to use a non-pointer -; struct(...) type are when you have an array of structs, or a struct -; containing another struct. -; -; For example, if you have -; struct s1 { -; int y_size; -; int * y; -; int z[3]; -; struct { char c; } a; -; struct { char c; } * b; -; } -; and a function -; void f(struct s1*) -; then the corresponding ltrace spec is -; void f(struct(int,array(int,elt0),array(int,3),struct(char),struct(char)*)*) -; which, formatted similarly to the C declaration, looks like -; void f(struct( -; int, -; array(int,elt0), -; array(int,3), -; struct(char), -; struct(char)* -; )* -; ) - +; See ltrace.conf(5) for description of syntax of this file. ; arpa/inet.h -int inet_aton(string,addr); -string inet_ntoa(addr); ; It isn't an ADDR but an hexa number... -addr inet_addr(string); +typedef in_addr = struct(hex(uint)); +int inet_aton(string, +in_addr*); +hex(uint) inet_addr(string); +hex(uint) inet_network(string); +string inet_ntoa(in_addr); +in_addr inet_makeaddr(hex(int), hex(int)); +hex(uint) inet_lnaof(in_addr); +hex(uint) inet_netof(in_addr); ; bfd.h -void bfd_init(void); +void bfd_init(); int bfd_set_default_target(string); addr bfd_scan_vma(string, addr, int); addr bfd_openr(string,string); @@ -110,9 +27,10 @@ int bfd_check_format(addr,int); ; ctype.h char tolower(char); char toupper(char); -addr __ctype_b_loc(void); -addr __ctype_tolower_loc(void); -addr __ctype_toupper_loc(void); +addr __ctype_b_loc(); +addr __ctype_tolower_loc(); +addr __ctype_toupper_loc(); +ulong __ctype_get_mb_cur_max(); ; curses.h int waddch(addr, char); @@ -129,12 +47,12 @@ addr readdir64(addr); ; dlfcn.h addr dlopen(string, int); -string dlerror(void); +string dlerror(); addr dlsym(addr, string); int dlclose(addr); ; errno.h -addr __errno_location(void); +addr __errno_location(); ; fcntl.h int open(string,int,octal); ; WARNING: 3rd argument may not be there @@ -148,10 +66,10 @@ int getopt_long(int,addr,string,addr,int*); int getopt_long_only(int,addr,string,addr,addr); ; grp.h -void endgrent(void); +void endgrent(); addr getgrnam(string); -void setgrent(void); -addr getgrent(void); +void setgrent(); +addr getgrent(); ; libintl.h string __dcgettext(string,string,int); @@ -163,16 +81,11 @@ char _IO_getc(file); int _IO_putc(char,file); ; locale.h -string setlocale(int, string); +string setlocale(enum(LC_CTYPE=0, LC_NUMERIC=1, LC_TIME=2, LC_COLLATE=3, LC_MONETARY=4, LC_MESSAGES=5, LC_ALL=6, LC_PAPER=7, LC_NAME=8, LC_ADDRESS=9, LC_TELEPHONE=10, LC_MEASUREMENT=11, LC_IDENTIFICATION=12), string); ; mcheck.h -void mtrace(void); -void muntrace(void); - -; mntent.h -int endmntent(file); -file setmntent(string,string); -addr getmntent(addr); +void mtrace(); +void muntrace(); ; mqueue.h int mq_open(string, int, octal, addr); ; WARNING: 3rd and 4th arguments may not be there @@ -187,28 +100,28 @@ long mq_receive(int, +string0, ulong, addr); long mq_timedreceive(int, +string0, ulong, addr, addr); ; netdb.h -void endhostent(void); -void endnetent(void); -void endnetgrent(void); -void endprotoent(void); -void endservent(void); +void endhostent(); +void endnetent(); +void endnetgrent(); +void endprotoent(); +void endservent(); void freeaddrinfo(addr); string gai_strerror(int); int getaddrinfo(string, string, addr, addr); addr gethostbyaddr(string, uint, int); addr gethostbyname(string); -addr gethostent(void); +addr gethostent(); int getnameinfo(addr, uint, string, uint, string, uint, uint); addr getnetbyaddr(uint, int); addr getnetbyname(string); -addr getnetent(void); +addr getnetent(); int getnetgrent(addr, addr, addr); addr getprotobyname(string); addr getprotobynumber(int); -addr getprotoent(void); +addr getprotoent(); addr getservbyname(string, string); addr getservbyport(int, string); -addr getservent(void); +addr getservent(); void herror(string); string hstrerror(int); int rcmd(addr, ushort, string, string, string, addr); @@ -237,25 +150,32 @@ int pcap_compile(addr, addr, string, int, addr); ; pwd.h string getpass(string); -void endpwent(void); +void endpwent(); addr getpwnam(string); -void setpwent(void); +void setpwent(); ; readline/readline.h string readline(string); ; signal.h -int kill(int,int); -addr signal(int,addr); -int sigemptyset(addr); -int sigfillset(addr); -int sigaddset(addr, int); -int sigdelset(addr, int); -int sigismember(addr, int); -int sigaction(int, addr, addr); -int sigprocmask(int, addr, addr); -int sigpending(addr); -int sigsuspend(addr); +typedef signum = enum(SIGHUP=1, SIGINT=2, SIGQUIT=3, SIGILL=4, SIGTRAP=5, SIGABRT=6, SIGBUS=7, SIGFPE=8, SIGKILL=9, SIGUSR1=10, SIGSEGV=11, SIGUSR2=12, SIGPIPE=13, SIGALRM=14, SIGTERM=15, SIGSTKFLT=16, SIGCHLD=17, SIGCONT=18, SIGSTOP=19, SIGTSTP=20, SIGTTIN=21, SIGTTOU=22, SIGURG=23, SIGXCPU=24, SIGXFSZ=25, SIGVTALRM=26, SIGPROF=27, SIGWINCH=28, SIGIO=29, SIGPWR=30, SIGSYS=31, SIGRTMIN_0=32, SIGRTMIN_1=33, SIGRTMIN_2=34, SIGRTMIN_3=35, SIGRTMIN_4=36, SIGRTMIN_5=37, SIGRTMIN_6=38, SIGRTMIN_7=39, SIGRTMIN_8=40, SIGRTMIN_9=41, SIGRTMIN_10=42, SIGRTMIN_11=43, SIGRTMIN_12=44, SIGRTMIN_13=45, SIGRTMIN_14=46, SIGRTMIN_15=47, SIGRTMIN_16=48, SIGRTMIN_17=49, SIGRTMIN_18=50, SIGRTMIN_19=51, SIGRTMIN_20=52, SIGRTMIN_21=53, SIGRTMIN_22=54, SIGRTMIN_23=55, SIGRTMIN_24=56, SIGRTMIN_25=57, SIGRTMIN_26=58, SIGRTMIN_27=59, SIGRTMIN_28=60, SIGRTMIN_29=61, SIGRTMIN_30=62, SIGRTMIN_31=63); +typedef sigset_t = bitvec(ulong); +; elm3 should be flags +typedef sigaction = struct(addr, sigset_t, hex(int), addr); +int kill(int, signum); +int sigemptyset(+sigset_t*); +int sigaddset(+sigset_t*, signum); +int sigdelset(+sigset_t*, signum); +int sigfillset(+sigset_t*); +int sigismember(sigset_t*, signum); +addr signal(signum,addr); +int sigaction(signum, sigaction*, +sigaction*); +int sigprocmask(enum(SIG_BLOCK=1, SIG_UNBLOCK=2, SIG_SETMASK=3), sigset_t*, +sigset_t*); +int sigpending(+sigset_t*); +int sigsuspend(sigset_t*); +int sigisemptyset(sigset_t*); +int sigorset(+sigset_t*, sigset_t*, sigset_t*); +int sigandset(+sigset_t*, sigset_t*, sigset_t*); ; stdio.h int fclose(file); @@ -305,7 +225,7 @@ int setenv(string,string,int); void unsetenv(string); addr malloc(ulong); void qsort(addr,ulong,ulong,addr); -int random(void); +int random(); addr realloc(addr,ulong); void srandom(uint); int system(string); @@ -316,7 +236,8 @@ void bzero(addr,ulong); string basename(string); string index(string,char); addr memchr(string,char,ulong); -addr memcpy(addr,string3,ulong); +addr memcpy(addr,string(array(char, arg3)*),ulong); +addr memmove(addr,string(array(char, arg3)*),ulong); addr memset(addr,char,long); string rindex(string,char); addr stpcpy(addr,string); @@ -363,7 +284,7 @@ int uname(addr); int statfs(string,addr); ; syslog.h -void closelog(void); +void closelog(); void openlog(string,int,int); void syslog(int,format); @@ -394,21 +315,21 @@ int dup2(int,int); int execlp(string,string,addr,addr,addr); int execv(string,addr); int fchdir(int); -int fork(void); +int fork(); int ftruncate(int,ulong); string2 getcwd(addr,ulong); int getdomainname(+string2,ulong); -int geteuid(void); -int getegid(void); -int getgid(void); +int geteuid(); +int getegid(); +int getgid(); int gethostname(+string2,ulong); -string getlogin(void); +string getlogin(); int getopt(int,addr,string); -int getpid(void); -int getppid(void); -int getuid(void); -int getpgrp(void); -int setpgrp(void); +int getpid(); +int getppid(); +int getuid(); +int getpgrp(); +int setpgrp(); int getpgid(int); int isatty(int); int link(string,string); @@ -423,21 +344,21 @@ int setreuid(uint, uint); int setuid(int); uint sleep(uint); int symlink(string,string); -int sync(void); +int sync(); int truncate(string,ulong); string ttyname(int); int unlink(string); void usleep(uint); long write(int, string3, ulong); addr sbrk(long); -int getpagesize(void); +int getpagesize(); long lseek(int,long,int); int pipe(addr); ; utmp.h -void endutent(void); -addr getutent(void); -void setutent(void); +void endutent(); +addr getutent(); +void setutent(); ; wchar.h int fwide(addr, int); @@ -479,7 +400,7 @@ int acl_set_qualifier(addr,addr); int acl_set_tag_type(addr,int); int acl_size(addr); string acl_to_text(addr,addr); -itn acl_valid(addr); +int acl_valid(addr); ; acl/libacl.h int acl_check(addr,addr); @@ -493,15 +414,33 @@ addr acl_from_mode(octal); int acl_get_perm(addr,uint); string acl_to_any_text(addr,string,char,int); +; other symbols not included above +long a64l(string); +string l64a(long); +void abort(); +int abs(int); +long labs(long); + +typedef mntent = struct(string, string, string, string, int, int); +int addmntent(file, mntent*); +int endmntent(file); +int __endmntent(file); +file setmntent(string,string); +file __setmntent(string,string); +mntent *getmntent(addr); +mntent *getmntent_r(file, +mntent*, string, int); +mntent *__getmntent_r(file, +mntent*, string, int); +string hasmntopt(mntent*, string); + ; SYSCALLS addr SYS_brk(addr); int SYS_close(int); int SYS_execve(string,addr,addr); void SYS_exit(int); void SYS_exit_group(int); -int SYS_fork(void); +int SYS_fork(); int SYS_getcwd(+string2,ulong); -int SYS_getpid(void); +int SYS_getpid(); ;addr SYS_mmap(addr,ulong,int,int,int,long); int SYS_munmap(addr,ulong); int SYS_open(string,int,octal); @@ -511,7 +450,7 @@ int SYS_stat(string,addr); octal SYS_umask(octal); int SYS_uname(addr); long SYS_write(int,string3,ulong); -int SYS_sync(void); +int SYS_sync(); int SYS_setxattr(string,string,addr,uint,int); int SYS_lsetxattr(string,string,addr,uint,int); int SYS_fsetxattr(int,string,addr,uint,int); @@ -544,16 +483,16 @@ int SYS_gettimeofday(addr,addr); int SYS_settimeofday(addr,addr); int SYS_setfsgid(int); int SYS_setfsuid(int); -int SYS_getuid(void); +int SYS_getuid(); int SYS_setuid(int); -int SYS_getgid(void); +int SYS_getgid(); int SYS_setgid(int); int SYS_getsid(int); int SYS_setsid(int); int SYS_setreuid(int,int); int SYS_setregid(int,int); -int SYS_geteuid(void); -int SYS_getegid(void); +int SYS_geteuid(); +int SYS_getegid(); int SYS_setpgid(int,int); int SYS_getresuid(addr,addr,addr); int SYS_setresuid(int,int,int); @@ -591,7 +530,7 @@ int SYS_utime(string,addr); long SYS_lseek(int,long,int); addr SYS_signal(int,addr); int SYS_sigaction(int,addr,addr); -int SYS_pause(void); +int SYS_pause(); int SYS_sigpending(addr); int SYS_sigprocmask(int,addr,addr); int SYS_sigqueue(int,int,addr); diff --git a/execute_program.c b/execute_program.c index 5fd6379..b24f2ee 100644 --- a/execute_program.c +++ b/execute_program.c @@ -1,5 +1,31 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1998,1999,2003,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #include "config.h" +#if defined(HAVE_LIBUNWIND) +#include <libunwind-ptrace.h> +#endif /* defined(HAVE_LIBUNWIND) */ + #include <stdio.h> #include <stdlib.h> #include <sys/types.h> @@ -10,10 +36,13 @@ #include <pwd.h> #include <grp.h> -#include "common.h" +#include "backend.h" +#include "options.h" +#include "debug.h" static void -change_uid(Process *proc) { +change_uid(const char * command) +{ uid_t run_uid, run_euid; gid_t run_gid, run_egid; @@ -45,7 +74,7 @@ change_uid(Process *proc) { run_euid = run_uid; run_egid = run_gid; - if (!stat(proc->filename, &statbuf)) { + if (!stat(command, &statbuf)) { if (statbuf.st_mode & S_ISUID) { run_euid = statbuf.st_uid; } @@ -64,28 +93,30 @@ change_uid(Process *proc) { } } -void -execute_program(Process *sp, char **argv) { +pid_t +execute_program(const char * command, char **argv) +{ pid_t pid; - debug(1, "Executing `%s'...", sp->filename); + debug(1, "Executing `%s'...", command); pid = fork(); if (pid < 0) { + fail: perror("ltrace: fork"); exit(1); } else if (!pid) { /* child */ - change_uid(sp); + change_uid(command); trace_me(); - execvp(sp->filename, argv); - fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, + execvp(command, argv); + fprintf(stderr, "Can't execute `%s': %s\n", command, strerror(errno)); _exit(1); } - debug(1, "PID=%d", pid); - - sp->pid = pid; + if (wait_for_proc(pid) < 0) + goto fail; - return; + debug(1, "PID=%d", pid); + return pid; } @@ -0,0 +1,338 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <error.h> +#include <stdlib.h> + +#include "expr.h" + +static void +expr_init_common(struct expr_node *node, enum expr_node_kind kind) +{ + node->kind = kind; + node->lhs = NULL; + node->own_lhs = 0; + memset(&node->u, 0, sizeof(node->u)); +} + +void +expr_init_self(struct expr_node *node) +{ + expr_init_common(node, EXPR_OP_SELF); +} + +void +expr_init_named(struct expr_node *node, + const char *name, int own_name) +{ + expr_init_common(node, EXPR_OP_NAMED); + node->u.name.s = name; + node->u.name.own = own_name; +} + +void +expr_init_argno(struct expr_node *node, size_t num) +{ + expr_init_common(node, EXPR_OP_ARGNO); + node->u.num = num; +} + +void +expr_init_const(struct expr_node *node, struct value *val) +{ + expr_init_common(node, EXPR_OP_CONST); + node->u.value = *val; +} + +void +expr_init_const_word(struct expr_node *node, long l, + struct arg_type_info *type, int own_type) +{ + struct value val; + value_init_detached(&val, NULL, type, own_type); + value_set_word(&val, l); + expr_init_const(node, &val); +} + +void +expr_init_index(struct expr_node *node, + struct expr_node *lhs, int own_lhs, + struct expr_node *rhs, int own_rhs) +{ + expr_init_common(node, EXPR_OP_INDEX); + node->lhs = lhs; + node->own_lhs = own_lhs; + node->u.node.n = rhs; + node->u.node.own = own_rhs; +} + +void +expr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs) +{ + assert(lhs != NULL); + expr_init_common(node, EXPR_OP_UP); + node->lhs = lhs; + node->own_lhs = own_lhs; +} + +void +expr_init_cb1(struct expr_node *node, + int (*cb)(struct value *ret_value, struct value *value, + struct value_dict *arguments, void *data), + struct expr_node *lhs, int own_lhs, void *data) +{ + expr_init_common(node, EXPR_OP_CALL1); + node->lhs = lhs; + node->own_lhs = own_lhs; + node->u.call.u.cb1 = cb; + node->u.call.data = data; +} + +void +expr_init_cb2(struct expr_node *node, + int (*cb)(struct value *ret_value, + struct value *lhs, struct value *rhs, + struct value_dict *arguments, void *data), + struct expr_node *lhs, int own_lhs, + struct expr_node *rhs, int own_rhs, void *data) +{ + expr_init_common(node, EXPR_OP_CALL2); + node->lhs = lhs; + node->own_lhs = own_lhs; + node->u.call.rhs = rhs; + node->u.call.own_rhs = own_rhs; + node->u.call.u.cb2 = cb; + node->u.call.data = data; +} + +static void +release_expr(struct expr_node *node, int own) +{ + if (own) { + expr_destroy(node); + free(node); + } +} + +void +expr_destroy(struct expr_node *node) +{ + if (node == NULL) + return; + + switch (node->kind) { + case EXPR_OP_ARGNO: + case EXPR_OP_SELF: + return; + + case EXPR_OP_CONST: + value_destroy(&node->u.value); + return; + + case EXPR_OP_NAMED: + if (node->u.name.own) + free((char *)node->u.name.s); + return; + + case EXPR_OP_INDEX: + release_expr(node->lhs, node->own_lhs); + release_expr(node->u.node.n, node->u.node.own); + return; + + case EXPR_OP_CALL2: + release_expr(node->u.call.rhs, node->u.call.own_rhs); + /* Fall through. */ + case EXPR_OP_UP: + case EXPR_OP_CALL1: + release_expr(node->lhs, node->own_lhs); + return; + } + + assert(!"Invalid value of node kind"); + abort(); +} + +int +expr_is_compile_constant(struct expr_node *node) +{ + return node->kind == EXPR_OP_CONST; +} + +static int +eval_up(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value) +{ + if (expr_eval(node->lhs, context, arguments, ret_value) < 0) + return -1; + struct value *parent = value_get_parental_struct(ret_value); + if (parent == NULL) { + value_destroy(ret_value); + return -1; + } + *ret_value = *parent; + return 0; +} + +static int +eval_cb1(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value) +{ + struct value val; + if (expr_eval(node->lhs, context, arguments, &val) < 0) + return -1; + + int ret = 0; + if (node->u.call.u.cb1(ret_value, &val, arguments, + node->u.call.data) < 0) + ret = -1; + + /* N.B. the callback must return its own value, or somehow + * clone the incoming argument. */ + value_destroy(&val); + return ret; +} + +static int +eval_cb2(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value) +{ + struct value lhs; + if (expr_eval(node->lhs, context, arguments, &lhs) < 0) + return -1; + + struct value rhs; + if (expr_eval(node->u.call.rhs, context, arguments, &rhs) < 0) { + value_destroy(&lhs); + return -1; + } + + int ret = 0; + if (node->u.call.u.cb2(ret_value, &lhs, &rhs, arguments, + node->u.call.data) < 0) + ret = -1; + + /* N.B. the callback must return its own value, or somehow + * clone the incoming argument. */ + value_destroy(&lhs); + value_destroy(&rhs); + return ret; +} + +int +eval_index(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value) +{ + struct value lhs; + if (expr_eval(node->lhs, context, arguments, &lhs) < 0) + return -1; + + long l; + if (expr_eval_word(node->u.node.n, context, arguments, &l) < 0) { + fail: + value_destroy(&lhs); + return -1; + } + + if (value_init_element(ret_value, &lhs, (size_t)l) < 0) + goto fail; + return 0; +} + +int +expr_eval(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value) +{ + switch (node->kind) { + struct value *valp; + case EXPR_OP_ARGNO: + valp = val_dict_get_num(arguments, node->u.num); + if (valp == NULL) + return -1; + *ret_value = *valp; + return 0; + + case EXPR_OP_NAMED: + valp = val_dict_get_name(arguments, node->u.name.s); + if (valp == NULL) + return -1; + *ret_value = *valp; + return 0; + + case EXPR_OP_SELF: + *ret_value = *context; + return 0; + + case EXPR_OP_CONST: + *ret_value = node->u.value; + return 0; + + case EXPR_OP_INDEX: + return eval_index(node, context, arguments, ret_value); + + case EXPR_OP_UP: + return eval_up(node, context, arguments, ret_value); + + case EXPR_OP_CALL1: + return eval_cb1(node, context, arguments, ret_value); + + case EXPR_OP_CALL2: + return eval_cb2(node, context, arguments, ret_value); + } + + assert(!"Unknown node kind."); + abort(); +} + +int +expr_eval_word(struct expr_node *node, struct value *context, + struct value_dict *arguments, long *ret_value) +{ + struct value val; + if (expr_eval(node, context, arguments, &val) < 0) + return -1; + int ret = 0; + if (value_extract_word(&val, ret_value, arguments) < 0) + ret = -1; + value_destroy(&val); + return ret; +} + +int +expr_eval_constant(struct expr_node *node, long *valuep) +{ + assert(expr_is_compile_constant(node)); + return expr_eval_word(node, NULL, NULL, valuep); +} + +struct expr_node * +expr_self(void) +{ + static struct expr_node *node = NULL; + if (node == NULL) { + node = malloc(sizeof(*node)); + if (node == NULL) + error(1, errno, "malloc expr_self"); + expr_init_self(node); + } + return node; +} @@ -0,0 +1,156 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef EXPR_H +#define EXPR_H + +#include "value.h" +#include "value_dict.h" + +/* Expressions serve as a way of encoding array lengths. */ + +enum expr_node_kind { + EXPR_OP_SELF, /* reference to the variable in question */ + EXPR_OP_NAMED, /* value of named argument */ + EXPR_OP_ARGNO, /* value of numbered argument */ + EXPR_OP_CONST, /* constant value */ + EXPR_OP_INDEX, /* A[B] */ + EXPR_OP_UP, /* reference to containing structure */ + EXPR_OP_CALL1, /* internal callback with one operand */ + EXPR_OP_CALL2, /* internal callback with two operands */ +}; + +struct expr_node { + enum expr_node_kind kind; + + struct expr_node *lhs; + int own_lhs; + + union { + struct { + const char *s; + int own; + } name; + struct { + struct expr_node *n; + int own; + } node; + struct value value; + size_t num; + struct { + union { + int (*cb1)(struct value *ret_value, + struct value *lhs, + struct value_dict *arguments, + void *data); + int (*cb2)(struct value *ret_value, + struct value *lhs, + struct value *rhs, + struct value_dict *arguments, + void *data); + } u; + void *data; + struct expr_node *rhs; + int own_rhs; + } call; + } u; +}; + +/* Expression of type self just returns the value in consideration. + * For example, if what we seek is length of an array, then the value + * representing that array is returned by the expression. */ +void expr_init_self(struct expr_node *node); + +/* Expression that yields the value of an argument named NAME. NAME + * is owned if OWN_NAME. */ +void expr_init_named(struct expr_node *node, + const char *name, int own_name); + +/* Expression that yields the value of an argument number NUM. */ +void expr_init_argno(struct expr_node *node, size_t num); + +/* Constant expression always returns the same value VAL. VAL is + * copied into NODE and owned by it. */ +void expr_init_const(struct expr_node *node, struct value *val); +void expr_init_const_word(struct expr_node *node, long l, + struct arg_type_info *type, int own_type); + +/* Expression LHS[RHS]. LHS and RHS are owned if, respectively, + * OWN_LHS and OWN_RHS. */ +void expr_init_index(struct expr_node *node, + struct expr_node *lhs, int own_lhs, + struct expr_node *rhs, int own_rhs); + +/* This expression returns the containing value of LHS (^LHS). LHS is + * owned if OWN_LHS. */ +void expr_init_up(struct expr_node *node, struct expr_node *lhs, int own_lhs); + +/* Callback expression calls CB(eval(LHS), DATA). LHS is owned if + * OWN_LHS. DATA is passed to callback verbatim. */ +void expr_init_cb1(struct expr_node *node, + int (*cb)(struct value *ret_value, + struct value *value, + struct value_dict *arguments, + void *data), + struct expr_node *lhs, int own_lhs, void *data); + +/* Callback expression calls CB(eval(LHS), eval(RHS), DATA). LHS and + * RHS are owned if, respectively, OWN_LHS and OWN_RHS. DATA is + * passed to callback verbatim. */ +void expr_init_cb2(struct expr_node *node, + int (*cb)(struct value *ret_value, + struct value *lhs, struct value *rhs, + struct value_dict *arguments, + void *data), + struct expr_node *lhs, int own_lhs, + struct expr_node *rhs, int own_rhs, void *data); + +/* Release the data inside NODE. Doesn't free NODE itself. */ +void expr_destroy(struct expr_node *node); + +/* Evaluate the expression NODE in context of VALUE. ARGUMENTS is a + * dictionary of named and numbered values that NODE may use. Returns + * 0 in case of success or a negative value on error. CONTEXT and + * ARGUMENTS may be NULL, but then the expression mustn't need them + * for evaluation. */ +int expr_eval(struct expr_node *node, struct value *context, + struct value_dict *arguments, struct value *ret_value); + +/* Evaluate compile-time expression. Returns 0 on success or negative + * value on failure. Computed value is passed back in *VALUEP. */ +int expr_eval_constant(struct expr_node *node, long *valuep); + +/* Evaluate expression, whose result should fit into a word. In order + * to easily support all the structure and array accesses, we simply + * operate on values represented by struct value. But eventually we need + * to be able to get out a word-size datum to use it as an index, a + * length, etc. */ +int expr_eval_word(struct expr_node *node, struct value *context, + struct value_dict *arguments, long *ret_value); + +/* Returns non-zero value if the expression is a compile-time + * constant. Currently this is only EXPR_OP_CONST, but eventually + * things like sizeof or simple expressions might be allowed. */ +int expr_is_compile_constant(struct expr_node *node); + +/* Returns a pre-computed expression "self". */ +struct expr_node *expr_self(void); + +#endif /* EXPR_H */ @@ -0,0 +1,166 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdlib.h> +#include <string.h> + +#include "fetch.h" +#include "sysdep.h" +#include "value.h" +#include "type.h" + +#ifdef ARCH_HAVE_FETCH_ARG +struct fetch_context *arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info); + +struct fetch_context *arch_fetch_arg_clone(struct Process *proc, + struct fetch_context *context); + +int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep); + +int arch_fetch_retval(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep); + +void arch_fetch_arg_done(struct fetch_context *context); + +# ifdef ARCH_HAVE_FETCH_PACK +int arch_fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor); + +void arch_fetch_param_pack_end(struct fetch_context *context); +# endif + +#else +/* Fall back to gimme_arg. */ + +long gimme_arg(enum tof type, struct Process *proc, int arg_num, + struct arg_type_info *info); + +struct fetch_context { + int argnum; +}; + +struct fetch_context * +arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + return calloc(sizeof(struct fetch_context), 1); +} + +struct fetch_context * +arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) +{ + struct fetch_context *ret = malloc(sizeof(*ret)); + if (ret == NULL) + return NULL; + return memcpy(ret, context, sizeof(*ret)); +} + +int +arch_fetch_arg_next(struct fetch_context *context, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + long l = gimme_arg(type, proc, context->argnum++, info); + value_set_word(valuep, l); + return 0; +} + +int +arch_fetch_retval(struct fetch_context *context, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + long l = gimme_arg(type, proc, -1, info); + value_set_word(valuep, l); + return 0; +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + free(context); +} +#endif + +#if !defined(ARCH_HAVE_FETCH_ARG) || !defined(ARCH_HAVE_FETCH_PACK) +int +arch_fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor) +{ + return 0; +} + +void +arch_fetch_param_pack_end(struct fetch_context *context) +{ +} +#endif + +struct fetch_context * +fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + return arch_fetch_arg_init(type, proc, ret_info); +} + +struct fetch_context * +fetch_arg_clone(struct Process *proc, struct fetch_context *context) +{ + return arch_fetch_arg_clone(proc, context); +} + +int +fetch_arg_next(struct fetch_context *context, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + return arch_fetch_arg_next(context, type, proc, info, valuep); +} + +int +fetch_retval(struct fetch_context *context, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + return arch_fetch_retval(context, type, proc, info, valuep); +} + +void +fetch_arg_done(struct fetch_context *context) +{ + return arch_fetch_arg_done(context); +} + +int +fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor) +{ + return arch_fetch_param_pack_start(context, ppflavor); +} + +void +fetch_param_pack_end(struct fetch_context *context) +{ + return arch_fetch_param_pack_end(context); +} @@ -0,0 +1,95 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef FETCH_H +#define FETCH_H + +#include "forward.h" +#include "param.h" + +/* XXX isn't SYSCALL TOF just a different ABI? Maybe we needed to + * support variant ABIs all along. */ +enum tof { + LT_TOF_FUNCTION, /* A real library function */ + LT_TOF_FUNCTIONR, /* Return from a real library function */ + LT_TOF_SYSCALL, /* A syscall */ + LT_TOF_SYSCALLR, /* Return from a syscall */ +}; + +/* The contents of the structure is defined by the back end. */ +struct fetch_context; + +/* Initialize argument fetching. Returns NULL on failure. RET_INFO + * is the return type of the function. */ +struct fetch_context *fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info); + +/* Make a clone of context. */ +struct fetch_context *fetch_arg_clone(struct Process *proc, + struct fetch_context *context); + +/* Load next argument. The function returns 0 on success or a + * negative value on failure. The extracted value is stored in + * *VALUEP. */ +int fetch_arg_next(struct fetch_context *context, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep); + +/* Load return value. The function returns 0 on success or a negative + * value on failure. The extracted value is stored in *VALUEP. */ +int fetch_retval(struct fetch_context *context, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep); + +/* Destroy fetch context. CONTEXT shall be the same memory location + * that was passed to fetch_arg_next. */ +void fetch_arg_done(struct fetch_context *context); + +/* Called before fetching arguments that come from parameter packs. + * Returns 0 on success or a negative value on failure. */ +int fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor); + +/* Called after a parameter pack has been fetched. */ +void fetch_param_pack_end(struct fetch_context *context); + + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_FETCH_ARG. These backend callbacks correspond to + * above functions. */ +struct fetch_context *arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info); +struct fetch_context *arch_fetch_arg_clone(struct Process *proc, + struct fetch_context *context); +int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep); +int arch_fetch_retval(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep); +void arch_fetch_arg_done(struct fetch_context *context); + +/* The following callbacks have to be implemented in backend if arch.h + * defines ARCH_HAVE_FETCH_ARG and ARCH_HAVE_FETCH_PACK. */ +int arch_fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor); +void arch_fetch_param_pack_end(struct fetch_context *context); + +#endif /* FETCH_H */ diff --git a/filter.c b/filter.c new file mode 100644 index 0000000..ba50c40 --- /dev/null +++ b/filter.c @@ -0,0 +1,191 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include "filter.h" +#include "library.h" +#include "callback.h" + +void +filter_init(struct filter *filt) +{ + filt->rules = NULL; + filt->next = NULL; +} + +void +filter_destroy(struct filter *filt) +{ + struct filter_rule *it; + for (it = filt->rules; it != NULL; ) { + struct filter_rule *next = it->next; + filter_rule_destroy(it); + it = next; + } +} + +void +filter_rule_init(struct filter_rule *rule, enum filter_rule_type type, + struct filter_lib_matcher *matcher, + regex_t symbol_re) +{ + rule->type = type; + rule->lib_matcher = matcher; + rule->symbol_re = symbol_re; + rule->next = NULL; +} + +void +filter_rule_destroy(struct filter_rule *rule) +{ + filter_lib_matcher_destroy(rule->lib_matcher); + regfree(&rule->symbol_re); +} + +void +filter_add_rule(struct filter *filt, struct filter_rule *rule) +{ + struct filter_rule **rulep; + for (rulep = &filt->rules; *rulep != NULL; rulep = &(*rulep)->next) + ; + *rulep = rule; +} + +void +filter_lib_matcher_name_init(struct filter_lib_matcher *matcher, + enum filter_lib_matcher_type type, + regex_t libname_re) +{ + switch (type) { + case FLM_MAIN: + assert(type != type); + abort(); + + case FLM_SONAME: + case FLM_PATHNAME: + matcher->type = type; + matcher->libname_re = libname_re; + } +} + +void +filter_lib_matcher_main_init(struct filter_lib_matcher *matcher) +{ + matcher->type = FLM_MAIN; +} + +void +filter_lib_matcher_destroy(struct filter_lib_matcher *matcher) +{ + switch (matcher->type) { + case FLM_SONAME: + case FLM_PATHNAME: + regfree(&matcher->libname_re); + break; + case FLM_MAIN: + break; + } +} + +static int +re_match_or_error(regex_t *re, const char *name, const char *what) +{ + int status = regexec(re, name, 0, NULL, 0); + if (status == 0) + return 1; + if (status == REG_NOMATCH) + return 0; + + char buf[200]; + regerror(status, re, buf, sizeof buf); + fprintf(stderr, "Error when matching %s: %s\n", name, buf); + + return 0; +} + +static int +matcher_matches_library(struct filter_lib_matcher *matcher, struct library *lib) +{ + switch (matcher->type) { + case FLM_SONAME: + return re_match_or_error(&matcher->libname_re, lib->soname, + "library soname"); + case FLM_PATHNAME: + return re_match_or_error(&matcher->libname_re, lib->pathname, + "library pathname"); + case FLM_MAIN: + return lib->type == LT_LIBTYPE_MAIN; + } + assert(matcher->type != matcher->type); + abort(); +} + +int +filter_matches_library(struct filter *filt, struct library *lib) +{ + if (filt == NULL) + return 0; + + for (; filt != NULL; filt = filt->next) { + struct filter_rule *it; + for (it = filt->rules; it != NULL; it = it->next) + switch (it->type) { + case FR_ADD: + if (matcher_matches_library(it->lib_matcher, lib)) + return 1; + case FR_SUBTRACT: + continue; + }; + } + return 0; +} + +int +filter_matches_symbol(struct filter *filt, + const char *sym_name, struct library *lib) +{ + for (; filt != NULL; filt = filt->next) { + int matches = 0; + struct filter_rule *it; + for (it = filt->rules; it != NULL; it = it->next) { + switch (it->type) { + case FR_ADD: + if (matches) + continue; + break; + case FR_SUBTRACT: + if (!matches) + continue; + } + + if (matcher_matches_library(it->lib_matcher, lib) + && re_match_or_error(&it->symbol_re, sym_name, + "symbol name")) + matches = !matches; + } + if (matches) + return 1; + } + return 0; +} diff --git a/filter.h b/filter.h new file mode 100644 index 0000000..65c575a --- /dev/null +++ b/filter.h @@ -0,0 +1,99 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* This file contains declarations and types for working with symbol + * filters. */ + +#ifndef FILTER_H +#define FILTER_H + +#include <sys/types.h> +#include <regex.h> + +struct library; +struct library_symbol; + +enum filter_lib_matcher_type { + /* Match by soname. */ + FLM_SONAME, + /* Match by path name. */ + FLM_PATHNAME, + /* Match main binary. */ + FLM_MAIN, +}; + +struct filter_lib_matcher { + enum filter_lib_matcher_type type; + regex_t libname_re; +}; + +enum filter_rule_type { + FR_ADD, + FR_SUBTRACT, +}; + +struct filter_rule { + struct filter_rule *next; + struct filter_lib_matcher *lib_matcher; + regex_t symbol_re; /* Regex for matching symbol name. */ + enum filter_rule_type type; +}; + +struct filter { + struct filter *next; + struct filter_rule *rules; +}; + +void filter_init(struct filter *filt); +void filter_destroy(struct filter *filt); + +/* Both SYMBOL_RE and MATCHER are owned and destroyed by RULE. */ +void filter_rule_init(struct filter_rule *rule, enum filter_rule_type type, + struct filter_lib_matcher *matcher, + regex_t symbol_re); + +void filter_rule_destroy(struct filter_rule *rule); + +/* RULE is added to FILT and owned and destroyed by it. */ +void filter_add_rule(struct filter *filt, struct filter_rule *rule); + +/* Create a matcher that matches library name. RE is owned and + * destroyed by MATCHER. TYPE shall be FLM_SONAME or + * FLM_PATHNAME. */ +void filter_lib_matcher_name_init(struct filter_lib_matcher *matcher, + enum filter_lib_matcher_type type, + regex_t re); + +/* Create a matcher that matches main binary. */ +void filter_lib_matcher_main_init(struct filter_lib_matcher *matcher); + +void filter_lib_matcher_destroy(struct filter_lib_matcher *matcher); + +/* Ask whether FILTER might match a symbol in LIB. 0 if no, non-0 if + * yes. Note that positive answer doesn't mean that anything will + * actually be matched, just that potentially it could. */ +int filter_matches_library(struct filter *filt, struct library *lib); + +/* Ask whether FILTER matches this symbol. Returns 0 if it doesn't, + * or non-0 value if it does. */ +int filter_matches_symbol(struct filter *filt, const char *sym_name, + struct library *lib); + +#endif /* FILTER_H */ diff --git a/forward.h b/forward.h new file mode 100644 index 0000000..85a0630 --- /dev/null +++ b/forward.h @@ -0,0 +1,35 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* Important types defined in other header files are declared + here. */ +struct Event; +struct Process; +struct arg_type_info; +struct breakpoint; +struct expr_node; +struct library; +struct library_symbol; +struct ltelf; +struct param; +struct param_enum; +struct value; +struct value_dict; +struct filter; @@ -0,0 +1,279 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2007, 2008, 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <sys/types.h> +#include <regex.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +static ssize_t +match_character_class(const char *glob, size_t length, size_t from) +{ + size_t i; + if (length > 0) + for (i = from + 2; i < length - 1 && glob[++i] != ':'; ) + ; + if (i >= length || glob[++i] != ']') + return -1; + return i; +} + +static ssize_t +match_brack(const char *glob, size_t length, size_t from, int *exclmp) +{ + size_t i = from + 1; + + if (i >= length) + return -1; + + /* Complement operator. */ + *exclmp = 0; + if (glob[i] == '^' || glob[i] == '!') { + *exclmp = glob[i++] == '!'; + if (i >= length) + return -1; + } + + /* On first character, both [ and ] are legal. But when [ is + * followed with :, it's character class. */ + if (glob[i] == '[' && glob[i + 1] == ':') { + ssize_t j = match_character_class(glob, length, i); + if (j < 0) + fail: + return -1; + i = j; + } + ++i; /* skip any character, including [ or ] */ + + int escape = 0; + for (; i < length; ++i) { + char c = glob[i]; + if (escape) { + ++i; + escape = 0; + + } else if (c == '[' && glob[i + 1] == ':') { + ssize_t j = match_character_class(glob, length, i); + if (j < 0) + goto fail; + i = j; + + } else if (c == ']') { + return i; + } + } + return -1; +} + +static int +append(char **bufp, const char *str, size_t str_size, + size_t *sizep, size_t *allocp) +{ + if (str_size == 0) + str_size = strlen(str); + size_t nsize = *sizep + str_size; + if (nsize > *allocp) { + size_t nalloc = nsize * 2; + char *nbuf = realloc(*bufp, nalloc); + if (nbuf == NULL) + return -1; + *allocp = nalloc; + *bufp = nbuf; + } + + memcpy(*bufp + *sizep, str, str_size); + *sizep = nsize; + return 0; +} + +static int +glob_to_regex(const char *glob, char **retp) +{ + size_t allocd = 0; + size_t size = 0; + char *buf = NULL; + + size_t length = strlen(glob); + int escape = 0; + size_t i; + for(i = 0; i < length; ++i) { + char c = glob[i]; + if (escape) { + if (c == '\\') { + if (append(&buf, "\\\\", 0, + &size, &allocd) < 0) { + fail: + free(buf); + return REG_ESPACE; + } + + } else if (c == '*') { + if (append(&buf, "\\*", 0, &size, &allocd) < 0) + goto fail; + } else if (c == '?') { + if (append(&buf, "?", 0, &size, &allocd) < 0) + goto fail; + } else if (append(&buf, (char[]){ '\\', c }, 2, + &size, &allocd) < 0) + goto fail; + escape = 0; + } else { + if (c == '\\') + escape = 1; + else if (c == '[') { + int exclm; + ssize_t j = match_brack(glob, length, i, &exclm); + if (j < 0) { + free(buf); + return REG_EBRACK; + } + if (exclm + && append(&buf, "[^", 2, + &size, &allocd) < 0) + goto fail; + if (append(&buf, glob + i + 2*exclm, + j - i + 1 - 2*exclm, + &size, &allocd) < 0) + goto fail; + i = j; + + } else if (c == '*') { + if (append(&buf, ".*", 0, &size, &allocd) < 0) + goto fail; + } else if (c == '?') { + if (append(&buf, ".", 0, &size, &allocd) < 0) + goto fail; + } else if (c == '.') { + if (append(&buf, "\\.", 0, &size, &allocd) < 0) + goto fail; + } else if (append(&buf, &c, 1, &size, &allocd) < 0) + goto fail; + } + } + + if (escape) { + free(buf); + return REG_EESCAPE; + } + + { + char c = 0; + if (append(&buf, &c, 1, &size, &allocd) < 0) + goto fail; + } + *retp = buf; + return REG_NOERROR; +} + +int +globcomp(regex_t *preg, const char *glob, int cflags) +{ + char *regex = NULL; + int status = glob_to_regex(glob, ®ex); + if (status != REG_NOERROR) + return status; + assert(regex != NULL); + status = regcomp(preg, regex, cflags); + free(regex); + return status; +} + +#ifdef TEST +#include <stdio.h> + +static void +translate(const char *glob, int exp_status, const char *expect) +{ + char *pattern = NULL; + int status = glob_to_regex(glob, &pattern); + if (status != exp_status) { + fprintf(stderr, "translating %s, expected status %d, got %d\n", + glob, exp_status, status); + return; + } + + if (status == 0) { + assert(pattern != NULL); + if (strcmp(pattern, expect) != 0) + fprintf(stderr, "translating %s, expected %s, got %s\n", + glob, expect, pattern); + free(pattern); + } else { + assert(pattern == NULL); + } +} + +static void +try_match(const char *glob, const char *str, int expect) +{ + regex_t preg; + int status = globcomp(&preg, glob, 0); + assert(status == 0); + status = regexec(&preg, str, 0, NULL, 0); + assert(status == expect); + regfree(&preg); +} + +int +main(void) +{ + translate("*", 0, ".*"); + translate("?", 0, "."); + translate(".*", 0, "\\..*"); + translate("*.*", 0, ".*\\..*"); + translate("*a*", 0, ".*a.*"); + translate("[abc]", 0, "[abc]"); + translate("[^abc]", 0, "[^abc]"); + translate("[!abc]", 0, "[^abc]"); + translate("[]]", 0, "[]]"); + translate("[[]", 0, "[[]"); + translate("[^]]", 0, "[^]]"); + translate("[^a-z]", 0, "[^a-z]"); + translate("[abc\\]]", 0, "[abc\\]]"); + translate("[abc\\]def]", 0, "[abc\\]def]"); + translate("[[:space:]]", 0, "[[:space:]]"); + translate("[^[:space:]]", 0, "[^[:space:]]"); + translate("[![:space:]]", 0, "[^[:space:]]"); + translate("[^a-z]*", 0, "[^a-z].*"); + translate("[^a-z]bar*", 0, "[^a-z]bar.*"); + translate("*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.", 0, + ".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\." + ".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\."); + + translate("\\", REG_EESCAPE, NULL); + translate("[^[:naotuh\\", REG_EBRACK, NULL); + translate("[^[:", REG_EBRACK, NULL); + translate("[^[", REG_EBRACK, NULL); + translate("[^", REG_EBRACK, NULL); + translate("[\\", REG_EBRACK, NULL); + translate("[", REG_EBRACK, NULL); + translate("abc[", REG_EBRACK, NULL); + + try_match("abc*def", "abc012def", 0); + try_match("abc*def", "ab012def", REG_NOMATCH); + try_match("[abc]*def", "a1def", 0); + try_match("[abc]*def", "b1def", 0); + try_match("[abc]*def", "d1def", REG_NOMATCH); + + return 0; +} + +#endif @@ -0,0 +1,32 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2007, 2008, 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include <sys/types.h> +#include <regex.h> + +/* This is akin to regcomp(3), except it compiles a glob expression + * passed in GLOB. See glob(7) for more information about the syntax + * supported by globcomp. */ +int globcomp(regex_t *preg, const char *glob, int cflags); + +#endif /* _GLOB_H_ */ diff --git a/handle_event.c b/handle_event.c index 1dfb82b..42a7a05 100644 --- a/handle_event.c +++ b/handle_event.c @@ -1,18 +1,46 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Arnaud Patard, Mandriva SA + * Copyright (C) 1998,2001,2002,2003,2004,2007,2008,2009 Juan Cespedes + * Copyright (C) 2008 Luis Machado, IBM Corporation + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2006 Paul Gilliam, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #define _GNU_SOURCE +#include <assert.h> +#include <errno.h> +#include <signal.h> #include <stdio.h> -#include <string.h> #include <stdlib.h> -#include <signal.h> -#include <assert.h> +#include <string.h> #include <sys/time.h> +#include "backend.h" +#include "breakpoint.h" #include "common.h" - -#ifdef __powerpc__ -#include <sys/ptrace.h> -#endif +#include "fetch.h" +#include "library.h" +#include "proc.h" +#include "value_dict.h" static void handle_signal(Event *event); static void handle_exit(Event *event); @@ -25,78 +53,134 @@ static void handle_clone(Event *event); static void handle_exec(Event *event); static void handle_breakpoint(Event *event); static void handle_new(Event *event); -static void remove_proc(Process *proc); static void callstack_push_syscall(Process *proc, int sysnum); static void callstack_push_symfunc(Process *proc, struct library_symbol *sym); -static void callstack_pop(Process *proc); +/* XXX Stack maintenance should be moved to a dedicated module, or to + * proc.c, and push/pop should be visible outside this module. For + * now, because we need this in proc.c, this is non-static. */ +void callstack_pop(struct Process *proc); static char * shortsignal(Process *proc, int signum); static char * sysname(Process *proc, int sysnum); static char * arch_sysname(Process *proc, int sysnum); +static Event * +call_handler(Process * proc, Event * event) +{ + assert(proc != NULL); + + struct event_handler *handler = proc->event_handler; + if (handler == NULL) + return event; + + return (*handler->on_event) (handler, event); +} + void -handle_event(Event *event) { - debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", event->proc ? event->proc->pid : -1, event->type); +handle_event(Event *event) +{ + if (exiting == 1) { + debug(1, "ltrace about to exit"); + os_ltrace_exiting(); + exiting = 2; + } + debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", + event->proc ? event->proc->pid : -1, event->type); + + /* If the thread group or an individual task define an + overriding event handler, give them a chance to kick in. + We will end up calling both handlers, if the first one + doesn't sink the event. */ + if (event->proc != NULL) { + event = call_handler(event->proc, event); + if (event == NULL) + /* It was handled. */ + return; + + /* Note: the previous handler has a chance to alter + * the event. */ + if (event->proc != NULL + && event->proc->leader != NULL + && event->proc != event->proc->leader) { + event = call_handler(event->proc->leader, event); + if (event == NULL) + return; + } + } + switch (event->type) { case EVENT_NONE: debug(1, "event: none"); return; case EVENT_SIGNAL: - debug(1, "event: signal (%s [%d])", + debug(1, "[%d] event: signal (%s [%d])", + event->proc->pid, shortsignal(event->proc, event->e_un.signum), event->e_un.signum); handle_signal(event); return; case EVENT_EXIT: - debug(1, "event: exit (%d)", event->e_un.ret_val); + debug(1, "[%d] event: exit (%d)", + event->proc->pid, + event->e_un.ret_val); handle_exit(event); return; case EVENT_EXIT_SIGNAL: - debug(1, "event: exit signal (%s [%d])", + debug(1, "[%d] event: exit signal (%s [%d])", + event->proc->pid, shortsignal(event->proc, event->e_un.signum), event->e_un.signum); handle_exit_signal(event); return; case EVENT_SYSCALL: - debug(1, "event: syscall (%s [%d])", + debug(1, "[%d] event: syscall (%s [%d])", + event->proc->pid, sysname(event->proc, event->e_un.sysnum), event->e_un.sysnum); handle_syscall(event); return; case EVENT_SYSRET: - debug(1, "event: sysret (%s [%d])", + debug(1, "[%d] event: sysret (%s [%d])", + event->proc->pid, sysname(event->proc, event->e_un.sysnum), event->e_un.sysnum); handle_sysret(event); return; case EVENT_ARCH_SYSCALL: - debug(1, "event: arch_syscall (%s [%d])", - arch_sysname(event->proc, event->e_un.sysnum), - event->e_un.sysnum); + debug(1, "[%d] event: arch_syscall (%s [%d])", + event->proc->pid, + arch_sysname(event->proc, event->e_un.sysnum), + event->e_un.sysnum); handle_arch_syscall(event); return; case EVENT_ARCH_SYSRET: - debug(1, "event: arch_sysret (%s [%d])", - arch_sysname(event->proc, event->e_un.sysnum), - event->e_un.sysnum); + debug(1, "[%d] event: arch_sysret (%s [%d])", + event->proc->pid, + arch_sysname(event->proc, event->e_un.sysnum), + event->e_un.sysnum); handle_arch_sysret(event); return; case EVENT_CLONE: - debug(1, "event: clone (%u)", event->e_un.newpid); + case EVENT_VFORK: + debug(1, "[%d] event: clone (%u)", + event->proc->pid, event->e_un.newpid); handle_clone(event); return; case EVENT_EXEC: - debug(1, "event: exec()"); + debug(1, "[%d] event: exec()", + event->proc->pid); handle_exec(event); return; case EVENT_BREAKPOINT: - debug(1, "event: breakpoint"); + debug(1, "[%d] event: breakpoint %p", + event->proc->pid, event->e_un.brk_addr); handle_breakpoint(event); return; case EVENT_NEW: - debug(1, "event: new process"); + debug(1, "[%d] event: new process", + event->e_un.newpid); handle_new(event); return; default: @@ -105,26 +189,6 @@ handle_event(Event *event) { } } -/* TODO */ -static void * -address_clone(void * addr) { - debug(DEBUG_FUNCTION, "address_clone(%p)", addr); - return addr; -} - -static void * -breakpoint_clone(void * bp) { - Breakpoint * b; - debug(DEBUG_FUNCTION, "breakpoint_clone(%p)", bp); - b = malloc(sizeof(Breakpoint)); - if (!b) { - perror("malloc()"); - exit(1); - } - memcpy(b, bp, sizeof(Breakpoint)); - return b; -} - typedef struct Pending_New Pending_New; struct Pending_New { pid_t pid; @@ -171,6 +235,7 @@ pending_new_remove(pid_t pid) { debug(DEBUG_FUNCTION, "pending_new_remove(%d)", pid); p = pending_news; + pred = NULL; if (p->pid == pid) { pending_news = p->next; free(p); @@ -187,41 +252,48 @@ pending_new_remove(pid_t pid) { } static void -handle_clone(Event * event) { - Process *p; - +handle_clone(Event *event) +{ debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid); - p = malloc(sizeof(Process)); - if (!p) { - perror("malloc()"); - exit(1); + struct Process *proc = malloc(sizeof(*proc)); + if (proc == NULL) { + fail: + free(proc); + fprintf(stderr, + "Error during init of tracing process %d\n" + "This process won't be traced.\n", + event->proc->pid); + return; } - memcpy(p, event->proc, sizeof(Process)); - p->breakpoints = dict_clone(event->proc->breakpoints, address_clone, breakpoint_clone); - p->pid = event->e_un.newpid; - p->parent = event->proc; - - if (pending_new(p->pid)) { - pending_new_remove(p->pid); - if (p->breakpoint_being_enabled) { - enable_breakpoint(p->pid, p->breakpoint_being_enabled); - p->breakpoint_being_enabled = NULL; - } - if (event->proc->state == STATE_ATTACHED && options.follow) { - p->state = STATE_ATTACHED; - } else { - p->state = STATE_IGNORED; - } - continue_process(p->pid); - p->next = list_of_processes; - list_of_processes = p; + + if (process_clone(proc, event->proc, event->e_un.newpid) < 0) + goto fail; + proc->parent = event->proc; + + /* We save register values to the arch pointer, and these need + to be per-thread. */ + proc->arch_ptr = NULL; + + if (pending_new(proc->pid)) { + pending_new_remove(proc->pid); + /* XXX this used to be destroy_event_handler call, but + * I don't think we want to call that on a shared + * state. */ + proc->event_handler = NULL; + if (event->proc->state == STATE_ATTACHED && options.follow) + proc->state = STATE_ATTACHED; + else + proc->state = STATE_IGNORED; + continue_process(proc->pid); } else { - p->state = STATE_BEING_CREATED; - p->next = list_of_processes; - list_of_processes = p; + proc->state = STATE_BEING_CREATED; } - continue_process(event->proc->pid); + + if (event->type == EVENT_VFORK) + continue_after_vfork(proc); + else + continue_process(event->proc->pid); } static void @@ -235,10 +307,6 @@ handle_new(Event * event) { pending_new_insert(event->e_un.newpid); } else { assert(proc->state == STATE_BEING_CREATED); - if (proc->breakpoint_being_enabled) { - enable_breakpoint(proc->pid, proc->breakpoint_being_enabled); - proc->breakpoint_being_enabled = NULL; - } if (options.follow) { proc->state = STATE_ATTACHED; } else { @@ -323,14 +391,7 @@ arch_sysname(Process *proc, int sysnum) { static void handle_signal(Event *event) { debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum); - if (exiting && event->e_un.signum == SIGSTOP) { - pid_t pid = event->proc->pid; - disable_all_breakpoints(event->proc); - untrace_pid(pid); - remove_proc(event->proc); - return; - } - if (event->proc->state != STATE_IGNORED) { + if (event->proc->state != STATE_IGNORED && !options.no_signals) { output_line(event->proc, "--- %s (%s) ---", shortsignal(event->proc, event->e_un.signum), strsignal(event->e_un.signum)); @@ -345,7 +406,7 @@ handle_exit(Event *event) { output_line(event->proc, "+++ exited (status %d) +++", event->e_un.ret_val); } - remove_proc(event->proc); + remove_process(event->proc); } static void @@ -355,71 +416,80 @@ handle_exit_signal(Event *event) { output_line(event->proc, "+++ killed by %s +++", shortsignal(event->proc, event->e_un.signum)); } - remove_proc(event->proc); + remove_process(event->proc); } static void -remove_proc(Process *proc) { - Process *tmp, *tmp2; +output_syscall(struct Process *proc, const char *name, enum tof tof, + void (*output)(enum tof, struct Process *, + struct library_symbol *)) +{ + struct library_symbol syscall; + if (library_symbol_init(&syscall, 0, name, 0, LS_TOPLT_NONE) >= 0) { + (*output)(tof, proc, &syscall); + library_symbol_destroy(&syscall); + } +} - debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid); +static void +output_syscall_left(struct Process *proc, const char *name) +{ + output_syscall(proc, name, LT_TOF_SYSCALL, &output_left); +} - if (list_of_processes == proc) { - tmp = list_of_processes; - list_of_processes = list_of_processes->next; - free(tmp); - return; - } - tmp = list_of_processes; - while (tmp->next) { - if (tmp->next == proc) { - tmp2 = tmp->next; - tmp->next = tmp->next->next; - free(tmp2); - continue; - } - tmp = tmp->next; - } +static void +output_syscall_right(struct Process *proc, const char *name) +{ + output_syscall(proc, name, LT_TOF_SYSCALLR, &output_right); } static void handle_syscall(Event *event) { debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); if (event->proc->state != STATE_IGNORED) { - if (options.syscalls) { - output_left(LT_TOF_SYSCALL, event->proc, - sysname(event->proc, event->e_un.sysnum)); - } - if (event->proc->breakpoints_enabled == 0) { - enable_all_breakpoints(event->proc); - } callstack_push_syscall(event->proc, event->e_un.sysnum); + if (options.syscalls) + output_syscall_left(event->proc, + sysname(event->proc, + event->e_un.sysnum)); } - continue_process(event->proc->pid); + continue_after_syscall(event->proc, event->e_un.sysnum, 0); } static void handle_exec(Event * event) { Process * proc = event->proc; - pid_t saved_pid; + + /* Save the PID so that we can use it after unsuccessful + * process_exec. */ + pid_t pid = proc->pid; debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid); if (proc->state == STATE_IGNORED) { - untrace_pid(proc->pid); - remove_proc(proc); + untrace: + untrace_pid(pid); + remove_process(proc); return; } output_line(proc, "--- Called exec() ---"); - proc->mask_32bit = 0; - proc->personality = 0; - proc->arch_ptr = NULL; - free(proc->filename); - proc->filename = pid2name(proc->pid); - saved_pid = proc->pid; - proc->pid = 0; - breakpoints_init(proc); - proc->pid = saved_pid; - proc->callstack_depth = 0; + + if (process_exec(proc) < 0) { + fprintf(stderr, + "couldn't reinitialize process %d after exec\n", pid); + goto untrace; + } + + continue_process(proc->pid); + + /* After the exec, we expect to hit the first executable + * instruction. + * + * XXX TODO It would be nice to have this removed, but then we + * need to do that also for initial call to wait_for_proc in + * execute_program. In that case we could generate a + * EVENT_FIRST event or something, or maybe this could somehow + * be rolled into EVENT_NEW. */ + wait_for_proc(proc->pid); continue_process(proc->pid); } @@ -427,14 +497,12 @@ static void handle_arch_syscall(Event *event) { debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); if (event->proc->state != STATE_IGNORED) { + callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum); if (options.syscalls) { - output_left(LT_TOF_SYSCALL, event->proc, - arch_sysname(event->proc, event->e_un.sysnum)); - } - if (event->proc->breakpoints_enabled == 0) { - enable_all_breakpoints(event->proc); + output_syscall_left(event->proc, + arch_sysname(event->proc, + event->e_un.sysnum)); } - callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum); } continue_process(event->proc->pid); } @@ -457,7 +525,7 @@ calc_time_spent(Process *proc) { if (tv.tv_usec >= elem->time_spent.tv_usec) { diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec; } else { - diff.tv_sec++; + diff.tv_sec--; diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec; } current_time_spent = diff; @@ -470,13 +538,17 @@ handle_sysret(Event *event) { if (opt_T || options.summary) { calc_time_spent(event->proc); } + if (options.syscalls) + output_syscall_right(event->proc, + sysname(event->proc, + event->e_un.sysnum)); + + assert(event->proc->callstack_depth > 0); + unsigned d = event->proc->callstack_depth - 1; + assert(event->proc->callstack[d].is_syscall); callstack_pop(event->proc); - if (options.syscalls) { - output_right(LT_TOF_SYSCALLR, event->proc, - sysname(event->proc, event->e_un.sysnum)); - } } - continue_process(event->proc->pid); + continue_after_syscall(event->proc, event->e_un.sysnum, 1); } static void @@ -486,105 +558,50 @@ handle_arch_sysret(Event *event) { if (opt_T || options.summary) { calc_time_spent(event->proc); } + if (options.syscalls) + output_syscall_right(event->proc, + arch_sysname(event->proc, + event->e_un.sysnum)); callstack_pop(event->proc); - if (options.syscalls) { - output_right(LT_TOF_SYSCALLR, event->proc, - arch_sysname(event->proc, event->e_un.sysnum)); - } } continue_process(event->proc->pid); } static void -handle_breakpoint(Event *event) { - int i, j; - Breakpoint *sbp; - - debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)", event->proc->pid, event->e_un.brk_addr); - debug(2, "event: breakpoint (%p)", event->e_un.brk_addr); - -#ifdef __powerpc__ - /* Need to skip following NOP's to prevent a fake function from being stacked. */ - long stub_addr = (long) get_count_register(event->proc); - Breakpoint *stub_bp = NULL; - char nop_instruction[] = PPC_NOP; +output_right_tos(struct Process *proc) +{ + size_t d = proc->callstack_depth; + struct callstack_element *elem = &proc->callstack[d - 1]; + if (proc->state != STATE_IGNORED) + output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc); +} - stub_bp = address2bpstruct (event->proc, event->e_un.brk_addr); +#ifndef ARCH_HAVE_SYMBOL_RET +void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym) +{ +} +#endif - if (stub_bp) { - unsigned char *bp_instruction = stub_bp->orig_value; +static void +handle_breakpoint(Event *event) +{ + int i, j; + struct breakpoint *sbp; + Process *leader = event->proc->leader; + void *brk_addr = event->e_un.brk_addr; - if (memcmp(bp_instruction, nop_instruction, - PPC_NOP_LENGTH) == 0) { - if (stub_addr != (long) event->e_un.brk_addr) { - set_instruction_pointer (event->proc, event->e_un.brk_addr + 4); - continue_process(event->proc->pid); - return; - } - } - } -#endif - if ((sbp = event->proc->breakpoint_being_enabled) != 0) { - /* Reinsert breakpoint */ - continue_enabling_breakpoint(event->proc->pid, - event->proc-> - breakpoint_being_enabled); - event->proc->breakpoint_being_enabled = NULL; + /* The leader has terminated. */ + if (leader == NULL) { + continue_process(event->proc->pid); return; } - for (i = event->proc->callstack_depth - 1; i >= 0; i--) { - if (event->e_un.brk_addr == - event->proc->callstack[i].return_addr) { -#ifdef __powerpc__ - /* - * PPC HACK! (XXX FIXME TODO) - * The PLT gets modified during the first call, - * so be sure to re-enable the breakpoint. - */ - unsigned long a; - struct library_symbol *libsym = - event->proc->callstack[i].c_un.libfunc; - void *addr = sym2addr(event->proc, libsym); - - if (libsym->plt_type != LS_TOPLT_POINT) { - unsigned char break_insn[] = BREAKPOINT_VALUE; + debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)", + event->proc->pid, brk_addr); + debug(2, "event: breakpoint (%p)", brk_addr); - sbp = address2bpstruct(event->proc, addr); - assert(sbp); - a = ptrace(PTRACE_PEEKTEXT, event->proc->pid, - addr); - - if (memcmp(&a, break_insn, BREAKPOINT_LENGTH)) { - sbp->enabled--; - insert_breakpoint(event->proc, addr, - libsym); - } - } else { - sbp = dict_find_entry(event->proc->breakpoints, sym2addr(event->proc, libsym)); - assert(sbp); - if (addr != sbp->addr) { - insert_breakpoint(event->proc, addr, - libsym); - } - } -#elif defined(__mips__) - void *addr; - void *old_addr; - struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc; - assert(sym); - old_addr = dict_find_entry(event->proc->breakpoints, sym2addr(event->proc, sym))->addr; - addr=sym2addr(event->proc,sym); - assert(old_addr !=0 && addr !=0); - if(addr != old_addr){ - struct library_symbol *new_sym; - new_sym=malloc(sizeof(*new_sym)); - memcpy(new_sym,sym,sizeof(*new_sym)); - new_sym->next=event->proc->list_of_symbols; - event->proc->list_of_symbols=new_sym; - insert_breakpoint(event->proc, addr, new_sym); - } -#endif + for (i = event->proc->callstack_depth - 1; i >= 0; i--) { + if (brk_addr == event->proc->callstack[i].return_addr) { for (j = event->proc->callstack_depth - 1; j > i; j--) { callstack_pop(event->proc); } @@ -593,42 +610,74 @@ handle_breakpoint(Event *event) { calc_time_spent(event->proc); } } + event->proc->return_addr = brk_addr; + + struct library_symbol *libsym = + event->proc->callstack[i].c_un.libfunc; + + arch_symbol_ret(event->proc, libsym); + output_right_tos(event->proc); callstack_pop(event->proc); - event->proc->return_addr = event->e_un.brk_addr; - if (event->proc->state != STATE_IGNORED) { - output_right(LT_TOF_FUNCTIONR, event->proc, - event->proc->callstack[i].c_un.libfunc->name); + + /* Pop also any other entries that seem like + * they are linked to the current one: they + * have the same return address, but were made + * for different symbols. This should only + * happen for entry point tracing, i.e. for -x + * everywhere, or -x and -e on MIPS. */ + while (event->proc->callstack_depth > 0) { + struct callstack_element *prev; + size_t d = event->proc->callstack_depth; + prev = &event->proc->callstack[d - 1]; + + if (prev->c_un.libfunc == libsym + || prev->return_addr != brk_addr) + break; + + arch_symbol_ret(event->proc, + prev->c_un.libfunc); + output_right_tos(event->proc); + callstack_pop(event->proc); + } + + /* Maybe the previous callstack_pop's got rid + * of the breakpoint, but if we are in a + * recursive call, it's still enabled. In + * that case we need to skip it properly. */ + if ((sbp = address2bpstruct(leader, brk_addr)) != NULL) { + continue_after_breakpoint(event->proc, sbp); + } else { + set_instruction_pointer(event->proc, brk_addr); + continue_process(event->proc->pid); } - continue_after_breakpoint(event->proc, - address2bpstruct(event->proc, - event->e_un.brk_addr)); return; } } - if ((sbp = address2bpstruct(event->proc, event->e_un.brk_addr))) { - if (event->proc->state != STATE_IGNORED) { + if ((sbp = address2bpstruct(leader, brk_addr)) != NULL) + breakpoint_on_hit(sbp, event->proc); + else if (event->proc->state != STATE_IGNORED) + output_line(event->proc, + "unexpected breakpoint at %p", brk_addr); + + /* breakpoint_on_hit may delete its own breakpoint, so we have + * to look it up again. */ + if ((sbp = address2bpstruct(leader, brk_addr)) != NULL) { + if (event->proc->state != STATE_IGNORED + && sbp->libsym != NULL) { event->proc->stack_pointer = get_stack_pointer(event->proc); event->proc->return_addr = get_return_addr(event->proc, event->proc->stack_pointer); - output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym->name); callstack_push_symfunc(event->proc, sbp->libsym); + output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym); } -#ifdef PLT_REINITALISATION_BP - if (event->proc->need_to_reinitialize_breakpoints - && (strcmp(sbp->libsym->name, PLTs_initialized_by_here) == - 0)) - reinitialize_breakpoints(event->proc); -#endif - continue_after_breakpoint(event->proc, sbp); + breakpoint_on_continue(sbp, event->proc); return; + } else { + set_instruction_pointer(event->proc, brk_addr); } - if (event->proc->state != STATE_IGNORED) { - output_line(event->proc, "unexpected breakpoint at %p", - (void *)event->e_un.brk_addr); - } continue_process(event->proc->pid); } @@ -639,11 +688,13 @@ callstack_push_syscall(Process *proc, int sysnum) { debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum); /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */ if (proc->callstack_depth == MAX_CALLDEPTH - 1) { - fprintf(stderr, "Error: call nesting too deep!\n"); + fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__); + abort(); return; } elem = &proc->callstack[proc->callstack_depth]; + *elem = (struct callstack_element){}; elem->is_syscall = 1; elem->c_un.syscall = sysnum; elem->return_addr = NULL; @@ -662,35 +713,44 @@ callstack_push_symfunc(Process *proc, struct library_symbol *sym) { debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name); /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */ if (proc->callstack_depth == MAX_CALLDEPTH - 1) { - fprintf(stderr, "Error: call nesting too deep!\n"); + fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__); + abort(); return; } - elem = &proc->callstack[proc->callstack_depth]; + elem = &proc->callstack[proc->callstack_depth++]; + *elem = (struct callstack_element){}; elem->is_syscall = 0; elem->c_un.libfunc = sym; elem->return_addr = proc->return_addr; - if (elem->return_addr) { - insert_breakpoint(proc, elem->return_addr, 0); - } + if (elem->return_addr) + insert_breakpoint(proc, elem->return_addr, NULL); - proc->callstack_depth++; if (opt_T || options.summary) { struct timezone tz; gettimeofday(&elem->time_spent, &tz); } } -static void -callstack_pop(Process *proc) { +void +callstack_pop(struct Process *proc) +{ struct callstack_element *elem; assert(proc->callstack_depth > 0); debug(DEBUG_FUNCTION, "callstack_pop(pid=%d)", proc->pid); elem = &proc->callstack[proc->callstack_depth - 1]; - if (!elem->is_syscall && elem->return_addr) { + if (!elem->is_syscall && elem->return_addr) delete_breakpoint(proc, elem->return_addr); + + if (elem->fetch_context != NULL) + fetch_arg_done(elem->fetch_context); + + if (elem->arguments != NULL) { + val_dict_destroy(elem->arguments); + free(elem->arguments); } + proc->callstack_depth--; } @@ -0,0 +1,62 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <assert.h> + +#include "lens.h" +#include "lens_default.h" +#include "type.h" +#include "value.h" + +int +format_argument(FILE *stream, struct value *value, + struct value_dict *arguments) +{ + /* Find the closest enclosing parental value whose type has a + * lens assigned. */ + struct value *parent; + for (parent = value; (parent != NULL && parent->type != NULL + && parent->type->lens == NULL); + parent = parent->parent) + ; + + struct lens *lens = &default_lens; + if (parent != NULL && parent->type != NULL + && parent->type->lens != NULL) + lens = parent->type->lens; + + return lens_format(lens, stream, value, arguments); +} + +int +lens_format(struct lens *lens, FILE *stream, struct value *value, + struct value_dict *arguments) +{ + assert(lens->format_cb != NULL); + return lens->format_cb(lens, stream, value, arguments); +} + +void +lens_destroy(struct lens *lens) +{ + if (lens != NULL + && lens->destroy_cb != NULL) + lens->destroy_cb(lens); +} @@ -0,0 +1,51 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LENS_H +#define LENS_H + +#include <stdio.h> +#include "forward.h" + +struct lens { + /* Format VALUE into STREAM. The dictionary of all arguments + * is given for purposes of evaluating array lengths and other + * dynamic expressions. Returns number of characters + * outputted, -1 in case of failure. */ + int (*format_cb)(struct lens *lens, FILE *stream, struct value *value, + struct value_dict *arguments); + + /* Erase any memory allocated for LENS. Keep the LENS pointer + * itself intact. */ + void (*destroy_cb)(struct lens *lens); +}; + +/* Extracts a lens from VALUE and calls lens_format on that. */ +int format_argument(FILE *stream, struct value *value, + struct value_dict *arguments); + +/* Calls format callback associated with LENS. */ +int lens_format(struct lens *lens, FILE *stream, struct value *value, + struct value_dict *arguments); + +/* Calls destroy callback associated with LENS. */ +void lens_destroy(struct lens *lens); + +#endif /* LENS_H */ diff --git a/lens_default.c b/lens_default.c new file mode 100644 index 0000000..ed3d0e1 --- /dev/null +++ b/lens_default.c @@ -0,0 +1,714 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2006 Steve Fink + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <ctype.h> +#include <stdlib.h> +#include <assert.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "proc.h" +#include "lens_default.h" +#include "value.h" +#include "expr.h" +#include "type.h" +#include "common.h" +#include "zero.h" + +#define READER(NAME, TYPE) \ + static int \ + NAME(struct value *value, TYPE *ret, struct value_dict *arguments) \ + { \ + union { \ + TYPE val; \ + unsigned char buf[0]; \ + } u; \ + if (value_extract_buf(value, u.buf, arguments) < 0) \ + return -1; \ + *ret = u.val; \ + return 0; \ + } + +READER(read_float, float) +READER(read_double, double) + +#undef READER + +#define HANDLE_WIDTH(BITS) \ + do { \ + long l; \ + if (value_extract_word(value, &l, arguments) < 0) \ + return -1; \ + int##BITS##_t i = l; \ + uint64_t v = (uint64_t)(uint##BITS##_t)i; \ + switch (format) { \ + case INT_FMT_unknown: \ + if (l < -10000 || l > 10000) \ + case INT_FMT_x: \ + return fprintf(stream, "%#"PRIx64, v); \ + case INT_FMT_i: \ + case INT_FMT_default: \ + return fprintf(stream, "%"PRIi##BITS, i); \ + case INT_FMT_u: \ + return fprintf(stream, "%"PRIu64, v); \ + case INT_FMT_o: \ + return fprintf(stream, "0%"PRIo64, v); \ + } \ + } while (0) + +enum int_fmt_t +{ + INT_FMT_i, + INT_FMT_u, + INT_FMT_o, + INT_FMT_x, + INT_FMT_unknown, + INT_FMT_default, +}; + +static int +format_integer(FILE *stream, struct value *value, enum int_fmt_t format, + struct value_dict *arguments) +{ + switch (type_sizeof(value->inferior, value->type)) { + + case 1: HANDLE_WIDTH(8); + case 2: HANDLE_WIDTH(16); + case 4: HANDLE_WIDTH(32); + case 8: HANDLE_WIDTH(64); + + default: + assert(!"unsupported integer width"); + abort(); + + case -1: + return -1; + } +} + +#undef HANDLE_WIDTH + +static int +acc_fprintf(int *countp, FILE *stream, const char *format, ...) +{ + va_list pa; + va_start(pa, format); + int i = account_output(countp, vfprintf(stream, format, pa)); + va_end(pa); + + return i; +} + +static int +format_char(FILE *stream, struct value *value, struct value_dict *arguments) +{ + long lc; + if (value_extract_word(value, &lc, arguments) < 0) + return -1; + int c = (int)lc; + + const char *fmt; + switch (c) { + case -1: + fmt = "EOF"; + break; + case 0: + fmt = "\\0"; + break; + case '\a': + fmt = "\\a"; + break; + case '\b': + fmt = "\\b"; + break; + case '\t': + fmt = "\\t"; + break; + case '\n': + fmt = "\\n"; + break; + case '\v': + fmt = "\\v"; + break; + case '\f': + fmt = "\\f"; + break; + case '\r': + fmt = "\\r"; + break; + case '\\': + fmt = "\\\\"; + break; + default: + if (isprint(c) || c == ' ') + fmt = "%c"; + else + fmt = "\\%03o"; + } + + return fprintf(stream, fmt, c); +} + +static int +format_naked_char(FILE *stream, struct value *value, + struct value_dict *arguments) +{ + int written = 0; + if (acc_fprintf(&written, stream, "'") < 0 + || account_output(&written, + format_char(stream, value, arguments)) < 0 + || acc_fprintf(&written, stream, "'") < 0) + return -1; + + return written; +} + +static int +format_double(FILE *stream, double value, enum int_fmt_t format) +{ + if (format == INT_FMT_x) + return fprintf(stream, "%a", value); + else + return fprintf(stream, "%f", value); +} + +static int +format_floating(FILE *stream, struct value *value, struct value_dict *arguments, + enum int_fmt_t format) +{ + switch (value->type->type) { + float f; + double d; + case ARGTYPE_FLOAT: + if (read_float(value, &f, arguments) < 0) + return -1; + return format_double(stream, f, format); + case ARGTYPE_DOUBLE: + if (read_double(value, &d, arguments) < 0) + return -1; + return format_double(stream, d, format); + default: + abort(); + } +} + +struct format_argument_data +{ + struct value *value; + struct value_dict *arguments; +}; + +static int +format_argument_cb(FILE *stream, void *ptr) +{ + struct format_argument_data *data = ptr; + return format_argument(stream, data->value, data->arguments); +} + +static int +format_struct(FILE *stream, struct value *value, struct value_dict *arguments) +{ + int written = 0; + if (acc_fprintf(&written, stream, "{ ") < 0) + return -1; + + int need_delim = 0; + size_t i; + for (i = 0; i < type_struct_size(value->type); ++i) { + struct value element; + if (value_init_element(&element, value, i) < 0) + return -1; + + struct format_argument_data data = { &element, arguments }; + int o = delim_output(stream, &need_delim, + format_argument_cb, &data); + value_destroy(&element); + if (o < 0) + return -1; + + written += o; + } + if (acc_fprintf(&written, stream, " }") < 0) + return -1; + return written; +} + +int +format_pointer(FILE *stream, struct value *value, struct value_dict *arguments) +{ + if (value_is_zero(value, arguments)) + return fprintf(stream, "nil"); + + /* The following is for detecting recursion. We keep track of + * the values that were already displayed. Each time a + * pointer should be dereferenced, we compare its value to the + * value of each of the pointers dereferenced so far. If one + * of them matches, instead of recursing, we just printf which + * superstructure this pointer recurses to. */ + static struct vect pointers = {}; + if (pointers.elt_size == 0) + VECT_INIT(&pointers, struct value *); + + /* Trim number of expanded structures of the same type. Even + * for non-recursive structure, we don't want to expand all of + * it if it's huge. */ + size_t i; + size_t len = vect_size(&pointers); + assert(value->type->type == ARGTYPE_POINTER); + struct arg_type_info *pointee = value->type->u.ptr_info.info; + if (pointee->type == ARGTYPE_STRUCT) { + size_t depth = 0; + for (i = 0; i < len; ++i) { + struct value *old + = *VECT_ELEMENT(&pointers, struct value *, i); + assert(old->type->type == ARGTYPE_POINTER); + struct arg_type_info *old_pointee + = old->type->u.ptr_info.info; + if (old_pointee == pointee) + depth++; + } + if (depth >= options.arraylen) + return fprintf(stream, "..."); + } + + for (i = len; i-- > 0 ;) { + struct value **old = VECT_ELEMENT(&pointers, struct value *, i); + int rc = value_equal(value, *old, arguments); + if (rc < 0) + return -1; + if (rc > 0) { + size_t reclevel = len - i - 1; + char buf[reclevel + 1]; + memset(buf, '^', sizeof buf); + buf[reclevel] = 0; + return fprintf(stream, "recurse%s", buf); + } + } + + /* OK, not a recursion. Remember this value for tracking. */ + if (VECT_PUSHBACK(&pointers, &value) < 0) + return -1; + + struct value element; + int o; + if (value_init_deref(&element, value) < 0) { + o = -1; + goto done; + } + o = format_argument(stream, &element, arguments); + value_destroy(&element); + +done: + vect_popback(&pointers); + return o; +} + +/* + * LENGTH is an expression whose evaluation will yield the actual + * length of the array. + * + * MAXLEN is the actual maximum length that we care about + * + * BEFORE if LENGTH>MAXLEN, we display ellipsis. We display it before + * the closing parenthesis if BEFORE, otherwise after it. + * + * OPEN, CLOSE, DELIM are opening and closing parenthesis and element + * delimiter. + */ +int +format_array(FILE *stream, struct value *value, struct value_dict *arguments, + struct expr_node *length, size_t maxlen, int before, + const char *open, const char *close, const char *delim) +{ + /* We need "long" to be long enough to cover the whole address + * space. */ + typedef char assert__long_enough_long[-(sizeof(long) < sizeof(void *))]; + long l; + if (expr_eval_word(length, value, arguments, &l) < 0) + return -1; + size_t len = (size_t)l; + + int written = 0; + if (acc_fprintf(&written, stream, "%s", open) < 0) + return -1; + + size_t i; + for (i = 0; i < len && i <= maxlen; ++i) { + if (i == maxlen) { + if (before && acc_fprintf(&written, stream, "...") < 0) + return -1; + break; + } + + if (i > 0 && acc_fprintf(&written, stream, "%s", delim) < 0) + return -1; + + struct value element; + if (value_init_element(&element, value, i) < 0) + return -1; + int o = format_argument(stream, &element, arguments); + value_destroy(&element); + if (o < 0) + return -1; + written += o; + } + if (acc_fprintf(&written, stream, "%s", close) < 0) + return -1; + if (i == maxlen && !before && acc_fprintf(&written, stream, "...") < 0) + return -1; + + return written; +} + +static int +toplevel_format_lens(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments, + enum int_fmt_t int_fmt) +{ + switch (value->type->type) { + case ARGTYPE_VOID: + return fprintf(stream, "<void>"); + + case ARGTYPE_SHORT: + case ARGTYPE_INT: + case ARGTYPE_LONG: + return format_integer(stream, value, int_fmt, arguments); + + case ARGTYPE_USHORT: + case ARGTYPE_UINT: + case ARGTYPE_ULONG: + if (int_fmt == INT_FMT_i || int_fmt == INT_FMT_default) + int_fmt = INT_FMT_u; + return format_integer(stream, value, int_fmt, arguments); + + case ARGTYPE_CHAR: + if (int_fmt == INT_FMT_default) + return format_naked_char(stream, value, arguments); + return format_integer(stream, value, int_fmt, arguments); + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + return format_floating(stream, value, arguments, int_fmt); + + case ARGTYPE_STRUCT: + return format_struct(stream, value, arguments); + + case ARGTYPE_POINTER: + if (value->type->u.array_info.elt_type->type != ARGTYPE_VOID) + return format_pointer(stream, value, arguments); + return format_integer(stream, value, INT_FMT_x, arguments); + + case ARGTYPE_ARRAY: + return format_array(stream, value, arguments, + value->type->u.array_info.length, + options.arraylen, 1, "[ ", " ]", ", "); + } + abort(); +} + +static int +default_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + return toplevel_format_lens(lens, stream, value, arguments, + INT_FMT_default); +} + +struct lens default_lens = { + .format_cb = default_lens_format_cb, +}; + + +static int +blind_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + return 0; +} + +struct lens blind_lens = { + .format_cb = blind_lens_format_cb, +}; + + +static int +octal_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_o); +} + +struct lens octal_lens = { + .format_cb = octal_lens_format_cb, +}; + + +static int +hex_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_x); +} + +struct lens hex_lens = { + .format_cb = hex_lens_format_cb, +}; + + +static int +dec_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_u); +} + +struct lens dec_lens = { + .format_cb = dec_lens_format_cb, +}; + + +static int +guess_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + return toplevel_format_lens(lens, stream, value, arguments, + INT_FMT_unknown); +} + +struct lens guess_lens = { + .format_cb = guess_lens_format_cb, +}; + + +static int +bool_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + switch (value->type->type) { + case ARGTYPE_VOID: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + case ARGTYPE_STRUCT: + case ARGTYPE_POINTER: + case ARGTYPE_ARRAY: + return toplevel_format_lens(lens, stream, value, + arguments, INT_FMT_default); + + int zero; + case ARGTYPE_SHORT: + case ARGTYPE_INT: + case ARGTYPE_LONG: + case ARGTYPE_USHORT: + case ARGTYPE_UINT: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + if ((zero = value_is_zero(value, arguments)) < 0) + return -1; + if (zero) + return fprintf(stream, "false"); + else + return fprintf(stream, "true"); + } + abort(); +} + +struct lens bool_lens = { + .format_cb = bool_lens_format_cb, +}; + + +static int +string_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + switch (value->type->type) { + case ARGTYPE_POINTER: + /* This should really be written as either "string", + * or, if lens, then string(array(char, zero)*). But + * I suspect people are so used to the char * C idiom, + * that string(char *) might actually turn up. So + * let's just support it. */ + if (value->type->u.ptr_info.info->type == ARGTYPE_CHAR) { + struct arg_type_info info[2]; + type_init_array(&info[1], + value->type->u.ptr_info.info, 0, + expr_node_zero(), 0); + type_init_pointer(&info[0], &info[1], 0); + info->lens = lens; + info->own_lens = 0; + struct value tmp; + if (value_clone(&tmp, value) < 0) + return -1; + value_set_type(&tmp, info, 0); + int ret = string_lens_format_cb(lens, stream, &tmp, + arguments); + type_destroy(&info[0]); + type_destroy(&info[1]); + value_destroy(&tmp); + return ret; + } + + /* fall-through */ + case ARGTYPE_VOID: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + case ARGTYPE_STRUCT: + case ARGTYPE_SHORT: + case ARGTYPE_INT: + case ARGTYPE_LONG: + case ARGTYPE_USHORT: + case ARGTYPE_UINT: + case ARGTYPE_ULONG: + return toplevel_format_lens(lens, stream, value, + arguments, INT_FMT_default); + + case ARGTYPE_CHAR: + return format_char(stream, value, arguments); + + case ARGTYPE_ARRAY: + return format_array(stream, value, arguments, + value->type->u.array_info.length, + options.strlen, 0, "\"", "\"", ""); + } + abort(); +} + +struct lens string_lens = { + .format_cb = string_lens_format_cb, +}; + +static int +out_bits(FILE *stream, size_t low, size_t high) +{ + if (low == high) + return fprintf(stream, "%zd", low); + else + return fprintf(stream, "%zd-%zd", low, high); +} + +static unsigned +bitcount(unsigned u) +{ + int c = 0; + for (; u > 0; u &= u - 1) + c++; + return c; +} + +static int +bitvect_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + unsigned char *data = value_get_data(value, arguments); + if (data == NULL) + return -1; + size_t sz = type_sizeof(value->inferior, value->type); + if (sz == (size_t)-1) + return -1; + + size_t i; + unsigned char buf[sz]; + switch ((int)value->type->type) { + union bitvect_integral_64 + { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + unsigned char buf[0]; + } bv; + + case ARGTYPE_POINTER: + return format_pointer(stream, value, arguments); + + case ARGTYPE_STRUCT: + case ARGTYPE_ARRAY: + break; + + default: + assert(sz <= sizeof(bv)); + memmove(bv.buf, data, sz); + + if (sz == 1) + bv.u64 = bv.u8; + else if (sz == 2) + bv.u64 = bv.u16; + else if (sz == 4) + bv.u64 = bv.u32; + + for (i = 0; i < sz; ++i) { + buf[i] = bv.u64 & 0xff; + bv.u64 >>= 8; + } + data = buf; + } + + size_t bits = 0; + for (i = 0; i < sz; ++i) + bits += bitcount(data[i]); + + /* If there's more 1's than 0's, show inverse. */ + unsigned neg = bits > sz * 4 ? 0xff : 0x00; + + int o = 0; + if (acc_fprintf(&o, stream, "%s<", "~" + (neg == 0x00)) < 0) + return -1; + + size_t bitno = 0; + ssize_t low = -1; + for (i = 0; i < sz; ++i) { + unsigned char m; + unsigned char d = data[i] ^ neg; + for (m = 0x01; m != 0; m <<= 1) { + int bit = !!(m & d); + if (low < 0) { + if (bit) { + if (low == -2 + && acc_fprintf(&o, stream, ",") < 0) + return -1; + low = bitno; + } + } else if (!bit) { + if (account_output(&o, out_bits(stream, low, + bitno-1)) < 0) + return -1; + low = -2; + } + bitno++; + } + } + if (low >= 0 && account_output(&o, out_bits(stream, low, bitno-1)) < 0) + return -1; + + if (fputc('>', stream) < 0) + return -1; + o += 1; + + return o; +} + +struct lens bitvect_lens = { + .format_cb = bitvect_lens_format_cb, +}; diff --git a/lens_default.h b/lens_default.h new file mode 100644 index 0000000..1206ffc --- /dev/null +++ b/lens_default.h @@ -0,0 +1,52 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LENS_DEFAULT_H +#define LENS_DEFAULT_H + +#include "lens.h" + +/* Default lens that does reasonable job for most cases. */ +extern struct lens default_lens; + +/* A lens that doesn't output anything. */ +extern struct lens blind_lens; + +/* A lens that formats integers in octal. */ +extern struct lens octal_lens; + +/* A lens that formats integers in hexadecimal. */ +extern struct lens hex_lens; + +/* A lens that formats integers as either "true" or "false". */ +extern struct lens bool_lens; + +/* A lens that tries to guess whether the value is "large" (i.e. a + * pointer, and should be formatted in hex), or "small" (and should be + * formatted in decimal). */ +extern struct lens guess_lens; + +/* A lens for strings. */ +extern struct lens string_lens; + +/* A lens for bit vector. */ +extern struct lens bitvect_lens; + +#endif /* LENS_DEFAULT_H */ diff --git a/lens_enum.c b/lens_enum.c new file mode 100644 index 0000000..052d6a9 --- /dev/null +++ b/lens_enum.c @@ -0,0 +1,159 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include "lens_enum.h" +#include "lens_default.h" +#include "value.h" +#include "sysdep.h" +#include "type.h" + +struct enum_entry { + char *key; + int own_key; + struct value *value; + int own_value; +}; + +static void +enum_entry_dtor(struct enum_entry *entry, void *data) +{ + if (entry->own_key) + free(entry->key); + if (entry->own_value) { + value_destroy(entry->value); + free(entry->value); + } +} + +static void +enum_lens_destroy_cb(struct lens *lens) +{ + struct enum_lens *self = (void *)lens; + + VECT_DESTROY(&self->entries, struct enum_entry, + enum_entry_dtor, NULL); +} + +enum { +#ifdef ARCH_ENDIAN_BIG + big_endian = 1, +#elif defined (ARCH_ENDIAN_LITTLE) + big_endian = 0, +#else +# error Undefined endianness. +#endif +}; + +/* Returns 0 if they are not equal, >0 if they are, and <0 if there + * was an error. */ +static int +enum_values_equal(struct value *inf_value, struct value *enum_value, + struct value_dict *arguments) +{ + /* Width may not match between what's defined in config file + * and what arrives from the back end. Typically, if there is + * a mismatch, the config file size will be larger, as we are + * in a situation where 64-bit tracer traces 32-bit process. + * But opposite situation can occur e.g. on PPC, where it's + * apparently possible for 32-bit tracer to trace 64-bit + * inferior, or hypothetically in a x32/x86_64 situation. */ + + unsigned char *inf_data = value_get_data(inf_value, arguments); + size_t inf_sz = value_size(inf_value, arguments); + if (inf_data == NULL || inf_sz == (size_t)-1) + return -1; + + assert(inf_value->type->type == enum_value->type->type); + + unsigned char *enum_data = value_get_data(enum_value, arguments); + size_t enum_sz = value_size(enum_value, arguments); + if (enum_data == NULL || enum_sz == (size_t)-1) + return -1; + + size_t sz = enum_sz > inf_sz ? inf_sz : enum_sz; + + if (big_endian) + return memcmp(enum_data + enum_sz - sz, + inf_data + inf_sz - sz, sz) == 0; + else + return memcmp(enum_data, inf_data, sz) == 0; +} + +static const char * +enum_get(struct enum_lens *lens, struct value *value, + struct value_dict *arguments) +{ + size_t i; + for (i = 0; i < vect_size(&lens->entries); ++i) { + struct enum_entry *entry = VECT_ELEMENT(&lens->entries, + struct enum_entry, i); + int st = enum_values_equal(value, entry->value, arguments); + if (st < 0) + return NULL; + else if (st != 0) + return entry->key; + } + return NULL; +} + +static int +enum_lens_format_cb(struct lens *lens, FILE *stream, + struct value *value, struct value_dict *arguments) +{ + struct enum_lens *self = (void *)lens; + + const char *name = enum_get(self, value, arguments); + if (name != NULL) + return fprintf(stream, "%s", name); + + return lens_format(&default_lens, stream, value, arguments); +} + + +void +lens_init_enum(struct enum_lens *lens) +{ + *lens = (struct enum_lens){ + { + .format_cb = enum_lens_format_cb, + .destroy_cb = enum_lens_destroy_cb, + }, + }; + VECT_INIT(&lens->entries, struct enum_entry); +} + +int +lens_enum_add(struct enum_lens *lens, + const char *key, int own_key, + struct value *value, int own_value) +{ + struct enum_entry entry = { (char *)key, own_key, value, own_value }; + return VECT_PUSHBACK(&lens->entries, &entry); +} + +size_t +lens_enum_size(struct enum_lens *lens) +{ + return vect_size(&lens->entries); +} diff --git a/lens_enum.h b/lens_enum.h new file mode 100644 index 0000000..8edd1a5 --- /dev/null +++ b/lens_enum.h @@ -0,0 +1,47 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LENS_ENUM_H +#define LENS_ENUM_H + +#include "lens.h" +#include "vect.h" + +struct enum_lens { + struct lens super; + struct vect entries; +}; + +/* Init enumeration LENS. */ +void lens_init_enum(struct enum_lens *lens); + +/* Push another member of the enumeration, named KEY, with given + * VALUE. If OWN_KEY, KEY is owned and released after the type is + * destroyed. KEY is typed as const char *, but note that if OWN_KEY, + * this value will be freed. If OWN_VALUE, then VALUE is owned and + * destroyed by LENS. */ +int lens_enum_add(struct enum_lens *lens, + const char *key, int own_key, + struct value *value, int own_value); + +/* Return number of enum elements of type INFO. */ +size_t lens_enum_size(struct enum_lens *lens); + +#endif /* LENS_ENUM_H */ diff --git a/libltrace.c b/libltrace.c index 0f48d11..559edfa 100644 --- a/libltrace.c +++ b/libltrace.c @@ -1,66 +1,93 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" +#include <sys/param.h> +#include <sys/wait.h> +#include <errno.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <string.h> -#include <errno.h> -#include <sys/param.h> -#include <signal.h> -#include <sys/wait.h> +#include <unistd.h> #include "common.h" +#include "proc.h" +#include "read_config_file.h" +#include "backend.h" char *command = NULL; -Process *list_of_processes = NULL; int exiting = 0; /* =1 if a SIGINT or SIGTERM has been received */ -static void -signal_alarm(int sig) { - Process *tmp = list_of_processes; +static enum callback_status +stop_non_p_processes(Process *proc, void *data) +{ + int stop = 1; - signal(SIGALRM, SIG_DFL); - while (tmp) { - struct opt_p_t *tmp2 = opt_p; - while (tmp2) { - if (tmp->pid == tmp2->pid) { - tmp = tmp->next; - if (!tmp) { - return; - } - tmp2 = opt_p; - continue; - } - tmp2 = tmp2->next; + struct opt_p_t *it; + for (it = opt_p; it != NULL; it = it->next) { + Process * p_proc = pid2proc(it->pid); + if (p_proc == NULL) { + printf("stop_non_p_processes: %d terminated?\n", it->pid); + continue; + } + if (p_proc == proc || p_proc->leader == proc->leader) { + stop = 0; + break; } - debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); - kill(tmp->pid, SIGSTOP); - tmp = tmp->next; } + + if (stop) { + debug(2, "Sending SIGSTOP to process %u", proc->pid); + kill(proc->pid, SIGSTOP); + } + + return CBS_CONT; } static void -signal_exit(int sig) { - exiting = 1; - debug(1, "Received interrupt signal; exiting..."); +signal_alarm(int sig) { + signal(SIGALRM, SIG_DFL); + each_process(NULL, &stop_non_p_processes, NULL); +} + +static void +signal_exit(int sig) +{ + if (exiting != 0) + return; + + exiting = 1 + !!os_ltrace_exiting_sighandler(); + signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGALRM, signal_alarm); - if (opt_p) { - struct opt_p_t *tmp = opt_p; - while (tmp) { - debug(2, "Sending SIGSTOP to process %u\n", tmp->pid); - kill(tmp->pid, SIGSTOP); - tmp = tmp->next; - } - } - alarm(1); + //alarm(1); } static void -normal_exit(void) { - output_line(0, 0); +normal_exit(void) +{ if (options.summary) { show_summary(); } @@ -79,6 +106,7 @@ ltrace_init(int argc, char **argv) { signal(SIGTERM, signal_exit); /* ... or killed */ argv = process_options(argc, argv); + init_global_config(); while (opt_F) { /* If filename begins with ~, expand it to the user's home */ /* directory. This does not correctly handle ~yoda, but that */ @@ -98,17 +126,30 @@ ltrace_init(int argc, char **argv) { } else { read_config_file(opt_F->filename); } - opt_F = opt_F->next; - } - if (opt_e) { - struct opt_e_t *tmp = opt_e; - while (tmp) { - debug(1, "Option -e: %s\n", tmp->name); - tmp = tmp->next; - } + + struct opt_F_t *next = opt_F->next; + if (opt_F->own_filename) + free(opt_F->filename); + free(opt_F); + opt_F = next; } if (command) { - execute_program(open_program(command, 0), argv); + /* Check that the binary ABI is supported before + * calling execute_program. */ + struct ltelf lte = {}; + open_elf(<e, command); + do_close_elf(<e); + + pid_t pid = execute_program(command, argv); + struct Process *proc = open_program(command, pid); + if (proc == NULL) { + fprintf(stderr, "couldn't open program '%s': %s\n", + command, strerror(errno)); + exit(EXIT_FAILURE); + } + + trace_set_options(proc); + continue_process(pid); } opt_p_tmp = opt_p; while (opt_p_tmp) { diff --git a/library.c b/library.c new file mode 100644 index 0000000..594472b --- /dev/null +++ b/library.c @@ -0,0 +1,428 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2001,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdio.h> + +#include "library.h" +#include "callback.h" +#include "debug.h" +#include "dict.h" +#include "backend.h" // for arch_library_symbol_init, arch_library_init + +#ifndef ARCH_HAVE_LIBRARY_DATA +void +arch_library_init(struct library *lib) +{ +} + +void +arch_library_destroy(struct library *lib) +{ +} + +void +arch_library_clone(struct library *retp, struct library *lib) +{ +} +#endif + +#ifndef ARCH_HAVE_LIBRARY_SYMBOL_DATA +int +arch_library_symbol_init(struct library_symbol *libsym) +{ + return 0; +} + +void +arch_library_symbol_destroy(struct library_symbol *libsym) +{ +} + +int +arch_library_symbol_clone(struct library_symbol *retp, + struct library_symbol *libsym) +{ + return 0; +} +#endif + +unsigned int +target_address_hash(const void *key) +{ + /* XXX this assumes that key is passed by value. */ + union { + arch_addr_t addr; + unsigned int ints[sizeof(arch_addr_t) + / sizeof(unsigned int)]; + } u = { .addr = (arch_addr_t)key }; + + size_t i; + unsigned int h = 0; + for (i = 0; i < sizeof(u.ints) / sizeof(*u.ints); ++i) + h ^= dict_key2hash_int((void *)(uintptr_t)u.ints[i]); + return h; +} + +int +target_address_cmp(const void *key1, const void *key2) +{ + /* XXX this assumes that key is passed by value. */ + arch_addr_t addr1 = (arch_addr_t)key1; + arch_addr_t addr2 = (arch_addr_t)key2; + return addr1 < addr2 ? 1 + : addr1 > addr2 ? -1 : 0; +} + +/* If the other symbol owns the name, we need to make the copy, so + * that the life-times of the two symbols are not dependent on each + * other. */ +static int +strdup_if_owned(const char **retp, const char *str, int owned) +{ + if (!owned || str == NULL) { + *retp = str; + return 0; + } else { + *retp = strdup(str); + return *retp != NULL ? 0 : -1; + } +} + +static void +private_library_symbol_init(struct library_symbol *libsym, + arch_addr_t addr, + const char *name, int own_name, + enum toplt type_of_plt, + int latent, int delayed) +{ + libsym->next = NULL; + libsym->lib = NULL; + libsym->plt_type = type_of_plt; + libsym->name = name; + libsym->own_name = own_name; + libsym->latent = latent; + libsym->delayed = delayed; + libsym->enter_addr = (void *)(uintptr_t)addr; +} + +static void +private_library_symbol_destroy(struct library_symbol *libsym) +{ + library_symbol_set_name(libsym, NULL, 0); +} + +int +library_symbol_init(struct library_symbol *libsym, + arch_addr_t addr, const char *name, int own_name, + enum toplt type_of_plt) +{ + private_library_symbol_init(libsym, addr, name, own_name, + type_of_plt, 0, 0); + + /* If arch init fails, we've already set libsym->name and + * own_name. But we return failure, and the client code isn't + * supposed to call library_symbol_destroy in such a case. */ + return arch_library_symbol_init(libsym); +} + +void +library_symbol_destroy(struct library_symbol *libsym) +{ + if (libsym != NULL) { + private_library_symbol_destroy(libsym); + arch_library_symbol_destroy(libsym); + } +} + +int +library_symbol_clone(struct library_symbol *retp, struct library_symbol *libsym) +{ + const char *name; + if (strdup_if_owned(&name, libsym->name, libsym->own_name) < 0) + return -1; + + private_library_symbol_init(retp, libsym->enter_addr, + name, libsym->own_name, libsym->plt_type, + libsym->latent, libsym->delayed); + + if (arch_library_symbol_clone(retp, libsym) < 0) { + private_library_symbol_destroy(retp); + return -1; + } + + return 0; +} + +int +library_symbol_cmp(struct library_symbol *a, struct library_symbol *b) +{ + if (a->enter_addr < b->enter_addr) + return -1; + if (a->enter_addr > b->enter_addr) + return 1; + if (a->name != NULL && b->name != NULL) + return strcmp(a->name, b->name); + if (a->name == NULL) { + if (b->name == NULL) + return 0; + return -1; + } + return 1; +} + +void +library_symbol_set_name(struct library_symbol *libsym, + const char *name, int own_name) +{ + if (libsym->own_name) + free((char *)libsym->name); + libsym->name = name; + libsym->own_name = own_name; +} + +enum callback_status +library_symbol_equal_cb(struct library_symbol *libsym, void *u) +{ + struct library_symbol *standard = u; + return library_symbol_cmp(libsym, standard) == 0 ? CBS_STOP : CBS_CONT; +} + +enum callback_status +library_symbol_named_cb(struct library_symbol *libsym, void *name) +{ + return strcmp(libsym->name, name) == 0 ? CBS_STOP : CBS_CONT; +} + +enum callback_status +library_symbol_delayed_cb(struct library_symbol *libsym, void *unused) +{ + return libsym->delayed ? CBS_STOP : CBS_CONT; +} + +static void +private_library_init(struct library *lib, enum library_type type) +{ + lib->next = NULL; + + lib->key = 0; + lib->base = 0; + lib->entry = 0; + lib->dyn_addr = 0; + + lib->soname = NULL; + lib->own_soname = 0; + + lib->pathname = NULL; + lib->own_pathname = 0; + + lib->symbols = NULL; + lib->exported_names = NULL; + lib->type = type; +} + +void +library_init(struct library *lib, enum library_type type) +{ + private_library_init(lib, type); + arch_library_init(lib); +} + +static int +library_exported_name_clone(struct library_exported_name *retp, + struct library_exported_name *exnm) +{ + char *name = exnm->own_name ? strdup(exnm->name) : (char *)exnm->name; + if (name == NULL) + return -1; + retp->name = name; + retp->own_name = exnm->own_name; + return 0; +} + +int +library_clone(struct library *retp, struct library *lib) +{ + const char *soname = NULL; + const char *pathname; + if (strdup_if_owned(&soname, lib->soname, lib->own_soname) < 0 + || strdup_if_owned(&pathname, + lib->pathname, lib->own_pathname) < 0) { + if (lib->own_soname) + free((char *)soname); + return -1; + } + + private_library_init(retp, lib->type); + library_set_soname(retp, soname, lib->own_soname); + library_set_pathname(retp, pathname, lib->own_pathname); + arch_library_clone(retp, lib); + + retp->key = lib->key; + + /* Clone symbols. */ + { + struct library_symbol *it; + struct library_symbol **nsymp = &retp->symbols; + for (it = lib->symbols; it != NULL; it = it->next) { + *nsymp = malloc(sizeof(**nsymp)); + if (*nsymp == NULL + || library_symbol_clone(*nsymp, it) < 0) { + free(*nsymp); + fail: + /* Release what we managed to allocate. */ + library_destroy(retp); + return -1; + } + + (*nsymp)->lib = retp; + nsymp = &(*nsymp)->next; + } + *nsymp = NULL; + } + + /* Clone exported names. */ + { + struct library_exported_name *it; + struct library_exported_name **nnamep = &retp->exported_names; + for (it = lib->exported_names; it != NULL; it = it->next) { + *nnamep = malloc(sizeof(**nnamep)); + if (*nnamep == NULL + || library_exported_name_clone(*nnamep, it) < 0) { + free(*nnamep); + goto fail; + } + nnamep = &(*nnamep)->next; + } + *nnamep = NULL; + } + + return 0; +} + +void +library_destroy(struct library *lib) +{ + if (lib == NULL) + return; + + arch_library_destroy(lib); + library_set_soname(lib, NULL, 0); + library_set_pathname(lib, NULL, 0); + + struct library_symbol *sym; + for (sym = lib->symbols; sym != NULL; ) { + struct library_symbol *next = sym->next; + library_symbol_destroy(sym); + free(sym); + sym = next; + } + + /* Release exported names. */ + struct library_exported_name *it; + for (it = lib->exported_names; it != NULL; ) { + struct library_exported_name *next = it->next; + if (it->own_name) + free((char *)it->name); + free(it); + it = next; + } +} + +void +library_set_soname(struct library *lib, const char *new_name, int own_name) +{ + if (lib->own_soname) + free((char *)lib->soname); + lib->soname = new_name; + lib->own_soname = own_name; +} + +void +library_set_pathname(struct library *lib, const char *new_name, int own_name) +{ + if (lib->own_pathname) + free((char *)lib->pathname); + lib->pathname = new_name; + lib->own_pathname = own_name; +} + +struct library_symbol * +library_each_symbol(struct library *lib, struct library_symbol *start_after, + enum callback_status (*cb)(struct library_symbol *, void *), + void *data) +{ + struct library_symbol *it = start_after == NULL ? lib->symbols + : start_after->next; + + while (it != NULL) { + struct library_symbol *next = it->next; + + switch ((*cb)(it, data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + return it; + case CBS_CONT: + break; + } + + it = next; + } + + return NULL; +} + +void +library_add_symbol(struct library *lib, struct library_symbol *first) +{ + struct library_symbol *last; + for (last = first; last != NULL; ) { + last->lib = lib; + if (last->next != NULL) + last = last->next; + else + break; + } + + assert(last->next == NULL); + last->next = lib->symbols; + lib->symbols = first; +} + +enum callback_status +library_named_cb(struct Process *proc, struct library *lib, void *name) +{ + if (name == lib->soname + || strcmp(lib->soname, (char *)name) == 0) + return CBS_STOP; + else + return CBS_CONT; +} + +enum callback_status +library_with_key_cb(struct Process *proc, struct library *lib, void *keyp) +{ + return lib->key == *(arch_addr_t *)keyp ? CBS_STOP : CBS_CONT; +} diff --git a/library.h b/library.h new file mode 100644 index 0000000..555fa80 --- /dev/null +++ b/library.h @@ -0,0 +1,226 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2006 Paul Gilliam, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _LIBRARY_H_ +#define _LIBRARY_H_ + +#include <stdint.h> +#include "callback.h" +#include "sysdep.h" + +struct Process; +struct library; + +enum toplt { + LS_TOPLT_NONE = 0, /* PLT not used for this symbol. */ + LS_TOPLT_EXEC, /* PLT for this symbol is executable. */ +}; + +/* Dict interface. */ +unsigned int target_address_hash(const void *key); +int target_address_cmp(const void *key1, const void *key2); + +/* For handling -l. */ +struct library_exported_name { + struct library_exported_name *next; + const char *name; + int own_name : 1; +}; + +struct library_symbol { + struct library_symbol *next; + struct library *lib; + const char *name; + arch_addr_t enter_addr; + enum toplt plt_type; + int own_name : 1; + + /* This is relevant for PLT symbols. Latent PLT symbols are + * those that don't match any of the -e rules, but that might + * potentially become active if a library implementing them + * appears that matches a -l rule. Ltrace core is responsible + * for clearing latent flag. */ + int latent : 1; + + /* Delayed symbols are those for which a breakpoint shouldn't + * be enabled yet. They are similar to latent symbols, but + * backend is responsible for clearing the delayed flag. See + * proc_activate_delayed_symbol. */ + int delayed : 1; + + struct arch_library_symbol_data arch; +}; + +/* Init LIBSYM. NAME will be freed when LIBSYM is destroyed if + * OWN_NAME. ARCH has to be initialized by a separate call. */ +int library_symbol_init(struct library_symbol *libsym, + arch_addr_t addr, const char *name, int own_name, + enum toplt type_of_plt); + +/* Copy library symbol SYM into the area pointed-to by RETP. Return 0 + * on success or a negative value on failure. */ +int library_symbol_clone(struct library_symbol *retp, + struct library_symbol *sym); + +/* Destroy library symbol. This essentially just frees name if it's + * owned. It doesn't free the memory associated with SYM pointer + * itself. Returns 0 on success or a negative value in case of an + * error (which would be an out of memory condition). */ +void library_symbol_destroy(struct library_symbol *sym); + +/* Compare two library symbols. Returns a negative value, 0, or a + * positive value, much like strcmp. The function compares symbol + * addresses, and if those are equal, it compares symbol names. If + * those are equal, too, the symbols are considered equal. */ +int library_symbol_cmp(struct library_symbol *a, struct library_symbol *b); + +/* Set a name for library symbol. This frees the old name, if + * that is owned. */ +void library_symbol_set_name(struct library_symbol *libsym, + const char *name, int own_name); + +/* A function that can be used as library_each_symbol callback. Looks + * for a symbol SYM for which library_symbol_cmp(SYM, STANDARD) + * returns 0. */ +enum callback_status library_symbol_equal_cb(struct library_symbol *libsym, + void *standard); + +/* A function that can be used as library_each_symbol callback. Looks + * for a symbol SYM for which strcmp(SYM->name, NAME) == 0. */ +enum callback_status library_symbol_named_cb(struct library_symbol *libsym, + void *name); + +/* A function that can be used as library_each_symbol callback. Looks + * for a delayed symbol. */ +enum callback_status library_symbol_delayed_cb(struct library_symbol *libsym, + void *unused); + +enum library_type { + LT_LIBTYPE_MAIN, + LT_LIBTYPE_DSO, +}; + +/* XXX we might consider sharing libraries across processes. Things + * like libc will be opened by every single process, no point cloning + * these everywhere. But for now, keep the ownership structure + * simple. */ +struct library { + struct library *next; + + /* Unique key. Two library objects are considered equal, if + * they have the same key. */ + arch_addr_t key; + + /* Address where the library is mapped. */ + arch_addr_t base; + + /* Absolute address of the entry point. Useful for main + * binary, though I suppose the value might be useful for the + * dynamic linker, too (in case we ever want to do early + * process tracing). */ + arch_addr_t entry; + + /* Address of PT_DYNAMIC segment. */ + arch_addr_t dyn_addr; + + /* Symbols associated with the library. This includes a + * symbols that don't have a breakpoint attached (yet). */ + struct library_symbol *symbols; + + /* List of names that this library implements, and that match + * -l filter. Each time a new library is mapped, its list of + * exports is examined, and corresponding PLT slots are + * enabled. */ + struct library_exported_name *exported_names; + + const char *soname; + const char *pathname; + + enum library_type type; + + char own_soname : 1; + char own_pathname : 1; + + struct arch_library_data arch; +}; + +/* Init LIB. */ +void library_init(struct library *lib, enum library_type type); + +/* Initialize RETP to a library identical to LIB. Symbols are not + * shared, but copied over. Returns 0 on success and a negative value + * in case of failure. */ +int library_clone(struct library *retp, struct library *lib); + +/* Destroy library. Doesn't free LIB itself. Symbols are destroyed + * and freed. */ +void library_destroy(struct library *lib); + +/* Set library soname. Frees the old name if necessary. */ +void library_set_soname(struct library *lib, + const char *new_name, int own_name); + +/* Set library pathname. Frees the old name if necessary. */ +void library_set_pathname(struct library *lib, + const char *new_name, int own_name); + +/* Iterate through list of symbols of library LIB. See callback.h for + * notes on this interface. */ +struct library_symbol *library_each_symbol + (struct library *lib, struct library_symbol *start_after, + enum callback_status (*cb)(struct library_symbol *, void *), + void *data); + +/* Add a new symbol SYM to LIB. SYM is assumed owned, we need to + * overwrite SYM->next. */ +void library_add_symbol(struct library *lib, struct library_symbol *sym); + +/* A function that can be used as proc_each_library callback. Looks + * for a library with the name passed in DATA. PROC is ignored. */ +enum callback_status library_named_cb(struct Process *proc, + struct library *lib, void *name); + +/* A function that can be used as proc_each_library callback. Looks + * for a library with given base. + * + * NOTE: The key is passed as a POINTER to arch_addr_t (that + * because in general, arch_addr_t doesn't fit in void*). */ +enum callback_status library_with_key_cb(struct Process *proc, + struct library *lib, void *keyp); + +/* XXX this should really be in backend.h (as on pmachata/revamp + * branch), or, on this branch, in common.h. But we need + * arch_addr_t (which should also be in backend.h, I reckon), so + * stuff it here for the time being. */ +/* This function is implemented in the back end. It is called for all + * raw addresses as read from symbol tables etc. If necessary on + * given architecture, this function should translate the address + * according to .opd or other indirection mechanism. Returns 0 on + * success and a negative value on failure. */ +struct ltelf; +int arch_translate_address(struct ltelf *lte, + arch_addr_t addr, arch_addr_t *ret); +/* This is the same function as arch_translate_address, except it's + * used at the point that we don't have ELF available anymore. */ +int arch_translate_address_dyn(struct Process *proc, + arch_addr_t addr, arch_addr_t *ret); + +#endif /* _LIBRARY_H_ */ diff --git a/ltrace-elf.c b/ltrace-elf.c new file mode 100644 index 0000000..c571d2a --- /dev/null +++ b/ltrace-elf.c @@ -0,0 +1,978 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006,2010,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Zachary T Welch, CodeSourcery + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1997,1998,2001,2004,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Olaf Hering, SUSE Linux GmbH + * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. + * Copyright (C) 2006 Paul Gilliam, IBM Corporation + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "config.h" + +#include <assert.h> +#ifdef __linux__ +#include <endian.h> +#endif +#include <errno.h> +#include <fcntl.h> +#include <gelf.h> +#include <inttypes.h> +#include <search.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "backend.h" +#include "filter.h" +#include "library.h" +#include "ltrace-elf.h" +#include "proc.h" +#include "debug.h" +#include "options.h" + +#ifndef ARCH_HAVE_LTELF_DATA +int +arch_elf_init(struct ltelf *lte, struct library *lib) +{ + return 0; +} + +void +arch_elf_destroy(struct ltelf *lte) +{ +} +#endif + +int +default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + char *name = strdup(a_name); + if (name == NULL) { + fail_message: + fprintf(stderr, "Couldn't create symbol for PLT entry: %s\n", + strerror(errno)); + fail: + free(name); + return -1; + } + + GElf_Addr addr = arch_plt_sym_val(lte, ndx, rela); + + struct library_symbol *libsym = malloc(sizeof(*libsym)); + if (libsym == NULL) + goto fail_message; + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t taddr = (arch_addr_t) + (uintptr_t)(addr + lte->bias); + + if (library_symbol_init(libsym, taddr, name, 1, LS_TOPLT_EXEC) < 0) { + free(libsym); + goto fail; + } + + libsym->next = *ret; + *ret = libsym; + return 0; +} + +#ifndef ARCH_HAVE_ADD_PLT_ENTRY +enum plt_status +arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + return plt_default; +} +#endif + +Elf_Data * +elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr) +{ + Elf_Data *data = elf_getdata(scn, NULL); + if (data == NULL || elf_getdata(scn, data) != NULL + || data->d_off || data->d_size != shdr->sh_size) + return NULL; + return data; +} + +static int +elf_get_section_if(struct ltelf *lte, Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr, + int (*predicate)(Elf_Scn *, GElf_Shdr *, void *data), + void *data) +{ + int i; + for (i = 1; i < lte->ehdr.e_shnum; ++i) { + Elf_Scn *scn; + GElf_Shdr shdr; + + scn = elf_getscn(lte->elf, i); + if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { + debug(1, "Couldn't read section or header."); + return -1; + } + if (predicate(scn, &shdr, data)) { + *tgt_sec = scn; + *tgt_shdr = shdr; + return 0; + } + } + return -1; + +} + +static int +inside_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data) +{ + GElf_Addr addr = *(GElf_Addr *)data; + return addr >= shdr->sh_addr + && addr < shdr->sh_addr + shdr->sh_size; +} + +int +elf_get_section_covering(struct ltelf *lte, GElf_Addr addr, + Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) +{ + return elf_get_section_if(lte, tgt_sec, tgt_shdr, + &inside_p, &addr); +} + +static int +type_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data) +{ + GElf_Word type = *(GElf_Word *)data; + return shdr->sh_type == type; +} + +int +elf_get_section_type(struct ltelf *lte, GElf_Word type, + Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) +{ + return elf_get_section_if(lte, tgt_sec, tgt_shdr, + &type_p, &type); +} + +struct section_named_data { + struct ltelf *lte; + const char *name; +}; + +static int +name_p(Elf_Scn *scn, GElf_Shdr *shdr, void *d) +{ + struct section_named_data *data = d; + const char *name = elf_strptr(data->lte->elf, + data->lte->ehdr.e_shstrndx, + shdr->sh_name); + return strcmp(name, data->name) == 0; +} + +int +elf_get_section_named(struct ltelf *lte, const char *name, + Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) +{ + struct section_named_data data = { + .lte = lte, + .name = name, + }; + return elf_get_section_if(lte, tgt_sec, tgt_shdr, + &name_p, &data); +} + +static int +need_data(Elf_Data *data, GElf_Xword offset, GElf_Xword size) +{ + assert(data != NULL); + if (data->d_size < size || offset > data->d_size - size) { + debug(1, "Not enough data to read %"PRId64"-byte value" + " at offset %"PRId64".", size, offset); + return -1; + } + return 0; +} + +#define DEF_READER(NAME, SIZE) \ + int \ + NAME(Elf_Data *data, GElf_Xword offset, uint##SIZE##_t *retp) \ + { \ + if (!need_data(data, offset, SIZE / 8) < 0) \ + return -1; \ + \ + if (data->d_buf == NULL) /* NODATA section */ { \ + *retp = 0; \ + return 0; \ + } \ + \ + union { \ + uint##SIZE##_t dst; \ + char buf[0]; \ + } u; \ + memcpy(u.buf, data->d_buf + offset, sizeof(u.dst)); \ + *retp = u.dst; \ + return 0; \ + } + +DEF_READER(elf_read_u16, 16) +DEF_READER(elf_read_u32, 32) +DEF_READER(elf_read_u64, 64) + +#undef DEF_READER + +int +open_elf(struct ltelf *lte, const char *filename) +{ + lte->fd = open(filename, O_RDONLY); + if (lte->fd == -1) + return 1; + + elf_version(EV_CURRENT); + +#ifdef HAVE_ELF_C_READ_MMAP + lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); +#else + lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); +#endif + + if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) { + fprintf(stderr, "\"%s\" is not an ELF file\n", filename); + exit(EXIT_FAILURE); + } + + if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) { + fprintf(stderr, "can't read ELF header of \"%s\": %s\n", + filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) { + fprintf(stderr, "\"%s\" is neither an ELF executable" + " nor a shared library\n", filename); + exit(EXIT_FAILURE); + } + + if (1 +#ifdef LT_ELF_MACHINE + && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS + || lte->ehdr.e_machine != LT_ELF_MACHINE) +#endif +#ifdef LT_ELF_MACHINE2 + && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 + || lte->ehdr.e_machine != LT_ELF_MACHINE2) +#endif +#ifdef LT_ELF_MACHINE3 + && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 + || lte->ehdr.e_machine != LT_ELF_MACHINE3) +#endif + ) { + fprintf(stderr, + "\"%s\" is ELF from incompatible architecture\n", + filename); + exit(EXIT_FAILURE); + } + + return 0; +} + +static void +read_symbol_table(struct ltelf *lte, const char *filename, + Elf_Scn *scn, GElf_Shdr *shdr, const char *name, + Elf_Data **datap, size_t *countp, const char **strsp) +{ + *datap = elf_getdata(scn, NULL); + *countp = shdr->sh_size / shdr->sh_entsize; + if ((*datap == NULL || elf_getdata(scn, *datap) != NULL) + && options.static_filter != NULL) { + fprintf(stderr, "Couldn't get data of section" + " %s from \"%s\": %s\n", + name, filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + scn = elf_getscn(lte->elf, shdr->sh_link); + GElf_Shdr shdr2; + if (scn == NULL || gelf_getshdr(scn, &shdr2) == NULL) { + fprintf(stderr, "Couldn't get header of section" + " #%d from \"%s\": %s\n", + shdr2.sh_link, filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + Elf_Data *data = elf_getdata(scn, NULL); + if (data == NULL || elf_getdata(scn, data) != NULL + || shdr2.sh_size != data->d_size || data->d_off) { + fprintf(stderr, "Couldn't get data of section" + " #%d from \"%s\": %s\n", + shdr2.sh_link, filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + *strsp = data->d_buf; +} + +static int +do_init_elf(struct ltelf *lte, const char *filename) +{ + int i; + GElf_Addr relplt_addr = 0; + GElf_Addr soname_offset = 0; + + debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename); + debug(1, "Reading ELF from %s...", filename); + + for (i = 1; i < lte->ehdr.e_shnum; ++i) { + Elf_Scn *scn; + GElf_Shdr shdr; + const char *name; + + scn = elf_getscn(lte->elf, i); + if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { + fprintf(stderr, "Couldn't get section #%d from" + " \"%s\": %s\n", i, filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); + if (name == NULL) { + fprintf(stderr, "Couldn't get name of section #%d from" + " \"%s\": %s\n", i, filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + if (shdr.sh_type == SHT_SYMTAB) { + read_symbol_table(lte, filename, + scn, &shdr, name, <e->symtab, + <e->symtab_count, <e->strtab); + + } else if (shdr.sh_type == SHT_DYNSYM) { + read_symbol_table(lte, filename, + scn, &shdr, name, <e->dynsym, + <e->dynsym_count, <e->dynstr); + + } else if (shdr.sh_type == SHT_DYNAMIC) { + Elf_Data *data; + size_t j; + + lte->dyn_addr = shdr.sh_addr + lte->bias; + lte->dyn_sz = shdr.sh_size; + + data = elf_getdata(scn, NULL); + if (data == NULL || elf_getdata(scn, data) != NULL) { + fprintf(stderr, "Couldn't get .dynamic data" + " from \"%s\": %s\n", + filename, strerror(errno)); + exit(EXIT_FAILURE); + } + + for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { + GElf_Dyn dyn; + + if (gelf_getdyn(data, j, &dyn) == NULL) { + fprintf(stderr, "Couldn't get .dynamic" + " data from \"%s\": %s\n", + filename, strerror(errno)); + exit(EXIT_FAILURE); + } + if (dyn.d_tag == DT_JMPREL) + relplt_addr = dyn.d_un.d_ptr; + else if (dyn.d_tag == DT_PLTRELSZ) + lte->relplt_size = dyn.d_un.d_val; + else if (dyn.d_tag == DT_SONAME) + soname_offset = dyn.d_un.d_val; + } + } else if (shdr.sh_type == SHT_PROGBITS + || shdr.sh_type == SHT_NOBITS) { + if (strcmp(name, ".plt") == 0) { + lte->plt_addr = shdr.sh_addr; + lte->plt_size = shdr.sh_size; + lte->plt_data = elf_loaddata(scn, &shdr); + if (lte->plt_data == NULL) + fprintf(stderr, + "Can't load .plt data\n"); + lte->plt_flags = shdr.sh_flags; + } +#ifdef ARCH_SUPPORTS_OPD + else if (strcmp(name, ".opd") == 0) { + lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; + lte->opd_size = shdr.sh_size; + lte->opd = elf_rawdata(scn, NULL); + } +#endif + } + } + + if (lte->dynsym == NULL || lte->dynstr == NULL) { + fprintf(stderr, "Couldn't find .dynsym or .dynstr in \"%s\"\n", + filename); + exit(EXIT_FAILURE); + } + + if (!relplt_addr || !lte->plt_addr) { + debug(1, "%s has no PLT relocations", filename); + lte->relplt = NULL; + lte->relplt_count = 0; + } else if (lte->relplt_size == 0) { + debug(1, "%s has unknown PLT size", filename); + lte->relplt = NULL; + lte->relplt_count = 0; + } else { + + for (i = 1; i < lte->ehdr.e_shnum; ++i) { + Elf_Scn *scn; + GElf_Shdr shdr; + + scn = elf_getscn(lte->elf, i); + if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { + fprintf(stderr, "Couldn't get section header" + " from \"%s\": %s\n", + filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + if (shdr.sh_addr == relplt_addr + && shdr.sh_size == lte->relplt_size) { + lte->relplt = elf_getdata(scn, NULL); + lte->relplt_count = + shdr.sh_size / shdr.sh_entsize; + if (lte->relplt == NULL + || elf_getdata(scn, lte->relplt) != NULL) { + fprintf(stderr, "Couldn't get .rel*.plt" + " data from \"%s\": %s\n", + filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + break; + } + } + + if (i == lte->ehdr.e_shnum) { + fprintf(stderr, + "Couldn't find .rel*.plt section in \"%s\"\n", + filename); + exit(EXIT_FAILURE); + } + + debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); + } + + if (soname_offset != 0) + lte->soname = lte->dynstr + soname_offset; + + return 0; +} + +void +do_close_elf(struct ltelf *lte) +{ + debug(DEBUG_FUNCTION, "do_close_elf()"); + arch_elf_destroy(lte); + elf_end(lte->elf); + close(lte->fd); +} + +int +elf_get_sym_info(struct ltelf *lte, const char *filename, + size_t sym_index, GElf_Rela *rela, GElf_Sym *sym) +{ + int i = sym_index; + GElf_Rel rel; + void *ret; + + if (lte->relplt->d_type == ELF_T_REL) { + ret = gelf_getrel(lte->relplt, i, &rel); + rela->r_offset = rel.r_offset; + rela->r_info = rel.r_info; + rela->r_addend = 0; + } else { + ret = gelf_getrela(lte->relplt, i, rela); + } + + if (ret == NULL + || ELF64_R_SYM(rela->r_info) >= lte->dynsym_count + || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela->r_info), + sym) == NULL) { + fprintf(stderr, + "Couldn't get relocation from \"%s\": %s\n", + filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + return 0; +} + +#ifndef ARCH_HAVE_GET_SYMINFO +int +arch_get_sym_info(struct ltelf *lte, const char *filename, + size_t sym_index, GElf_Rela *rela, GElf_Sym *sym) +{ + return elf_get_sym_info(lte, filename, sym_index, rela, sym); +} +#endif + +static void +mark_chain_latent(struct library_symbol *libsym) +{ + for (; libsym != NULL; libsym = libsym->next) { + debug(DEBUG_FUNCTION, "marking %s latent", libsym->name); + libsym->latent = 1; + } +} + +static int +populate_plt(struct Process *proc, const char *filename, + struct ltelf *lte, struct library *lib, + int latent_plts) +{ + size_t i; + for (i = 0; i < lte->relplt_count; ++i) { + GElf_Rela rela; + GElf_Sym sym; + + if (arch_get_sym_info(lte, filename, i, &rela, &sym) < 0) + continue; /* Skip this entry. */ + + char const *name = lte->dynstr + sym.st_name; + + /* If the symbol wasn't matched, reject it, unless we + * need to keep latent PLT breakpoints for tracing + * exports. */ + int matched = filter_matches_symbol(options.plt_filter, + name, lib); + if (!matched && !latent_plts) + continue; + + struct library_symbol *libsym = NULL; + switch (arch_elf_add_plt_entry(proc, lte, name, + &rela, i, &libsym)) { + case plt_default: + if (default_elf_add_plt_entry(proc, lte, name, + &rela, i, &libsym) < 0) + /* fall-through */ + case plt_fail: + return -1; + /* fall-through */ + case plt_ok: + if (libsym != NULL) { + /* If we are adding those symbols just + * for tracing exports, mark them all + * latent. */ + if (!matched) + mark_chain_latent(libsym); + library_add_symbol(lib, libsym); + } + } + } + return 0; +} + +/* When -x rules result in request to trace several aliases, we only + * want to add such symbol once. The only way that those symbols + * differ in is their name, e.g. in glibc you have __GI___libc_free, + * __cfree, __free, __libc_free, cfree and free all defined on the + * same address. So instead we keep this unique symbol struct for + * each address, and replace name in libsym with a shorter variant if + * we find it. */ +struct unique_symbol { + arch_addr_t addr; + struct library_symbol *libsym; +}; + +static int +unique_symbol_cmp(const void *key, const void *val) +{ + const struct unique_symbol *sym_key = key; + const struct unique_symbol *sym_val = val; + return sym_key->addr != sym_val->addr; +} + +static enum callback_status +symbol_with_address(struct library_symbol *sym, void *addrptr) +{ + return sym->enter_addr == *(arch_addr_t *)addrptr + ? CBS_STOP : CBS_CONT; +} + +static int +populate_this_symtab(struct Process *proc, const char *filename, + struct ltelf *lte, struct library *lib, + Elf_Data *symtab, const char *strtab, size_t size, + struct library_exported_name **names) +{ + /* If a valid NAMES is passed, we pass in *NAMES a list of + * symbol names that this library exports. */ + if (names != NULL) + *names = NULL; + + /* Using sorted array would be arguably better, but this + * should be well enough for the number of symbols that we + * typically deal with. */ + size_t num_symbols = 0; + struct unique_symbol *symbols = malloc(sizeof(*symbols) * size); + if (symbols == NULL) { + fprintf(stderr, "couldn't insert symbols for -x: %s\n", + strerror(errno)); + return -1; + } + + GElf_Word secflags[lte->ehdr.e_shnum]; + size_t i; + for (i = 1; i < lte->ehdr.e_shnum; ++i) { + Elf_Scn *scn = elf_getscn(lte->elf, i); + if (scn == NULL) + continue; + GElf_Shdr shdr; + if (gelf_getshdr(scn, &shdr) == NULL) + continue; + secflags[i] = shdr.sh_flags; + } + + for (i = 0; i < size; ++i) { + GElf_Sym sym; + if (gelf_getsym(symtab, i, &sym) == NULL) { + fail: + fprintf(stderr, + "couldn't get symbol #%zd from %s: %s\n", + i, filename, elf_errmsg(-1)); + continue; + } + + /* XXX support IFUNC as well. */ + if (GELF_ST_TYPE(sym.st_info) != STT_FUNC + || sym.st_value == 0 + || sym.st_shndx == STN_UNDEF) + continue; + + /* Find symbol name and snip version. */ + const char *orig_name = strtab + sym.st_name; + const char *version = strchr(orig_name, '@'); + size_t len = version != NULL ? (assert(version > orig_name), + (size_t)(version - orig_name)) + : strlen(orig_name); + char name[len + 1]; + memcpy(name, orig_name, len); + name[len] = 0; + + /* If we are interested in exports, store this name. */ + char *name_copy = NULL; + if (names != NULL) { + struct library_exported_name *export = NULL; + name_copy = strdup(name); + + if (name_copy == NULL + || (export = malloc(sizeof(*export))) == NULL) { + free(name_copy); + fprintf(stderr, "Couldn't store symbol %s. " + "Tracing may be incomplete.\n", name); + } else { + export->name = name_copy; + export->own_name = 1; + export->next = *names; + *names = export; + } + } + + /* If the symbol is not matched, skip it. We already + * stored it to export list above. */ + if (!filter_matches_symbol(options.static_filter, name, lib)) + continue; + + arch_addr_t addr = (arch_addr_t) + (uintptr_t)(sym.st_value + lte->bias); + arch_addr_t naddr; + + /* On arches that support OPD, the value of typical + * function symbol will be a pointer to .opd, but some + * will point directly to .text. We don't want to + * translate those. */ + if (secflags[sym.st_shndx] & SHF_EXECINSTR) { + naddr = addr; + } else if (arch_translate_address(lte, addr, &naddr) < 0) { + fprintf(stderr, + "couldn't translate address of %s@%s: %s\n", + name, lib->soname, strerror(errno)); + continue; + } + + char *full_name; + int own_full_name = 1; + if (name_copy == NULL) { + full_name = strdup(name); + if (full_name == NULL) + goto fail; + } else { + full_name = name_copy; + own_full_name = 0; + } + + /* Look whether we already have a symbol for this + * address. If not, add this one. */ + struct unique_symbol key = { naddr, NULL }; + struct unique_symbol *unique + = lsearch(&key, symbols, &num_symbols, + sizeof(*symbols), &unique_symbol_cmp); + + if (unique->libsym == NULL) { + struct library_symbol *libsym = malloc(sizeof(*libsym)); + if (libsym == NULL + || library_symbol_init(libsym, naddr, + full_name, own_full_name, + LS_TOPLT_NONE) < 0) { + --num_symbols; + goto fail; + } + unique->libsym = libsym; + unique->addr = naddr; + + } else if (strlen(full_name) < strlen(unique->libsym->name)) { + library_symbol_set_name(unique->libsym, + full_name, own_full_name); + + } else if (own_full_name) { + free(full_name); + } + } + + /* Now we do the union of this set of unique symbols with + * what's already in the library. */ + for (i = 0; i < num_symbols; ++i) { + struct library_symbol *this_sym = symbols[i].libsym; + assert(this_sym != NULL); + struct library_symbol *other + = library_each_symbol(lib, NULL, symbol_with_address, + &this_sym->enter_addr); + if (other != NULL) { + library_symbol_destroy(this_sym); + free(this_sym); + symbols[i].libsym = NULL; + } + } + + for (i = 0; i < num_symbols; ++i) + if (symbols[i].libsym != NULL) + library_add_symbol(lib, symbols[i].libsym); + + free(symbols); + return 0; +} + +static int +populate_symtab(struct Process *proc, const char *filename, + struct ltelf *lte, struct library *lib, + int symtabs, int exports) +{ + int status; + if (symtabs && lte->symtab != NULL && lte->strtab != NULL + && (status = populate_this_symtab(proc, filename, lte, lib, + lte->symtab, lte->strtab, + lte->symtab_count, NULL)) < 0) + return status; + + /* Check whether we want to trace symbols implemented by this + * library (-l). */ + struct library_exported_name **names = NULL; + if (exports) { + debug(DEBUG_FUNCTION, "-l matches %s", lib->soname); + names = &lib->exported_names; + } + + return populate_this_symtab(proc, filename, lte, lib, + lte->dynsym, lte->dynstr, + lte->dynsym_count, names); +} + +static int +read_module(struct library *lib, struct Process *proc, + const char *filename, GElf_Addr bias, int main) +{ + struct ltelf lte = {}; + if (open_elf(<e, filename) < 0) + return -1; + + /* XXX When we abstract ABI into a module, this should instead + * become something like + * + * proc->abi = arch_get_abi(lte.ehdr); + * + * The code in open_elf needs to be replaced by this logic. + * Be warned that libltrace.c calls open_elf as well to + * determine whether ABI is supported. This is to get + * reasonable error messages when trying to run 64-bit binary + * with 32-bit ltrace. It is desirable to preserve this. */ + proc->e_machine = lte.ehdr.e_machine; + proc->e_class = lte.ehdr.e_ident[EI_CLASS]; + get_arch_dep(proc); + + /* Find out the base address. For PIE main binaries we look + * into auxv, otherwise we scan phdrs. */ + if (main && lte.ehdr.e_type == ET_DYN) { + arch_addr_t entry; + if (process_get_entry(proc, &entry, NULL) < 0) { + fprintf(stderr, "Couldn't find entry of PIE %s\n", + filename); + return -1; + } + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + lte.entry_addr = (GElf_Addr)(uintptr_t)entry; + lte.bias = (GElf_Addr)(uintptr_t)entry - lte.ehdr.e_entry; + + } else { + GElf_Phdr phdr; + size_t i; + for (i = 0; gelf_getphdr (lte.elf, i, &phdr) != NULL; ++i) { + if (phdr.p_type == PT_LOAD) { + lte.base_addr = phdr.p_vaddr + bias; + break; + } + } + + lte.bias = bias; + lte.entry_addr = lte.ehdr.e_entry + lte.bias; + + if (lte.base_addr == 0) { + fprintf(stderr, + "Couldn't determine base address of %s\n", + filename); + return -1; + } + } + + if (do_init_elf(<e, filename) < 0) + return -1; + + if (arch_elf_init(<e, lib) < 0) { + fprintf(stderr, "Backend initialization failed.\n"); + return -1; + } + + int status = 0; + if (lib == NULL) + goto fail; + + /* Note that we set soname and pathname as soon as they are + * allocated, so in case of further errors, this get released + * when LIB is release, which should happen in the caller when + * we return error. */ + + if (lib->pathname == NULL) { + char *pathname = strdup(filename); + if (pathname == NULL) + goto fail; + library_set_pathname(lib, pathname, 1); + } + + if (lte.soname != NULL) { + char *soname = strdup(lte.soname); + if (soname == NULL) + goto fail; + library_set_soname(lib, soname, 1); + } else { + const char *soname = rindex(lib->pathname, '/') + 1; + if (soname == NULL) + soname = lib->pathname; + library_set_soname(lib, soname, 0); + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t entry = (arch_addr_t)(uintptr_t)lte.entry_addr; + if (arch_translate_address(<e, entry, &entry) < 0) + goto fail; + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + lib->base = (arch_addr_t)(uintptr_t)lte.base_addr; + lib->entry = entry; + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + lib->dyn_addr = (arch_addr_t)(uintptr_t)lte.dyn_addr; + + /* There are two reasons that we need to inspect symbol tables + * or populate PLT entries. Either the user requested + * corresponding tracing features (respectively -x and -e), or + * they requested tracing exported symbols (-l). + * + * In the latter case we need to keep even those PLT slots + * that are not requested by -e (but we keep them latent). We + * also need to inspect .dynsym to find what exports this + * library provide, to turn on existing latent PLT + * entries. */ + + int plts = filter_matches_library(options.plt_filter, lib); + if ((plts || options.export_filter != NULL) + && populate_plt(proc, filename, <e, lib, + options.export_filter != NULL) < 0) + goto fail; + + int exports = filter_matches_library(options.export_filter, lib); + int symtabs = filter_matches_library(options.static_filter, lib); + if ((symtabs || exports) + && populate_symtab(proc, filename, <e, lib, + symtabs, exports) < 0) + goto fail; + +done: + do_close_elf(<e); + return status; + +fail: + status = -1; + goto done; +} + +int +ltelf_read_library(struct library *lib, struct Process *proc, + const char *filename, GElf_Addr bias) +{ + return read_module(lib, proc, filename, bias, 0); +} + + +struct library * +ltelf_read_main_binary(struct Process *proc, const char *path) +{ + struct library *lib = malloc(sizeof(*lib)); + if (lib == NULL) + return NULL; + library_init(lib, LT_LIBTYPE_MAIN); + library_set_pathname(lib, path, 0); + + /* There is a race between running the process and reading its + * binary for internal consumption. So open the binary from + * the /proc filesystem. XXX Note that there is similar race + * for libraries, but there we don't have a nice answer like + * that. Presumably we could read the DSOs from the process + * memory image, but that's not currently done. */ + char *fname = pid2name(proc->pid); + if (fname == NULL) + return NULL; + if (read_module(lib, proc, fname, 0, 1) < 0) { + library_destroy(lib); + free(lib); + return NULL; + } + free(fname); + + return lib; +} diff --git a/ltrace-elf.h b/ltrace-elf.h new file mode 100644 index 0000000..1a1321e --- /dev/null +++ b/ltrace-elf.h @@ -0,0 +1,122 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006,2010,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Zachary T Welch + * Copyright (C) 2001,2004,2007,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LTRACE_ELF_H +#define LTRACE_ELF_H + +#include <gelf.h> +#include <stdlib.h> +#include "sysdep.h" + +struct Process; +struct library; +struct library_symbol; + +/* XXX Ok, the original idea was to separate the low-level ELF data + * from the abstract "struct library" object, but we use some of the + * following extensively in the back end. Not all though. So what we + * use should be move to struct library, and the rest of this + * structure maybe could be safely hidden in .c. How to integrate the + * arch-specific bits into struct library is unclear as of now. */ +struct ltelf { + int fd; + Elf *elf; + GElf_Ehdr ehdr; + Elf_Data *dynsym; + size_t dynsym_count; + const char *dynstr; + GElf_Addr plt_addr; + GElf_Word plt_flags; + size_t plt_size; + Elf_Data *relplt; + Elf_Data *plt_data; + size_t relplt_count; + Elf_Data *symtab; + const char *strtab; + const char *soname; + size_t symtab_count; + Elf_Data *opd; + GElf_Addr *opd_addr; + size_t opd_size; + GElf_Addr dyn_addr; + size_t dyn_sz; + size_t relplt_size; + GElf_Addr bias; + GElf_Addr entry_addr; + GElf_Addr base_addr; + struct arch_ltelf_data arch; +}; + +int open_elf(struct ltelf *lte, const char *filename); +void do_close_elf(struct ltelf *lte); + +/* XXX is it possible to put breakpoints in VDSO and VSYSCALL + * pseudo-libraries? For now we assume that all libraries can be + * opened via a filesystem. BASE is ignored for ET_EXEC files. */ +int ltelf_read_library(struct library *lib, struct Process *proc, + const char *filename, GElf_Addr bias); + +/* Create a library object representing the main binary. The entry + * point address is stored to *ENTRYP. */ +struct library *ltelf_read_main_binary(struct Process *proc, const char *path); + +/* Create a default PLT entry. This can be used instead (or in + * addition to) returning plt_default from arch_elf_add_plt_entry. + * RET shall be initialized, the created symbol will be added to the + * beginning of the linked list at *RET. This function doesn't add + * the symbol to LTE. arch_elf_add_plt_entry has the chance to adjust + * symbol internals to its liking, and then return either plt_default + * or plt_ok. */ +int default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret); + +/* The base implementation of backend.h (arch_get_sym_info). + * See backend.h for details. */ +int elf_get_sym_info(struct ltelf *lte, const char *filename, + size_t sym_index, GElf_Rela *rela, GElf_Sym *sym); + +Elf_Data *elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr); +int elf_get_section_covering(struct ltelf *lte, GElf_Addr addr, + Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr); +int elf_get_section_type(struct ltelf *lte, GElf_Word type, + Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr); +int elf_get_section_named(struct ltelf *lte, const char *name, + Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr); + +/* Read, respectively, 2, 4, or 8 bytes from Elf data at given OFFSET, + * and store it in *RETP. Returns 0 on success or a negative value if + * there's not enough data. */ +int elf_read_u16(Elf_Data *data, GElf_Xword offset, uint16_t *retp); +int elf_read_u32(Elf_Data *data, GElf_Xword offset, uint32_t *retp); +int elf_read_u64(Elf_Data *data, GElf_Xword offset, uint64_t *retp); + +#if __WORDSIZE == 32 +#define PRI_ELF_ADDR PRIx32 +#define GELF_ADDR_CAST(x) (void *)(uint32_t)(x) +#else +#define PRI_ELF_ADDR PRIx64 +#define GELF_ADDR_CAST(x) (void *)(x) +#endif + +#endif @@ -1,12 +1,29 @@ +.\" -*-nroff-*- +.\" Copyright (c) 2012 Petr Machata, Red Hat Inc. .\" Copyright (c) 1997-2005 Juan Cespedes <cespedes@debian.org> -.\" This file is covered by the GNU GPL -.TH ltrace 1 +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of the +.\" License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +.\" 02110-1301 USA +.\" +.TH LTRACE "1" "October 2012" "" "User Commands" .SH NAME ltrace \- A library call tracer .SH SYNOPSIS .B ltrace -.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 ...]]" +.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l library_pattern] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=library_pattern] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]" .SH DESCRIPTION .B ltrace @@ -23,10 +40,17 @@ Its use is very similar to .SH OPTIONS .TP .I \-a, \-\-align column -Align return values in a specific column (default column is 5/8 of screen width). +Align return values in a specific +.IR column +(default column is 5/8 of screen width). .TP .I \-A maxelts -Maximum number of array elements to print before suppressing the rest with an ellipsis ("...") +Maximum number of array elements to print before suppressing the rest +with an ellipsis ("..."). This also limits number of recursive +structure expansions. +.TP +.I \-b, \-\-no-signals +Disable printing of signals recieved by the traced process. .TP .I \-c Count time and calls for each library call and report a summary on program exit. @@ -59,22 +83,12 @@ carries upon a traced process DEBUG_FUNCTION. Shows every entry to internal functions .RE .TP -.I \-e expr -A qualifying expression which modifies which events to trace. -The format of the expression is: -.br -[!]value1[,value2]... -.br -where the values are the functions to trace. Using an exclamation -mark negates the set of values. For example -.I \-e printf -means to trace only the printf library call. By contrast, -.I \-e !printf -means to trace every library call except printf. -.IP -Note that some shells use the exclamation point for history -expansion; even inside quoted arguments. If so, you must escape -the exclamation point with a backslash. +.I \-e filter +A qualifying expression which modifies which library calls to trace. +The format of the filter expression is described in the section +\fBFILTER EXPRESSIONS\fR. If more than one \-e option appears on the +command line, the library calls that match any of them are traced. If +no \-e is given, \fB@MAIN\fR is assumed as a default. .TP .I \-f Trace child processes as they are created by @@ -94,16 +108,22 @@ Show a summary of the options to ltrace and exit. .I \-i Print the instruction pointer at the time of the library call. .TP -.I \-l, \-\-library filename -Display only the symbols included in the library -.I filename. -Up to 30 library names can be specified with several instances -of this option. +.I \-l, \-\-library library_pattern +Display only calls to functions implemented by libraries that match +.I library_pattern. +Multiple library patters can be specified with several instances of +this option. Syntax of library_pattern is described in section +\fBFILTER EXPRESSIONS\fR. + +Note that while this option selects calls that might be directed to +the selected libraries, there's no actual guarantee that the call +won't be directed elsewhere due to e.g. LD_PRELOAD or simply +dependency ordering. If you want to make sure that symbols in given +library are actually called, use \fB-x @\fIlibrary_pattern\fR instead. .TP .I \-L -DON'T display library calls (use it with the -.I \-S -option). +When no -e option is given, don't assume the default action of +\fB@MAIN\fR. .TP .I \-n, \-\-indent nr Indent trace output by @@ -153,35 +173,83 @@ Run command with the userid, groupid and supplementary groups of This option is only useful when running as root and enables the correct execution of setuid and/or setgid binaries. .TP -.I \-X extern -Some architectures need to know where to set a breakpoint that will be hit -after the dynamic linker has run. If this flag is used, then the breakpoint -is set at -.IR extern , -which must be an external function. By default, '_start' is used. -NOTE: this flag is only available on the architectures that need it. +.I \-w, --where NR +Show backtrace of NR stack frames for each traced function. This option enabled +only if libunwind support was enabled at compile time. .TP -.I \-x extern -Trace the external function -.IR extern . -This option may be repeated. +.I \-x filter +A qualifying expression which modifies which symbol table entry points +to trace. The format of the filter expression is described in the +section \fBFILTER EXPRESSIONS\fR. If more than one \-x option appears +on the command line, the symbols that match any of them are traced. +No entry points are traced if no \-x is given. .TP .I \-V, \-\-version Show the version number of ltrace and exit. +.SH FILTER EXPRESSIONS + +Filter expression is a chain of glob- or regexp-based rules that are +used to pick symbols for tracing from libraries that the process uses. +Most of it is intuitive, so as an example, the following would trace +calls to malloc and free, except those done by libc: + +-e malloc+free-@libc.so* + +This reads: trace malloc and free, but don't trace anything that comes +from libc. Semi-formally, the syntax of the above example looks +approximately like this: + +{[+-][\fIsymbol_pattern\fR][@\fIlibrary_pattern\fR]} + +\fISymbol_pattern\fR is used to match symbol names, +\fIlibrary_pattern\fR to match library SONAMEs. Both are implicitly +globs, but can be regular expressions as well (see below). The glob +syntax supports meta-characters \fB*\fR and \fB?\fR and character +classes, similarly to what basic bash globs support. \fB^\fR and +\fB$\fR are recognized to mean, respectively, start and end of given +name. + +Both \fIsymbol_pattern\fR and \fIlibrary_pattern\fR have to match the +whole name. If you want to match only part of the name, surround it +with one or two *'s as appropriate. The exception is if the pattern +is not mentioned at all, in which case it's as if the corresponding +pattern were \fB*\fR. (So \fBmalloc\fR is really \fBmalloc@*\fR and +\fB@libc.*\fR is really \fB*@libc.*\fR.) + +In libraries that don't have an explicit SONAME, basename is taken for +SONAME. That holds for main binary as well: \fB/bin/echo\fR has an +implicit SONAME of \fBecho\fR. In addition to that, special library +pattern \fBMAIN\fR always matches symbols in the main binary and never +a library with actual SONAME \fBMAIN\fR (use e.g. \fB^MAIN\fR or +\fB[M]AIN\fR for that). + +If the symbol or library pattern is surrounded in slashes (/like +this/), then it is considered a regular expression instead. As a +shorthand, instead of writing \fB/x/@/y/\fR, you can write +\fB/x@y/\fR. + +If the library pattern starts with a slash, it is not a SONAME +expression, but a path expression, and is matched against the library +path name. + +The first rule may lack a sign, in which case \fB+\fR is assumed. If, +on the other hand, the first rule has a \fB-\fR sign, it is as if +there was another rule \fB@*\fR in front of it. + +The above rules are used to construct the set of traced symbols. Each +candidate symbol is passed through the chain of above rules. +Initially, the symbol is \fIunmarked\fR. If it matches a \fB+\fR +rule, it becomes \fImarked\fR, if it matches a \fB-\fR rule, it +becomes \fIunmarked\fR again. If, after applying all rules, the +symbol is \fImarked\fR, it will be traced. + .SH BUGS It has most of the bugs stated in .BR strace(1) . .LP -Manual page and documentation are not very up-to-date. -.LP -Option -f sometimes fails to trace some children. -.LP It only works on Linux and in a small subset of architectures. .LP -Only ELF32 binaries are supported. -.LP -Calls to dlopen()ed libraries will not be traced. .PP If you would like to report a bug, send a message to the mailing list (ltrace-devel@lists.alioth.debian.org), or use the @@ -199,8 +267,10 @@ Personal config file, overrides .SH AUTHOR Juan Cespedes <cespedes@debian.org> +.br +Petr Machata <pmachata@redhat.com> .SH "SEE ALSO" +.BR ltrace.conf(5), .BR strace(1) , .BR ptrace(2) - diff --git a/ltrace.conf.5 b/ltrace.conf.5 new file mode 100644 index 0000000..957fe8b --- /dev/null +++ b/ltrace.conf.5 @@ -0,0 +1,408 @@ +.\" -*-nroff-*- +.\" Copyright (c) 2012 Petr Machata, Red Hat Inc. +.\" Copyright (c) 1997-2005 Juan Cespedes <cespedes@debian.org> +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of the +.\" License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +.\" 02110-1301 USA +.\" +.TH ltrace.conf "5" "October 2012" "" "ltrace configuration file" +.SH "NAME" +.LP +\fBltrace.conf\fR \- Configuration file for \fBltrace(1)\fR. + +.SH DESCRIPTION + +This manual page describes \fBltrace.conf\fR, a file that describes +prototypes of functions in binaries for \fBltrace(1)\fR to use. +Ltrace needs this information to display function call arguments. + +Each line of a configuration file describes at most a single item. +Lines composed entirely of white space are ignored, as are lines +starting with semicolon character (comment lines). Described items +can be either function prototypes, or definitions of type aliases. + +.SH PROTOTYPES + +A prototype describes return type and parameter types of a single +function. The syntax is as follows: + +.RS +\fILENS\fR \fINAME\fR \fB(\fR[\fILENS\fR{,\fILENS\fR}]\fB);\fR +.RE + +\fINAME\fR is the (mangled) name of a symbol. In the elementary case, +\fILENS\fR is simply a type. Both lenses and types are described +below. For example, a simple function prototype might look like this: + +.RS +.B int\fR kill\fB(int,int); +.RE + +Despite the apparent similarity with C, \fBltrace.conf\fR is really +its own language that's only somewhat inspired by C. + +.SH TYPES + +Ltrace understands a range of primitive types. Those are interpreted +according to C convention native on a given architecture. +E.g. \fBulong\fR is interpreted as 4-byte unsigned integer on 32-bit +GNU/Linux machine, but 8-byte unsigned integer on 64-bit GNU/Linux +machine. + +.TP +.B void +Denotes that a function does not return anything. Can be also used to +construct a generic pointer, i.e. pointer-sized number formatted in +hexadecimal format. +.TP +.B char +8-bit quantity rendered as a character +.TP +.B ushort,short +Denotes unsigned or signed short integer. +.TP +.B uint,int +Denotes unsigned or signed integer. +.TP +.B ulong,long +Denotes unsigned or signed long integer. +.TP +.B float +Denotes floating point number with single precision. +.TP +.B double +Denotes floating point number with double precision. +.PP + +Besides primitive types, the following composed types are possible: + +.TP +.B struct(\fR[\fILENS\fR{,\fILENS\fR}]\fB)\fR +Describes a structure with given types as fields, +e.g. \fBstruct(int,int,float)\fR. + +Alignment is computed as customary on the architecture. Custom +alignment (e.g. packed structs) and bit-fields are not supported. +It's also not possible to differentiate between structs and non-POD +C++ classes, for arches where it makes a difference. + +.TP +.B array(\fR\fILENS\fR\fB,\fIEXPR\fR\fB) +Describes array of length \fIEXPR\fR, which is composed of types +described by \fILENS\fR, e.g. \fBarray(int, \fR6\fB)\fR. + +Note that in C, arrays in role of function argument decay into +pointers. Ltrace currently handles this automatically, but for full +formal correctness, any such arguments should be described as pointers +to arrays. + +.TP +.I LENS\fR\fB* +Describes a pointer to a given type, e.g. \fBchar*\fR or \fBint***\fR. +Note that the former example actually describes a pointer to a +character, not a string. See below for \fBstring\fR lens, which is +applicable to these cases. + +.SH LENSES + +Lenses change the way that types are described. In the simplest case, +a lens is directly a type. Otherwise a type is decorated by the lens. +Ltrace understands the following lenses: + +.TP +.B oct(\fITYPE\fB) +The argument, which should be an integer type, is formatted in base-8. + +.TP +.B hex(\fITYPE\fB) +The argument, which should be an integer or floating point type, is +formatted in base-16. Floating point arguments are converted to +double and then displayed using the \fB%a\fR fprintf modifier. + +.TP +.B hide(\fITYPE\fB) +The argument is not shown in argument list. + +.TP +.B bool(\fITYPE\fB) +Arguments with zero value are shown as "false", others are shown as +"true". + +.TP +.B bitvec(\fITYPE\fB) +Underlying argument is interpreted as a bit vector and a summary of +bits set in the vector is displayed. For example if bits 3,4,5 and 7 +of the bit vector are set, ltrace shows <3-5,7>. Empty bit vector is +displayed as <>. If there are more bits set than unset, inverse is +shown instead: e.g. ~<0> when a number 0xfffffffe is displayed. Full +set is thus displayed ~<>. + +If the underlying type is integral, then bits are shown in their +natural big-endian order, with LSB being bit 0. +E.g. \fBbitvec(ushort)\fR with value 0x0102 would be displayed as +<1,8>, irrespective of underlying byte order. + +For other data types (notably structures and arrays), the underlying +data is interpreted byte after byte. Bit 0 of first byte has number +0, bit 0 of second byte number 8, and so on. Thus +\fBbitvec(struct(int))\fR is endian sensitive, and will show bytes +comprising the integer in their memory order. Pointers are first +dereferenced, thus \fBbitvec(array(char, \fR32\fB)*)\fR is actually a +pointer to 256-bit bit vector. + +.PP +.B string(\fITYPE\fB) +.br +.B string[\fIEXPR\fB] +.br +.B string +.RS +The first form of the argument is canonical, the latter two are +syntactic sugar. In the canonical form, the function argument is +formatted as string. The \fITYPE\fR shall be either a \fBchar*\fR, or +\fBarray(char,\fIEXPR\fB)\fR, or \fBarray(char,\fIEXPR\fB)*\fR. If an +array is given, the length will typically be a \fBzero\fR expression +(but doesn't have to be). Using argument that is plain array +(i.e. not a pointer to array) makes sense e.g. in C structs, in cases +like \fBstruct(string(array(char, \fR6\fB)))\fR, which describes the C +type \fBstruct {char \fRs\fB[\fR6\fB];}\fR. + +Because simple C-like strings are pretty common, there are two +shorthand forms. The first shorthand form (with brackets) means the +same as \fBstring(array(char, \fIEXPR\fB)*)\fR. Plain \fBstring\fR +without an argument is then taken to mean the same as +\fBstring[zero]\fR. + +Note that \fBchar*\fR by itself describes a pointer to a char. Ltrace +will dereference the pointer, and read and display the single +character that it points to. +.RE + +.B enum(\fINAME\fR[\fB=\fIVALUE\fR]{,\fINAME\fR[\fB=\fIVALUE\fR]}\fB) +.br +.B enum[\fITYPE\fB]\fB(\fINAME\fR[\fB=\fIVALUE\fR]{,\fINAME\fR[\fB=\fIVALUE\fR]}\fB) +.RS +This describes an enumeration lens. If an argument has any of the +given values, it is instead shown as the corresponding \fINAME\fR. If +a \fIVALUE\fR is omitted, the next consecutive value following after +the previous \fIVALUE\fR is taken instead. If the first \fIVALUE\fR +is omitted, it's \fB0\fR by default. + +\fITYPE\fR, if given, is the underlying type. It is thus possible to +create enums over shorts or longs\(emarguments that are themselves +plain, non-enum types in C, but whose values can be meaningfully +described as enumerations. If omitted, \fITYPE\fR is taken to be +\fBint\fR. +.RE + +.SH TYPE ALIASES + +A line in config file can, instead of describing a prototype, create a +type alias. Instead of writing the same enum or struct on many places +(and possibly updating when it changes), one can introduce a name for +such type, and later just use that name: + +.RS +\fBtypedef \fINAME\fB = \fILENS\fB;\fR +.RE + +.SH RECURSIVE STRUCTURES + +Ltrace allows you to express recursive structures. Such structures +are expanded to the depth described by the parameter -A. To declare a +recursive type, you first have to introduce the type to ltrace by +using forward declaration. Then you can use the type in other type +definitions in the usual way: + +.RS +.B typedef \fINAME\fB = struct; +.br +.B typedef \fINAME\fB = struct(\fINAME\fR can be used here\fB) +.RE + +For example, consider the following singy-linked structure and a +function that takes such list as an argument: + +.RS +.B typedef\fR int_list \fB= struct; +.br +.B typedef\fR int_list \fB= struct(int,\fR int_list\fB*); +.br +.B void\fR ll\fB(\fRint_list\fB*); +.RE + +Such declarations might lead to an output like the following: + +.RS +ll({ 9, { 8, { 7, { 6, ... } } } }) = <void> +.RE + +Ltrace detects recursion and will not expand already-expanded +structures. Thus a doubly-linked list would look like the following: + +.RS +.B typedef\fR int_list \fB= struct; +.br +.B typedef\fR int_list \fB= struct(int,\fR int_list\fB*,\fR int_list\fB*); +.RE + +With output e.g. like: + +.RS +ll({ 9, { 8, { 7, { 6, ..., ... }, recurse^ }, recurse^ }, nil }) +.RE + +The "recurse^" tokens mean that given pointer points to a structure +that was expanded in the previous layer. Simple "recurse" would mean +that it points back to this object. E.g. "recurse^^^" means it points +to a structure three layers up. For doubly-linked list, the pointer +to the previous element is of course the one that has been just +expanded in the previous round, and therefore all of them are either +recurse^, or nil. If the next and previous pointers are swapped, the +output adjusts correspondingly: + +.RS +ll({ 9, nil, { 8, recurse^, { 7, recurse^, { 6, ..., ... } } } }) +.RE + + +.SH EXPRESSIONS + +Ltrace has support for some elementary expressions. Each expression +can be either of the following: + +.TP +.I NUM +An integer number. + +.TP +.B arg\fINUM +Value of \fINUM\fR-th argument. The expression has the same value as +the corresponding argument. \fBarg1\fR refers to the first argument, +\fBarg0\fR to the return value of the given function. + +.TP +.B retval +Return value of function, same as \fBarg0\fR. + +.TP +.B elt\fINUM +Value of \fINUM\fR-th element of the surrounding structure type. E.g. +\fBstruct(ulong,array(int,elt1))\fR describes a structure whose first +element is a length, and second element an array of ints of that +length. + +.PP +.B zero +.br +.B zero(\fIEXPR\fB) +.RS +Describes array which extends until the first element, whose each byte +is 0. If an expression is given, that is the maximum length of the +array. If NUL terminator is not found earlier, that's where the array +ends. +.RE + +.SH PARAMETER PACKS + +Sometimes the actual function prototype varies slightly depending on +the exact parameters given. For example, the number and types of +printf parameters are not known in advance, but ltrace might be able +to determine them in runtime. This feature has wider applicability, +but currently the only parameter pack that ltrace supports is +printf-style format string itself: + +.TP +.B format +When \fBformat\fR is seen in the parameter list, the underlying string +argument is parsed, and GNU-style format specifiers are used to +determine what the following actual arguments are. E.g. if the format +string is "%s %d\\n", it's as if the \fBformat\fR was replaced by +\fBstring, string, int\fR. + +.SH RETURN ARGUMENTS + +C functions often use one or more arguments for returning values back +to the caller. The caller provides a pointer to storage, which the +called function initializes. Ltrace has some support for this idiom. + +When a traced binary hits a function call, ltrace first fetches all +arguments. It then displays \fIleft\fR portion of the argument list. +Only when the function returns does ltrace display \fIright\fR portion +as well. Typically, left portion takes up all the arguments, and +right portion only contains return value. But ltrace allows you to +configure where exactly to put the dividing line by means of a \fB+\fR +operator placed in front of an argument: + +.RS +.B int\fR asprintf\fB(+string*, format); +.RE + +Here, the first argument to asprintf is denoted as return argument, +which means that displaying the whole argument list is delayed until +the function returns: + +.RS +a.out->asprintf( <unfinished ...> +.br +libc.so.6->malloc(100) = 0x245b010 +.br +[... more calls here ...] +.br +<... asprintf resumed> "X=1", "X=%d", 1) = 5 +.RE + +It is currently not possible to have an "inout" argument that passes +information in both directions. + +.SH EXAMPLES + +In the following, the first is the C prototype, and following that is +ltrace configuration line. + +.TP +.B void\fR func_charp_string\fB(char\fR str\fB[]); +.B void\fR func_charp_string\fB(string); + +.PP +.B enum\fR e_foo \fB{\fRRED\fB, \fRGREEN\fB, \fRBLUE\fB}; +.br +.B void\fR func_enum\fB(enum\fR e_foo bar\fB);\fR +.RS +.B void\fR func_enum\fB(enum(\fRRED\fB,\fRGREEN\fB,\fRBLUE\fB));\fR +.RS +- or - +.RE +.B typedef\fR e_foo \fB= enum(\fRRED\fB,\fRGREEN\fB,\fRBLUE\fB);\fR +.br +.B void\fR func_enum\fB(\fRe_foo\fB);\fR +.RE + +.TP +.B void\fR func_arrayi\fB(int\fR arr\fB[],\fR int len\fB); +.B void\fR func_arrayi\fB(array(int,arg2)*,int); + +.PP +.B struct\fR S1 \fB{float\fR f\fB; char\fR a\fB; char \fRb\fB;}; +.br +.B struct\fR S2 \fB{char\fR str\fB[\fR6\fB]; float\fR f\fB;}; +.br +.B struct\fR S1 func_struct\fB(int \fRa\fB, struct \fRS2\fB, double \fRd\fB); +.RS +.B struct(float,char,char)\fR func_struct_2\fB(int, struct(string(array(char, \fR6\fB)),float), double); +.RE + +.SH AUTHOR +Petr Machata <pmachata@redhat.com> @@ -1,3 +1,26 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _LTRACE_H_ +#define _LTRACE_H_ + typedef enum Event_type Event_type; enum Event_type { EVENT_NONE=0, @@ -9,6 +32,7 @@ enum Event_type { EVENT_ARCH_SYSCALL, EVENT_ARCH_SYSRET, EVENT_CLONE, + EVENT_VFORK, EVENT_EXEC, EVENT_BREAKPOINT, EVENT_LIBCALL, @@ -17,10 +41,10 @@ enum Event_type { EVENT_MAX }; -typedef struct Process Process; typedef struct Event Event; struct Event { - Process * proc; + struct Event * next; + struct Process * proc; Event_type type; union { int ret_val; /* EVENT_EXIT */ @@ -36,3 +60,5 @@ typedef void (*callback_func) (Event *); extern void ltrace_init(int argc, char **argv); extern void ltrace_add_callback(callback_func f, Event_type type); extern void ltrace_main(void); + +#endif /* _LTRACE_H_ */ @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <stdio.h> #include <unistd.h> @@ -1,19 +0,0 @@ -#!/bin/sh -e - -# Create ltrace-${version}.tar.gz from a GIT repository - -if [ ! -d .git -o ! -f libltrace.c ] -then - echo "This must be called inside a ltrace GIT repository" 1>&2 - exit 1 -fi - -VERSION=$( cat VERSION ) - -echo Building ltrace-$VERSION.tar.gz ... -rm -rf ltrace-$VERSION -git clone ./ ltrace-$VERSION >/dev/null -GZIP=-9 tar --exclude .git -zcf ltrace-$VERSION.tar.gz ltrace-$VERSION -rm -rf ltrace-$VERSION -echo Done. - @@ -1,16 +1,44 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2009,2010 Joe Damato + * Copyright (C) 1998,1999,2002,2003,2004,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2006 Steve Fink + * Copyright (C) 2006 Paul Gilliam, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <limits.h> #include <sys/ioctl.h> - +#include <assert.h> +#include <errno.h> +#include <fcntl.h> #include <getopt.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> #include "common.h" +#include "filter.h" +#include "glob.h" #ifndef SYSCONFDIR #define SYSCONFDIR "/etc" @@ -23,7 +51,6 @@ struct options_t options = { .align = DEFAULT_ALIGN, /* alignment column for results */ .user = NULL, /* username to run command as */ .syscalls = 0, /* display syscalls */ - .libcalls = 1, /* display library calls */ #ifdef USE_DEMANGLE .demangle = 0, /* Demangle low-level symbol names */ #endif @@ -36,8 +63,6 @@ struct options_t options = { .follow = 0, /* trace child processes */ }; -char *library[MAX_LIBRARIES]; -int library_num = 0; static char *progname; /* Program name (`ltrace') */ int opt_i = 0; /* instruction pointer */ int opt_r = 0; /* print relative timestamp */ @@ -47,25 +72,12 @@ int opt_T = 0; /* show the time spent inside each call */ /* List of pids given to option -p: */ struct opt_p_t *opt_p = NULL; /* attach to process with a given pid */ -/* List of function names given to option -e: */ -struct opt_e_t *opt_e = NULL; -int opt_e_enable = 1; - -/* List of global function names given to -x: */ -struct opt_x_t *opt_x = NULL; - /* List of filenames give to option -F: */ struct opt_F_t *opt_F = NULL; /* alternate configuration file(s) */ -#ifdef PLT_REINITALISATION_BP -/* Set a break on the routine named here in order to re-initialize breakpoints - after all the PLTs have been initialzed */ -char *PLTs_initialized_by_here = PLT_REINITALISATION_BP; -#endif - static void err_usage(void) { - fprintf(stderr, "Try `%s --help' for more information\n", progname); + fprintf(stderr, "Try `%s --help' for more information.\n", progname); exit(1); } @@ -75,6 +87,7 @@ usage(void) { "Trace library calls of a given program.\n\n" " -a, --align=COLUMN align return values in a secific column.\n" " -A ARRAYLEN maximum number of array elements to print.\n" + " -b, --no-signals don't print signals.\n" " -c count time and calls, and report a summary on exit.\n" # ifdef USE_DEMANGLE " -C, --demangle decode low-level symbol names into user-level names.\n" @@ -86,7 +99,7 @@ usage(void) { " -F, --config=FILE load alternate configuration file (may be repeated).\n" " -h, --help display this help and exit.\n" " -i print instruction pointer at time of library call.\n" - " -l, --library=FILE print library calls from this library only.\n" + " -l, --library=FILE only trace symbols implemented by this library.\n" " -L do NOT display library calls.\n" " -n, --indent=NR indent output by NR spaces for each call level nesting.\n" " -o, --output=FILE write the trace output to that file.\n" @@ -98,10 +111,10 @@ usage(void) { " -T show the time spent inside each call.\n" " -u USERNAME run command with the userid, groupid of username.\n" " -V, --version output version information and exit.\n" +#if defined(HAVE_LIBUNWIND) + " -w, --where=NR print backtrace showing NR stack frames at most.\n" +#endif /* defined(HAVE_LIBUNWIND) */ " -x NAME treat the global NAME like a library subroutine.\n" -#ifdef PLT_REINITALISATION_BP - " -X NAME same as -x; and PLT's will be initialized by here.\n" -#endif "\nReport bugs to ltrace-devel@lists.alioth.debian.org\n", progname); } @@ -139,7 +152,7 @@ search_for_command(char *filename) { m = n = strlen(path); } if (n + strlen(filename) + 1 >= PATH_MAX) { - fprintf(stderr, "Error: filename too long\n"); + fprintf(stderr, "Error: filename too long.\n"); exit(1); } strncpy(pathname, path, n); @@ -175,13 +188,274 @@ guess_cols(void) { } } +static int +compile_libname(const char *expr, const char *a_lib, int lib_re_p, + struct filter_lib_matcher *matcher) +{ + if (strcmp(a_lib, "MAIN") == 0) { + filter_lib_matcher_main_init(matcher); + } else { + /* Add ^ and $ to the library expression as well. */ + char lib[strlen(a_lib) + 3]; + sprintf(lib, "^%s$", a_lib); + + enum filter_lib_matcher_type type + = lib[0] == '/' ? FLM_PATHNAME : FLM_SONAME; + + regex_t lib_re; + int status = (lib_re_p ? regcomp : globcomp)(&lib_re, lib, 0); + if (status != REG_NOERROR) { + char buf[100]; + regerror(status, &lib_re, buf, sizeof buf); + fprintf(stderr, "Rule near '%s' will be ignored: %s.\n", + expr, buf); + return -1; + } + filter_lib_matcher_name_init(matcher, type, lib_re); + } + return 0; +} + +static void +add_filter_rule(struct filter *filt, const char *expr, + enum filter_rule_type type, + const char *a_sym, int sym_re_p, + const char *a_lib, int lib_re_p) +{ + struct filter_rule *rule = malloc(sizeof(*rule)); + struct filter_lib_matcher *matcher = malloc(sizeof(*matcher)); + + if (rule == NULL || matcher == NULL) { + fprintf(stderr, "Rule near '%s' will be ignored: %s.\n", + expr, strerror(errno)); + fail: + free(rule); + free(matcher); + return; + } + + regex_t symbol_re; + { + /* Add ^ to the start of expression and $ to the end, so that + * we match the whole symbol name. Let the user write the "*" + * explicitly if they wish. */ + char sym[strlen(a_sym) + 3]; + sprintf(sym, "^%s$", a_sym); + int status = (sym_re_p ? regcomp : globcomp) + (&symbol_re, sym, 0); + if (status != 0) { + char buf[100]; + regerror(status, &symbol_re, buf, sizeof buf); + fprintf(stderr, "Rule near '%s' will be ignored: %s.\n", + expr, buf); + goto fail; + } + } + + if (compile_libname(expr, a_lib, lib_re_p, matcher) < 0) { + regfree(&symbol_re); + goto fail; + } + + filter_rule_init(rule, type, matcher, symbol_re); + filter_add_rule(filt, rule); +} + +static int +grok_libname_pattern(char **libnamep, char **libendp) +{ + char *libname = *libnamep; + char *libend = *libendp; + + if (libend[0] != '/') + return 0; + + *libend-- = 0; + if (libname != libend && libname[0] == '/') + ++libname; + else + fprintf(stderr, "Unmatched '/' in library name.\n"); + + *libendp = libend; + *libnamep = libname; + return 1; +} + +static int +parse_filter(struct filter *filt, char *expr, int operators) +{ + /* Filter is a chain of sym@lib rules separated by '-' or '+'. + * If the filter expression starts with '-', the missing + * initial rule is implicitly *@*. */ + + enum filter_rule_type type = FR_ADD; + + while (*expr != 0) { + size_t s = strcspn(expr, "-+@" + (operators ? 0 : 2)); + char *symname = expr; + char *libname; + char *next = expr + s + 1; + enum filter_rule_type this_type = type; + + if (expr[s] == 0) { + libname = "*"; + expr = next - 1; + + } else if (expr[s] == '-' || expr[s] == '+') { + type = expr[s] == '-' ? FR_SUBTRACT : FR_ADD; + expr[s] = 0; + libname = "*"; + expr = next; + + } else { + assert(expr[s] == '@'); + expr[s] = 0; + s = strcspn(next, "-+" + (operators ? 0 : 2)); + if (s == 0) { + libname = "*"; + expr = next; + } else if (next[s] == 0) { + expr = next + s; + libname = next; + } else { + assert(next[s] == '-' || next[s] == '+'); + type = next[s] == '-' ? FR_SUBTRACT : FR_ADD; + next[s] = 0; + expr = next + s + 1; + libname = next; + } + } + + assert(*libname != 0); + char *symend = symname + strlen(symname) - 1; + char *libend = libname + strlen(libname) - 1; + int sym_is_re = 0; + int lib_is_re = 0; + + /* + * /xxx/@... and ...@/xxx/ means that xxx are regular + * expressions. They are globs otherwise. + * + * /xxx@yyy/ is the same as /xxx/@/yyy/ + * + * @/xxx matches library path name + * @.xxx matches library relative path name + */ + if (symname[0] == '/') { + if (symname != symend && symend[0] == '/') { + ++symname; + *symend-- = 0; + sym_is_re = 1; + + } else { + sym_is_re = 1; + lib_is_re = 1; + ++symname; + + /* /XXX@YYY/ is the same as + * /XXX/@/YYY/. */ + if (libend[0] != '/') + fprintf(stderr, "Unmatched '/'" + " in symbol name.\n"); + else + *libend-- = 0; + } + } + + /* If libname ends in '/', then we expect '/' in the + * beginning too. Otherwise the initial '/' is part + * of absolute file name. */ + if (!lib_is_re) + lib_is_re = grok_libname_pattern(&libname, &libend); + + if (*symname == 0) /* /@AA/ */ + symname = "*"; + if (*libname == 0) /* /aa@/ */ + libname = "*"; + + add_filter_rule(filt, expr, this_type, + symname, sym_is_re, + libname, lib_is_re); + } + + return 0; +} + +static struct filter * +recursive_parse_chain(char *expr, int operators) +{ + struct filter *filt = malloc(sizeof(*filt)); + if (filt == NULL) { + fprintf(stderr, "(Part of) filter will be ignored: '%s': %s.\n", + expr, strerror(errno)); + return NULL; + } + + filter_init(filt); + if (parse_filter(filt, expr, operators) < 0) { + fprintf(stderr, "Filter '%s' will be ignored.\n", expr); + free(filt); + filt = NULL; + } + + return filt; +} + +static struct filter ** +slist_chase_end(struct filter **begin) +{ + for (; *begin != NULL; begin = &(*begin)->next) + ; + return begin; +} + +static void +parse_filter_chain(const char *expr, struct filter **retp) +{ + char *str = strdup(expr); + if (str == NULL) { + fprintf(stderr, "Filter '%s' will be ignored: %s.\n", + expr, strerror(errno)); + return; + } + /* Support initial '!' for backward compatibility. */ + if (str[0] == '!') + str[0] = '-'; + + *slist_chase_end(retp) = recursive_parse_chain(str, 1); + free(str); +} + +static int +parse_int(const char *optarg, char opt, int min, int max) +{ + char *endptr; + long int l = strtol(optarg, &endptr, 0); + if (l < min || (max != 0 && l > max) + || *optarg == 0 || *endptr != 0) { + const char *fmt = max != 0 + ? "Invalid argument to -%c: '%s'. Use integer %d..%d.\n" + : "Invalid argument to -%c: '%s'. Use integer >=%d.\n"; + fprintf(stderr, fmt, opt, optarg, min, max); + exit(1); + } + return (int)l; +} + char ** -process_options(int argc, char **argv) { +process_options(int argc, char **argv) +{ progname = argv[0]; options.output = stderr; + options.no_signals = 0; +#if defined(HAVE_LIBUNWIND) + options.bt_depth = -1; +#endif /* defined(HAVE_LIBUNWIND) */ guess_cols(); + int libcalls = 1; + while (1) { int c; char *p; @@ -198,23 +472,34 @@ process_options(int argc, char **argv) { {"library", 1, 0, 'l'}, {"output", 1, 0, 'o'}, {"version", 0, 0, 'V'}, + {"no-signals", 0, 0, 'b'}, +#if defined(HAVE_LIBUNWIND) + {"where", 1, 0, 'w'}, +#endif /* defined(HAVE_LIBUNWIND) */ {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "+cfhiLrStTV" + c = getopt_long(argc, argv, "+cfhiLrStTVb" # ifdef USE_DEMANGLE "C" # endif +#if defined(HAVE_LIBUNWIND) + "a:A:D:e:F:l:n:o:p:s:u:x:X:w:", long_options, +#else /* !defined(HAVE_LIBUNWIND) */ "a:A:D:e:F:l:n:o:p:s:u:x:X:", long_options, +#endif &option_index); if (c == -1) { break; } switch (c) { case 'a': - options.align = atoi(optarg); + options.align = parse_int(optarg, 'a', 0, 0); break; case 'A': - options.arraylen = atoi(optarg); + options.arraylen = parse_int(optarg, 'A', 0, 0); + break; + case 'b': + options.no_signals = 1; break; case 'c': options.summary++; @@ -235,50 +520,28 @@ process_options(int argc, char **argv) { err_usage(); } break; + case 'e': - { - char *str_e = strdup(optarg); - if (!str_e) { - perror("ltrace: strdup"); - exit(1); - } - if (str_e[0] == '!') { - opt_e_enable = 0; - str_e++; - } - while (*str_e) { - struct opt_e_t *tmp; - char *str2 = strchr(str_e, ','); - if (str2) { - *str2 = '\0'; - } - tmp = malloc(sizeof(struct opt_e_t)); - if (!tmp) { - perror("ltrace: malloc"); - exit(1); - } - tmp->name = str_e; - tmp->next = opt_e; - opt_e = tmp; - if (str2) { - str_e = str2 + 1; - } else { - break; - } - } - break; - } + parse_filter_chain(optarg, &options.plt_filter); + break; + case 'f': options.follow = 1; break; case 'F': { - struct opt_F_t *tmp = malloc(sizeof(struct opt_F_t)); - if (!tmp) { - perror("ltrace: malloc"); + struct opt_F_t *tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) { + fail: + fprintf(stderr, "%s\n", + strerror(errno)); + free(tmp); exit(1); } tmp->filename = strdup(optarg); + if (tmp->filename == NULL) + goto fail; + tmp->own_filename = 1; tmp->next = opt_F; opt_F = tmp; break; @@ -289,26 +552,27 @@ process_options(int argc, char **argv) { case 'i': opt_i++; break; - case 'l': - if (library_num == MAX_LIBRARIES) { - fprintf(stderr, - "Too many libraries. Maximum is %i.\n", - MAX_LIBRARIES); - exit(1); - } - library[library_num++] = optarg; + + case 'l': { + size_t patlen = strlen(optarg); + char buf[patlen + 2]; + sprintf(buf, "@%s", optarg); + *slist_chase_end(&options.export_filter) + = recursive_parse_chain(buf, 0); break; + } + case 'L': - options.libcalls = 0; + libcalls = 0; break; case 'n': - options.indent = atoi(optarg); + options.indent = parse_int(optarg, 'n', 0, 20); break; case 'o': options.output = fopen(optarg, "w"); if (!options.output) { fprintf(stderr, - "Can't open %s for output: %s\n", + "can't open %s for writing: %s\n", optarg, strerror(errno)); exit(1); } @@ -322,7 +586,7 @@ process_options(int argc, char **argv) { perror("ltrace: malloc"); exit(1); } - tmp->pid = atoi(optarg); + tmp->pid = parse_int(optarg, 'p', 1, 0); tmp->next = opt_p; opt_p = tmp; break; @@ -331,7 +595,7 @@ process_options(int argc, char **argv) { opt_r++; break; case 's': - options.strlen = atoi(optarg); + options.strlen = parse_int(optarg, 's', 0, 0); break; case 'S': options.syscalls = 1; @@ -351,39 +615,16 @@ process_options(int argc, char **argv) { "This is free software; see the GNU General Public Licence\n" "version 2 or later for copying conditions. There is NO warranty.\n"); exit(0); - case 'X': -#ifdef PLT_REINITALISATION_BP - PLTs_initialized_by_here = optarg; -#else - fprintf(stderr, "WARNING: \"-X\" not used for this " - "architecture: assuming you meant \"-x\"\n"); -#endif - /* Fall Thru */ + break; +#if defined(HAVE_LIBUNWIND) + case 'w': + options.bt_depth = parse_int(optarg, 'w', 1, 0); + break; +#endif /* defined(HAVE_LIBUNWIND) */ case 'x': - { - struct opt_x_t *p = opt_x; - - /* First, check for duplicate. */ - while (p && strcmp(p->name, optarg)) { - p = p->next; - } - if (p) { - break; - } - - /* If not duplicate, add to list. */ - p = malloc(sizeof(struct opt_x_t)); - if (!p) { - perror("ltrace: malloc"); - exit(1); - } - p->name = optarg; - p->found = 0; - p->next = opt_x; - opt_x = p; - break; - } + parse_filter_chain(optarg, &options.static_filter); + break; default: err_usage(); @@ -397,7 +638,9 @@ process_options(int argc, char **argv) { opt_F->next = malloc(sizeof(struct opt_F_t)); opt_F->next->next = NULL; opt_F->filename = USER_CONFIG_FILE; + opt_F->own_filename = 0; opt_F->next->filename = SYSTEM_CONFIG_FILE; + opt_F->next->own_filename = 0; } /* Reverse the config file list since it was built by * prepending, and it would make more sense to process the @@ -415,12 +658,29 @@ process_options(int argc, char **argv) { opt_F = egg; } + /* If neither -e, nor -l, nor -L are used, set default -e. + * Use @MAIN for now, as that's what ltrace used to have in + * the past. XXX Maybe we should make this "*" instead. */ + if (libcalls + && options.plt_filter == NULL + && options.export_filter == NULL) { + parse_filter_chain("@MAIN", &options.plt_filter); + options.hide_caller = 1; + } + if (!libcalls && options.plt_filter != NULL) { + fprintf(stderr, + "%s: Option -L can't be used with -e or -l.\n", + progname); + err_usage(); + } + if (!opt_p && argc < 1) { fprintf(stderr, "%s: too few arguments\n", progname); err_usage(); } if (opt_r && opt_t) { - fprintf(stderr, "%s: Incompatible options -r and -t\n", + fprintf(stderr, + "%s: Options -r and -t can't be used together\n", progname); err_usage(); } @@ -1,19 +1,55 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2009,2010 Joe Damato + * Copyright (C) 1998,2002,2008 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2006 Steve Fink + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <stdio.h> #include <sys/types.h> +#include "forward.h" + struct options_t { - int align; /* -a: default alignment column for results */ - char * user; /* -u: username to run command as */ - int syscalls; /* -S: display system calls */ - int libcalls; /* -L: display library calls */ - int demangle; /* -C: demangle low-level names into user-level names */ - int indent; /* -n: indent trace output according to program flow */ - FILE *output; /* output to a specific file */ - int summary; /* count time, calls, and report a summary on program exit */ - int debug; /* debug */ - int arraylen; /* default maximum # of array elements printed */ - int strlen; /* default maximum # of bytes printed in strings */ - int follow; /* trace child processes */ + int align; /* -a: default alignment column for results */ + char * user; /* -u: username to run command as */ + int syscalls; /* -S: display system calls */ + int demangle; /* -C: demangle low-level names into user-level names */ + int indent; /* -n: indent trace output according to program flow */ + FILE *output; /* output to a specific file */ + int summary; /* count time, calls, and report a summary on program exit */ + int debug; /* debug */ + size_t arraylen; /* default maximum # of array elements printed */ + size_t strlen; /* default maximum # of bytes printed in strings */ + int follow; /* trace child processes */ + int no_signals; /* don't print signals */ +#if defined(HAVE_LIBUNWIND) + int bt_depth; /* how may levels of stack frames to show */ +#endif /* defined(HAVE_LIBUNWIND) */ + struct filter *plt_filter; + struct filter *static_filter; + + /* A filter matching library names of libraries, whose + * exported symbols we wish to trace. */ + struct filter *export_filter; + + int hide_caller; /* Whether caller library should be hidden. */ }; extern struct options_t options; @@ -27,29 +63,15 @@ struct opt_p_t { struct opt_p_t *next; }; -struct opt_e_t { - char *name; - struct opt_e_t *next; -}; - -struct opt_F_t { - char *filename; +struct opt_F_t +{ struct opt_F_t *next; -}; - -struct opt_x_t { - char *name; - int found; - struct opt_x_t *next; + char *filename; + int own_filename : 1; }; extern struct opt_p_t *opt_p; /* attach to process with a given pid */ -extern struct opt_e_t *opt_e; /* list of function names to display */ -extern int opt_e_enable; /* 0 if '!' is used, 1 otherwise */ - extern struct opt_F_t *opt_F; /* alternate configuration file(s) */ -extern struct opt_x_t *opt_x; /* list of functions to break at */ - extern char **process_options(int argc, char **argv); @@ -1,3 +1,31 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1997,1998,1999,2001,2002,2003,2004,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Paul Gilliam, IBM Corporation + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* glibc before 2.10, eglibc and uClibc all need _GNU_SOURCE defined + * for open_memstream to become visible. */ +#define _GNU_SOURCE + #include "config.h" #include <stdio.h> @@ -7,8 +35,18 @@ #include <time.h> #include <sys/time.h> #include <unistd.h> +#include <errno.h> +#include <assert.h> #include "common.h" +#include "proc.h" +#include "library.h" +#include "type.h" +#include "value.h" +#include "value_dict.h" +#include "param.h" +#include "fetch.h" +#include "lens_default.h" /* TODO FIXME XXX: include in common.h: */ extern struct timeval current_time_spent; @@ -16,17 +54,19 @@ extern struct timeval current_time_spent; Dict *dict_opt_c = NULL; static Process *current_proc = 0; -static int current_depth = 0; +static size_t current_depth = 0; static int current_column = 0; static void -output_indent(Process *proc) { - current_column += - fprintf(options.output, "%*s", options.indent * proc->callstack_depth, ""); +output_indent(struct Process *proc) +{ + int d = options.indent * (proc->callstack_depth - 1); + current_column += fprintf(options.output, "%*s", d, ""); } static void -begin_of_line(enum tof type, Process *proc) { +begin_of_line(Process *proc, int is_func, int indent) +{ current_column = 0; if (!proc) { return; @@ -82,66 +122,115 @@ begin_of_line(enum tof type, Process *proc) { } } if (opt_i) { - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { + if (is_func) current_column += fprintf(options.output, "[%p] ", proc->return_addr); - } else { + else current_column += fprintf(options.output, "[%p] ", proc->instruction_pointer); - } } - if (options.indent > 0 && type != LT_TOF_NONE) { + if (options.indent > 0 && indent) { output_indent(proc); } } +static struct arg_type_info * +get_unknown_type(void) +{ + static struct arg_type_info *info = NULL; + if (info == NULL) { + info = malloc(sizeof(*info)); + if (info == NULL) { + report_global_error("malloc: %s", strerror(errno)); + abort(); + } + *info = *type_get_simple(ARGTYPE_LONG); + info->lens = &guess_lens; + } + return info; +} + +/* The default prototype is: long X(long, long, long, long). */ +static Function * +build_default_prototype(void) +{ + Function *ret = malloc(sizeof(*ret)); + size_t i = 0; + if (ret == NULL) + goto err; + memset(ret, 0, sizeof(*ret)); + + struct arg_type_info *unknown_type = get_unknown_type(); + + ret->return_info = unknown_type; + ret->own_return_info = 0; + + ret->num_params = 4; + ret->params = malloc(sizeof(*ret->params) * ret->num_params); + if (ret->params == NULL) + goto err; + + for (i = 0; i < ret->num_params; ++i) + param_init_type(&ret->params[i], unknown_type, 0); + + return ret; + +err: + report_global_error("malloc: %s", strerror(errno)); + if (ret->params != NULL) { + while (i-- > 0) + param_destroy(&ret->params[i]); + free(ret->params); + } + + free(ret); + + return NULL; +} + static Function * -name2func(char *name) { +name2func(char const *name) { Function *tmp; const char *str1, *str2; - tmp = list_of_functions; - while (tmp) { -#ifdef USE_DEMANGLE - str1 = options.demangle ? my_demangle(tmp->name) : tmp->name; - str2 = options.demangle ? my_demangle(name) : name; -#else + for (tmp = list_of_functions; tmp != NULL; tmp = tmp->next) { str1 = tmp->name; str2 = name; -#endif - if (!strcmp(str1, str2)) { - + if (!strcmp(str1, str2)) return tmp; - } - tmp = tmp->next; } - return NULL; + + static Function *def = NULL; + if (def == NULL) + def = build_default_prototype(); + + return def; } void -output_line(Process *proc, char *fmt, ...) { - va_list args; - - if (options.summary) { +output_line(struct Process *proc, const char *fmt, ...) +{ + if (options.summary) return; - } - if (current_proc) { - if (current_proc->callstack[current_depth].return_addr) { + + if (current_proc != NULL) { + if (current_proc->callstack[current_depth].return_addr) fprintf(options.output, " <unfinished ...>\n"); - } else { + else fprintf(options.output, " <no return ...>\n"); - } } - current_proc = 0; - if (!fmt) { + current_proc = NULL; + if (fmt == NULL) return; - } - begin_of_line(LT_TOF_NONE, proc); + begin_of_line(proc, 0, 0); + + va_list args; va_start(args, fmt); vfprintf(options.output, fmt, args); fprintf(options.output, "\n"); va_end(args); + current_column = 0; } @@ -152,69 +241,270 @@ tabto(int col) { } } +static int +output_error(FILE *stream) +{ + return fprintf(stream, "?"); +} + +static int +fetch_simple_param(enum tof type, Process *proc, struct fetch_context *context, + struct value_dict *arguments, + struct arg_type_info *info, int own, + struct value *valuep) +{ + /* Arrays decay into pointers per C standard. We check for + * this here, because here we also capture arrays that come + * from parameter packs. */ + if (info->type == ARGTYPE_ARRAY) { + struct arg_type_info *tmp = malloc(sizeof(*tmp)); + if (tmp != NULL) { + type_init_pointer(tmp, info, own); + tmp->lens = info->lens; + info = tmp; + own = 1; + } + } + + struct value value; + value_init(&value, proc, NULL, info, own); + if (fetch_arg_next(context, type, proc, info, &value) < 0) + return -1; + + if (val_dict_push_next(arguments, &value) < 0) { + value_destroy(&value); + return -1; + } + + if (valuep != NULL) + *valuep = value; + + return 0; +} + +static void +fetch_param_stop(struct value_dict *arguments, ssize_t *params_leftp) +{ + if (*params_leftp == -1) + *params_leftp = val_dict_count(arguments); +} + +static int +fetch_param_pack(enum tof type, Process *proc, struct fetch_context *context, + struct value_dict *arguments, struct param *param, + ssize_t *params_leftp) +{ + struct param_enum *e = param_pack_init(param, arguments); + if (e == NULL) + return -1; + + int ret = 0; + while (1) { + int insert_stop = 0; + struct arg_type_info *info = malloc(sizeof(*info)); + if (info == NULL + || param_pack_next(param, e, info, &insert_stop) < 0) { + fail: + free(info); + ret = -1; + break; + } + + if (insert_stop) + fetch_param_stop(arguments, params_leftp); + + if (info->type == ARGTYPE_VOID) { + type_destroy(info); + free(info); + break; + } + + struct value val; + if (fetch_simple_param(type, proc, context, arguments, + info, 1, &val) < 0) + goto fail; + + int stop = 0; + switch (param_pack_stop(param, e, &val)) { + case PPCB_ERR: + goto fail; + case PPCB_STOP: + stop = 1; + case PPCB_CONT: + break; + } + + if (stop) + break; + } + + param_pack_done(param, e); + return ret; +} + +static int +fetch_one_param(enum tof type, Process *proc, struct fetch_context *context, + struct value_dict *arguments, struct param *param, + ssize_t *params_leftp) +{ + switch (param->flavor) { + int rc; + case PARAM_FLAVOR_TYPE: + return fetch_simple_param(type, proc, context, arguments, + param->u.type.type, 0, NULL); + + case PARAM_FLAVOR_PACK: + if (fetch_param_pack_start(context, + param->u.pack.ppflavor) < 0) + return -1; + rc = fetch_param_pack(type, proc, context, arguments, + param, params_leftp); + fetch_param_pack_end(context); + return rc; + + case PARAM_FLAVOR_STOP: + fetch_param_stop(arguments, params_leftp); + return 0; + } + + assert(!"Invalid param flavor!"); + abort(); +} + +static int +fetch_params(enum tof type, Process *proc, struct fetch_context *context, + struct value_dict *arguments, Function *func, ssize_t *params_leftp) +{ + size_t i; + for (i = 0; i < func->num_params; ++i) + if (fetch_one_param(type, proc, context, arguments, + &func->params[i], params_leftp) < 0) + return -1; + + /* Implicit stop at the end of parameter list. */ + fetch_param_stop(arguments, params_leftp); + + return 0; +} + +struct format_argument_data +{ + struct value *value; + struct value_dict *arguments; +}; + +static int +format_argument_cb(FILE *stream, void *ptr) +{ + struct format_argument_data *data = ptr; + int o = format_argument(stream, data->value, data->arguments); + if (o < 0) + o = output_error(stream); + return o; +} + +static int +output_params(struct value_dict *arguments, size_t start, size_t end, + int *need_delimp) +{ + size_t i; + for (i = start; i < end; ++i) { + struct value *value = val_dict_get_num(arguments, i); + if (value == NULL) + return -1; + + struct format_argument_data data = { value, arguments }; + int o = delim_output(options.output, need_delimp, + format_argument_cb, &data); + if (o < 0) + return -1; + current_column += o; + } + return 0; +} + void -output_left(enum tof type, Process *proc, char *function_name) { +output_left(enum tof type, struct Process *proc, + struct library_symbol *libsym) +{ + const char *function_name = libsym->name; Function *func; - static arg_type_info *arg_unknown = NULL; - if (arg_unknown == NULL) - arg_unknown = lookup_prototype(ARGTYPE_UNKNOWN); if (options.summary) { return; } if (current_proc) { fprintf(options.output, " <unfinished ...>\n"); - current_proc = 0; current_column = 0; } current_proc = proc; current_depth = proc->callstack_depth; - proc->type_being_displayed = type; - begin_of_line(type, proc); + begin_of_line(proc, type == LT_TOF_FUNCTION, 1); + if (!options.hide_caller && libsym->lib != NULL + && libsym->plt_type != LS_TOPLT_NONE) + /* We don't terribly mind failing this. */ + account_output(¤t_column, + fprintf(options.output, "%s->", + libsym->lib->soname)); + + const char *name = function_name; #ifdef USE_DEMANGLE - current_column += - fprintf(options.output, "%s(", - options.demangle ? my_demangle(function_name) : function_name); -#else - current_column += fprintf(options.output, "%s(", function_name); + if (options.demangle) + name = my_demangle(function_name); #endif + if (account_output(¤t_column, + fprintf(options.output, "%s", name)) < 0) + return; + + if (libsym->lib != NULL + && libsym->lib->type != LT_LIBTYPE_MAIN + && libsym->plt_type == LS_TOPLT_NONE + && account_output(¤t_column, + fprintf(options.output, "@%s", + libsym->lib->soname)) < 0) + /* We do mind failing this though. */ + return; + + account_output(¤t_column, fprintf(options.output, "(")); func = name2func(function_name); - if (!func) { - int i; - for (i = 0; i < 4; i++) { - current_column += - display_arg(type, proc, i, arg_unknown); - current_column += fprintf(options.output, ", "); - } - current_column += display_arg(type, proc, 4, arg_unknown); + if (func == NULL) { + account_output(¤t_column, fprintf(options.output, "???")); return; - } else { - int i; - for (i = 0; i < func->num_params - func->params_right - 1; i++) { - current_column += - display_arg(type, proc, i, func->arg_info[i]); - current_column += fprintf(options.output, ", "); - } - if (func->num_params > func->params_right) { - current_column += - display_arg(type, proc, i, func->arg_info[i]); - if (func->params_right) { - current_column += fprintf(options.output, ", "); - } - } - if (func->params_right) { - save_register_args(type, proc); - } } + + struct fetch_context *context = fetch_arg_init(type, proc, + func->return_info); + struct value_dict *arguments = malloc(sizeof(*arguments)); + if (arguments == NULL) + return; + val_dict_init(arguments); + + ssize_t params_left = -1; + int need_delim = 0; + if (fetch_params(type, proc, context, arguments, func, ¶ms_left) < 0 + || output_params(arguments, 0, params_left, &need_delim) < 0) { + val_dict_destroy(arguments); + fetch_arg_done(context); + arguments = NULL; + context = NULL; + } + + struct callstack_element *stel + = &proc->callstack[proc->callstack_depth - 1]; + stel->fetch_context = context; + stel->arguments = arguments; + stel->out.params_left = params_left; + stel->out.need_delim = need_delim; } void -output_right(enum tof type, Process *proc, char *function_name) { +output_right(enum tof type, struct Process *proc, struct library_symbol *libsym) +{ + const char *function_name = libsym->name; Function *func = name2func(function_name); - static arg_type_info *arg_unknown = NULL; - if (arg_unknown == NULL) - arg_unknown = lookup_prototype(ARGTYPE_UNKNOWN); + if (func == NULL) + return; if (options.summary) { struct opt_c_struct *st; @@ -255,7 +545,7 @@ output_right(enum tof type, Process *proc, char *function_name) { current_proc = 0; } if (current_proc != proc) { - begin_of_line(type, proc); + begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1); #ifdef USE_DEMANGLE current_column += fprintf(options.output, "<... %s resumed> ", @@ -266,38 +556,156 @@ output_right(enum tof type, Process *proc, char *function_name) { #endif } - if (!func) { - current_column += fprintf(options.output, ") "); - tabto(options.align - 1); - fprintf(options.output, "= "); - display_arg(type, proc, -1, arg_unknown); - } else { - int i; - for (i = func->num_params - func->params_right; - i < func->num_params - 1; i++) { - current_column += - display_arg(type, proc, i, func->arg_info[i]); - current_column += fprintf(options.output, ", "); - } - if (func->params_right) { - current_column += - display_arg(type, proc, i, func->arg_info[i]); - } - current_column += fprintf(options.output, ") "); - tabto(options.align - 1); - fprintf(options.output, "= "); - if (func->return_info->type == ARGTYPE_VOID) { - fprintf(options.output, "<void>"); - } else { - display_arg(type, proc, -1, func->return_info); - } + struct callstack_element *stel + = &proc->callstack[proc->callstack_depth - 1]; + + struct fetch_context *context = stel->fetch_context; + + /* Fetch & enter into dictionary the retval first, so that + * other values can use it in expressions. */ + struct value retval; + int own_retval = 0; + if (context != NULL) { + value_init(&retval, proc, NULL, func->return_info, 0); + own_retval = 1; + if (fetch_retval(context, type, proc, func->return_info, + &retval) < 0) + value_set_type(&retval, NULL, 0); + else if (stel->arguments != NULL + && val_dict_push_named(stel->arguments, &retval, + "retval", 0) == 0) + own_retval = 0; + } + + if (stel->arguments != NULL) + output_params(stel->arguments, stel->out.params_left, + val_dict_count(stel->arguments), + &stel->out.need_delim); + + current_column += fprintf(options.output, ") "); + tabto(options.align - 1); + fprintf(options.output, "= "); + + if (context != NULL && retval.type != NULL) { + struct format_argument_data data = { &retval, stel->arguments }; + format_argument_cb(options.output, &data); } + + if (own_retval) + value_destroy(&retval); + if (opt_T) { fprintf(options.output, " <%lu.%06d>", current_time_spent.tv_sec, (int)current_time_spent.tv_usec); } fprintf(options.output, "\n"); + +#if defined(HAVE_LIBUNWIND) + if (options.bt_depth > 0) { + unw_cursor_t cursor; + unw_word_t ip, sp; + int unwind_depth = options.bt_depth; + char fn_name[100]; + + unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv); + while (unwind_depth) { + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + unw_get_proc_name(&cursor, fn_name, 100, NULL); + fprintf(options.output, "\t\t\t%s (ip = 0x%lx)\n", fn_name, (long) ip); + if (unw_step(&cursor) <= 0) + break; + unwind_depth--; + } + fprintf(options.output, "\n"); + } +#endif /* defined(HAVE_LIBUNWIND) */ + current_proc = 0; current_column = 0; } + +int +delim_output(FILE *stream, int *need_delimp, + int (*writer)(FILE *stream, void *data), + void *data) +{ + int o; + + /* If we don't need a delimiter, then we don't need to go + * through a temporary stream. It's all the same whether + * WRITER emits anything or not. */ + if (!*need_delimp) { + o = writer(stream, data); + + } else { + char *buf; + size_t bufsz; + FILE *tmp = open_memstream(&buf, &bufsz); + o = writer(tmp, data); + fclose(tmp); + + if (o > 0 && ((*need_delimp + && account_output(&o, fprintf(stream, ", ")) < 0) + || fwrite(buf, 1, bufsz, stream) != bufsz)) + o = -1; + + free(buf); + } + + if (o < 0) + return -1; + + *need_delimp = *need_delimp || o > 0; + return o; +} + +int +account_output(int *countp, int c) +{ + if (c > 0) + *countp += c; + return c; +} + +static void +do_report(const char *filename, unsigned line_no, const char *severity, + const char *fmt, va_list args) +{ + char buf[128]; + vsnprintf(buf, sizeof(buf), fmt, args); + buf[sizeof(buf) - 1] = 0; + if (filename != NULL) + output_line(0, "%s:%d: %s: %s", + filename, line_no, severity, buf); + else + output_line(0, "%s: %s", severity, buf); +} + +void +report_error(const char *filename, unsigned line_no, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_report(filename, line_no, "error", fmt, args); + va_end(args); +} + +void +report_warning(const char *filename, unsigned line_no, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_report(filename, line_no, "warning", fmt, args); + va_end(args); +} + +void +report_global_error(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_report(NULL, 0, "error", fmt, args); + va_end(args); +} @@ -1,3 +1,58 @@ -void output_line(Process *proc, char *fmt, ...); -void output_left(enum tof type, Process *proc, char *function_name); -void output_right(enum tof type, Process *proc, char *function_name); +/* + * This file is part of ltrace. + * Copyright (C) 2011, 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef _OUTPUT_H_ +#define _OUTPUT_H_ + +#include "fetch.h" +#include "forward.h" + +void output_line(struct Process *proc, const char *fmt, ...); +void output_left(enum tof type, struct Process *proc, + struct library_symbol *libsym); +void output_right(enum tof type, struct Process *proc, + struct library_symbol *libsym); + +/* This function is for emitting lists of comma-separated strings. + * + * STREAM is where the output should be eventually sent. + * + * WRITER is the function to do the output. It returns number of + * characters written, or a negative value if there were errors (like + * what fprintf does). If WRITER returns 0, it means nothing was + * written, and separator shouldn't therefore be emitted either. + * + * NEED_DELIMP serves for keeping state between calls. It should + * point to a variable that is initialized to 0. DATA is passed + * verbatim to the WRITER. + * + * Returns number of characters written to STREAM (including any + * separators), or a negative value if there were errors. */ +int delim_output(FILE *stream, int *need_delimp, + int (*writer)(FILE *stream, void *data), void *data); + +/* If C is positive, add it to *COUNTP. Returns C. */ +int account_output(int *countp, int c); + +void report_error(char const *file, unsigned line_no, const char *fmt, ...); +void report_warning(char const *file, unsigned line_no, const char *fmt, ...); +void report_global_error(const char *fmt, ...); + +#endif /* _OUTPUT_H_ */ @@ -0,0 +1,141 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <assert.h> +#include <stdlib.h> + +#include "param.h" +#include "type.h" +#include "value.h" +#include "expr.h" + +void +param_init_type(struct param *param, struct arg_type_info *type, int own) +{ + param->flavor = PARAM_FLAVOR_TYPE; + param->u.type.type = type; + param->u.type.own_type = own; +} + +void +param_init_stop(struct param *param) +{ + param->flavor = PARAM_FLAVOR_STOP; +} + +void +param_init_pack(struct param *param, enum param_pack_flavor ppflavor, + struct expr_node *args, size_t nargs, int own_args, + struct param_enum *(*init)(struct value *cb_args, + size_t nargs, + struct value_dict *arguments), + int (*next)(struct param_enum *context, + struct arg_type_info *infop, + int *insert_stop), + enum param_status (*stop)(struct param_enum *ctx, + struct value *value), + void (*done)(struct param_enum *)) +{ + param->flavor = PARAM_FLAVOR_PACK; + param->u.pack.args = args; + param->u.pack.nargs = nargs; + param->u.pack.own_args = own_args; + param->u.pack.ppflavor = ppflavor; + param->u.pack.init = init; + param->u.pack.next = next; + param->u.pack.stop = stop; + param->u.pack.done = done; +} + +struct param_enum * +param_pack_init(struct param *param, struct value_dict *fargs) +{ + struct value cb_args[param->u.pack.nargs]; + size_t i; + + /* For evaluation of argument expressions, we pass in this as + * a "current" value. */ + struct arg_type_info *void_type = type_get_simple(ARGTYPE_VOID); + struct value void_val; + value_init_detached(&void_val, NULL, void_type, 0); + + struct param_enum *ret = NULL; + for (i = 0; i < param->u.pack.nargs; ++i) { + if (expr_eval(¶m->u.pack.args[i], &void_val, + fargs, &cb_args[i]) < 0) + goto release; + } + + ret = param->u.pack.init(cb_args, param->u.pack.nargs, fargs); + +release: + while (i-- > 0) + value_destroy(&cb_args[i]); + return ret; +} + +int +param_pack_next(struct param *param, struct param_enum *context, + struct arg_type_info *infop, int *insert_stop) +{ + return param->u.pack.next(context, infop, insert_stop); +} + +enum param_status +param_pack_stop(struct param *param, + struct param_enum *context, struct value *value) +{ + return param->u.pack.stop(context, value); +} + +void +param_pack_done(struct param *param, struct param_enum *context) +{ + return param->u.pack.done(context); +} + +void +param_destroy(struct param *param) +{ + if (param == NULL) + return; + + switch (param->flavor) { + case PARAM_FLAVOR_TYPE: + if (param->u.type.own_type) { + type_destroy(param->u.type.type); + free(param->u.type.type); + } + return; + + case PARAM_FLAVOR_PACK: + if (param->u.pack.own_args) { + size_t i; + for (i = 0; i < param->u.pack.nargs; ++i) + expr_destroy(¶m->u.pack.args[i]); + free(param->u.pack.args); + } + case PARAM_FLAVOR_STOP: + return; + } + + assert(!"Unknown value of param flavor!"); + abort(); +} @@ -0,0 +1,163 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef PARAM_H +#define PARAM_H + +#include "forward.h" + +/* The structure param holds information about a parameter of a + * function. It's used to configure a function prototype. There are + * two flavors of parameters: + * + * - simple types + * - parameter packs + * + * Parameter packs are used to describe various vararg constructs. + * They themselves are parametrized by ltrace expressions. Those will + * typically be references to other arguments, but constants might + * also make sense, and it principle, anything can be used. */ + +enum param_flavor { + PARAM_FLAVOR_TYPE, + PARAM_FLAVOR_PACK, + + /* This is for emitting arguments in two bunches. This is + * where we should stop emitting "left" bunch. All that's + * after this parameter should be emitted in the "right" + * bunch. */ + PARAM_FLAVOR_STOP, +}; + +enum param_pack_flavor { + /* This parameter pack expands to a list of ordinary + * arguments. For example if the last argument is sometimes + * ignored, that would be described by a PARAM_PACK_ARGS + * parameter pack. ioctl or ptrace are two examples that + * would benefit from this. */ + PARAM_PACK_ARGS, + + /* This parameter pack represents a vararg argument. */ + PARAM_PACK_VARARGS, +}; + +enum param_status { + PPCB_ERR = -1, /* An error occurred. */ + PPCB_STOP, /* Stop fetching the arguments. */ + PPCB_CONT, /* Display this argument and keep going. */ +}; + +/* Each parameter enumerator defines its own context object. + * Definitions of these are in respective .c files of each + * enumerator. */ +struct param_enum; + +/* int printf(string, pack(format, arg1)); */ +struct param { + enum param_flavor flavor; + union { + struct { + struct arg_type_info *type; + int own_type; + } type; + struct { + struct expr_node *args; + size_t nargs; + int own_args; + enum param_pack_flavor ppflavor; + + struct param_enum *(*init)(struct value *cb_args, + size_t nargs, + struct value_dict *arguments); + int (*next)(struct param_enum *self, + struct arg_type_info *info, + int *insert_stop); + enum param_status (*stop)(struct param_enum *self, + struct value *value); + void (*done)(struct param_enum *self); + } pack; + } u; +}; + +/* Initialize simple type parameter. TYPE is owned and released by + * PARAM if OWN_TYPE. */ +void param_init_type(struct param *param, + struct arg_type_info *type, int own_type); + +/* Initialize a stop. */ +void param_init_stop(struct param *param); + +/* Initialize parameter pack PARAM. ARGS is an array of expressions + * with parameters. ARGS is owned and released by the pack if + * OWN_ARGS. NARGS is number of ARGS. + * + * When the parameter pack should be expanded, those expressions are + * evaluated and passed to the INIT callback. This has to return a + * non-NULL context object. + * + * The NEXT callback is then called repeatedly, and should initialize + * its INFOP argument to a type of the next parameter in the pack. + * When there are no more parameters in the pack, the NEXT callback + * will set INFOP to a VOID parameter. If the callback sets + * INSERT_STOP to a non-zero value, a stop parameter shall be inserted + * before this actual parameter. + * + * Core then uses the passed-in type to fetch the next argument, which + * is in turn passed to STOP callback. This callback then tells + * ltrace core what to do next: whether there are more arguments, and + * if not, whether this argument should be displayed. + * + * After the enumeration is ended, DONE callback is called. */ +void param_init_pack(struct param *param, enum param_pack_flavor ppflavor, + struct expr_node *args, size_t nargs, int own_args, + struct param_enum *(*init)(struct value *cb_args, + size_t nargs, + struct value_dict *arguments), + int (*next)(struct param_enum *self, + struct arg_type_info *infop, + int *insert_stop), + enum param_status (*stop)(struct param_enum *self, + struct value *value), + void (*done)(struct param_enum *self)); + +/* Start enumerating types in parameter pack. This evaluates the + * parameter the pack arguments and calls the init callback. See the + * documentation of param_init_pack for details. */ +struct param_enum *param_pack_init(struct param *param, + struct value_dict *fargs); + +/* Ask for next type in enumeration. See the documentation of + * param_init_pack for details. */ +int param_pack_next(struct param *param, struct param_enum *self, + struct arg_type_info *infop, int *insert_stop); + +/* Ask whether we should stop enumerating. See the documentation of + * param_init_pack for details. */ +enum param_status param_pack_stop(struct param *param, + struct param_enum *self, struct value *value); + +/* Finish enumerating types in parameter pack. See the documentation + * of param_init_pack for details. */ +void param_pack_done(struct param *param, struct param_enum *self); + +/* Destroy data held by PARAM, but not the PARAM pointer itself. */ +void param_destroy(struct param *param); + +#endif /* PARAM_H */ diff --git a/printf.c b/printf.c new file mode 100644 index 0000000..97e2c2d --- /dev/null +++ b/printf.c @@ -0,0 +1,365 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Steve Fink + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <assert.h> +#include <stdlib.h> + +#include "printf.h" +#include "type.h" +#include "value.h" +#include "expr.h" +#include "zero.h" +#include "param.h" +#include "lens_default.h" + +struct param_enum { + struct value array; + int percent; + size_t *future_length; + char *format; + char const *ptr; + char const *end; +}; + +static struct param_enum * +param_printf_init(struct value *cb_args, size_t nargs, + struct value_dict *arguments) +{ + assert(nargs == 1); + + /* We expect a char array pointer. */ + if (cb_args->type->type != ARGTYPE_POINTER + || cb_args->type->u.ptr_info.info->type != ARGTYPE_ARRAY + || (cb_args->type->u.ptr_info.info->u.array_info.elt_type->type + != ARGTYPE_CHAR)) + return NULL; + + struct param_enum *self = malloc(sizeof(*self)); + if (self == NULL) { + fail: + free(self); + return NULL; + } + + if (value_init_deref(&self->array, cb_args) < 0) + goto fail; + + assert(self->array.type->type == ARGTYPE_ARRAY); + + self->format = (char *)value_get_data(&self->array, arguments); + if (self->format == NULL) { + value_destroy(&self->array); + goto fail; + } + + size_t size = value_size(&self->array, arguments); + if (size == (size_t)-1) { + value_destroy(&self->array); + goto fail; + } + + self->percent = 0; + self->ptr = self->format; + self->end = self->format + size; + self->future_length = NULL; + return self; +} + +static void +drop_future_length(struct param_enum *self) +{ + if (self->future_length != NULL) { + free(self->future_length); + self->future_length = NULL; + } +} + +static int +form_next_param(struct param_enum *self, + enum arg_type format_type, enum arg_type elt_type, + unsigned hlf, unsigned lng, char *len_buf, size_t len_buf_len, + struct arg_type_info *infop) +{ + /* XXX note: Some types are wrong because we lack + ARGTYPE_LONGLONG, ARGTYPE_UCHAR and ARGTYPE_SCHAR. */ + assert(lng <= 2); + assert(hlf <= 2); + static enum arg_type ints[] = + { ARGTYPE_CHAR, ARGTYPE_SHORT, ARGTYPE_INT, + ARGTYPE_LONG, ARGTYPE_ULONG }; + static enum arg_type uints[] = + { ARGTYPE_CHAR, ARGTYPE_USHORT, ARGTYPE_UINT, + ARGTYPE_ULONG, ARGTYPE_ULONG }; + + struct arg_type_info *elt_info = NULL; + if (format_type == ARGTYPE_ARRAY || format_type == ARGTYPE_POINTER) + elt_info = type_get_simple(elt_type); + else if (format_type == ARGTYPE_INT) + format_type = ints[2 + lng - hlf]; + else if (format_type == ARGTYPE_UINT) + format_type = uints[2 + lng - hlf]; + + + if (format_type == ARGTYPE_ARRAY) { + struct arg_type_info *array = malloc(sizeof(*array)); + if (array == NULL) + return -1; + + struct expr_node *node = NULL; + int own_node; + if (len_buf_len != 0 + || self->future_length != NULL) { + struct tmp { + struct expr_node node; + struct arg_type_info type; + }; + struct tmp *len = malloc(sizeof(*len)); + if (len == NULL) { + fail: + free(len); + free(array); + return -1; + } + + len->type = *type_get_simple(ARGTYPE_LONG); + + long l; + if (self->future_length != NULL) { + l = *self->future_length; + drop_future_length(self); + } else { + l = atol(len_buf); + } + + expr_init_const_word(&len->node, l, &len->type, 0); + + node = build_zero_w_arg(&len->node, 1); + if (node == NULL) + goto fail; + own_node = 1; + + } else { + node = expr_node_zero(); + own_node = 0; + } + assert(node != NULL); + + type_init_array(array, elt_info, 0, node, own_node); + type_init_pointer(infop, array, 1); + + } else if (format_type == ARGTYPE_POINTER) { + type_init_pointer(infop, elt_info, 1); + + } else { + *infop = *type_get_simple(format_type); + } + + return 0; +} + +static int +param_printf_next(struct param_enum *self, struct arg_type_info *infop, + int *insert_stop) +{ + unsigned hlf = 0; + unsigned lng = 0; + enum arg_type format_type = ARGTYPE_VOID; + enum arg_type elt_type = ARGTYPE_VOID; + char len_buf[25] = {}; + size_t len_buf_len = 0; + struct lens *lens = NULL; + + for (; self->ptr < self->end; ++self->ptr) { + if (!self->percent) { + if (*self->ptr == '%') + self->percent = 1; + continue; + } + + switch (*self->ptr) { + case '#': case ' ': case '-': + case '+': case 'I': case '\'': + /* These are only important for formatting, + * not for interpreting the type. */ + continue; + + case '*': + /* Length parameter given in the next + * argument. */ + if (self->future_length == NULL) + /* This should really be an assert, + * but we can't just fail on invalid + * format string. */ + self->future_length + = malloc(sizeof(*self->future_length)); + + if (self->future_length != NULL) { + ++self->ptr; + format_type = ARGTYPE_INT; + break; + } + + case '0': + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + /* Field length likewise, but we need to parse + * this to attach the appropriate string + * length expression. */ + if (len_buf_len < sizeof(len_buf) - 1) + len_buf[len_buf_len++] = *self->ptr; + continue; + + case 'h': + if (hlf < 2) + hlf++; + continue; + + case 'l': + if (lng < 2) + lng++; + continue; + + case 'q': + lng = 2; + continue; + + case 'L': /* long double */ + lng = 1; + continue; + + case 'j': /* intmax_t */ + /* XXX ABI should know */ + lng = 2; + continue; + + case 't': /* ptrdiff_t */ + case 'Z': case 'z': /* size_t */ + lng = 1; /* XXX ABI should tell */ + continue; + + case 'd': + case 'i': + format_type = ARGTYPE_INT; + self->percent = 0; + break; + + case 'o': + lens = &octal_lens; + goto uint; + + case 'x': case 'X': + lens = &hex_lens; + case 'u': + uint: + format_type = ARGTYPE_UINT; + self->percent = 0; + break; + + case 'e': case 'E': + case 'f': case 'F': + case 'g': case 'G': + case 'a': case 'A': + format_type = ARGTYPE_DOUBLE; + self->percent = 0; + break; + + case 'C': /* like "lc" */ + if (lng == 0) + lng++; + case 'c': + /* XXX "lc" means wchar_t string. */ + format_type = ARGTYPE_CHAR; + self->percent = 0; + break; + + case 'S': /* like "ls" */ + if (lng == 0) + lng++; + case 's': + format_type = ARGTYPE_ARRAY; + /* XXX "ls" means wchar_t string. */ + elt_type = ARGTYPE_CHAR; + self->percent = 0; + lens = &string_lens; + break; + + case 'p': + case 'n': /* int* where to store no. of printed chars. */ + format_type = ARGTYPE_POINTER; + elt_type = ARGTYPE_VOID; + self->percent = 0; + break; + + case 'm': /* (glibc) print argument of errno */ + case '%': + lng = 0; + hlf = 0; + self->percent = 0; + continue; + + default: + continue; + } + + /* If we got here, the type must have been set. */ + assert(format_type != ARGTYPE_VOID); + + if (form_next_param(self, format_type, elt_type, hlf, lng, + len_buf, len_buf_len, infop) < 0) + return -1; + + infop->lens = lens; + infop->own_lens = 0; + + return 0; + } + + *infop = *type_get_simple(ARGTYPE_VOID); + return 0; +} + +static enum param_status +param_printf_stop(struct param_enum *self, struct value *value) +{ + if (self->future_length != NULL + && value_extract_word(value, (long *)self->future_length, NULL) < 0) + drop_future_length(self); + + return PPCB_CONT; +} + +static void +param_printf_done(struct param_enum *context) +{ + value_destroy(&context->array); + free(context); +} + +void +param_pack_init_printf(struct param *param, struct expr_node *arg, int own_arg) +{ + param_init_pack(param, PARAM_PACK_VARARGS, arg, 1, own_arg, + ¶m_printf_init, ¶m_printf_next, + ¶m_printf_stop, ¶m_printf_done); +} diff --git a/printf.h b/printf.h new file mode 100644 index 0000000..983c951 --- /dev/null +++ b/printf.h @@ -0,0 +1,34 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef PRINTF_H +#define PRINTF_H + +#include <stddef.h> +#include "forward.h" + +/* Wrapper around param_init_pack with callbacks to handle + * printf-style format strings. ARG should be an expression that + * evaluates to a pointer to a character array with the format string + * contents. */ +void param_pack_init_printf(struct param *param, + struct expr_node *arg, int own_arg); + +#endif /* PRINTF_H */ @@ -1,65 +1,1037 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1998,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "config.h" + #include <sys/types.h> -#include <string.h> -#include <stdio.h> +#include <assert.h> #include <errno.h> +#include <stdio.h> #include <stdlib.h> +#include <string.h> -#include "common.h" +#if defined(HAVE_LIBUNWIND) +#include <libunwind.h> +#include <libunwind-ptrace.h> +#endif /* defined(HAVE_LIBUNWIND) */ -Process * -open_program(char *filename, pid_t pid) { - Process *proc; - proc = calloc(sizeof(Process), 1); - if (!proc) { - perror("malloc"); - exit(1); +#include "backend.h" +#include "breakpoint.h" +#include "debug.h" +#include "fetch.h" +#include "proc.h" +#include "value_dict.h" + +#ifndef ARCH_HAVE_PROCESS_DATA +int +arch_process_init(struct Process *proc) +{ + return 0; +} + +void +arch_process_destroy(struct Process *proc) +{ +} + +int +arch_process_clone(struct Process *retp, struct Process *proc) +{ + return 0; +} + +int +arch_process_exec(struct Process *proc) +{ + return 0; +} +#endif + +#ifndef OS_HAVE_PROCESS_DATA +int +os_process_init(struct Process *proc) +{ + return 0; +} + +void +os_process_destroy(struct Process *proc) +{ +} + +int +os_process_clone(struct Process *retp, struct Process *proc) +{ + return 0; +} + +int +os_process_exec(struct Process *proc) +{ + return 0; +} +#endif + +#ifndef ARCH_HAVE_DYNLINK_DONE +void +arch_dynlink_done(struct Process *proc) +{ +} +#endif + +static void add_process(struct Process *proc, int was_exec); +static void unlist_process(struct Process *proc); + +static void +destroy_unwind(struct Process *proc) +{ +#if defined(HAVE_LIBUNWIND) + _UPT_destroy(proc->unwind_priv); + unw_destroy_addr_space(proc->unwind_as); +#endif /* defined(HAVE_LIBUNWIND) */ +} + +static int +process_bare_init(struct Process *proc, const char *filename, + pid_t pid, int was_exec) +{ + if (!was_exec) { + memset(proc, 0, sizeof(*proc)); + + proc->filename = strdup(filename); + if (proc->filename == NULL) { + fail: + free(proc->filename); + if (proc->breakpoints != NULL) + dict_clear(proc->breakpoints); + return -1; + } } - proc->filename = strdup(filename); - proc->breakpoints_enabled = -1; - if (pid) { - proc->pid = pid; + + /* Add process so that we know who the leader is. */ + proc->pid = pid; + add_process(proc, was_exec); + if (proc->leader == NULL) + goto fail; + + if (proc->leader == proc) { + proc->breakpoints = dict_init(target_address_hash, + target_address_cmp); + if (proc->breakpoints == NULL) + goto fail; + } else { + proc->breakpoints = NULL; } - breakpoints_init(proc); - proc->next = list_of_processes; - list_of_processes = proc; - return proc; +#if defined(HAVE_LIBUNWIND) + proc->unwind_priv = _UPT_create(pid); + proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0); +#endif /* defined(HAVE_LIBUNWIND) */ + + return 0; +} + +static void +process_bare_destroy(struct Process *proc, int was_exec) +{ + dict_clear(proc->breakpoints); + if (!was_exec) { + free(proc->filename); + unlist_process(proc); + destroy_unwind(proc); + } +} + +static int +process_init_main(struct Process *proc) +{ + if (breakpoints_init(proc) < 0) { + fprintf(stderr, "failed to init breakpoints %d\n", + proc->pid); + return -1; + } + + return 0; +} + +int +process_init(struct Process *proc, const char *filename, pid_t pid) +{ + if (process_bare_init(proc, filename, pid, 0) < 0) { + fail: + fprintf(stderr, "failed to initialize process %d: %s\n", + pid, strerror(errno)); + return -1; + } + + if (os_process_init(proc) < 0) { + process_bare_destroy(proc, 0); + goto fail; + } + + if (arch_process_init(proc) < 0) { + os_process_destroy(proc); + process_bare_destroy(proc, 0); + goto fail; + } + + if (proc->leader != proc) + return 0; + if (process_init_main(proc) < 0) { + process_bare_destroy(proc, 0); + goto fail; + } + return 0; +} + +static enum callback_status +destroy_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data) +{ + breakpoint_destroy(bp); + free(bp); + return CBS_CONT; +} + +// XXX see comment in handle_event.c +void callstack_pop(struct Process *proc); + +static void +private_process_destroy(struct Process *proc, int was_exec) +{ + /* Pop remaining stack elements. */ + while (proc->callstack_depth > 0) { + /* When this is called just before a process is + * destroyed, the breakpoints should either have been + * retracted by now, or were killed by exec. In any + * case, it's safe to pretend that there are no + * breakpoints associated with the stack elements, so + * that stack_pop doesn't attempt to destroy them. */ + size_t i = proc->callstack_depth - 1; + if (!proc->callstack[i].is_syscall) + proc->callstack[i].return_addr = 0; + + callstack_pop(proc); + } + + if (!was_exec) + free(proc->filename); + + /* Libraries and symbols. This is only relevant in + * leader. */ + struct library *lib; + for (lib = proc->libraries; lib != NULL; ) { + struct library *next = lib->next; + library_destroy(lib); + free(lib); + lib = next; + } + proc->libraries = NULL; + + /* Breakpoints. */ + if (proc->breakpoints != NULL) { + proc_each_breakpoint(proc, NULL, destroy_breakpoint_cb, NULL); + dict_clear(proc->breakpoints); + proc->breakpoints = NULL; + } + + destroy_unwind(proc); } void -open_pid(pid_t pid) { +process_destroy(struct Process *proc) +{ + arch_process_destroy(proc); + os_process_destroy(proc); + private_process_destroy(proc, 0); +} + +int +process_exec(struct Process *proc) +{ + /* Call exec handlers first, before we destroy the main + * state. */ + if (arch_process_exec(proc) < 0 + || os_process_exec(proc) < 0) + return -1; + + private_process_destroy(proc, 1); + + if (process_bare_init(proc, NULL, proc->pid, 1) < 0) + return -1; + if (process_init_main(proc) < 0) { + process_bare_destroy(proc, 1); + return -1; + } + return 0; +} + +struct Process * +open_program(const char *filename, pid_t pid) +{ + assert(pid != 0); + struct Process *proc = malloc(sizeof(*proc)); + if (proc == NULL || process_init(proc, filename, pid) < 0) { + free(proc); + return NULL; + } + return proc; +} + +struct clone_single_bp_data { + struct Process *old_proc; + struct Process *new_proc; + int error; +}; + +static void +clone_single_bp(void *key, void *value, void *u) +{ + struct breakpoint *bp = value; + struct clone_single_bp_data *data = u; + + /* Don't bother if there were errors anyway. */ + if (data->error != 0) + return; + + struct breakpoint *clone = malloc(sizeof(*clone)); + if (clone == NULL + || breakpoint_clone(clone, data->new_proc, + bp, data->old_proc) < 0) { + fail: + free(clone); + data->error = -1; + } + if (proc_add_breakpoint(data->new_proc->leader, clone) < 0) { + breakpoint_destroy(clone); + goto fail; + } +} + +int +process_clone(struct Process *retp, struct Process *proc, pid_t pid) +{ + if (process_bare_init(retp, proc->filename, pid, 0) < 0) { + fail1: + fprintf(stderr, "failed to clone process %d->%d : %s\n", + proc->pid, pid, strerror(errno)); + return -1; + } + + retp->tracesysgood = proc->tracesysgood; + retp->e_machine = proc->e_machine; + retp->e_class = proc->e_class; + + /* For non-leader processes, that's all we need to do. */ + if (retp->leader != retp) + return 0; + + /* Clone symbols first so that we can clone and relink + * breakpoints. */ + struct library *lib; + struct library **nlibp = &retp->libraries; + for (lib = proc->leader->libraries; lib != NULL; lib = lib->next) { + *nlibp = malloc(sizeof(**nlibp)); + if (*nlibp == NULL + || library_clone(*nlibp, lib) < 0) { + fail2: + process_bare_destroy(retp, 0); + + /* Error when cloning. Unroll what was done. */ + for (lib = retp->libraries; lib != NULL; ) { + struct library *next = lib->next; + library_destroy(lib); + free(lib); + lib = next; + } + goto fail1; + } + + nlibp = &(*nlibp)->next; + } + + /* Now clone breakpoints. Symbol relinking is done in + * clone_single_bp. */ + struct clone_single_bp_data data = { + .old_proc = proc, + .new_proc = retp, + .error = 0, + }; + dict_apply_to_all(proc->leader->breakpoints, &clone_single_bp, &data); + if (data.error < 0) + goto fail2; + + /* And finally the call stack. */ + /* XXX clearly the callstack handling should be moved to a + * separate module and this whole business extracted to + * callstack_clone, or callstack_element_clone. */ + memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack)); + retp->callstack_depth = proc->callstack_depth; + + size_t i; + for (i = 0; i < retp->callstack_depth; ++i) { + struct callstack_element *elem = &retp->callstack[i]; + struct fetch_context *ctx = elem->fetch_context; + if (ctx != NULL) { + struct fetch_context *nctx = fetch_arg_clone(retp, ctx); + if (nctx == NULL) { + size_t j; + fail3: + for (j = 0; j < i; ++j) { + nctx = elem->fetch_context; + fetch_arg_done(nctx); + elem->fetch_context = NULL; + } + goto fail2; + } + elem->fetch_context = nctx; + } + + struct value_dict *args = elem->arguments; + if (args != NULL) { + struct value_dict *nargs = malloc(sizeof(*nargs)); + if (nargs == NULL + || val_dict_clone(nargs, args) < 0) { + size_t j; + for (j = 0; j < i; ++j) { + nargs = elem->arguments; + val_dict_destroy(nargs); + free(nargs); + elem->arguments = NULL; + } + + /* Pretend that this round went well, + * so that fail3 frees I-th + * fetch_context. */ + ++i; + goto fail3; + } + elem->arguments = nargs; + } + + /* If it's not a syscall, we need to find the + * corresponding library symbol in the cloned + * library. */ + if (!elem->is_syscall && elem->c_un.libfunc != NULL) { + struct library_symbol *libfunc = elem->c_un.libfunc; + int rc = proc_find_symbol(retp, libfunc, + NULL, &elem->c_un.libfunc); + assert(rc == 0); + } + } + + /* At this point, retp is fully initialized, except for OS and + * arch parts, and we can call private_process_destroy. */ + if (os_process_clone(retp, proc) < 0) { + private_process_destroy(retp, 0); + return -1; + } + if (arch_process_clone(retp, proc) < 0) { + os_process_destroy(retp); + private_process_destroy(retp, 0); + return -1; + } + + return 0; +} + +static int +open_one_pid(pid_t pid) +{ Process *proc; char *filename; + debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid); - if (trace_pid(pid) < 0) { - fprintf(stderr, "Cannot attach to pid %u: %s\n", pid, - strerror(errno)); - return; + /* Get the filename first. Should the trace_pid fail, we can + * easily free it, untracing is more work. */ + if ((filename = pid2name(pid)) == NULL + || trace_pid(pid) < 0) { + fail: + free(filename); + return -1; } - filename = pid2name(pid); + proc = open_program(filename, pid); + if (proc == NULL) + goto fail; + free(filename); + trace_set_options(proc); + + return 0; +} - if (!filename) { - fprintf(stderr, "Cannot trace pid %u: %s\n", pid, - strerror(errno)); +static enum callback_status +start_one_pid(Process * proc, void * data) +{ + continue_process(proc->pid); + return CBS_CONT; +} + +void +open_pid(pid_t pid) +{ + debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid); + /* If we are already tracing this guy, we should be seeing all + * his children via normal tracing route. */ + if (pid2proc(pid) != NULL) + return; + + /* First, see if we can attach the requested PID itself. */ + if (open_one_pid(pid)) { + fprintf(stderr, "Cannot attach to pid %u: %s\n", + pid, strerror(errno)); + trace_fail_warning(pid); return; } - proc = open_program(filename, pid); - continue_process(pid); - proc->breakpoints_enabled = 1; + /* Now attach to all tasks that belong to that PID. There's a + * race between process_tasks and open_one_pid. So when we + * fail in open_one_pid below, we just do another round. + * Chances are that by then that PID will have gone away, and + * that's why we have seen the failure. The processes that we + * manage to open_one_pid are stopped, so we should eventually + * reach a point where process_tasks doesn't give any new + * processes (because there's nobody left to produce + * them). */ + size_t old_ntasks = 0; + int have_all; + while (1) { + pid_t *tasks; + size_t ntasks; + size_t i; + + if (process_tasks(pid, &tasks, &ntasks) < 0) { + fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n", + pid, strerror(errno)); + break; + } + + have_all = 1; + for (i = 0; i < ntasks; ++i) + if (pid2proc(tasks[i]) == NULL + && open_one_pid(tasks[i])) + have_all = 0; + + free(tasks); + + if (have_all && old_ntasks == ntasks) + break; + old_ntasks = ntasks; + } + + struct Process *leader = pid2proc(pid)->leader; + + /* XXX Is there a way to figure out whether _start has + * actually already been hit? */ + arch_dynlink_done(leader); + + /* Done. Continue everyone. */ + each_task(leader, NULL, start_one_pid, NULL); +} + +static enum callback_status +find_proc(Process * proc, void * data) +{ + pid_t pid = (pid_t)(uintptr_t)data; + return proc->pid == pid ? CBS_STOP : CBS_CONT; } Process * pid2proc(pid_t pid) { + return each_process(NULL, &find_proc, (void *)(uintptr_t)pid); +} + +static Process * list_of_processes = NULL; + +static void +unlist_process(Process * proc) +{ Process *tmp; - tmp = list_of_processes; - while (tmp) { - if (pid == tmp->pid) { - return tmp; + if (list_of_processes == proc) { + list_of_processes = list_of_processes->next; + return; + } + + for (tmp = list_of_processes; ; tmp = tmp->next) { + /* If the following assert fails, the process wasn't + * in the list. */ + assert(tmp->next != NULL); + + if (tmp->next == proc) { + tmp->next = tmp->next->next; + return; + } + } +} + +struct Process * +each_process(struct Process *start_after, + enum callback_status(*cb)(struct Process *proc, void *data), + void *data) +{ + struct Process *it = start_after == NULL ? list_of_processes + : start_after->next; + + while (it != NULL) { + /* Callback might call remove_process. */ + struct Process *next = it->next; + switch ((*cb)(it, data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + return it; + case CBS_CONT: + break; + } + it = next; + } + return NULL; +} + +Process * +each_task(struct Process *proc, struct Process *start_after, + enum callback_status(*cb)(struct Process *proc, void *data), + void *data) +{ + assert(proc != NULL); + struct Process *it = start_after == NULL ? proc->leader + : start_after->next; + + if (it != NULL) { + struct Process *leader = it->leader; + while (it != NULL && it->leader == leader) { + /* Callback might call remove_process. */ + struct Process *next = it->next; + switch ((*cb)(it, data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + return it; + case CBS_CONT: + break; + } + it = next; + } + } + return NULL; +} + +static void +add_process(struct Process *proc, int was_exec) +{ + Process ** leaderp = &list_of_processes; + if (proc->pid) { + pid_t tgid = process_leader(proc->pid); + if (tgid == 0) + /* Must have been terminated before we managed + * to fully attach. */ + return; + if (tgid == proc->pid) + proc->leader = proc; + else { + Process * leader = pid2proc(tgid); + proc->leader = leader; + if (leader != NULL) + leaderp = &leader->next; } - tmp = tmp->next; } + + if (!was_exec) { + proc->next = *leaderp; + *leaderp = proc; + } +} + +void +change_process_leader(Process * proc, Process * leader) +{ + Process ** leaderp = &list_of_processes; + if (proc->leader == leader) + return; + + assert(leader != NULL); + unlist_process(proc); + if (proc != leader) + leaderp = &leader->next; + + proc->leader = leader; + proc->next = *leaderp; + *leaderp = proc; +} + +static enum callback_status +clear_leader(struct Process *proc, void *data) +{ + debug(DEBUG_FUNCTION, "detach_task %d from leader %d", + proc->pid, proc->leader->pid); + proc->leader = NULL; + return CBS_CONT; +} + +void +remove_process(Process *proc) +{ + debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid); + + if (proc->leader == proc) + each_task(proc, NULL, &clear_leader, NULL); + + unlist_process(proc); + process_removed(proc); + process_destroy(proc); + free(proc); +} + +void +install_event_handler(Process *proc, struct event_handler *handler) +{ + debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler); + assert(proc->event_handler == NULL); + proc->event_handler = handler; +} + +void +destroy_event_handler(Process * proc) +{ + struct event_handler *handler = proc->event_handler; + debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler); + assert(handler != NULL); + if (handler->destroy != NULL) + handler->destroy(handler); + free(handler); + proc->event_handler = NULL; +} + +static int +breakpoint_for_symbol(struct library_symbol *libsym, struct Process *proc) +{ + arch_addr_t bp_addr; + assert(proc->leader == proc); + + /* Don't enable latent or delayed symbols. */ + if (libsym->latent || libsym->delayed) { + debug(DEBUG_FUNCTION, + "delayed and/or latent breakpoint pid=%d, %s@%p", + proc->pid, libsym->name, libsym->enter_addr); + return 0; + } + + bp_addr = sym2addr(proc, libsym); + + /* If there is an artificial breakpoint on the same address, + * its libsym will be NULL, and we can smuggle our libsym + * there. That artificial breakpoint is there presumably for + * the callbacks, which we don't touch. If there is a real + * breakpoint, then this is a bug. ltrace-elf.c should filter + * symbols and ignore extra symbol aliases. + * + * The other direction is more complicated and currently not + * supported. If a breakpoint has custom callbacks, it might + * be also custom-allocated, and we would really need to swap + * the two: delete the one now in the dictionary, swap values + * around, and put the new breakpoint back in. */ + struct breakpoint *bp = dict_find_entry(proc->breakpoints, + bp_addr); + if (bp != NULL) { + /* MIPS backend makes duplicate requests. This is + * likely a bug in the backend. Currently there's no + * point assigning more than one symbol to a + * breakpoint, because when it hits, we won't know + * what to print out. But it's easier to fix it here + * before someone who understands MIPS has the time to + * look into it. So turn the sanity check off on + * MIPS. References: + * + * http://lists.alioth.debian.org/pipermail/ltrace-devel/2012-November/000764.html + * http://lists.alioth.debian.org/pipermail/ltrace-devel/2012-November/000770.html + */ +#ifndef __mips__ + assert(bp->libsym == NULL); + bp->libsym = libsym; +#endif + return 0; + } + + bp = malloc(sizeof(*bp)); + if (bp == NULL + || breakpoint_init(bp, proc, bp_addr, libsym) < 0) { + fail: + free(bp); + return -1; + } + if (proc_add_breakpoint(proc, bp) < 0) { + breakpoint_destroy(bp); + goto fail; + } + + if (breakpoint_turn_on(bp, proc) < 0) { + proc_remove_breakpoint(proc, bp); + breakpoint_destroy(bp); + goto fail; + } + + return 0; +} + +static enum callback_status +cb_breakpoint_for_symbol(struct library_symbol *libsym, void *data) +{ + return breakpoint_for_symbol(libsym, data) < 0 ? CBS_FAIL : CBS_CONT; +} + +static int +proc_activate_latent_symbol(struct Process *proc, + struct library_symbol *libsym) +{ + assert(libsym->latent); + libsym->latent = 0; + debug(DEBUG_FUNCTION, "activated latent symbol"); + return breakpoint_for_symbol(libsym, proc); +} + +int +proc_activate_delayed_symbol(struct Process *proc, + struct library_symbol *libsym) +{ + assert(libsym->delayed); + libsym->delayed = 0; + debug(DEBUG_FUNCTION, "activated delayed symbol"); + return breakpoint_for_symbol(libsym, proc); +} + +static enum callback_status +activate_latent_in(struct Process *proc, struct library *lib, void *data) +{ + struct library_exported_name *exported; + for (exported = data; exported != NULL; exported = exported->next) { + struct library_symbol *libsym = NULL; + while ((libsym = library_each_symbol(lib, libsym, + library_symbol_named_cb, + (void *)exported->name)) + != NULL) + if (libsym->latent + && proc_activate_latent_symbol(proc, libsym) < 0) + return CBS_FAIL; + } + return CBS_CONT; +} + +void +proc_add_library(struct Process *proc, struct library *lib) +{ + assert(lib->next == NULL); + lib->next = proc->libraries; + proc->libraries = lib; + debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d", + lib->soname, lib->base, lib->pathname, proc->pid); + + /* Insert breakpoints for all active (non-latent) symbols. */ + struct library_symbol *libsym = NULL; + while ((libsym = library_each_symbol(lib, libsym, + cb_breakpoint_for_symbol, + proc)) != NULL) + fprintf(stderr, "Couldn't insert breakpoint for %s to %d: %s.", + libsym->name, proc->pid, strerror(errno)); + + /* Look through export list of the new library and compare it + * with latent symbols of all libraries (including this + * library itself). */ + struct library *lib2 = NULL; + while ((lib2 = proc_each_library(proc, lib2, activate_latent_in, + lib->exported_names)) != NULL) + fprintf(stderr, + "Couldn't activate latent symbols for %s in %d: %s.", + libsym->name, proc->pid, strerror(errno)); +} + +int +proc_remove_library(struct Process *proc, struct library *lib) +{ + struct library **libp; + for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next) + if (*libp == lib) { + *libp = lib->next; + return 0; + } + return -1; +} + +struct library * +proc_each_library(struct Process *proc, struct library *it, + enum callback_status (*cb)(struct Process *proc, + struct library *lib, void *data), + void *data) +{ + if (it == NULL) + it = proc->libraries; + + while (it != NULL) { + struct library *next = it->next; + + switch (cb(proc, it, data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + return it; + case CBS_CONT: + break; + } + + it = next; + } + + return NULL; +} + +static void +check_leader(struct Process *proc) +{ + /* Only the group leader should be getting the breakpoints and + * thus have ->breakpoint initialized. */ + assert(proc->leader != NULL); + assert(proc->leader == proc); + assert(proc->breakpoints != NULL); +} + +int +proc_add_breakpoint(struct Process *proc, struct breakpoint *bp) +{ + debug(DEBUG_FUNCTION, "proc_add_breakpoint(pid=%d, %s@%p)", + proc->pid, breakpoint_name(bp), bp->addr); + check_leader(proc); + + /* XXX We might merge bp->libsym instead of the following + * assert, but that's not necessary right now. Read the + * comment in breakpoint_for_symbol. */ + assert(dict_find_entry(proc->breakpoints, bp->addr) == NULL); + + if (dict_enter(proc->breakpoints, bp->addr, bp) < 0) { + fprintf(stderr, + "couldn't enter breakpoint %s@%p to dictionary: %s\n", + breakpoint_name(bp), bp->addr, strerror(errno)); + return -1; + } + + return 0; +} + +void +proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp) +{ + debug(DEBUG_FUNCTION, "proc_remove_breakpoint(pid=%d, %s@%p)", + proc->pid, breakpoint_name(bp), bp->addr); + check_leader(proc); + struct breakpoint *removed = dict_remove(proc->breakpoints, bp->addr); + assert(removed == bp); +} + +/* Dict doesn't support iteration restarts, so here's this contraption + * for now. XXX add restarts to dict. */ +struct each_breakpoint_data +{ + void *start; + void *end; + struct Process *proc; + enum callback_status (*cb)(struct Process *proc, + struct breakpoint *bp, + void *data); + void *cb_data; +}; + +static void +each_breakpoint_cb(void *key, void *value, void *d) +{ + struct each_breakpoint_data *data = d; + if (data->end != NULL) + return; + if (data->start == key) + data->start = NULL; + + if (data->start == NULL) { + switch (data->cb(data->proc, value, data->cb_data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + data->end = key; + case CBS_CONT: + return; + } + } +} + +void * +proc_each_breakpoint(struct Process *proc, void *start, + enum callback_status (*cb)(struct Process *proc, + struct breakpoint *bp, + void *data), void *data) +{ + struct each_breakpoint_data dd = { + .start = start, + .proc = proc, + .cb = cb, + .cb_data = data, + }; + dict_apply_to_all(proc->breakpoints, &each_breakpoint_cb, &dd); + return dd.end; +} + +int +proc_find_symbol(struct Process *proc, struct library_symbol *sym, + struct library **retlib, struct library_symbol **retsym) +{ + struct library *lib = sym->lib; + assert(lib != NULL); + + struct library *flib + = proc_each_library(proc, NULL, library_with_key_cb, &lib->key); + if (flib == NULL) + return -1; + + struct library_symbol *fsym + = library_each_symbol(flib, NULL, library_symbol_named_cb, + (char *)sym->name); + if (fsym == NULL) + return -1; + + if (retlib != NULL) + *retlib = flib; + if (retsym != NULL) + *retsym = fsym; + + return 0; +} + +struct library_symbol * +proc_each_symbol(struct Process *proc, struct library_symbol *start_after, + enum callback_status (*cb)(struct library_symbol *, void *), + void *data) +{ + struct library *lib; + for (lib = start_after != NULL ? start_after->lib : proc->libraries; + lib != NULL; lib = lib->next) { + start_after = library_each_symbol(lib, start_after, cb, data); + if (start_after != NULL) + return start_after; + } + return NULL; } @@ -0,0 +1,257 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1998,2001,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _PROC_H_ +#define _PROC_H_ + +#include "config.h" + +#include <sys/time.h> + +#if defined(HAVE_LIBUNWIND) +# include <libunwind.h> +#endif /* defined(HAVE_LIBUNWIND) */ + +#include "ltrace.h" +#include "dict.h" +#include "sysdep.h" +#include "callback.h" +#include "forward.h" + +struct event_handler { + /* Event handler that overrides the default one. Should + * return NULL if the event was handled, otherwise the + * returned event is passed to the default handler. */ + Event *(*on_event)(struct event_handler *self, Event *event); + + /* Called when the event handler removal is requested. */ + void (*destroy)(struct event_handler *self); +}; + +enum process_state { + STATE_ATTACHED = 0, + STATE_BEING_CREATED, + STATE_IGNORED /* ignore this process (it's a fork and no -f was used) */ +}; + +struct output_state { + size_t params_left; + int need_delim; +}; + +struct callstack_element { + union { + int syscall; + struct library_symbol * libfunc; + } c_un; + int is_syscall; + void * return_addr; + struct timeval time_spent; + struct fetch_context *fetch_context; + struct value_dict *arguments; + struct output_state out; +}; + +/* XXX We should get rid of this. */ +#define MAX_CALLDEPTH 64 + +/* XXX We would rather have this all organized a little differently, + * have Process for the whole group and Task for what's there for + * per-thread stuff. But for now this is the less invasive way of + * structuring it. */ +typedef struct Process Process; +struct Process { + enum process_state state; + Process * parent; /* needed by STATE_BEING_CREATED */ + char * filename; + pid_t pid; + + /* Dictionary of breakpoints (which is a mapping + * address->breakpoint). This is NULL for non-leader + * processes. XXX note that we store addresses (keys) by + * value. That assumes that arch_addr_t fits in host + * pointer. */ + Dict * breakpoints; + + int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */ + unsigned int personality; + int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */ + + size_t callstack_depth; + struct callstack_element callstack[MAX_CALLDEPTH]; + + /* Linked list of libraries in backwards order of mapping. + * The last element is the executed binary itself. */ + struct library *libraries; + + /* Arch-dependent: */ + void * instruction_pointer; + void * stack_pointer; /* To get return addr, args... */ + void * return_addr; + void * arch_ptr; + + /* XXX We would like to replace this with a pointer to ABI + * object that would provide the relevant services, instead of + * checking the necessary flags in the back end ad + * nauseam. */ + short e_machine; + char e_class; + + /* XXX this shoudl go to ARM's arch_process_data. */ +#ifdef __arm__ + int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */ +#endif + +#if defined(HAVE_LIBUNWIND) + /* libunwind address space */ + unw_addr_space_t unwind_as; + void *unwind_priv; +#endif /* defined(HAVE_LIBUNWIND) */ + + /* Set in leader. */ + struct event_handler *event_handler; + + /** + * Process chaining. + **/ + Process * next; + + /* LEADER points to the leader thread of the POSIX.1 process. + If X->LEADER == X, then X is the leader thread and the + Process structures chained by NEXT represent other threads, + up until, but not including, the next leader thread. + LEADER may be NULL after the leader has already exited. In + that case this process is waiting to be collected. */ + Process * leader; + + struct os_process_data os; + struct arch_process_data arch; +}; + +/* Initialize a process given a path to binary FILENAME, with a PID, + * and add the process to an internal chain of traced processes. */ +int process_init(struct Process *proc, const char *filename, pid_t pid); + +/* PROC underwent an exec. This is a bit like process_destroy + * followed by process_init, except that some state is kept and the + * process doesn't lose it's place in the list of processes. */ +int process_exec(struct Process *proc); + +/* Release any memory allocated for PROC (but not PROC itself). Does + * NOT remove PROC from internal chain. + * + * XXX clearly this init/destroy pair is different than others and + * should be fixed. process_init should presumably be separate from + * process_add. */ +void process_destroy(struct Process *proc); + +struct Process *open_program(const char *filename, pid_t pid); +void open_pid(pid_t pid); +Process * pid2proc(pid_t pid); + +/* Clone the contents of PROC into the memory referenced by RETP. + * Returns 0 on success or a negative value on failure. */ +int process_clone(struct Process *retp, struct Process *proc, pid_t pid); + +/* Iterate through the processes that ltrace currently traces. Tasks + * are considered to be processes for the purpose of this iterator. + * See callback.h for notes on iteration interfaces. */ +Process *each_process(Process *start_after, + enum callback_status (*cb)(struct Process *proc, + void *data), + void *data); + +/* Iterate through list of tasks of given process PROC. See + * callback.h for notes on iteration interfaces. */ +Process *each_task(struct Process *proc, struct Process *start_after, + enum callback_status (*cb)(struct Process *proc, + void *data), + void *data); + +void change_process_leader(Process *proc, Process *leader); + +/* Remove process from the list of traced processes, drop any events + * in the event queue, destroy it and free memory. */ +void remove_process(struct Process *proc); + +void install_event_handler(Process *proc, struct event_handler *handler); +void destroy_event_handler(Process *proc); + +/* Add a library LIB to the list of PROC's libraries. */ +void proc_add_library(struct Process *proc, struct library *lib); + +/* Remove LIB from list of PROC's libraries. Returns 0 if the library + * was found and unlinked, otherwise returns a negative value. */ +int proc_remove_library(struct Process *proc, struct library *lib); + +/* Clear a delayed flag. If a symbol is neither latent, nor delayed, + * a breakpoint is inserted for it. Returns 0 if the activation was + * successful or a negative value if it failed. Note that if a symbol + * is both latent and delayed, this will not enable the corresponding + * breakpoint. */ +int proc_activate_delayed_symbol(struct Process *proc, + struct library_symbol *libsym); + +/* Iterate through the libraries of PROC. See callback.h for notes on + * iteration interfaces. */ +struct library *proc_each_library(struct Process *proc, struct library *start, + enum callback_status (*cb)(struct Process *p, + struct library *l, + void *data), + void *data); + +/* Insert BP into PROC. */ +int proc_add_breakpoint(struct Process *proc, struct breakpoint *bp); + +/* Remove BP from PROC. This has no reason to fail in runtime. If it + * does not find BP in PROC, it's hard error guarded by assertion. */ +void proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp); + +/* Iterate through the breakpoints of PROC. See callback.h for notes + * on iteration interfaces. */ +void *proc_each_breakpoint(struct Process *proc, void *start, + enum callback_status (*cb)(struct Process *proc, + struct breakpoint *bp, + void *data), + void *data); + +/* Iterate through the dynamic section at src_addr looking for D_TAG. + * If tag is found, fill it's value in RET and return 0. + * If tag is not found, return a negative value. */ +int proc_find_dynamic_entry_addr(struct Process *proc, arch_addr_t src_addr, + int d_tag, arch_addr_t *ret); + +/* Finds a symbol corresponding to LIBSYM in a process PROC. Returns + * 0 and sets *RETLIB and *RETSYM if the corresponding pointer is + * non-NULL. Returns a negative value when the symbols couldn't be + * found. */ +int proc_find_symbol(struct Process *proc, struct library_symbol *sym, + struct library **retlib, struct library_symbol **retsym); + +/* Iterate through all symbols in all libraries of PROC. See + * callback.h for notes on this interface. */ +struct library_symbol *proc_each_symbol + (struct Process *proc, struct library_symbol *start_after, + enum callback_status (*cb)(struct library_symbol *, void *), + void *data); + +#endif /* _PROC_H_ */ diff --git a/read_config_file.c b/read_config_file.c index b4b1b56..e247436 100644 --- a/read_config_file.c +++ b/read_config_file.c @@ -1,95 +1,108 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1998,1999,2003,2007,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2006 Steve Fink + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <string.h> #include <stdlib.h> #include <ctype.h> +#include <errno.h> +#include <error.h> +#include <assert.h> #include "common.h" +#include "output.h" +#include "expr.h" +#include "param.h" +#include "printf.h" +#include "zero.h" +#include "type.h" +#include "lens.h" +#include "lens_default.h" +#include "lens_enum.h" static int line_no; static char *filename; -static int error_count = 0; - -static arg_type_info *parse_type(char **str); +struct typedef_node_t; + +static struct arg_type_info *parse_nonpointer_type(char **str, + struct param **extra_param, + size_t param_num, int *ownp, + struct typedef_node_t *td); +static struct arg_type_info *parse_type(char **str, struct param **extra_param, + size_t param_num, int *ownp, + struct typedef_node_t *in_typedef); +static struct arg_type_info *parse_lens(char **str, struct param **extra_param, + size_t param_num, int *ownp, + struct typedef_node_t *in_typedef); +static int parse_enum(char **str, struct arg_type_info **retp, int *ownp); Function *list_of_functions = NULL; -/* Map of strings to type names. These do not need to be in any - * particular order */ -static struct list_of_pt_t { - char *name; - enum arg_type pt; -} list_of_pt[] = { - { - "void", ARGTYPE_VOID}, { - "int", ARGTYPE_INT}, { - "uint", ARGTYPE_UINT}, { - "long", ARGTYPE_LONG}, { - "ulong", ARGTYPE_ULONG}, { - "octal", ARGTYPE_OCTAL}, { - "char", ARGTYPE_CHAR}, { - "short", ARGTYPE_SHORT}, { - "ushort", ARGTYPE_USHORT}, { - "float", ARGTYPE_FLOAT}, { - "double", ARGTYPE_DOUBLE}, { - "addr", ARGTYPE_ADDR}, { - "file", ARGTYPE_FILE}, { - "format", ARGTYPE_FORMAT}, { - "string", ARGTYPE_STRING}, { - "array", ARGTYPE_ARRAY}, { - "struct", ARGTYPE_STRUCT}, { - "enum", ARGTYPE_ENUM}, { - NULL, ARGTYPE_UNKNOWN} /* Must finish with NULL */ -}; - -/* Array of prototype objects for each of the types. The order in this - * array must exactly match the list of enumerated values in - * common.h */ -static arg_type_info arg_type_prototypes[] = { - { ARGTYPE_VOID }, - { ARGTYPE_INT }, - { ARGTYPE_UINT }, - { ARGTYPE_LONG }, - { ARGTYPE_ULONG }, - { ARGTYPE_OCTAL }, - { ARGTYPE_CHAR }, - { ARGTYPE_SHORT }, - { ARGTYPE_USHORT }, - { ARGTYPE_FLOAT }, - { ARGTYPE_DOUBLE }, - { ARGTYPE_ADDR }, - { ARGTYPE_FILE }, - { ARGTYPE_FORMAT }, - { ARGTYPE_STRING }, - { ARGTYPE_STRING_N }, - { ARGTYPE_ARRAY }, - { ARGTYPE_ENUM }, - { ARGTYPE_STRUCT }, - { ARGTYPE_POINTER }, - { ARGTYPE_UNKNOWN } -}; - -arg_type_info * -lookup_prototype(enum arg_type at) { - if (at >= 0 && at <= ARGTYPE_COUNT) - return &arg_type_prototypes[at]; - else - return &arg_type_prototypes[ARGTYPE_COUNT]; /* UNKNOWN */ -} - -static arg_type_info * -str2type(char **str) { - struct list_of_pt_t *tmp = &list_of_pt[0]; - - while (tmp->name) { - if (!strncmp(*str, tmp->name, strlen(tmp->name)) - && index(" ,()#*;012345[", *(*str + strlen(tmp->name)))) { - *str += strlen(tmp->name); - return lookup_prototype(tmp->pt); - } - tmp++; - } - return lookup_prototype(ARGTYPE_UNKNOWN); +static int +parse_arg_type(char **name, enum arg_type *ret) +{ + char *rest = NULL; + enum arg_type candidate; + +#define KEYWORD(KWD, TYPE) \ + do { \ + if (strncmp(*name, KWD, sizeof(KWD) - 1) == 0) { \ + rest = *name + sizeof(KWD) - 1; \ + candidate = TYPE; \ + goto ok; \ + } \ + } while (0) + + KEYWORD("void", ARGTYPE_VOID); + KEYWORD("int", ARGTYPE_INT); + KEYWORD("uint", ARGTYPE_UINT); + KEYWORD("long", ARGTYPE_LONG); + KEYWORD("ulong", ARGTYPE_ULONG); + KEYWORD("char", ARGTYPE_CHAR); + KEYWORD("short", ARGTYPE_SHORT); + KEYWORD("ushort", ARGTYPE_USHORT); + KEYWORD("float", ARGTYPE_FLOAT); + KEYWORD("double", ARGTYPE_DOUBLE); + KEYWORD("array", ARGTYPE_ARRAY); + KEYWORD("struct", ARGTYPE_STRUCT); + + /* Misspelling of int used in ltrace.conf that we used to + * ship. */ + KEYWORD("itn", ARGTYPE_INT); + + assert(rest == NULL); + return -1; + +#undef KEYWORD + +ok: + if (isalnum(*rest)) + return -1; + + *name = rest; + *ret = candidate; + return 0; } static void @@ -102,6 +115,10 @@ eat_spaces(char **str) { static char * xstrndup(char *str, size_t len) { char *ret = (char *) malloc(len + 1); + if (ret == NULL) { + report_global_error("malloc: %s", strerror(errno)); + return NULL; + } strncpy(ret, str, len); ret[len] = 0; return ret; @@ -111,10 +128,8 @@ static char * parse_ident(char **str) { char *ident = *str; - if (!isalnum(**str) && **str != '_') { - output_line(0, "Syntax error in `%s', line %d: Bad identifier", - filename, line_no); - error_count++; + if (!isalpha(**str) && **str != '_') { + report_error(filename, line_no, "bad identifier"); return NULL; } @@ -158,473 +173,1023 @@ start_of_arg_sig(char *str) { } static int -parse_int(char **str) { +parse_int(char **str, long *ret) +{ char *end; long n = strtol(*str, &end, 0); if (end == *str) { - output_line(0, "Syntax error in `%s', line %d: Bad number (%s)", - filename, line_no, *str); - error_count++; - return 0; + report_error(filename, line_no, "bad number"); + return -1; } *str = end; - return n; + if (ret != NULL) + *ret = n; + return 0; +} + +static int +check_nonnegative(long l) +{ + if (l < 0) { + report_error(filename, line_no, + "expected non-negative value, got %ld", l); + return -1; + } + return 0; +} + +static int +check_int(long l) +{ + int i = l; + if ((long)i != l) { + report_error(filename, line_no, + "Number too large: %ld", l); + return -1; + } + return 0; +} + +static int +parse_char(char **str, char expected) +{ + if (**str != expected) { + report_error(filename, line_no, + "expected '%c', got '%c'", expected, **str); + return -1; + } + + ++*str; + return 0; +} + +static struct expr_node *parse_argnum(char **str, int *ownp, int zero); + +static struct expr_node * +parse_zero(char **str, struct expr_node *ret, int *ownp) +{ + eat_spaces(str); + if (**str == '(') { + ++*str; + int own; + struct expr_node *arg = parse_argnum(str, &own, 0); + if (arg == NULL) + return NULL; + if (parse_char(str, ')') < 0) { + fail: + expr_destroy(arg); + free(arg); + return NULL; + } + + struct expr_node *ret = build_zero_w_arg(arg, own); + if (ret == NULL) + goto fail; + *ownp = 1; + return ret; + + } else { + free(ret); + *ownp = 0; + return expr_node_zero(); + } +} + +static int +wrap_in_zero(struct expr_node **nodep) +{ + struct expr_node *n = build_zero_w_arg(*nodep, 1); + if (n == NULL) + return -1; + *nodep = n; + return 0; } /* * Input: - * argN : The value of argument #N, counting from 1 (arg0 = retval) + * argN : The value of argument #N, counting from 1 * eltN : The value of element #N of the containing structure * retval : The return value - * 0 : Error - * N : The numeric value N, if N > 0 - * - * Output: - * > 0 actual numeric value - * = 0 return value - * < 0 (arg -n), counting from one + * N : The numeric value N */ -static int -parse_argnum(char **str) { - int multiplier = 1; - int n = 0; - - if (strncmp(*str, "arg", 3) == 0) { - (*str) += 3; - multiplier = -1; - } else if (strncmp(*str, "elt", 3) == 0) { - (*str) += 3; - multiplier = -1; - } else if (strncmp(*str, "retval", 6) == 0) { - (*str) += 6; - return 0; - } +static struct expr_node * +parse_argnum(char **str, int *ownp, int zero) +{ + struct expr_node *expr = malloc(sizeof(*expr)); + if (expr == NULL) + return NULL; + + if (isdigit(**str)) { + long l; + if (parse_int(str, &l) < 0 + || check_nonnegative(l) < 0 + || check_int(l) < 0) + goto fail; + + expr_init_const_word(expr, l, type_get_simple(ARGTYPE_LONG), 0); + + if (zero && wrap_in_zero(&expr) < 0) + goto fail; + + *ownp = 1; + return expr; + + } else { + char *const name = parse_ident(str); + if (name == NULL) { + fail_ident: + free(name); + goto fail; + } + + int is_arg = strncmp(name, "arg", 3) == 0; + if (is_arg || strncmp(name, "elt", 3) == 0) { + long l; + char *num = name + 3; + if (parse_int(&num, &l) < 0 || check_int(l) < 0) + goto fail_ident; + + if (is_arg) { + if (l == 0) + expr_init_named(expr, "retval", 0); + else + expr_init_argno(expr, l - 1); + } else { + struct expr_node *e_up = malloc(sizeof(*e_up)); + struct expr_node *e_ix = malloc(sizeof(*e_ix)); + if (e_up == NULL || e_ix == NULL) { + free(e_up); + free(e_ix); + goto fail_ident; + } + + expr_init_up(e_up, expr_self(), 0); + struct arg_type_info *ti + = type_get_simple(ARGTYPE_LONG); + expr_init_const_word(e_ix, l - 1, ti, 0); + expr_init_index(expr, e_up, 1, e_ix, 1); + } + + } else if (strcmp(name, "retval") == 0) { + expr_init_named(expr, "retval", 0); + + } else if (strcmp(name, "zero") == 0) { + struct expr_node *ret = parse_zero(str, expr, ownp); + if (ret == NULL) + goto fail_ident; + return ret; - n = parse_int(str); + } else { + report_error(filename, line_no, + "Unknown length specifier: '%s'", name); + goto fail_ident; + } + + if (zero && wrap_in_zero(&expr) < 0) + goto fail_ident; + + free(name); + *ownp = 1; + return expr; + } - return n * multiplier; +fail: + free(expr); + return NULL; } struct typedef_node_t { char *name; - arg_type_info *info; + struct arg_type_info *info; + int own_type; + int forward : 1; struct typedef_node_t *next; } *typedefs = NULL; -static arg_type_info * -lookup_typedef(char **str) { +static struct typedef_node_t * +lookup_typedef(const char *name) +{ struct typedef_node_t *node; + for (node = typedefs; node != NULL; node = node->next) + if (strcmp(name, node->name) == 0) + return node; + return NULL; +} + +static struct arg_type_info * +parse_typedef_name(char **str) +{ char *end = *str; while (*end && (isalnum(*end) || *end == '_')) ++end; if (end == *str) return NULL; - for (node = typedefs; node != NULL; node = node->next) { - if (strncmp(*str, node->name, end - *str) == 0) { - (*str) += strlen(node->name); - return node->info; - } - } + size_t len = end - *str; + char buf[len + 1]; + memcpy(buf, *str, len); + *str += len; + buf[len] = 0; - return NULL; + struct typedef_node_t *td = lookup_typedef(buf); + if (td == NULL) + return NULL; + return td->info; } static void -parse_typedef(char **str) { - char *name; - arg_type_info *info; - struct typedef_node_t *binding; +insert_typedef(struct typedef_node_t *td) +{ + if (td == NULL) + return; + td->next = typedefs; + typedefs = td; +} + +static struct typedef_node_t * +new_typedef(char *name, struct arg_type_info *info, int own_type) +{ + struct typedef_node_t *binding = malloc(sizeof(*binding)); + binding->name = name; + binding->info = info; + binding->own_type = own_type; + binding->forward = 0; + binding->next = NULL; + return binding; +} +static void +parse_typedef(char **str) +{ (*str) += strlen("typedef"); eat_spaces(str); - - // Grab out the name of the type - name = parse_ident(str); + char *name = parse_ident(str); + + /* Look through the typedef list whether we already have a + * forward of this type. If we do, it must be forward + * structure. */ + struct typedef_node_t *forward = lookup_typedef(name); + if (forward != NULL + && (forward->info->type != ARGTYPE_STRUCT + || !forward->forward)) { + report_error(filename, line_no, + "Redefinition of typedef '%s'", name); + free(name); + return; + } // Skip = sign eat_spaces(str); - if (**str != '=') { - output_line(0, - "Syntax error in `%s', line %d: expected '=', got '%c'", - filename, line_no, **str); - error_count++; + if (parse_char(str, '=') < 0) { + free(name); return; } - (*str)++; eat_spaces(str); - // Parse the type - info = parse_type(str); + struct typedef_node_t *this_td = new_typedef(name, NULL, 0); + this_td->info = parse_lens(str, NULL, 0, &this_td->own_type, this_td); - // Insert onto beginning of linked list - binding = malloc(sizeof(*binding)); - binding->name = name; - binding->info = info; - binding->next = typedefs; - typedefs = binding; -} - -static size_t -arg_sizeof(arg_type_info * arg) { - if (arg->type == ARGTYPE_CHAR) { - return sizeof(char); - } else if (arg->type == ARGTYPE_SHORT || arg->type == ARGTYPE_USHORT) { - return sizeof(short); - } else if (arg->type == ARGTYPE_FLOAT) { - return sizeof(float); - } else if (arg->type == ARGTYPE_DOUBLE) { - return sizeof(double); - } else if (arg->type == ARGTYPE_ENUM) { - return sizeof(int); - } else if (arg->type == ARGTYPE_STRUCT) { - return arg->u.struct_info.size; - } else if (arg->type == ARGTYPE_POINTER) { - return sizeof(void*); - } else if (arg->type == ARGTYPE_ARRAY) { - if (arg->u.array_info.len_spec > 0) - return arg->u.array_info.len_spec * arg->u.array_info.elt_size; + if (this_td->info == NULL) { + free(this_td); + free(name); + return; + } + + if (forward == NULL) { + insert_typedef(this_td); + return; + } + + /* If we are defining a forward, make sure the definition is a + * structure as well. */ + if (this_td->info->type != ARGTYPE_STRUCT) { + report_error(filename, line_no, + "Definition of forward '%s' must be a structure.", + name); + if (this_td->own_type) { + type_destroy(this_td->info); + free(this_td->info); + } + free(this_td); + free(name); + return; + } + + /* Now move guts of the actual type over to the + * forward type. We can't just move pointers around, + * because references to forward must stay intact. */ + assert(this_td->own_type); + type_destroy(forward->info); + *forward->info = *this_td->info; + forward->forward = 0; + free(this_td->info); + free(name); + free(this_td); +} + +static void +destroy_fun(Function *fun) +{ + size_t i; + if (fun == NULL) + return; + if (fun->own_return_info) { + type_destroy(fun->return_info); + free(fun->return_info); + } + for (i = 0; i < fun->num_params; ++i) + param_destroy(&fun->params[i]); + free(fun->params); +} + +/* Syntax: struct ( type,type,type,... ) */ +static int +parse_struct(char **str, struct arg_type_info *info, + struct typedef_node_t *in_typedef) +{ + eat_spaces(str); + + if (**str == ';') { + if (in_typedef == NULL) { + report_error(filename, line_no, + "Forward struct can be declared only " + "directly after a typedef."); + return -1; + } + + /* Forward declaration is currently handled as an + * empty struct. */ + type_init_struct(info); + in_typedef->forward = 1; + return 0; + } + + if (parse_char(str, '(') < 0) + return -1; + + eat_spaces(str); // Empty arg list with whitespace inside + + type_init_struct(info); + + while (1) { + eat_spaces(str); + if (**str == 0 || **str == ')') { + parse_char(str, ')'); + return 0; + } + + /* Field delimiter. */ + if (type_struct_size(info) > 0) + parse_char(str, ','); + + eat_spaces(str); + int own; + struct arg_type_info *field = parse_lens(str, NULL, 0, &own, + NULL); + if (field == NULL || type_struct_add(info, field, own)) { + type_destroy(info); + return -1; + } + } +} + +static int +parse_string(char **str, struct arg_type_info **retp, int *ownp) +{ + struct arg_type_info *info = malloc(sizeof(*info) * 2); + if (info == NULL) { + fail: + free(info); + return -1; + } + + struct expr_node *length; + int own_length; + int with_arg = 0; + + if (isdigit(**str)) { + /* string0 is string[retval], length is zero(retval) + * stringN is string[argN], length is zero(argN) */ + long l; + if (parse_int(str, &l) < 0 + || check_int(l) < 0) + goto fail; + + struct expr_node *length_arg = malloc(sizeof(*length_arg)); + if (length_arg == NULL) + goto fail; + + if (l == 0) + expr_init_named(length_arg, "retval", 0); else - return sizeof(void *); + expr_init_argno(length_arg, l - 1); + + length = build_zero_w_arg(length_arg, 1); + if (length == NULL) { + expr_destroy(length_arg); + free(length_arg); + goto fail; + } + own_length = 1; + } else { - return sizeof(int); - } -} - -#undef alignof -#define alignof(field,st) ((size_t) ((char*) &st.field - (char*) &st)) -static size_t -arg_align(arg_type_info * arg) { - struct { char c; char C; } cC; - struct { char c; short s; } cs; - struct { char c; int i; } ci; - struct { char c; long l; } cl; - struct { char c; void* p; } cp; - struct { char c; float f; } cf; - struct { char c; double d; } cd; - - static size_t char_alignment = alignof(C, cC); - static size_t short_alignment = alignof(s, cs); - static size_t int_alignment = alignof(i, ci); - static size_t long_alignment = alignof(l, cl); - static size_t ptr_alignment = alignof(p, cp); - static size_t float_alignment = alignof(f, cf); - static size_t double_alignment = alignof(d, cd); - - switch (arg->type) { - case ARGTYPE_LONG: - case ARGTYPE_ULONG: - return long_alignment; - case ARGTYPE_CHAR: - return char_alignment; - case ARGTYPE_SHORT: - case ARGTYPE_USHORT: - return short_alignment; - case ARGTYPE_FLOAT: - return float_alignment; - case ARGTYPE_DOUBLE: - return double_alignment; - case ARGTYPE_ADDR: - case ARGTYPE_FILE: - case ARGTYPE_FORMAT: - case ARGTYPE_STRING: - case ARGTYPE_STRING_N: - case ARGTYPE_POINTER: - return ptr_alignment; - - case ARGTYPE_ARRAY: - return arg_align(&arg->u.array_info.elt_type[0]); - - case ARGTYPE_STRUCT: - return arg_align(arg->u.struct_info.fields[0]); - - default: - return int_alignment; - } -} - -static size_t -align_skip(size_t alignment, size_t offset) { - if (offset % alignment) - return alignment - (offset % alignment); - else - return 0; + eat_spaces(str); + if (**str == '[') { + (*str)++; + eat_spaces(str); + + length = parse_argnum(str, &own_length, 1); + if (length == NULL) + goto fail; + + eat_spaces(str); + parse_char(str, ']'); + + } else if (**str == '(') { + /* Usage of "string" as lens. */ + ++*str; + + free(info); + + eat_spaces(str); + info = parse_type(str, NULL, 0, ownp, NULL); + if (info == NULL) + goto fail; + + eat_spaces(str); + parse_char(str, ')'); + + with_arg = 1; + + } else { + /* It was just a simple string after all. */ + length = expr_node_zero(); + own_length = 0; + } + } + + /* String is a pointer to array of chars. */ + if (!with_arg) { + type_init_array(&info[1], type_get_simple(ARGTYPE_CHAR), 0, + length, own_length); + + type_init_pointer(&info[0], &info[1], 0); + *ownp = 1; + } + + info->lens = &string_lens; + info->own_lens = 0; + + *retp = info; + return 0; } -/* I'm sure this isn't completely correct, but just try to get most of - * them right for now. */ -static void -align_struct(arg_type_info* info) { - size_t offset; - int i; +static int +build_printf_pack(struct param **packp, size_t param_num) +{ + if (packp == NULL) { + report_error(filename, line_no, + "'format' type in unexpected context"); + return -1; + } + if (*packp != NULL) { + report_error(filename, line_no, + "only one 'format' type per function supported"); + return -1; + } - if (info->u.struct_info.size != 0) - return; // Already done + *packp = malloc(sizeof(**packp)); + if (*packp == NULL) + return -1; - // Compute internal padding due to alignment constraints for - // various types. - offset = 0; - for (i = 0; info->u.struct_info.fields[i] != NULL; i++) { - arg_type_info *field = info->u.struct_info.fields[i]; - offset += align_skip(arg_align(field), offset); - info->u.struct_info.offset[i] = offset; - offset += arg_sizeof(field); + struct expr_node *node = malloc(sizeof(*node)); + if (node == NULL) { + free(*packp); + return -1; } - info->u.struct_info.size = offset; + expr_init_argno(node, param_num); + + param_pack_init_printf(*packp, node, 1); + + return 0; +} + +/* Match and consume KWD if it's next in stream, and return 0. + * Otherwise return negative number. */ +static int +try_parse_kwd(char **str, const char *kwd) +{ + size_t len = strlen(kwd); + if (strncmp(*str, kwd, len) == 0 + && !isalnum((*str)[len])) { + (*str) += len; + return 0; + } + return -1; } -static arg_type_info * -parse_nonpointer_type(char **str) { - arg_type_info *simple; - arg_type_info *info; +/* Make a copy of INFO and set the *OWN bit if it's not already + * owned. */ +static int +unshare_type_info(struct arg_type_info **infop, int *ownp) +{ + if (*ownp) + return 0; - if (strncmp(*str, "typedef", 7) == 0) { - parse_typedef(str); - return lookup_prototype(ARGTYPE_UNKNOWN); + struct arg_type_info *ninfo = malloc(sizeof(*ninfo)); + if (ninfo == NULL) { + report_error(filename, line_no, + "malloc: %s", strerror(errno)); + return -1; } + *ninfo = **infop; + *infop = ninfo; + *ownp = 1; + return 0; +} - simple = str2type(str); - if (simple->type == ARGTYPE_UNKNOWN) { - info = lookup_typedef(str); - if (info) - return info; - else - return simple; // UNKNOWN +/* XXX extra_param and param_num are a kludge to get in + * backward-compatible support for "format" parameter type. The + * latter is only valid if the former is non-NULL, which is only in + * top-level context. */ +static int +parse_alias(char **str, struct arg_type_info **retp, int *ownp, + struct param **extra_param, size_t param_num) +{ + /* For backward compatibility, we need to support things like + * stringN (which is like string[argN], string[N], and also + * bare string. We might, in theory, replace this by + * preprocessing configure file sources with M4, but for now, + * "string" is syntax. */ + if (strncmp(*str, "string", 6) == 0) { + (*str) += 6; + return parse_string(str, retp, ownp); + + } else if (try_parse_kwd(str, "format") >= 0 + && extra_param != NULL) { + /* For backward compatibility, format is parsed as + * "string", but it smuggles to the parameter list of + * a function a "printf" argument pack with this + * parameter as argument. */ + if (parse_string(str, retp, ownp) < 0) + return -1; + + return build_printf_pack(extra_param, param_num); + + } else if (try_parse_kwd(str, "enum") >=0) { + + return parse_enum(str, retp, ownp); + + } else { + *retp = NULL; + return 0; } +} + +/* Syntax: array ( type, N|argN ) */ +static int +parse_array(char **str, struct arg_type_info *info) +{ + eat_spaces(str); + if (parse_char(str, '(') < 0) + return -1; + + eat_spaces(str); + int own; + struct arg_type_info *elt_info = parse_lens(str, NULL, 0, &own, NULL); + if (elt_info == NULL) + return -1; - info = malloc(sizeof(*info)); - info->type = simple->type; + eat_spaces(str); + parse_char(str, ','); - /* Code to parse parameterized types will go into the following - switch statement. */ + eat_spaces(str); + int own_length; + struct expr_node *length = parse_argnum(str, &own_length, 0); + if (length == NULL) { + if (own) { + type_destroy(elt_info); + free(elt_info); + } + return -1; + } - switch (info->type) { + type_init_array(info, elt_info, own, length, own_length); - /* Syntax: array ( type, N|argN ) */ - case ARGTYPE_ARRAY: - (*str)++; // Get past open paren - eat_spaces(str); - if ((info->u.array_info.elt_type = parse_type(str)) == NULL) - return NULL; - info->u.array_info.elt_size = - arg_sizeof(info->u.array_info.elt_type); - (*str)++; // Get past comma + eat_spaces(str); + parse_char(str, ')'); + return 0; +} + +/* Syntax: + * enum (keyname[=value],keyname[=value],... ) + * enum<type> (keyname[=value],keyname[=value],... ) + */ +static int +parse_enum(char **str, struct arg_type_info **retp, int *ownp) +{ + /* Optional type argument. */ + eat_spaces(str); + if (**str == '[') { + parse_char(str, '['); eat_spaces(str); - info->u.array_info.len_spec = parse_argnum(str); - (*str)++; // Get past close paren - return info; - - /* Syntax: enum ( keyname=value,keyname=value,... ) */ - case ARGTYPE_ENUM:{ - struct enum_opt { - char *key; - int value; - struct enum_opt *next; - }; - struct enum_opt *list = NULL; - struct enum_opt *p; - int entries = 0; - int ii; + *retp = parse_nonpointer_type(str, NULL, 0, ownp, 0); + if (*retp == NULL) + return -1; + + if (!type_is_integral((*retp)->type)) { + report_error(filename, line_no, + "integral type required as enum argument"); + fail: + if (*ownp) { + /* This also releases associated lens + * if any was set so far. */ + type_destroy(*retp); + free(*retp); + } + return -1; + } eat_spaces(str); - (*str)++; // Get past open paren + if (parse_char(str, ']') < 0) + goto fail; + + } else { + *retp = type_get_simple(ARGTYPE_INT); + *ownp = 0; + } + + /* We'll need to set the lens, so unshare. */ + if (unshare_type_info(retp, ownp) < 0) + goto fail; + + eat_spaces(str); + if (parse_char(str, '(') < 0) + goto fail; + + struct enum_lens *lens = malloc(sizeof(*lens)); + if (lens == NULL) { + report_error(filename, line_no, + "malloc enum lens: %s", strerror(errno)); + return -1; + } + + lens_init_enum(lens); + (*retp)->lens = &lens->super; + (*retp)->own_lens = 1; + + long last_val = 0; + while (1) { eat_spaces(str); + if (**str == 0 || **str == ')') { + parse_char(str, ')'); + return 0; + } - while (**str && **str != ')') { - p = (struct enum_opt *) malloc(sizeof(*p)); - eat_spaces(str); - p->key = parse_ident(str); - if (error_count) { - free(p); - return NULL; - } - eat_spaces(str); - if (**str != '=') { - free(p->key); - free(p); - output_line(0, - "Syntax error in `%s', line %d: expected '=', got '%c'", - filename, line_no, **str); - error_count++; - return NULL; - } - ++(*str); - eat_spaces(str); - p->value = parse_int(str); - p->next = list; - list = p; - ++entries; + /* Field delimiter. XXX should we support the C + * syntax, where the enumeration can end in pending + * comma? */ + if (lens_enum_size(lens) > 0) + parse_char(str, ','); + + eat_spaces(str); + char *key = parse_ident(str); + if (key == NULL) { + err: + free(key); + goto fail; + } - // Skip comma + if (**str == '=') { + ++*str; eat_spaces(str); - if (**str == ',') { - (*str)++; - eat_spaces(str); - } + if (parse_int(str, &last_val) < 0) + goto err; } - info->u.enum_info.entries = entries; - info->u.enum_info.keys = - (char **) malloc(entries * sizeof(char *)); - info->u.enum_info.values = - (int *) malloc(entries * sizeof(int)); - for (ii = 0, p = NULL; list; ++ii, list = list->next) { - if (p) - free(p); - info->u.enum_info.keys[ii] = list->key; - info->u.enum_info.values[ii] = list->value; - p = list; + struct value *value = malloc(sizeof(*value)); + if (value == NULL) + goto err; + value_init_detached(value, NULL, *retp, 0); + value_set_word(value, last_val); + + if (lens_enum_add(lens, key, 1, value, 1) < 0) + goto err; + + last_val++; + } + + return 0; +} + +static struct arg_type_info * +parse_nonpointer_type(char **str, struct param **extra_param, size_t param_num, + int *ownp, struct typedef_node_t *in_typedef) +{ + enum arg_type type; + if (parse_arg_type(str, &type) < 0) { + struct arg_type_info *simple; + if (parse_alias(str, &simple, ownp, extra_param, param_num) < 0) + return NULL; + if (simple == NULL) + simple = parse_typedef_name(str); + if (simple != NULL) { + *ownp = 0; + return simple; } - if (p) - free(p); - return info; + report_error(filename, line_no, + "unknown type around '%s'", *str); + return NULL; + } + + /* For some types that's all we need. */ + switch (type) { + case ARGTYPE_VOID: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + *ownp = 0; + return type_get_simple(type); + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + break; + + case ARGTYPE_POINTER: + /* Pointer syntax is not based on keyword, so we + * should never get this type. */ + assert(type != ARGTYPE_POINTER); + abort(); } - case ARGTYPE_STRING: - if (!isdigit(**str) && **str != '[') { - /* Oops, was just a simple string after all */ + struct arg_type_info *info = malloc(sizeof(*info)); + if (info == NULL) { + report_error(filename, line_no, + "malloc: %s", strerror(errno)); + return NULL; + } + *ownp = 1; + + if (type == ARGTYPE_ARRAY) { + if (parse_array(str, info) < 0) { + fail: free(info); - return simple; + return NULL; } + } else { + assert(type == ARGTYPE_STRUCT); + if (parse_struct(str, info, in_typedef) < 0) + goto fail; + } + + return info; +} - info->type = ARGTYPE_STRING_N; +static struct named_lens { + const char *name; + struct lens *lens; +} lenses[] = { + { "hide", &blind_lens }, + { "octal", &octal_lens }, + { "oct", &octal_lens }, + { "bitvec", &bitvect_lens }, + { "hex", &hex_lens }, + { "bool", &bool_lens }, + { "guess", &guess_lens }, +}; - /* Backwards compatibility for string0, string1, ... */ - if (isdigit(**str)) { - info->u.string_n_info.size_spec = -parse_int(str); - return info; +static struct lens * +name2lens(char **str, int *own_lensp) +{ + size_t i; + for (i = 0; i < sizeof(lenses)/sizeof(*lenses); ++i) + if (try_parse_kwd(str, lenses[i].name) == 0) { + *own_lensp = 0; + return lenses[i].lens; } - (*str)++; // Skip past opening [ - eat_spaces(str); - info->u.string_n_info.size_spec = parse_argnum(str); + return NULL; +} + +static struct arg_type_info * +parse_type(char **str, struct param **extra_param, size_t param_num, int *ownp, + struct typedef_node_t *in_typedef) +{ + struct arg_type_info *info + = parse_nonpointer_type(str, extra_param, + param_num, ownp, in_typedef); + if (info == NULL) + return NULL; + + while (1) { eat_spaces(str); - (*str)++; // Skip past closing ] - return info; - - // Syntax: struct ( type,type,type,... ) - case ARGTYPE_STRUCT:{ - int field_num = 0; - (*str)++; // Get past open paren - info->u.struct_info.fields = - malloc((MAX_ARGS + 1) * sizeof(void *)); - info->u.struct_info.offset = - malloc((MAX_ARGS + 1) * sizeof(size_t)); - info->u.struct_info.size = 0; - eat_spaces(str); // Empty arg list with whitespace inside - while (**str && **str != ')') { - if (field_num == MAX_ARGS) { - output_line(0, - "Error in `%s', line %d: Too many structure elements", - filename, line_no); - error_count++; + if (**str == '*') { + struct arg_type_info *outer = malloc(sizeof(*outer)); + if (outer == NULL) { + if (*ownp) { + type_destroy(info); + free(info); + } + report_error(filename, line_no, + "malloc: %s", strerror(errno)); return NULL; } - eat_spaces(str); - if (field_num != 0) { - (*str)++; // Get past comma - eat_spaces(str); - } - if ((info->u.struct_info.fields[field_num++] = - parse_type(str)) == NULL) - return NULL; + type_init_pointer(outer, info, *ownp); + *ownp = 1; + (*str)++; + info = outer; + } else + break; + } + return info; +} - // Must trim trailing spaces so the check for - // the closing paren is simple - eat_spaces(str); +static struct arg_type_info * +parse_lens(char **str, struct param **extra_param, size_t param_num, int *ownp, + struct typedef_node_t *in_typedef) +{ + int own_lens; + struct lens *lens = name2lens(str, &own_lens); + int has_args = 1; + struct arg_type_info *info; + if (lens != NULL) { + eat_spaces(str); + + /* Octal lens gets special treatment, because of + * backward compatibility. */ + if (lens == &octal_lens && **str != '(') { + has_args = 0; + info = type_get_simple(ARGTYPE_INT); + *ownp = 0; + } else if (parse_char(str, '(') < 0) { + report_error(filename, line_no, + "expected type argument after the lens"); + return NULL; } - (*str)++; // Get past closing paren - info->u.struct_info.fields[field_num] = NULL; - align_struct(info); - return info; } - default: - if (info->type == ARGTYPE_UNKNOWN) { - output_line(0, "Syntax error in `%s', line %d: " - "Unknown type encountered", - filename, line_no); - free(info); - error_count++; + if (has_args) { + eat_spaces(str); + info = parse_type(str, extra_param, param_num, ownp, + in_typedef); + if (info == NULL) { + fail: + if (own_lens && lens != NULL) + lens_destroy(lens); return NULL; - } else { - return info; } } + + if (lens != NULL && has_args) { + eat_spaces(str); + parse_char(str, ')'); + } + + /* We can't modify shared types. Make a copy if we have a + * lens. */ + if (lens != NULL && unshare_type_info(&info, ownp) < 0) + goto fail; + + if (lens != NULL) { + info->lens = lens; + info->own_lens = own_lens; + } + + return info; } -static arg_type_info * -parse_type(char **str) { - arg_type_info *info = parse_nonpointer_type(str); - while (**str == '*') { - arg_type_info *outer = malloc(sizeof(*info)); - outer->type = ARGTYPE_POINTER; - outer->u.ptr_info.info = info; - (*str)++; - info = outer; +static int +add_param(Function *fun, size_t *allocdp) +{ + size_t allocd = *allocdp; + /* XXX +1 is for the extra_param handling hack. */ + if ((fun->num_params + 1) >= allocd) { + allocd = allocd > 0 ? 2 * allocd : 8; + void *na = realloc(fun->params, sizeof(*fun->params) * allocd); + if (na == NULL) + return -1; + + fun->params = na; + *allocdp = allocd; } + return 0; +} + +static int +param_is_void(struct param *param) +{ + return param->flavor == PARAM_FLAVOR_TYPE + && param->u.type.type->type == ARGTYPE_VOID; +} + +static struct arg_type_info * +get_hidden_int(void) +{ + char *str = strdup("hide(int)"); + char *ptr = str; + assert(str != NULL); + int own; + struct arg_type_info *info = parse_lens(&ptr, NULL, 0, &own, NULL); + assert(info != NULL); + free(str); return info; } static Function * process_line(char *buf) { - Function fun; - Function *fun_p; char *str = buf; char *tmp; - int i; - int float_num = 0; line_no++; debug(3, "Reading line %d of `%s'", line_no, filename); eat_spaces(&str); - fun.return_info = parse_type(&str); - if (fun.return_info == NULL) + + /* A comment or empty line. */ + if (*str == ';' || *str == 0 || *str == '\n') + return NULL; + + if (strncmp(str, "typedef", 7) == 0) { + parse_typedef(&str); + return NULL; + } + + Function *fun = calloc(1, sizeof(*fun)); + if (fun == NULL) { + report_error(filename, line_no, + "alloc function: %s", strerror(errno)); return NULL; - if (fun.return_info->type == ARGTYPE_UNKNOWN) { + } + + fun->return_info = parse_lens(&str, NULL, 0, + &fun->own_return_info, NULL); + if (fun->return_info == NULL) { + err: debug(3, " Skipping line %d", line_no); + destroy_fun(fun); return NULL; } - debug(4, " return_type = %d", fun.return_info->type); + debug(4, " return_type = %d", fun->return_info->type); + eat_spaces(&str); tmp = start_of_arg_sig(str); - if (!tmp) { - output_line(0, "Syntax error in `%s', line %d", filename, - line_no); - error_count++; - return NULL; + if (tmp == NULL) { + report_error(filename, line_no, "syntax error"); + goto err; } *tmp = '\0'; - fun.name = strdup(str); + fun->name = strdup(str); str = tmp + 1; - debug(3, " name = %s", fun.name); - fun.params_right = 0; - for (i = 0; i < MAX_ARGS; i++) { + debug(3, " name = %s", fun->name); + + size_t allocd = 0; + struct param *extra_param = NULL; + + int have_stop = 0; + + while (1) { eat_spaces(&str); - if (*str == ')') { + if (*str == ')') break; - } + if (str[0] == '+') { - fun.params_right++; + if (have_stop == 0) { + if (add_param(fun, &allocd) < 0) + goto add_err; + param_init_stop + (&fun->params[fun->num_params++]); + have_stop = 1; + } str++; - } else if (fun.params_right) { - fun.params_right++; } - fun.arg_info[i] = parse_type(&str); - if (fun.arg_info[i] == NULL) { - output_line(0, "Syntax error in `%s', line %d" - ": unknown argument type", - filename, line_no); - error_count++; - return NULL; + + if (add_param(fun, &allocd) < 0) { + add_err: + report_error(filename, line_no, "(re)alloc params: %s", + strerror(errno)); + goto err; + } + + int own; + struct arg_type_info *type + = parse_lens(&str, &extra_param, + fun->num_params - have_stop, &own, NULL); + if (type == NULL) { + report_error(filename, line_no, + "unknown argument type"); + goto err; } - if (fun.arg_info[i]->type == ARGTYPE_FLOAT) - fun.arg_info[i]->u.float_info.float_index = float_num++; - else if (fun.arg_info[i]->type == ARGTYPE_DOUBLE) - fun.arg_info[i]->u.double_info.float_index = float_num++; + + param_init_type(&fun->params[fun->num_params++], type, own); + eat_spaces(&str); if (*str == ',') { str++; @@ -634,20 +1199,75 @@ process_line(char *buf) { } else { if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0'; - output_line(0, "Syntax error in `%s', line %d at ...\"%s\"", - filename, line_no, str); - error_count++; - return NULL; + report_error(filename, line_no, + "syntax error around \"%s\"", str); + goto err; } } - fun.num_params = i; - fun_p = malloc(sizeof(Function)); - if (!fun_p) { - perror("ltrace: malloc"); - exit(1); + + /* We used to allow void parameter as a synonym to an argument + * that shouldn't be displayed. But backends really need to + * know the exact type that they are dealing with. The proper + * way to do this these days is to use the hide lens. + * + * So if there are any voids in the parameter list, show a + * warning and assume that they are ints. If there's a sole + * void, assume the function doesn't take any arguments. The + * latter is conservative, we can drop the argument + * altogether, instead of fetching and then not showing it, + * without breaking any observable behavior. */ + if (fun->num_params == 1 && param_is_void(&fun->params[0])) { + if (0) + /* Don't show this warning. Pre-0.7.0 + * ltrace.conf often used this idiom. This + * should be postponed until much later, when + * extant uses are likely gone. */ + report_warning(filename, line_no, + "sole void parameter ignored"); + param_destroy(&fun->params[0]); + fun->num_params = 0; + } else { + size_t i; + for (i = 0; i < fun->num_params; ++i) { + if (param_is_void(&fun->params[i])) { + report_warning + (filename, line_no, + "void parameter assumed to be " + "'hide(int)'"); + + static struct arg_type_info *type = NULL; + if (type == NULL) + type = get_hidden_int(); + param_destroy(&fun->params[i]); + param_init_type(&fun->params[i], type, 0); + } + } + } + + if (extra_param != NULL) { + assert(fun->num_params < allocd); + memcpy(&fun->params[fun->num_params++], extra_param, + sizeof(*extra_param)); + free(extra_param); } - memcpy(fun_p, &fun, sizeof(Function)); - return fun_p; + + return fun; +} + +void +init_global_config(void) +{ + struct arg_type_info *info = malloc(2 * sizeof(*info)); + if (info == NULL) + error(1, errno, "malloc in init_global_config"); + + memset(info, 0, 2 * sizeof(*info)); + info[0].type = ARGTYPE_POINTER; + info[0].u.ptr_info.info = &info[1]; + info[1].type = ARGTYPE_VOID; + + insert_typedef(new_typedef(strdup("addr"), info, 0)); + insert_typedef(new_typedef(strdup("file"), info, 1)); } void @@ -667,7 +1287,6 @@ read_config_file(char *file) { while (fgets(buf, 1024, stream)) { Function *tmp; - error_count = 0; tmp = process_line(buf); if (tmp) { diff --git a/read_config_file.h b/read_config_file.h index 8000b1c..7c60253 100644 --- a/read_config_file.h +++ b/read_config_file.h @@ -1 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + extern void read_config_file(char *); +extern void init_global_config(void); @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2003,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <stdio.h> diff --git a/sysdeps/Makefile.am b/sysdeps/Makefile.am new file mode 100644 index 0000000..36f93c1 --- /dev/null +++ b/sysdeps/Makefile.am @@ -0,0 +1,29 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +DIST_SUBDIRS = \ + linux-gnu + +SUBDIRS = \ + $(HOST_OS) + +noinst_HEADERS = \ + sysdep.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/Makefile.in b/sysdeps/Makefile.in new file mode 100644 index 0000000..d072917 --- /dev/null +++ b/sysdeps/Makefile.in @@ -0,0 +1,602 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps +DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +DIST_SUBDIRS = \ + linux-gnu + +SUBDIRS = \ + $(HOST_OS) + +noinst_HEADERS = \ + sysdep.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/README b/sysdeps/README index ce033ef..db51c9e 100644 --- a/sysdeps/README +++ b/sysdeps/README @@ -7,26 +7,5 @@ first target, and must remove "sysdep.o" in this dir. Files "sysdep.h", "signalent.h" and "syscallent.h" must be present inside the directory after invoking the first target of the Makefile. ------------ -"sysdep.o" must export the following functions: - -Event * next_event(void); -void continue_after_breakpoint(Process * proc, Breakpoint * sbp, int delete_it); -void continue_after_signal(pid_t pid, int signum); -void continue_enabling_breakpoint(pid_t pid, Breakpoint * sbp); -void continue_process(pid_t pid); -void enable_breakpoint(pid_t pid, Breakpoint * sbp); -void disable_breakpoint(pid_t pid, Breakpoint * sbp); -int fork_p(int sysnum); -int exec_p(int sysnum); -int syscall_p(Process * proc, int status, int * sysnum); -void * get_instruction_pointer(pid_t pid); -void * get_stack_pointer(pid_t pid); -void * get_return_addr(pid_t pid, void * stack_pointer); -long gimme_arg(enum tof type, Process * proc, arg_type_info*); -int umovestr(Process * proc, void * addr, int len, void * laddr); -int umovelong(Process * proc, void * addr, long * result); -char * pid2name(pid_t pid); -void trace_me(void); -int trace_pid(pid_t pid); -void untrace_pid(pid_t pid); +See the file "backend.h" for description of backend interfaces, which +have to be provided by "sysdep.o". diff --git a/sysdeps/linux-gnu/Makefile b/sysdeps/linux-gnu/Makefile deleted file mode 100644 index eb1ec60..0000000 --- a/sysdeps/linux-gnu/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -ARCH := $(shell uname -m | sed \ - -e s/i.86/i386/ \ - -e s/sun4u/sparc64/ \ - -e s/sparc64/sparc/ \ - -e s/arm.*/arm/ \ - -e s/sa110/arm/ \ - -e s/ppc64/ppc/ \ - -e s/s390x/s390/ \ - ) - -CPPFLAGS += -I$(TOPDIR)/sysdeps/linux-gnu/$(ARCH) - -OBJ = events.o trace.o proc.o breakpoint.o - -all: sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o - -sysdep.h: $(ARCH)/arch.h - cat $(ARCH)/arch.h > sysdep.h - -signalent.h: - cp $(ARCH)/signalent.h signalent.h -signalent1.h: - if [ -f $(ARCH)/signalent1.h ]; then \ - cp $(ARCH)/signalent1.h signalent1.h; \ - else \ - > signalent1.h; \ - fi - -syscallent.h: - cp $(ARCH)/syscallent.h syscallent.h - -syscallent1.h: - if [ -f $(ARCH)/syscallent1.h ]; then \ - cp $(ARCH)/syscallent1.h syscallent1.h; \ - else \ - > syscallent1.h; \ - fi - -arch_syscallent.h: - if [ -f $(ARCH)/arch_syscallent.h ]; then \ - cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \ - else \ - > arch_syscallent.h; \ - fi - -../sysdep.o: os.o $(ARCH)/arch.o - $(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o - -os.o: $(OBJ) - $(CC) -nostdlib -r -o os.o $(OBJ) - -$(ARCH)/arch.o: dummy - $(MAKE) -C $(ARCH) - -clean: - $(MAKE) -C $(ARCH) clean - rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h - rm -f syscallent1.h os.o sysdep.o ../sysdep.o - -dummy: diff --git a/sysdeps/linux-gnu/Makefile.am b/sysdeps/linux-gnu/Makefile.am new file mode 100644 index 0000000..bfa67d6 --- /dev/null +++ b/sysdeps/linux-gnu/Makefile.am @@ -0,0 +1,46 @@ +# This file is part of ltrace. +# Copyright (C) 2010,2012 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +DIST_SUBDIRS = alpha arm cris ia64 m68k mipsel ppc s390 sparc x86 + +SUBDIRS = \ + $(HOST_CPU) + +noinst_LTLIBRARIES = \ + ../libos.la + +___libos_la_SOURCES = \ + events.c \ + trace.c \ + proc.c \ + breakpoint.c + +___libos_la_LIBADD = \ + libcpu.la + +noinst_HEADERS = arch_syscallent.h signalent1.h syscallent1.h trace.h \ + trace-defs.h events.h os.h + +EXTRA_DIST = \ + arch_mksyscallent \ + mksignalent \ + mksyscallent \ + mksyscallent_s390 + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/Makefile.in b/sysdeps/linux-gnu/Makefile.in new file mode 100644 index 0000000..e00136b --- /dev/null +++ b/sysdeps/linux-gnu/Makefile.in @@ -0,0 +1,692 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010,2012 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu +DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libos_la_DEPENDENCIES = libcpu.la +am____libos_la_OBJECTS = events.lo trace.lo proc.lo breakpoint.lo +___libos_la_OBJECTS = $(am____libos_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libos_la_SOURCES) +DIST_SOURCES = $(___libos_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +DIST_SUBDIRS = alpha arm cris ia64 m68k mipsel ppc s390 sparc x86 +SUBDIRS = \ + $(HOST_CPU) + +noinst_LTLIBRARIES = \ + ../libos.la + +___libos_la_SOURCES = \ + events.c \ + trace.c \ + proc.c \ + breakpoint.c + +___libos_la_LIBADD = \ + libcpu.la + +noinst_HEADERS = arch_syscallent.h signalent1.h syscallent1.h trace.h \ + trace-defs.h events.h os.h + +EXTRA_DIST = \ + arch_mksyscallent \ + mksignalent \ + mksyscallent \ + mksyscallent_s390 + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libos.la: $(___libos_la_OBJECTS) $(___libos_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libos_la_OBJECTS) $(___libos_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/alpha/Makefile b/sysdeps/linux-gnu/alpha/Makefile deleted file mode 100644 index 60d7531..0000000 --- a/sysdeps/linux-gnu/alpha/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OBJ = trace.o regs.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o - diff --git a/sysdeps/linux-gnu/alpha/Makefile.am b/sysdeps/linux-gnu/alpha/Makefile.am new file mode 100644 index 0000000..5c6ecc2 --- /dev/null +++ b/sysdeps/linux-gnu/alpha/Makefile.am @@ -0,0 +1,34 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/alpha/Makefile.in b/sysdeps/linux-gnu/alpha/Makefile.in new file mode 100644 index 0000000..99a5886 --- /dev/null +++ b/sysdeps/linux-gnu/alpha/Makefile.in @@ -0,0 +1,528 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/alpha +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/alpha/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/alpha/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/alpha/arch.h b/sysdeps/linux-gnu/alpha/arch.h index 1107b5f..0696621 100644 --- a/sysdeps/linux-gnu/alpha/arch.h +++ b/sysdeps/linux-gnu/alpha/arch.h @@ -1,6 +1,27 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #define BREAKPOINT_VALUE { 0x80, 0x00, 0x00, 0x00 } #define BREAKPOINT_LENGTH 4 #define DECR_PC_AFTER_BREAK 4 +#define ARCH_ENDIAN_LITTLE #define LT_ELFCLASS ELFCLASS64 #define LT_ELF_MACHINE EM_ALPHA diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c index 83337b2..c7ce9fe 100644 --- a/sysdeps/linux-gnu/alpha/plt.c +++ b/sysdeps/linux-gnu/alpha/plt.c @@ -1,4 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <gelf.h> +#include "proc.h" #include "common.h" GElf_Addr diff --git a/sysdeps/linux-gnu/alpha/ptrace.h b/sysdeps/linux-gnu/alpha/ptrace.h index c3cbcb6..ad7e0d6 100644 --- a/sysdeps/linux-gnu/alpha/ptrace.h +++ b/sysdeps/linux-gnu/alpha/ptrace.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/alpha/regs.c b/sysdeps/linux-gnu/alpha/regs.c index 9554e48..0b46afd 100644 --- a/sysdeps/linux-gnu/alpha/regs.c +++ b/sysdeps/linux-gnu/alpha/regs.c @@ -1,9 +1,30 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) diff --git a/sysdeps/linux-gnu/alpha/signalent.h b/sysdeps/linux-gnu/alpha/signalent.h index c2a6170..e9588fa 100644 --- a/sysdeps/linux-gnu/alpha/signalent.h +++ b/sysdeps/linux-gnu/alpha/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/alpha/syscallent.h b/sysdeps/linux-gnu/alpha/syscallent.h index 7cacc8c..9a24315 100644 --- a/sysdeps/linux-gnu/alpha/syscallent.h +++ b/sysdeps/linux-gnu/alpha/syscallent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "osf_syscall", /* 0, not implemented */ "exit", /* 1 */ "fork", /* 2 */ diff --git a/sysdeps/linux-gnu/alpha/trace.c b/sysdeps/linux-gnu/alpha/trace.c index e4d4063..a7c5e59 100644 --- a/sysdeps/linux-gnu/alpha/trace.c +++ b/sysdeps/linux-gnu/alpha/trace.c @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> @@ -6,6 +27,7 @@ #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #include "debug.h" @@ -47,7 +69,8 @@ syscall_p(Process *proc, int status, int *sysnum) { } long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { +gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +{ if (arg_num == -1) { /* return value */ return ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0); } @@ -69,7 +92,3 @@ gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { } return 0; } - -void -save_register_args(enum tof type, Process *proc) { -} diff --git a/sysdeps/linux-gnu/arch_mksyscallent b/sysdeps/linux-gnu/arch_mksyscallent index 853d62d..ce79e26 100644 --- a/sysdeps/linux-gnu/arch_mksyscallent +++ b/sysdeps/linux-gnu/arch_mksyscallent @@ -1,4 +1,21 @@ #!/usr/bin/awk -f +# This file is part of ltrace. +# Copyright (C) 2008 Juan Cespedes +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA # hack expression to generate arch_syscallent.h from <asm/unistd.h> # It reads from stdin and writes to stdout diff --git a/sysdeps/linux-gnu/arch_syscallent.h b/sysdeps/linux-gnu/arch_syscallent.h new file mode 100644 index 0000000..74d8e19 --- /dev/null +++ b/sysdeps/linux-gnu/arch_syscallent.h @@ -0,0 +1 @@ +/* This file is intentionally left blank */ diff --git a/sysdeps/linux-gnu/arm/Makefile b/sysdeps/linux-gnu/arm/Makefile deleted file mode 100644 index f55ba48..0000000 --- a/sysdeps/linux-gnu/arm/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OBJ = trace.o regs.o plt.o breakpoint.o - -all: arch.o - -arch.o: $(OBJ) arch.h - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o - diff --git a/sysdeps/linux-gnu/arm/Makefile.am b/sysdeps/linux-gnu/arm/Makefile.am new file mode 100644 index 0000000..385424c --- /dev/null +++ b/sysdeps/linux-gnu/arm/Makefile.am @@ -0,0 +1,36 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + breakpoint.c \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + arch_syscallent.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/arm/Makefile.in b/sysdeps/linux-gnu/arm/Makefile.in new file mode 100644 index 0000000..ad6475d --- /dev/null +++ b/sysdeps/linux-gnu/arm/Makefile.in @@ -0,0 +1,531 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/arm +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = breakpoint.lo plt.lo regs.lo trace.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + breakpoint.c \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + arch_syscallent.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/arm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/arm/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/arm/arch.h b/sysdeps/linux-gnu/arm/arch.h index 8f2dfb3..291443a 100644 --- a/sysdeps/linux-gnu/arm/arch.h +++ b/sysdeps/linux-gnu/arm/arch.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2004,2008 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #define ARCH_HAVE_ENABLE_BREAKPOINT 1 #define ARCH_HAVE_DISABLE_BREAKPOINT 1 @@ -6,6 +26,12 @@ #define THUMB_BREAKPOINT_VALUE { 0x01, 0xde } #define THUMB_BREAKPOINT_LENGTH 2 #define DECR_PC_AFTER_BREAK 0 +#define ARCH_ENDIAN_LITTLE #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_ARM + +#define ARCH_HAVE_BREAKPOINT_DATA +struct arch_breakpoint_data { + int thumb_mode; +}; diff --git a/sysdeps/linux-gnu/arm/arch_syscallent.h b/sysdeps/linux-gnu/arm/arch_syscallent.h index ce1e844..f5bb295 100644 --- a/sysdeps/linux-gnu/arm/arch_syscallent.h +++ b/sysdeps/linux-gnu/arm/arch_syscallent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2008 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "0", /* 0 */ "breakpoint", /* 1 */ "cacheflush", /* 2 */ diff --git a/sysdeps/linux-gnu/arm/breakpoint.c b/sysdeps/linux-gnu/arm/breakpoint.c index 4c20260..5748401 100644 --- a/sysdeps/linux-gnu/arm/breakpoint.c +++ b/sysdeps/linux-gnu/arm/breakpoint.c @@ -23,14 +23,16 @@ */ #include <sys/ptrace.h> +#include <sys/types.h> + #include "config.h" -#include "arch.h" -#include "options.h" -#include "output.h" +#include "breakpoint.h" #include "debug.h" +#include "proc.h" void -arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) { +arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp) +{ unsigned int i, j; const unsigned char break_insn[] = BREAKPOINT_VALUE; const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE; @@ -38,40 +40,79 @@ arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) { debug(1, "arch_enable_breakpoint(%d,%p)", pid, sbp->addr); for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { - long a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 0); - unsigned char *bytes = (unsigned char *)&a; + union _ { long l; unsigned char b[SIZEOF_LONG]; }; + union _ orig, current; + unsigned char *bytes = current.b; + for (j = 0; j < sizeof(long); j++) { + orig.b[j] = sbp->orig_value[i * sizeof(long) + j]; + } + current.l = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 0); - debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode); + debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", + current.l, orig.l, sbp->arch.thumb_mode); for (j = 0; j < sizeof(long) && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { sbp->orig_value[i * sizeof(long) + j] = bytes[j]; - if (!sbp->thumb_mode) { + if (!sbp->arch.thumb_mode) { bytes[j] = break_insn[i * sizeof(long) + j]; } else if (j < THUMB_BREAKPOINT_LENGTH) { bytes[j] = thumb_break_insn[i * sizeof(long) + j]; } } - ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); + ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), + (void *)current.l); } } void -arch_disable_breakpoint(pid_t pid, const Breakpoint *sbp) { +arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp) +{ unsigned int i, j; - const unsigned char break_insn[] = BREAKPOINT_VALUE; - const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE; debug(1, "arch_disable_breakpoint(%d,%p)", pid, sbp->addr); for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { - long a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 0); - unsigned char *bytes = (unsigned char *)&a; + union _ { long l; unsigned char b[SIZEOF_LONG]; }; + union _ orig, current; + unsigned char *bytes = current.b; + for (j = 0; j < sizeof(long); j++) { + orig.b[j] = sbp->orig_value[i * sizeof(long) + j]; + } + current.l = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 0); - debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode); + debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", + current.l, orig.l, sbp->arch.thumb_mode); for (j = 0; j < sizeof(long) && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { bytes[j] = sbp->orig_value[i * sizeof(long) + j]; } - ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); + ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), + (void *)current.l); } } + +int +arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp) +{ + /* XXX That uintptr_t cast is there temporarily until + * arch_addr_t becomes integral type. */ + int thumb_mode = ((uintptr_t)sbp->addr) & 1; + if (thumb_mode) + sbp->addr = (void *)((uintptr_t)sbp->addr & ~1); + sbp->arch.thumb_mode = thumb_mode | proc->thumb_mode; + /* XXX This doesn't seem like it belongs here. */ + proc->thumb_mode = 0; + return 0; +} + +void +arch_breakpoint_destroy(struct breakpoint *sbp) +{ +} + +int +arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) +{ + retp->arch.thumb_mode = sbp->arch.thumb_mode; + return 0; +} diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c index bd92a63..1b97705 100644 --- a/sysdeps/linux-gnu/arm/plt.c +++ b/sysdeps/linux-gnu/arm/plt.c @@ -1,9 +1,45 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Zach Welch, CodeSourcery + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <gelf.h> -#include "common.h" + +#include "proc.h" +#include "library.h" +#include "ltrace-elf.h" + +static int +arch_plt_entry_has_stub(struct ltelf *lte, size_t off) { + uint16_t op = *(uint16_t *)((char *)lte->relplt->d_buf + off); + return op == 0x4778; +} GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - return lte->plt_addr + 20 + ndx * 12; + size_t start = lte->relplt->d_size + 12; + size_t off = start + 20, i; + for (i = 0; i < ndx; i++) + off += arch_plt_entry_has_stub(lte, off) ? 16 : 12; + if (arch_plt_entry_has_stub(lte, off)) + off += 4; + return lte->plt_addr + off - start; } void * diff --git a/sysdeps/linux-gnu/arm/ptrace.h b/sysdeps/linux-gnu/arm/ptrace.h index 52215bc..41106d8 100644 --- a/sysdeps/linux-gnu/arm/ptrace.h +++ b/sysdeps/linux-gnu/arm/ptrace.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> #include <asm/ptrace.h> diff --git a/sysdeps/linux-gnu/arm/regs.c b/sysdeps/linux-gnu/arm/regs.c index 2488b0a..484de7f 100644 --- a/sysdeps/linux-gnu/arm/regs.c +++ b/sysdeps/linux-gnu/arm/regs.c @@ -1,9 +1,31 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2002,2004,2008,2009 Juan Cespedes + * Copyright (C) 2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) @@ -14,9 +36,9 @@ # define PTRACE_POKEUSER PTRACE_POKEUSR #endif -#define off_pc 60 -#define off_lr 56 -#define off_sp 52 +#define off_pc ((void *)60) +#define off_lr ((void *)56) +#define off_sp ((void *)52) void * get_instruction_pointer(Process *proc) { @@ -39,13 +61,20 @@ void * get_return_addr(Process *proc, void *stack_pointer) { long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0); + /* Remember & unset the thumb mode bit. XXX This is really a + * bit of a hack, as we assume that the following + * insert_breakpoint call will be related to this address. + * This interface should really be get_return_breakpoint, or + * maybe install_return_breakpoint. */ proc->thumb_mode = addr & 1; if (proc->thumb_mode) addr &= ~1; + return (void *)addr; } void set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, off_lr, addr); + long iaddr = (int)addr | proc->thumb_mode; + ptrace(PTRACE_POKEUSER, proc->pid, off_lr, (void *)iaddr); } diff --git a/sysdeps/linux-gnu/arm/signalent.h b/sysdeps/linux-gnu/arm/signalent.h index 0afb004..4c28c9d 100644 --- a/sysdeps/linux-gnu/arm/signalent.h +++ b/sysdeps/linux-gnu/arm/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/arm/syscallent.h b/sysdeps/linux-gnu/arm/syscallent.h index 4113234..3b9bcfd 100644 --- a/sysdeps/linux-gnu/arm/syscallent.h +++ b/sysdeps/linux-gnu/arm/syscallent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "restart_syscall", /* 0 */ "exit", /* 1 */ "fork", /* 2 */ diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c index 10f7cc4..c528cfb 100644 --- a/sysdeps/linux-gnu/arm/trace.c +++ b/sysdeps/linux-gnu/arm/trace.c @@ -1,3 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1998,2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <string.h> @@ -7,6 +29,7 @@ #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #include "output.h" #include "ptrace.h" @@ -19,10 +42,10 @@ # define PTRACE_POKEUSER PTRACE_POKEUSR #endif -#define off_r0 0 -#define off_r7 28 -#define off_ip 48 -#define off_pc 60 +#define off_r0 ((void *)0) +#define off_r7 ((void *)28) +#define off_ip ((void *)48) +#define off_pc ((void *)60) void get_arch_dep(Process *proc) { @@ -44,12 +67,15 @@ syscall_p(Process *proc, int status, int *sysnum) { if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { /* get the user's pc (plus 8) */ - int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); + unsigned pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); + pc = pc - 4; /* fetch the SWI instruction */ - int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0); + unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid, + (void *)pc, 0); int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0); - if (insn == 0xef000000 || insn == 0x0f000000) { + if (insn == 0xef000000 || insn == 0x0f000000 + || (insn & 0xffff0000) == 0xdf000000) { /* EABI syscall */ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0); } else if ((insn & 0xfff00000) == 0xef900000) { @@ -61,8 +87,9 @@ syscall_p(Process *proc, int status, int *sysnum) { * are coming from a signal handler, so the current * PC does not point to the instruction just after the * "swi" one. */ - output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4); - return -1; + output_line(proc, "unexpected instruction 0x%x at %p", + insn, pc); + return 0; } if ((*sysnum & 0xf0000) == 0xf0000) { /* arch-specific syscall */ @@ -77,7 +104,8 @@ syscall_p(Process *proc, int status, int *sysnum) { } long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { +gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +{ proc_archdep *a = (proc_archdep *) proc->arch_ptr; if (arg_num == -1) { /* return value */ @@ -91,8 +119,8 @@ gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { return a->regs.uregs[arg_num]; if (a->valid && type == LT_TOF_FUNCTIONR) return a->func_arg[arg_num]; - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, - 0); + return ptrace(PTRACE_PEEKUSER, proc->pid, + (void *)(4 * arg_num), 0); } else { return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer + 4 * (arg_num - 4), @@ -104,8 +132,8 @@ gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { return a->regs.uregs[arg_num]; if (a->valid && type == LT_TOF_SYSCALLR) return a->sysc_arg[arg_num]; - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, - 0); + return ptrace(PTRACE_PEEKUSER, proc->pid, + (void *)(4 * arg_num), 0); } else { return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer + 4 * (arg_num - 5), @@ -118,14 +146,3 @@ gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { return 0; } - -void -save_register_args(enum tof type, Process *proc) { - proc_archdep *a = (proc_archdep *) proc->arch_ptr; - if (a->valid) { - if (type == LT_TOF_FUNCTION) - memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg)); - else - memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg)); - } -} diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c index 5ca131a..fe336b1 100644 --- a/sysdeps/linux-gnu/breakpoint.c +++ b/sysdeps/linux-gnu/breakpoint.c @@ -1,39 +1,62 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011 Petr Machata, Red Hat Inc. + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2002,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/ptrace.h> +#include <errno.h> #include <string.h> +#include <stdio.h> #include "common.h" -#include "arch.h" - -static unsigned char break_insn[] = BREAKPOINT_VALUE; +#include "backend.h" +#include "sysdep.h" +#include "breakpoint.h" +#include "proc.h" +#include "library.h" #ifdef ARCH_HAVE_ENABLE_BREAKPOINT -extern void arch_enable_breakpoint(pid_t, Breakpoint *); -void -enable_breakpoint(pid_t pid, Breakpoint *sbp) { - if (sbp->libsym) { - debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name); - } else { - debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr); - } - arch_enable_breakpoint(pid, sbp); -} -#else +extern void arch_enable_breakpoint(pid_t, struct breakpoint *); +#else /* ARCH_HAVE_ENABLE_BREAKPOINT */ void -enable_breakpoint(pid_t pid, Breakpoint *sbp) { +arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp) +{ + static unsigned char break_insn[] = BREAKPOINT_VALUE; unsigned int i, j; - if (sbp->libsym) { - debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name); - } else { - debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr); - } + debug(DEBUG_PROCESS, + "arch_enable_breakpoint: pid=%d, addr=%p, symbol=%s", + pid, sbp->addr, breakpoint_name(sbp)); for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { - long a = - ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), - 0); + long a = ptrace(PTRACE_PEEKTEXT, pid, + sbp->addr + i * sizeof(long), 0); + if (a == -1 && errno) { + fprintf(stderr, "enable_breakpoint" + " pid=%d, addr=%p, symbol=%s: %s\n", + pid, sbp->addr, breakpoint_name(sbp), + strerror(errno)); + return; + } for (j = 0; j < sizeof(long) && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { @@ -42,37 +65,48 @@ enable_breakpoint(pid_t pid, Breakpoint *sbp) { sbp->orig_value[i * sizeof(long) + j] = bytes[j]; bytes[j] = break_insn[i * sizeof(long) + j]; } - ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); + a = ptrace(PTRACE_POKETEXT, pid, + sbp->addr + i * sizeof(long), a); + if (a == -1) { + fprintf(stderr, "enable_breakpoint" + " pid=%d, addr=%p, symbol=%s: %s\n", + pid, sbp->addr, breakpoint_name(sbp), + strerror(errno)); + return; + } } } #endif /* ARCH_HAVE_ENABLE_BREAKPOINT */ -#ifdef ARCH_HAVE_DISABLE_BREAKPOINT -extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp); void -disable_breakpoint(pid_t pid, const Breakpoint *sbp) { - if (sbp->libsym) { - debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name); - } else { - debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr); - } - arch_disable_breakpoint(pid, sbp); +enable_breakpoint(Process *proc, struct breakpoint *sbp) +{ + debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", + proc->pid, sbp->addr, breakpoint_name(sbp)); + arch_enable_breakpoint(proc->pid, sbp); } -#else + +#ifdef ARCH_HAVE_DISABLE_BREAKPOINT +extern void arch_disable_breakpoint(pid_t, const struct breakpoint *sbp); +#else /* ARCH_HAVE_DISABLE_BREAKPOINT */ void -disable_breakpoint(pid_t pid, const Breakpoint *sbp) { +arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp) +{ unsigned int i, j; - if (sbp->libsym) { - debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name); - } else { - debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr); - } + debug(DEBUG_PROCESS, + "arch_disable_breakpoint: pid=%d, addr=%p, symbol=%s", + pid, sbp->addr, breakpoint_name(sbp)); for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { - long a = - ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), - 0); + long a = ptrace(PTRACE_PEEKTEXT, pid, + sbp->addr + i * sizeof(long), 0); + if (a == -1 && errno) { + fprintf(stderr, + "disable_breakpoint pid=%d, addr=%p: %s\n", + pid, sbp->addr, strerror(errno)); + return; + } for (j = 0; j < sizeof(long) && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { @@ -80,7 +114,22 @@ disable_breakpoint(pid_t pid, const Breakpoint *sbp) { bytes[j] = sbp->orig_value[i * sizeof(long) + j]; } - ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); + a = ptrace(PTRACE_POKETEXT, pid, + sbp->addr + i * sizeof(long), a); + if (a == -1 && errno) { + fprintf(stderr, + "disable_breakpoint pid=%d, addr=%p: %s\n", + pid, sbp->addr, strerror(errno)); + return; + } } } #endif /* ARCH_HAVE_DISABLE_BREAKPOINT */ + +void +disable_breakpoint(Process *proc, struct breakpoint *sbp) +{ + debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", + proc->pid, sbp->addr, breakpoint_name(sbp)); + arch_disable_breakpoint(proc->pid, sbp); +} diff --git a/sysdeps/linux-gnu/cris/Makefile.am b/sysdeps/linux-gnu/cris/Makefile.am new file mode 100644 index 0000000..30cb0fd --- /dev/null +++ b/sysdeps/linux-gnu/cris/Makefile.am @@ -0,0 +1,34 @@ +# This file is part of ltrace. +# Copyright (C) 2012 Edgar E. Iglesias, Axis Communications +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/cris/Makefile.in b/sysdeps/linux-gnu/cris/Makefile.in new file mode 100644 index 0000000..c978410 --- /dev/null +++ b/sysdeps/linux-gnu/cris/Makefile.in @@ -0,0 +1,528 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2012 Edgar E. Iglesias, Axis Communications +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/cris +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/cris/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/cris/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/cris/arch.h b/sysdeps/linux-gnu/cris/arch.h new file mode 100644 index 0000000..099dc3f --- /dev/null +++ b/sysdeps/linux-gnu/cris/arch.h @@ -0,0 +1,27 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#define BREAKPOINT_VALUE { 0x38, 0xe9 } +#define BREAKPOINT_LENGTH 2 +#define DECR_PC_AFTER_BREAK 0 +#define ARCH_ENDIAN_LITTLE + +#define LT_ELFCLASS ELFCLASS32 +#define LT_ELF_MACHINE EM_CRIS diff --git a/sysdeps/linux-gnu/cris/plt.c b/sysdeps/linux-gnu/cris/plt.c new file mode 100644 index 0000000..427ae93 --- /dev/null +++ b/sysdeps/linux-gnu/cris/plt.c @@ -0,0 +1,34 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <gelf.h> +#include "proc.h" +#include "common.h" +#include "library.h" + +GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) +{ + return lte->plt_addr + 0x20 + (ndx * 26); +} + +void *sym2addr(Process *proc, struct library_symbol *sym) +{ + return sym->enter_addr; +} diff --git a/sysdeps/linux-gnu/cris/ptrace.h b/sysdeps/linux-gnu/cris/ptrace.h new file mode 100644 index 0000000..8f04f16 --- /dev/null +++ b/sysdeps/linux-gnu/cris/ptrace.h @@ -0,0 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/cris/regs.c b/sysdeps/linux-gnu/cris/regs.c new file mode 100644 index 0000000..7028b9e --- /dev/null +++ b/sysdeps/linux-gnu/cris/regs.c @@ -0,0 +1,58 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/ptrace.h> +#include <asm/ptrace.h> + +#include "proc.h" +#include "common.h" + +#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) +# define PTRACE_PEEKUSER PTRACE_PEEKUSR +#endif + +#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) +# define PTRACE_POKEUSER PTRACE_POKEUSR +#endif + +void *get_instruction_pointer(Process *proc) +{ + return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PPC, 0); +} + +void set_instruction_pointer(Process *proc, void *addr) +{ + ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PPC, addr); +} + +void *get_stack_pointer(Process *proc) +{ + return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0); +} + +void *get_return_addr(Process *proc, void *stack_pointer) +{ + return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_SRP, 0); +} diff --git a/sysdeps/linux-gnu/cris/signalent.h b/sysdeps/linux-gnu/cris/signalent.h new file mode 100644 index 0000000..71cedbe --- /dev/null +++ b/sysdeps/linux-gnu/cris/signalent.h @@ -0,0 +1,52 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + "SIG_0", /* 0 */ + "SIGHUP", /* 1 */ + "SIGINT", /* 2 */ + "SIGQUIT", /* 3 */ + "SIGILL", /* 4 */ + "SIGTRAP", /* 5 */ + "SIGABRT", /* 6 */ + "SIGBUS", /* 7 */ + "SIGFPE", /* 8 */ + "SIGKILL", /* 9 */ + "SIGUSR1", /* 10 */ + "SIGSEGV", /* 11 */ + "SIGUSR2", /* 12 */ + "SIGPIPE", /* 13 */ + "SIGALRM", /* 14 */ + "SIGTERM", /* 15 */ + "SIGSTKFLT", /* 16 */ + "SIGCHLD", /* 17 */ + "SIGCONT", /* 18 */ + "SIGSTOP", /* 19 */ + "SIGTSTP", /* 20 */ + "SIGTTIN", /* 21 */ + "SIGTTOU", /* 22 */ + "SIGURG", /* 23 */ + "SIGXCPU", /* 24 */ + "SIGXFSZ", /* 25 */ + "SIGVTALRM", /* 26 */ + "SIGPROF", /* 27 */ + "SIGWINCH", /* 28 */ + "SIGIO", /* 29 */ + "SIGPWR", /* 30 */ + "SIGSYS", /* 31 */ diff --git a/sysdeps/linux-gnu/cris/syscallent.h b/sysdeps/linux-gnu/cris/syscallent.h new file mode 100644 index 0000000..7a7d1ca --- /dev/null +++ b/sysdeps/linux-gnu/cris/syscallent.h @@ -0,0 +1,345 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +"0", /* 0 */ + "exit", +"fork", +"read", +"write", +"open", +"close", +"waitpid", +"creat", +"link", +"unlink", +"execve", +"chdir", +"time", +"mknod", +"chmod", +"lchown", +"break", +"oldstat", +"lseek", +"getpid", +"mount", +"umount", +"setuid", +"getuid", +"stime", +"ptrace", +"alarm", +"oldfstat", +"pause", +"utime", +"stty", +"gtty", +"access", +"nice", +"ftime", +"sync", +"kill", +"rename", +"mkdir", +"rmdir", +"dup", +"pipe", +"times", +"prof", +"brk", +"setgid", +"getgid", +"signal", +"geteuid", +"getegid", +"acct", +"umount2", +"lock", +"ioctl", +"fcntl", +"mpx", +"setpgid", +"ulimit", +"oldolduname", +"umask", +"chroot", +"ustat", +"dup2", +"getppid", +"getpgrp", +"setsid", +"sigaction", +"sgetmask", +"ssetmask", +"setreuid", +"setregid", +"sigsuspend", +"sigpending", +"sethostname", +"setrlimit", +"getrlimit", +"getrusage", +"gettimeofday", +"settimeofday", +"getgroups", +"setgroups", +"select", +"symlink", +"oldlstat", +"readlink", +"uselib", +"swapon", +"reboot", +"readdir", +"mmap", +"munmap", +"truncate", +"ftruncate", +"fchmod", +"fchown", +"getpriority", +"setpriority", +"profil", +"statfs", +"fstatfs", +"ioperm", +"socketcall", +"syslog", +"setitimer", +"getitimer", +"stat", +"lstat", +"fstat", +"olduname", +"iopl", +"vhangup", +"idle", +"vm86", +"wait4", +"swapoff", +"sysinfo", +"ipc", +"fsync", +"sigreturn", +"clone", +"setdomainname", +"uname", +"modify_ldt", +"adjtimex", +"mprotect", +"sigprocmask", +"create_module", +"init_module", +"delete_module", +"get_kernel_syms", +"quotactl", +"getpgid", +"fchdir", +"bdflush", +"sysfs", +"personality", +"afs_syscall", +"setfsuid", +"setfsgid", +"_llseek", +"getdents", +"_newselect", +"flock", +"msync", +"readv", +"writev", +"getsid", +"fdatasync", +"_sysctl", +"mlock", +"munlock", +"mlockall", +"munlockall", +"sched_setparam", +"sched_getparam", +"sched_setscheduler", +"sched_getscheduler", +"sched_yield", +"sched_get_priority_max", +"sched_get_priority_min", +"sched_rr_get_interval", +"nanosleep", +"mremap", +"setresuid", +"getresuid", +"invalid", +"query_module", +"poll", +"nfsservctl", +"setresgid", +"getresgid", +"prctl", +"rt_sigreturn", +"rt_sigaction", +"rt_sigprocmask", +"rt_sigpending", +"rt_sigtimedwait", +"rt_sigqueueinfo", +"rt_sigsuspend", +"pread64", +"pwrite64", +"chown", +"getcwd", +"capget", +"capset", +"sigaltstack", +"sendfile", +"getpmsg", +"putpmsg", +"vfork", +"ugetrlimit", +"mmap2", +"truncate64", +"ftruncate64", +"stat64", +"lstat64", +"fstat64", +"lchown32", +"getuid32", +"getgid32", +"geteuid32", +"getegid32", +"setreuid32", +"setregid32", +"getgroups32", +"setgroups32", +"fchown32", +"setresuid32", +"getresuid32", +"setresgid32", +"getresgid32", +"chown32", +"setuid32", +"setgid32", +"setfsuid32", +"setfsgid32", +"pivot_root", +"mincore", +"madvise", +"getdents64", +"fcntl64", +"invalid", +"invalid", +"gettid", +"readahead", +"setxattr", +"lsetxattr", +"fsetxattr", +"getxattr", +"lgetxattr", +"fgetxattr", +"listxattr", +"llistxattr", +"flistxattr", +"removexattr", +"lremovexattr", +"fremovexattr", +"tkill", +"sendfile64", +"futex", +"sched_setaffinity", +"sched_getaffinity", +"set_thread_area", +"get_thread_area", +"io_setup", +"io_destroy", +"io_getevents", +"io_submit", +"io_cancel", +"fadvise64", +"invalid", +"exit_group", +"lookup_dcookie", +"epoll_create", +"epoll_ctl", +"epoll_wait", +"remap_file_pages", +"set_tid_address", +"timer_create", +"timer_settime", +"timer_gettime", +"timer_getoverrun", +"timer_delete", +"clock_settime", +"clock_gettime", +"clock_getres", +"clock_nanosleep", +"statfs64", +"fstatfs64", +"tgkill", +"utimes", +"fadvise64_64", +"vserver", +"mbind", +"get_mempolicy", +"set_mempolicy", +"mq_open", +"mq_unlink", +"mq_timedsend", +"mq_timedreceive", +"mq_notify", +"mq_getsetattr", +"kexec_load", +"waitid", +"invalid", +"add_key", +"request_key", +"keyctl", +"ioprio_set", +"ioprio_get", +"inotify_init", +"inotify_add_watch", +"inotify_rm_watch", +"migrate_pages", +"openat", +"mkdirat", +"mknodat", +"fchownat", +"futimesat", +"fstatat64", +"unlinkat", +"renameat", +"linkat", +"symlinkat", +"readlinkat", +"fchmodat", +"faccessat", +"pselect6", +"ppoll", +"unshare", +"set_robust_list", +"get_robust_list", +"splice", +"sync_file_range", +"tee", +"vmsplice", +"move_pages", +"getcpu", +"epoll_pwait", +"utimensat", +"signalfd", +"timerfd", +"eventfd", +"fallocate", diff --git a/sysdeps/linux-gnu/cris/trace.c b/sysdeps/linux-gnu/cris/trace.c new file mode 100644 index 0000000..98cb7d8 --- /dev/null +++ b/sysdeps/linux-gnu/cris/trace.c @@ -0,0 +1,93 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> +#include <sys/ptrace.h> +#include <asm/ptrace.h> +#include <elf.h> + +#include "proc.h" +#include "common.h" + +#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) +# define PTRACE_PEEKUSER PTRACE_PEEKUSR +#endif + +#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) +# define PTRACE_POKEUSER PTRACE_POKEUSR +#endif + +void get_arch_dep(Process *proc) +{ +} + +/* Returns 1 if syscall, 2 if sysret, 0 otherwise. + */ +#define SYSCALL_INSN 0xe93d +int syscall_p(Process *proc, int status, int *sysnum) +{ + if (WIFSTOPPED(status) + && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { + long pc = (long)get_instruction_pointer(proc); + unsigned int insn = + (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc - sizeof(long), + 0); + + if ((insn >> 16) == SYSCALL_INSN) { + *sysnum = + (int)ptrace(PTRACE_PEEKUSER, proc->pid, + sizeof(long) * PT_R9, 0); + if (proc->callstack_depth > 0 + && proc->callstack[proc->callstack_depth - + 1].is_syscall) { + return 2; + } + return 1; + } + } + return 0; +} + +long gimme_arg(enum tof type, Process *proc, int arg_num, + struct arg_type_info *info) +{ + int pid = proc->pid; + + if (arg_num == -1) { /* return value */ + return ptrace(PTRACE_PEEKUSER, pid, PT_R10 * 4, 0); + } else if (arg_num < 6) { + int pt_arg[6] = + { + PT_ORIG_R10, PT_R11, PT_R12, PT_R13, PT_MOF, + PT_SRP + }; + return ptrace(PTRACE_PEEKUSER, pid, pt_arg[arg_num] * 4, 0); + } else { + return ptrace(PTRACE_PEEKDATA, pid, + proc->stack_pointer + 4 * (arg_num - 6), 0); + } + return 0; +} diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c index a1e2a14..077a656 100644 --- a/sysdeps/linux-gnu/events.c +++ b/sysdeps/linux-gnu/events.c @@ -1,31 +1,163 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2007,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1998,2001,2004,2007,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #define _GNU_SOURCE 1 -#include <stdlib.h> +#include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> +#include <assert.h> #include <errno.h> #include <signal.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> -#include <sys/ptrace.h> +#include <unistd.h> -#include "common.h" +#include "backend.h" +#include "breakpoint.h" +#include "debug.h" +#include "events.h" +#include "proc.h" +#include "linux-gnu/trace-defs.h" static Event event; +/* A queue of events that we missed while enabling the + * breakpoint in one of tasks. */ +static Event * delayed_events = NULL; +static Event * end_delayed_events = NULL; + +static enum callback_status +first (Process * proc, void * data) +{ + return CBS_STOP; +} + +void +enque_event(Event * event) +{ + debug(DEBUG_FUNCTION, "%d: queuing event %d for later", + event->proc->pid, event->type); + Event * ne = malloc(sizeof(*ne)); + if (ne == NULL) { + fprintf(stderr, "event will be missed: %s\n", strerror(errno)); + return; + } + + *ne = *event; + ne->next = NULL; + if (end_delayed_events == NULL) { + assert(delayed_events == NULL); + end_delayed_events = delayed_events = ne; + } + else { + assert(delayed_events != NULL); + end_delayed_events = end_delayed_events->next = ne; + } +} + Event * -next_event(void) { +each_qd_event(enum ecb_status (*pred)(Event *, void *), void * data) +{ + Event * prev = delayed_events; + Event * event; + for (event = prev; event != NULL; ) { + switch ((*pred)(event, data)) { + case ecb_cont: + prev = event; + event = event->next; + continue; + + case ecb_deque: + debug(DEBUG_FUNCTION, "dequeuing event %d for %d", + event->type, + event->proc != NULL ? event->proc->pid : -1); + /* + printf("dequeuing event %d for %d\n", event->type, + event->proc != NULL ? event->proc->pid : -1) ; + */ + if (end_delayed_events == event) + end_delayed_events = prev; + if (delayed_events == event) + delayed_events = event->next; + else + prev->next = event->next; + if (delayed_events == NULL) + end_delayed_events = NULL; + /* fall-through */ + + case ecb_yield: + return event; + } + } + + return NULL; +} + +static enum ecb_status +event_process_not_reenabling(Event * event, void * data) +{ + if (event->proc == NULL + || event->proc->leader == NULL + || event->proc->leader->event_handler == NULL) + return ecb_deque; + else + return ecb_cont; +} + +static Event * +next_qd_event(void) +{ + return each_qd_event(&event_process_not_reenabling, NULL); +} + +int linux_in_waitpid = 0; + +Event * +next_event(void) +{ pid_t pid; int status; int tmp; int stop_signal; debug(DEBUG_FUNCTION, "next_event()"); - if (!list_of_processes) { + Event * ev; + if ((ev = next_qd_event()) != NULL) { + event = *ev; + free(ev); + return &event; + } + + if (!each_process(NULL, &first, NULL)) { debug(DEBUG_EVENT, "event: No more traced programs: exiting"); exit(0); } + + linux_in_waitpid = 1; pid = waitpid(-1, &status, __WALL); + linux_in_waitpid = 0; + if (pid == -1) { if (errno == ECHILD) { debug(DEBUG_EVENT, "event: No more traced programs: exiting"); @@ -40,26 +172,84 @@ next_event(void) { } event.proc = pid2proc(pid); if (!event.proc || event.proc->state == STATE_BEING_CREATED) { + /* Work around (presumably) a bug on some kernels, + * where we are seeing a waitpid event even though the + * process is still reported to be running. Wait for + * the tracing stop to propagate. But don't get stuck + * here forever. + * + * We need the process in T, because there's a lot of + * ptracing going on all over the place, and these + * calls fail when the process is not in T. + * + * N.B. This was observed on RHEL 5 Itanium, but I'm + * turning this on globally, to save some poor soul + * down the road (which could well be me a year from + * now) the pain of figuring this out all over again. + * Petr Machata 2011-11-22. */ + int i = 0; + for (; i < 100 && process_status(pid) != ps_tracing_stop; ++i) { + debug(2, "waiting for %d to stop", pid); + usleep(10000); + } event.type = EVENT_NEW; event.e_un.newpid = pid; debug(DEBUG_EVENT, "event: NEW: pid=%d", pid); return &event; } get_arch_dep(event.proc); - event.proc->instruction_pointer = NULL; debug(3, "event from pid %u", pid); - if (event.proc->breakpoints_enabled == -1) { - enable_all_breakpoints(event.proc); - event.type = EVENT_NONE; - trace_set_options(event.proc, event.proc->pid); - continue_process(event.proc->pid); - debug(DEBUG_EVENT, "event: NONE: pid=%d (enabling breakpoints)", pid); + Process *leader = event.proc->leader; + + /* The process should be stopped after the waitpid call. But + * when the whole thread group is terminated, we see + * individual tasks spontaneously transitioning from 't' to + * 'R' and 'Z'. Calls to ptrace fail and /proc/pid/status may + * not even be available anymore, so we can't check in + * advance. So we just drop the error checking around ptrace + * calls. We check for termination ex post when it fails, + * suppress the event, and let the event loop collect the + * termination in the next iteration. */ +#define CHECK_PROCESS_TERMINATED \ + do { \ + int errno_save = errno; \ + switch (process_stopped(pid)) \ + case 0: \ + case -1: { \ + debug(DEBUG_EVENT, \ + "process not stopped, is it terminating?"); \ + event.type = EVENT_NONE; \ + continue_process(event.proc->pid); \ + return &event; \ + } \ + errno = errno_save; \ + } while (0) + + event.proc->instruction_pointer = (void *)(uintptr_t)-1; + + /* Check for task termination now, before we have a need to + * call CHECK_PROCESS_TERMINATED later. That would suppress + * the event that we are processing. */ + if (WIFSIGNALED(status)) { + event.type = EVENT_EXIT_SIGNAL; + event.e_un.signum = WTERMSIG(status); + debug(DEBUG_EVENT, "event: EXIT_SIGNAL: pid=%d, signum=%d", pid, event.e_un.signum); return &event; } - if (opt_i) { - event.proc->instruction_pointer = - get_instruction_pointer(event.proc); + if (WIFEXITED(status)) { + event.type = EVENT_EXIT; + event.e_un.ret_val = WEXITSTATUS(status); + debug(DEBUG_EVENT, "event: EXIT: pid=%d, status=%d", pid, event.e_un.ret_val); + return &event; } + + event.proc->instruction_pointer = get_instruction_pointer(event.proc); + if (event.proc->instruction_pointer == (void *)(uintptr_t)-1) { + CHECK_PROCESS_TERMINATED; + if (errno != 0) + perror("get_instruction_pointer"); + } + switch (syscall_p(event.proc, status, &tmp)) { case 1: event.type = EVENT_SYSCALL; @@ -82,36 +272,30 @@ next_event(void) { debug(DEBUG_EVENT, "event: ARCH_SYSRET: pid=%d, sysnum=%d", pid, tmp); return &event; case -1: - event.type = EVENT_NONE; - continue_process(event.proc->pid); - debug(DEBUG_EVENT, "event: NONE: pid=%d (syscall_p returned -1)", pid); - return &event; + CHECK_PROCESS_TERMINATED; + if (errno != 0) + perror("syscall_p"); } - if (WIFSTOPPED(status) && ((status>>16 == PTRACE_EVENT_FORK) || (status>>16 == PTRACE_EVENT_VFORK) || (status>>16 == PTRACE_EVENT_CLONE))) { - unsigned long data; - ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data); - event.type = EVENT_CLONE; - event.e_un.newpid = data; - debug(DEBUG_EVENT, "event: CLONE: pid=%d, newpid=%d", pid, (int)data); - return &event; + if (WIFSTOPPED(status)) { + int what = status >> 16; + if (what == PTRACE_EVENT_VFORK + || what == PTRACE_EVENT_FORK + || what == PTRACE_EVENT_CLONE) { + unsigned long data; + event.type = what == PTRACE_EVENT_VFORK + ? EVENT_VFORK : EVENT_CLONE; + ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data); + event.e_un.newpid = data; + debug(DEBUG_EVENT, "event: CLONE: pid=%d, newpid=%d", + pid, (int)data); + return &event; + } } if (WIFSTOPPED(status) && (status>>16 == PTRACE_EVENT_EXEC)) { event.type = EVENT_EXEC; debug(DEBUG_EVENT, "event: EXEC: pid=%d", pid); return &event; } - if (WIFEXITED(status)) { - event.type = EVENT_EXIT; - event.e_un.ret_val = WEXITSTATUS(status); - debug(DEBUG_EVENT, "event: EXIT: pid=%d, status=%d", pid, event.e_un.ret_val); - return &event; - } - if (WIFSIGNALED(status)) { - event.type = EVENT_EXIT_SIGNAL; - event.e_un.signum = WTERMSIG(status); - debug(DEBUG_EVENT, "event: EXIT_SIGNAL: pid=%d, signum=%d", pid, event.e_un.signum); - return &event; - } if (!WIFSTOPPED(status)) { /* should never happen */ event.type = EVENT_NONE; @@ -122,22 +306,19 @@ next_event(void) { stop_signal = WSTOPSIG(status); /* On some targets, breakpoints are signalled not using - SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. Check - for these. (TODO: is this true?) */ - if (stop_signal == SIGSEGV - || stop_signal == SIGILL -#ifdef SIGEMT - || stop_signal == SIGEMT -#endif - ) { - if (!event.proc->instruction_pointer) { - event.proc->instruction_pointer = - get_instruction_pointer(event.proc); - } + SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. SIGEMT + is not defined on Linux, but check for the others. - if (address2bpstruct(event.proc, event.proc->instruction_pointer)) + N.B. see comments in GDB's infrun.c for details. I've + actually seen this on an Itanium machine on RHEL 5, I don't + remember the exact kernel version anymore. ia64-sigill.s + in the test suite tests this. Petr Machata 2011-06-08. */ + void * break_address + = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK; + if ((stop_signal == SIGSEGV || stop_signal == SIGILL) + && leader != NULL + && address2bpstruct(leader, break_address)) stop_signal = SIGTRAP; - } if (stop_signal != (SIGTRAP | event.proc->tracesysgood) && stop_signal != SIGTRAP) { @@ -150,12 +331,25 @@ next_event(void) { /* last case [by exhaustion] */ event.type = EVENT_BREAKPOINT; - if (!event.proc->instruction_pointer) { - event.proc->instruction_pointer = - get_instruction_pointer(event.proc); - } - event.e_un.brk_addr = - event.proc->instruction_pointer - DECR_PC_AFTER_BREAK; + event.e_un.brk_addr = break_address; debug(DEBUG_EVENT, "event: BREAKPOINT: pid=%d, addr=%p", pid, event.e_un.brk_addr); + return &event; } + +static enum ecb_status +event_for_proc(struct Event *event, void *data) +{ + if (event->proc == data) + return ecb_deque; + else + return ecb_cont; +} + +void +delete_events_for(struct Process *proc) +{ + struct Event *event; + while ((event = each_qd_event(&event_for_proc, proc)) != NULL) + free(event); +} diff --git a/sysdeps/linux-gnu/events.h b/sysdeps/linux-gnu/events.h new file mode 100644 index 0000000..3802aff --- /dev/null +++ b/sysdeps/linux-gnu/events.h @@ -0,0 +1,41 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef SYSDEPS_LINUX_GNU_EVENTS_H +#define SYSDEPS_LINUX_GNU_EVENTS_H + +#include "forward.h" + +/* Declarations for event que functions. */ + +enum ecb_status { + ecb_cont, /* The iteration should continue. */ + ecb_yield, /* The iteration should stop, yielding this + * event. */ + ecb_deque, /* Like ecb_stop, but the event should be removed + * from the queue. */ +}; + +struct Event *each_qd_event(enum ecb_status (*cb)(struct Event *event, + void *data), void *data); +void delete_events_for(struct Process * proc); +void enque_event(struct Event *event); + +#endif /* SYSDEPS_LINUX_GNU_EVENTS_H */ diff --git a/sysdeps/linux-gnu/i386/Makefile b/sysdeps/linux-gnu/i386/Makefile deleted file mode 100644 index 60d7531..0000000 --- a/sysdeps/linux-gnu/i386/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OBJ = trace.o regs.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o - diff --git a/sysdeps/linux-gnu/i386/arch.h b/sysdeps/linux-gnu/i386/arch.h deleted file mode 100644 index dc7383f..0000000 --- a/sysdeps/linux-gnu/i386/arch.h +++ /dev/null @@ -1,6 +0,0 @@ -#define BREAKPOINT_VALUE {0xcc} -#define BREAKPOINT_LENGTH 1 -#define DECR_PC_AFTER_BREAK 1 - -#define LT_ELFCLASS ELFCLASS32 -#define LT_ELF_MACHINE EM_386 diff --git a/sysdeps/linux-gnu/i386/plt.c b/sysdeps/linux-gnu/i386/plt.c deleted file mode 100644 index b53ff44..0000000 --- a/sysdeps/linux-gnu/i386/plt.c +++ /dev/null @@ -1,12 +0,0 @@ -#include <gelf.h> -#include "common.h" - -GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - return lte->plt_addr + (ndx + 1) * 16; -} - -void * -sym2addr(Process *proc, struct library_symbol *sym) { - return sym->enter_addr; -} diff --git a/sysdeps/linux-gnu/i386/ptrace.h b/sysdeps/linux-gnu/i386/ptrace.h deleted file mode 100644 index c3cbcb6..0000000 --- a/sysdeps/linux-gnu/i386/ptrace.h +++ /dev/null @@ -1 +0,0 @@ -#include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/i386/regs.c b/sysdeps/linux-gnu/i386/regs.c deleted file mode 100644 index 6777f17..0000000 --- a/sysdeps/linux-gnu/i386/regs.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "config.h" - -#include <sys/types.h> -#include <sys/ptrace.h> -#include <asm/ptrace.h> - -#include "common.h" - -#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) -# define PTRACE_PEEKUSER PTRACE_PEEKUSR -#endif - -#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) -# define PTRACE_POKEUSER PTRACE_POKEUSR -#endif - -void * -get_instruction_pointer(Process *proc) { - return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EIP, 0); -} - -void -set_instruction_pointer(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, 4 * EIP, (long)addr); -} - -void * -get_stack_pointer(Process *proc) { - return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * UESP, 0); -} - -void * -get_return_addr(Process *proc, void *stack_pointer) { - return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0); -} - -void -set_return_addr(Process *proc, void *addr) { - ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, (long)addr); -} diff --git a/sysdeps/linux-gnu/i386/syscallent.h b/sysdeps/linux-gnu/i386/syscallent.h deleted file mode 100644 index 8f4c887..0000000 --- a/sysdeps/linux-gnu/i386/syscallent.h +++ /dev/null @@ -1,317 +0,0 @@ - "restart_syscall", /* 0 */ - "exit", /* 1 */ - "fork", /* 2 */ - "read", /* 3 */ - "write", /* 4 */ - "open", /* 5 */ - "close", /* 6 */ - "waitpid", /* 7 */ - "creat", /* 8 */ - "link", /* 9 */ - "unlink", /* 10 */ - "execve", /* 11 */ - "chdir", /* 12 */ - "time", /* 13 */ - "mknod", /* 14 */ - "chmod", /* 15 */ - "lchown", /* 16 */ - "break", /* 17 */ - "oldstat", /* 18 */ - "lseek", /* 19 */ - "getpid", /* 20 */ - "mount", /* 21 */ - "umount", /* 22 */ - "setuid", /* 23 */ - "getuid", /* 24 */ - "stime", /* 25 */ - "ptrace", /* 26 */ - "alarm", /* 27 */ - "oldfstat", /* 28 */ - "pause", /* 29 */ - "utime", /* 30 */ - "stty", /* 31 */ - "gtty", /* 32 */ - "access", /* 33 */ - "nice", /* 34 */ - "ftime", /* 35 */ - "sync", /* 36 */ - "kill", /* 37 */ - "rename", /* 38 */ - "mkdir", /* 39 */ - "rmdir", /* 40 */ - "dup", /* 41 */ - "pipe", /* 42 */ - "times", /* 43 */ - "prof", /* 44 */ - "brk", /* 45 */ - "setgid", /* 46 */ - "getgid", /* 47 */ - "signal", /* 48 */ - "geteuid", /* 49 */ - "getegid", /* 50 */ - "acct", /* 51 */ - "umount2", /* 52 */ - "lock", /* 53 */ - "ioctl", /* 54 */ - "fcntl", /* 55 */ - "mpx", /* 56 */ - "setpgid", /* 57 */ - "ulimit", /* 58 */ - "oldolduname", /* 59 */ - "umask", /* 60 */ - "chroot", /* 61 */ - "ustat", /* 62 */ - "dup2", /* 63 */ - "getppid", /* 64 */ - "getpgrp", /* 65 */ - "setsid", /* 66 */ - "sigaction", /* 67 */ - "sgetmask", /* 68 */ - "ssetmask", /* 69 */ - "setreuid", /* 70 */ - "setregid", /* 71 */ - "sigsuspend", /* 72 */ - "sigpending", /* 73 */ - "sethostname", /* 74 */ - "setrlimit", /* 75 */ - "getrlimit", /* 76 */ - "getrusage", /* 77 */ - "gettimeofday", /* 78 */ - "settimeofday", /* 79 */ - "getgroups", /* 80 */ - "setgroups", /* 81 */ - "select", /* 82 */ - "symlink", /* 83 */ - "oldlstat", /* 84 */ - "readlink", /* 85 */ - "uselib", /* 86 */ - "swapon", /* 87 */ - "reboot", /* 88 */ - "readdir", /* 89 */ - "mmap", /* 90 */ - "munmap", /* 91 */ - "truncate", /* 92 */ - "ftruncate", /* 93 */ - "fchmod", /* 94 */ - "fchown", /* 95 */ - "getpriority", /* 96 */ - "setpriority", /* 97 */ - "profil", /* 98 */ - "statfs", /* 99 */ - "fstatfs", /* 100 */ - "ioperm", /* 101 */ - "socketcall", /* 102 */ - "syslog", /* 103 */ - "setitimer", /* 104 */ - "getitimer", /* 105 */ - "stat", /* 106 */ - "lstat", /* 107 */ - "fstat", /* 108 */ - "olduname", /* 109 */ - "iopl", /* 110 */ - "vhangup", /* 111 */ - "idle", /* 112 */ - "vm86old", /* 113 */ - "wait4", /* 114 */ - "swapoff", /* 115 */ - "sysinfo", /* 116 */ - "ipc", /* 117 */ - "fsync", /* 118 */ - "sigreturn", /* 119 */ - "clone", /* 120 */ - "setdomainname", /* 121 */ - "uname", /* 122 */ - "modify_ldt", /* 123 */ - "adjtimex", /* 124 */ - "mprotect", /* 125 */ - "sigprocmask", /* 126 */ - "create_module", /* 127 */ - "init_module", /* 128 */ - "delete_module", /* 129 */ - "get_kernel_syms", /* 130 */ - "quotactl", /* 131 */ - "getpgid", /* 132 */ - "fchdir", /* 133 */ - "bdflush", /* 134 */ - "sysfs", /* 135 */ - "personality", /* 136 */ - "afs_syscall", /* 137 */ - "setfsuid", /* 138 */ - "setfsgid", /* 139 */ - "_llseek", /* 140 */ - "getdents", /* 141 */ - "_newselect", /* 142 */ - "flock", /* 143 */ - "msync", /* 144 */ - "readv", /* 145 */ - "writev", /* 146 */ - "getsid", /* 147 */ - "fdatasync", /* 148 */ - "_sysctl", /* 149 */ - "mlock", /* 150 */ - "munlock", /* 151 */ - "mlockall", /* 152 */ - "munlockall", /* 153 */ - "sched_setparam", /* 154 */ - "sched_getparam", /* 155 */ - "sched_setscheduler", /* 156 */ - "sched_getscheduler", /* 157 */ - "sched_yield", /* 158 */ - "sched_get_priority_max", /* 159 */ - "sched_get_priority_min", /* 160 */ - "sched_rr_get_interval", /* 161 */ - "nanosleep", /* 162 */ - "mremap", /* 163 */ - "setresuid", /* 164 */ - "getresuid", /* 165 */ - "vm86", /* 166 */ - "query_module", /* 167 */ - "poll", /* 168 */ - "nfsservctl", /* 169 */ - "setresgid", /* 170 */ - "getresgid", /* 171 */ - "prctl", /* 172 */ - "rt_sigreturn", /* 173 */ - "rt_sigaction", /* 174 */ - "rt_sigprocmask", /* 175 */ - "rt_sigpending", /* 176 */ - "rt_sigtimedwait", /* 177 */ - "rt_sigqueueinfo", /* 178 */ - "rt_sigsuspend", /* 179 */ - "pread64", /* 180 */ - "pwrite64", /* 181 */ - "chown", /* 182 */ - "getcwd", /* 183 */ - "capget", /* 184 */ - "capset", /* 185 */ - "sigaltstack", /* 186 */ - "sendfile", /* 187 */ - "getpmsg", /* 188 */ - "putpmsg", /* 189 */ - "vfork", /* 190 */ - "ugetrlimit", /* 191 */ - "mmap2", /* 192 */ - "truncate64", /* 193 */ - "ftruncate64", /* 194 */ - "stat64", /* 195 */ - "lstat64", /* 196 */ - "fstat64", /* 197 */ - "lchown32", /* 198 */ - "getuid32", /* 199 */ - "getgid32", /* 200 */ - "geteuid32", /* 201 */ - "getegid32", /* 202 */ - "setreuid32", /* 203 */ - "setregid32", /* 204 */ - "getgroups32", /* 205 */ - "setgroups32", /* 206 */ - "fchown32", /* 207 */ - "setresuid32", /* 208 */ - "getresuid32", /* 209 */ - "setresgid32", /* 210 */ - "getresgid32", /* 211 */ - "chown32", /* 212 */ - "setuid32", /* 213 */ - "setgid32", /* 214 */ - "setfsuid32", /* 215 */ - "setfsgid32", /* 216 */ - "pivot_root", /* 217 */ - "mincore", /* 218 */ - "madvise1", /* 219 */ - "getdents64", /* 220 */ - "fcntl64", /* 221 */ - "222", /* 222 */ - "223", /* 223 */ - "gettid", /* 224 */ - "readahead", /* 225 */ - "setxattr", /* 226 */ - "lsetxattr", /* 227 */ - "fsetxattr", /* 228 */ - "getxattr", /* 229 */ - "lgetxattr", /* 230 */ - "fgetxattr", /* 231 */ - "listxattr", /* 232 */ - "llistxattr", /* 233 */ - "flistxattr", /* 234 */ - "removexattr", /* 235 */ - "lremovexattr", /* 236 */ - "fremovexattr", /* 237 */ - "tkill", /* 238 */ - "sendfile64", /* 239 */ - "futex", /* 240 */ - "sched_setaffinity", /* 241 */ - "sched_getaffinity", /* 242 */ - "set_thread_area", /* 243 */ - "get_thread_area", /* 244 */ - "io_setup", /* 245 */ - "io_destroy", /* 246 */ - "io_getevents", /* 247 */ - "io_submit", /* 248 */ - "io_cancel", /* 249 */ - "fadvise64", /* 250 */ - "251", /* 251 */ - "exit_group", /* 252 */ - "lookup_dcookie", /* 253 */ - "epoll_create", /* 254 */ - "epoll_ctl", /* 255 */ - "epoll_wait", /* 256 */ - "remap_file_pages", /* 257 */ - "set_tid_address", /* 258 */ - "timer_create", /* 259 */ - "260", /* 260 */ - "261", /* 261 */ - "262", /* 262 */ - "263", /* 263 */ - "264", /* 264 */ - "265", /* 265 */ - "266", /* 266 */ - "267", /* 267 */ - "statfs64", /* 268 */ - "fstatfs64", /* 269 */ - "tgkill", /* 270 */ - "utimes", /* 271 */ - "fadvise64_64", /* 272 */ - "vserver", /* 273 */ - "mbind", /* 274 */ - "get_mempolicy", /* 275 */ - "set_mempolicy", /* 276 */ - "mq_open", /* 277 */ - "278", /* 278 */ - "279", /* 279 */ - "280", /* 280 */ - "281", /* 281 */ - "282", /* 282 */ - "kexec_load", /* 283 */ - "waitid", /* 284 */ - "285", /* 285 */ - "add_key", /* 286 */ - "request_key", /* 287 */ - "keyctl", /* 288 */ - "ioprio_set", /* 289 */ - "ioprio_get", /* 290 */ - "inotify_init", /* 291 */ - "inotify_add_watch", /* 292 */ - "inotify_rm_watch", /* 293 */ - "migrate_pages", /* 294 */ - "openat", /* 295 */ - "mkdirat", /* 296 */ - "mknodat", /* 297 */ - "fchownat", /* 298 */ - "futimesat", /* 299 */ - "fstatat64", /* 300 */ - "unlinkat", /* 301 */ - "renameat", /* 302 */ - "linkat", /* 303 */ - "symlinkat", /* 304 */ - "readlinkat", /* 305 */ - "fchmodat", /* 306 */ - "faccessat", /* 307 */ - "pselect6", /* 308 */ - "ppoll", /* 309 */ - "unshare", /* 310 */ - "set_robust_list", /* 311 */ - "get_robust_list", /* 312 */ - "splice", /* 313 */ - "sync_file_range", /* 314 */ - "tee", /* 315 */ - "vmsplice", /* 316 */ diff --git a/sysdeps/linux-gnu/i386/trace.c b/sysdeps/linux-gnu/i386/trace.c deleted file mode 100644 index 76f1105..0000000 --- a/sysdeps/linux-gnu/i386/trace.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "config.h" - -#include <stdlib.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <sys/ptrace.h> -#include <asm/ptrace.h> - -#include "common.h" - -#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) -# define PTRACE_PEEKUSER PTRACE_PEEKUSR -#endif - -#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) -# define PTRACE_POKEUSER PTRACE_POKEUSR -#endif - -void -get_arch_dep(Process *proc) { -} - -/* Returns 1 if syscall, 2 if sysret, 0 otherwise. - */ -int -syscall_p(Process *proc, int status, int *sysnum) { - if (WIFSTOPPED(status) - && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { - *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ORIG_EAX, 0); - - if (proc->callstack_depth > 0 && - proc->callstack[proc->callstack_depth - 1].is_syscall && - proc->callstack[proc->callstack_depth - 1].c_un.syscall == *sysnum) { - return 2; - } - - if (*sysnum >= 0) { - return 1; - } - } - return 0; -} - -long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { - if (arg_num == -1) { /* return value */ - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EAX, 0); - } - - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - return ptrace(PTRACE_PEEKTEXT, proc->pid, - proc->stack_pointer + 4 * (arg_num + 1), 0); - } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { -#if 0 - switch (arg_num) { - case 0: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EBX, 0); - case 1: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ECX, 0); - case 2: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EDX, 0); - case 3: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ESI, 0); - case 4: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EDI, 0); - default: - fprintf(stderr, - "gimme_arg called with wrong arguments\n"); - exit(2); - } -#else - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 0); -#endif - } else { - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); - } - - return 0; -} - -void -save_register_args(enum tof type, Process *proc) { -} diff --git a/sysdeps/linux-gnu/ia64/Makefile b/sysdeps/linux-gnu/ia64/Makefile deleted file mode 100644 index 4f0ef63..0000000 --- a/sysdeps/linux-gnu/ia64/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OBJ = trace.o regs.o plt.o breakpoint.o - -all: arch.o - -arch.o: $(OBJ) - $(LD) -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o - diff --git a/sysdeps/linux-gnu/ia64/Makefile.am b/sysdeps/linux-gnu/ia64/Makefile.am new file mode 100644 index 0000000..c5fd360 --- /dev/null +++ b/sysdeps/linux-gnu/ia64/Makefile.am @@ -0,0 +1,36 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + breakpoint.c \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/ia64/Makefile.in b/sysdeps/linux-gnu/ia64/Makefile.in new file mode 100644 index 0000000..a4eb305 --- /dev/null +++ b/sysdeps/linux-gnu/ia64/Makefile.in @@ -0,0 +1,533 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/ia64 +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = breakpoint.lo plt.lo regs.lo trace.lo \ + fetch.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + breakpoint.c \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/ia64/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/ia64/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/breakpoint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/ia64/arch.h b/sysdeps/linux-gnu/ia64/arch.h index 673047c..82780d4 100644 --- a/sysdeps/linux-gnu/ia64/arch.h +++ b/sysdeps/linux-gnu/ia64/arch.h @@ -1,9 +1,34 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #define ARCH_HAVE_DISABLE_BREAKPOINT 1 #define ARCH_HAVE_ENABLE_BREAKPOINT 1 +#define ARCH_HAVE_FETCH_ARG +#define ARCH_HAVE_FETCH_PACK #define BREAKPOINT_LENGTH 16 #define BREAKPOINT_VALUE {0} #define DECR_PC_AFTER_BREAK 0 +#define ARCH_ENDIAN_LITTLE +#define ARCH_HAVE_TRANSLATE_ADDRESS #define LT_ELFCLASS ELFCLASS64 #define LT_ELF_MACHINE EM_IA_64 diff --git a/sysdeps/linux-gnu/ia64/breakpoint.c b/sysdeps/linux-gnu/ia64/breakpoint.c index 4f09173..ca34e93 100644 --- a/sysdeps/linux-gnu/ia64/breakpoint.c +++ b/sysdeps/linux-gnu/ia64/breakpoint.c @@ -1,14 +1,33 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2005,2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + /* IA64 breakpoint support. Much of this clagged from gdb * -Ian Wienand <ianw@gelato.unsw.edu.au> 10/3/2005 */ -#include "config.h" - #include <sys/ptrace.h> #include <string.h> -#include "arch.h" -#include "options.h" -#include "output.h" +#include <assert.h> + +#include "breakpoint.h" #include "debug.h" static long long @@ -153,7 +172,8 @@ union bundle_t { }; void -arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) { +arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp) +{ unsigned long addr = (unsigned long)sbp->addr; union bundle_t bundle; @@ -163,9 +183,7 @@ arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) { debug(1, "Enable Breakpoint at %p)", sbp->addr); - if (slotnum > 2) - printf - ("Can't insert breakpoint for slot numbers greater than 2."); + assert(slotnum <= 2); addr &= ~0x0f; bundle.ubundle[0] = ptrace(PTRACE_PEEKTEXT, pid, addr, 0); @@ -190,7 +208,8 @@ arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) { } void -arch_disable_breakpoint(pid_t pid, const Breakpoint *sbp) { +arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp) +{ unsigned long addr = (unsigned long)sbp->addr; int slotnum = (int)(addr & 0x0f) & 0x3; diff --git a/sysdeps/linux-gnu/ia64/fetch.c b/sysdeps/linux-gnu/ia64/fetch.c new file mode 100644 index 0000000..54dc5b8 --- /dev/null +++ b/sysdeps/linux-gnu/ia64/fetch.c @@ -0,0 +1,502 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Steve Fink + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdlib.h> +#include <assert.h> +#include <sys/rse.h> +#include <ptrace.h> +#include <string.h> +#include <errno.h> + +#include "backend.h" +#include "fetch.h" +#include "type.h" +#include "proc.h" +#include "value.h" + +struct fetch_context { + arch_addr_t stack_pointer; + struct pt_all_user_regs regs; + enum param_pack_flavor ppflavor; + + /* Return values larger than 256 bits (except HFAs of up to 8 + * elements) are returned in a buffer allocated by the + * caller. A pointer to the buffer is passed to the called + * procedure in r8. This register is not guaranteed to be + * preserved by the called procedure. */ + unsigned long r8; + + int slot_n; + int flt; +}; + +union cfm_t { + struct { + unsigned long sof:7; + unsigned long sol:7; + unsigned long sor:4; + unsigned long rrb_gr:7; + unsigned long rrb_fr:7; + unsigned long rrb_pr:6; + } cfm; + unsigned long value; +}; + +static int +fetch_context_init(struct Process *proc, struct fetch_context *context) +{ + context->slot_n = 0; + context->flt = 8; + if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0) + return -1; + context->stack_pointer = (void *)(context->regs.gr[12] + 16); + context->ppflavor = PARAM_PACK_ARGS; + + return 0; +} + +struct fetch_context * +arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + struct fetch_context *context = malloc(sizeof(*context)); + if (context == NULL + || fetch_context_init(proc, context) < 0) { + free(context); + return NULL; + } + context->r8 = context->regs.gr[8]; + + return context; +} + +struct fetch_context * +arch_fetch_arg_clone(struct Process *proc, + struct fetch_context *context) +{ + struct fetch_context *clone = malloc(sizeof(*context)); + if (clone == NULL) + return NULL; + *clone = *context; + return clone; +} + +int +allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + size_t al = type_alignof(proc, info); + size_t sz = type_sizeof(proc, info); + if (al == (size_t)-1 || sz == (size_t)-1) + return -1; + + errno = 0; + long value = ptrace(PTRACE_PEEKDATA, proc->pid, ctx->stack_pointer, 0); + if (value == -1 && errno != 0) + return -1; + ctx->stack_pointer += 8; + value_set_word(valuep, value); + + return 0; +} + +static int +allocate_reg(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + if (ctx->slot_n >= 8) + return allocate_stack_slot(ctx, proc, info, valuep); + + int reg_num = ctx->slot_n++; + if (ctx->slot_n == 8) + ctx->flt = 16; + if (valuep == NULL) + return 0; + + /* This would normally be brought over from asm/ptrace.h, but + * when we do, we get namespace conflicts between asm/fpu.h + * and libunwind. */ + enum { PT_AUR_BSP = 17 }; + + union cfm_t cfm = { .value = ctx->regs.cfm }; + unsigned long *bsp = (unsigned long *)ctx->regs.ar[PT_AUR_BSP]; + unsigned long idx = -cfm.cfm.sof + reg_num; + unsigned long *ptr = ia64_rse_skip_regs(bsp, idx); + errno = 0; + long ret = ptrace(PTRACE_PEEKDATA, proc->pid, ptr, 0); + if (ret == -1 && errno != 0) + return -1; + + value_set_word(valuep, ret); + return 0; +} + +static int +copy_aggregate_part(struct fetch_context *ctx, struct Process *proc, + unsigned char *buf, size_t size) +{ + size_t slots = (size + 7) / 8; + struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); + while (slots-- > 0) { + size_t chunk_sz = size > 8 ? 8 : size; + size -= 8; + + struct value tmp; + value_init(&tmp, proc, NULL, long_info, 0); + int rc = allocate_reg(ctx, proc, long_info, &tmp); + if (rc >= 0) { + memcpy(buf, value_get_data(&tmp, NULL), chunk_sz); + buf += 8; + } + value_destroy(&tmp); + if (rc < 0) + return -1; + } + return 0; +} + +static int +allocate_arg(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + size_t sz = type_sizeof(proc, info); + size_t align = type_alignof(proc, info); + if (sz == (size_t)-1 || align == (size_t)-1) + return -1; + + unsigned char *buf = value_reserve(valuep, sz); + if (buf == NULL) + return -1; + + assert(align == 0 || align == 1 || align == 2 || align == 4 + || align == 8 || align == 16); + + /* For aggregates with an external alignment of 16 bytes, the + * Next Even policy is used. 128-bit integers use the Next + * Even policy as well. */ + if (align == 16 && ctx->slot_n % 2 != 0) + allocate_reg(ctx, proc, info, NULL); + + int rc= copy_aggregate_part(ctx, proc, buf, sz); + + return rc; +} + +/* Stolen from David Mosberger's utrace tool, which he released under + the GPL + (http://www.gelato.unsw.edu.au/archives/linux-ia64/0104/1405.html) */ +static inline double +fpreg_to_double (struct ia64_fpreg *fp) { + double result; + asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp)); + return result; +} + +static int +allocate_float(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep, + int take_slot) +{ + /* The actual parameter is passed in the next available + * floating-point parameter register, if one is + * available. Floating-point parameter registers are allocated + * as needed from the range f8-f15, starting with f8. */ + /* Any register parameters corresponding to a + * variable-argument specification are passed in GRs. */ + if (ctx->flt > 15 || ctx->ppflavor == PARAM_PACK_VARARGS) + /* If all available floating-point parameter registers + * have been used, the actual parameter is passed in + * the appropriate general register(s). */ + return allocate_reg(ctx, proc, info, valuep); + + union { + double d; + float f; + char buf[0]; + } u = { .d = fpreg_to_double(&ctx->regs.fr[ctx->flt++]) }; + if (take_slot) + allocate_reg(ctx, proc, info, NULL); + + if (info->type == ARGTYPE_FLOAT) + u.f = u.d; + else + assert(info->type == ARGTYPE_DOUBLE); + + if (value_reserve(valuep, sizeof(u)) == NULL) + return -1; + memmove(value_get_raw_data(valuep), u.buf, sizeof(u)); + + return 0; +} + +static enum arg_type +get_hfa_type(struct arg_type_info *info, size_t *countp) +{ + size_t n = type_aggregate_size(info); + if (n == (size_t)-1) + return ARGTYPE_VOID; + + enum arg_type type = ARGTYPE_VOID; + *countp = 0; + + while (n-- > 0) { + struct arg_type_info *emt = type_element(info, n); + + enum arg_type emt_type = emt->type; + size_t emt_count = 1; + if (emt_type == ARGTYPE_STRUCT || emt_type == ARGTYPE_ARRAY) + emt_type = get_hfa_type(emt, &emt_count); + + if (type == ARGTYPE_VOID) { + if (emt_type != ARGTYPE_FLOAT + && emt_type != ARGTYPE_DOUBLE) + return ARGTYPE_VOID; + type = emt_type; + } + if (emt_type != type) + return ARGTYPE_VOID; + *countp += emt_count; + } + return type; +} + +static int +allocate_hfa(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep, + enum arg_type hfa_type, size_t hfa_count) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + + /* If an actual parameter is known to correspond to an HFA + * formal parameter, each element is passed in the next + * available floating-point argument register, until the eight + * argument registers are exhausted. The remaining elements of + * the aggregate are passed in output GRs, according to the + * normal conventions. + * + * Because HFAs are mapped to parameter slots as aggregates, + * single-precision HFAs will be allocated with two + * floating-point values in each parameter slot, but only one + * value per register. + * + * It is possible for the first of two values in a parameter + * slot to occupy the last available floating- point parameter + * register. In this case, the second value is passed in its + * designated GR, but the half of the GR that would have + * contained the first value is undefined. */ + + size_t slot_off = 0; + + unsigned char *buf = value_reserve(valuep, sz); + if (buf == NULL) + return -1; + + struct arg_type_info *hfa_info = type_get_simple(hfa_type); + size_t hfa_sz = type_sizeof(proc, hfa_info); + + /* Pass in register the part that we can. */ + while (ctx->flt <= 15 && hfa_count > 0) { + struct value tmp; + value_init(&tmp, proc, NULL, hfa_info, 0); + int rc = allocate_float(ctx, proc, hfa_info, &tmp, 0); + if (rc >= 0) { + memcpy(buf, value_get_data(&tmp, NULL), hfa_sz); + slot_off += hfa_sz; + buf += hfa_sz; + hfa_count--; + + /* Scratch each fully used slot. */ + while (slot_off >= 8) { + if (allocate_reg(ctx, proc, info, NULL) < 0) + rc = -1; + slot_off -= 8; + } + } + value_destroy(&tmp); + if (rc < 0) + return -1; + } + + /* If we have half-slot opened (the case where odd + * ARGTYPE_FLOAT member fits into the last floating point + * register, and the following even member does not), finish + * it first. */ + struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); + if (slot_off != 0 && hfa_count > 0) { + struct value tmp; + value_init(&tmp, proc, NULL, long_info, 0); + int rc = allocate_reg(ctx, proc, long_info, &tmp); + if (rc >= 0) { + unsigned char *data = value_get_data(&tmp, NULL); + memcpy(buf, data, 8 - slot_off); + buf += 8 - slot_off; + hfa_count--; + } + value_destroy(&tmp); + if (rc < 0) { + return -1; + } + } + + /* The rest is passed in registers and on stack. */ + size_t rest = hfa_count * hfa_sz; + return copy_aggregate_part(ctx, proc, buf, rest); +} + +static int +allocate_ret(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + + /* Homogeneous floating-point aggregates [...] are returned in + * floating-point registers, provided the array or structure + * contains no more than eight individual values. The + * elements of the aggregate are placed in successive + * floating-point registers, beginning with f8. */ + if (info->type == ARGTYPE_STRUCT || info->type == ARGTYPE_ARRAY) { + size_t hfa_size; + enum arg_type hfa_type = get_hfa_type(info, &hfa_size); + if (hfa_type != ARGTYPE_VOID && hfa_size <= 8) + return allocate_hfa(ctx, proc, info, valuep, + hfa_type, hfa_size); + } + + /* Integers and pointers are passed in r8. 128-bit integers + * are passed in r8 and r9. Aggregates of up to 256 bits [32 + * bytes] are passed in registers r8...r11. */ + if (sz <= 32) { + unsigned char *buf = value_reserve(valuep, sz); + if (buf == NULL) + return -1; + memcpy(buf, ctx->regs.gr + 8, sz); + return 0; + } + + if (value_pass_by_reference(valuep) < 0) + return -1; + value_set_word(valuep, ctx->r8); + return 0; +} + +int +arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + switch (info->type) { + enum arg_type hfa_type; + size_t hfa_size; + + case ARGTYPE_VOID: + value_set_word(valuep, 0); + return 0; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + return allocate_float(ctx, proc, info, valuep, 1); + + case ARGTYPE_STRUCT: + hfa_type = get_hfa_type(info, &hfa_size); + if (hfa_type != ARGTYPE_VOID) + return allocate_hfa(ctx, proc, info, valuep, + hfa_type, hfa_size); + /* Fall through. */ + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return allocate_arg(ctx, proc, info, valuep); + + case ARGTYPE_ARRAY: + /* Arrays decay into pointers. XXX Fortran? */ + default: + assert(info->type != info->type); + abort(); + } +} + +int +arch_fetch_retval(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (fetch_context_init(proc, ctx) < 0) + return -1; + + switch (info->type) { + case ARGTYPE_VOID: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + /* The rules for returning those types are the same as + * for passing them in arguments. */ + return arch_fetch_arg_next(ctx, type, proc, info, valuep); + + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + case ARGTYPE_STRUCT: + return allocate_ret(ctx, proc, info, valuep); + + case ARGTYPE_ARRAY: + /* Arrays decay into pointers. XXX Fortran? */ + assert(info->type != ARGTYPE_ARRAY); + abort(); + } + assert("unhandled type"); + abort(); + return arch_fetch_arg_next(ctx, type, proc, info, valuep); +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + free(context); +} + +int +arch_fetch_param_pack_start(struct fetch_context *context, + enum param_pack_flavor ppflavor) +{ + context->ppflavor = ppflavor; + return 0; +} + +void +arch_fetch_param_pack_end(struct fetch_context *context) +{ + context->ppflavor = PARAM_PACK_ARGS; +} diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c index 7fd451b..a29488f 100644 --- a/sysdeps/linux-gnu/ia64/plt.c +++ b/sysdeps/linux-gnu/ia64/plt.c @@ -1,29 +1,56 @@ -#include <gelf.h> -#include "common.h" - -/* A bundle is 128 bits */ -#define BUNDLE_SIZE 16 - /* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ - The PLT has - - ] 3 bundles as a header - - ] The special reserved entry +#include <errno.h> +#include <gelf.h> +#include <stdio.h> +#include <string.h> +#include <sys/ptrace.h> - ] Following that, each PLT entry has it's initial code that the GOT entry - points to. Each PLT entry has one bundle allocated. +#include "proc.h" +#include "common.h" +#include "library.h" - ] Following that, each PLT entry has two bundles of actual PLT code, - i.e. load up the address from the GOT and jump to it. This is the - point we want to insert the breakpoint, as this will be captured - every time we jump to the PLT entry in the code. +/* A bundle is 128 bits. */ +#define BUNDLE_SIZE 16 -*/ +/* The PLT has + * + * - 3 bundles as a header + * + * - The special reserved entry + * + * - Following that, each PLT entry has it's initial code that the GOT + * entry points to. Each PLT entry has one bundle allocated. + * + * - Following that, each PLT entry has two bundles of actual PLT + * code, i.e. load up the address from the GOT and jump to it. This + * is the point we want to insert the breakpoint, as this will be + * captured every time we jump to the PLT entry in the code. + */ GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) +{ /* Find number of entires by removing header and special * entry, dividing total size by three, since each PLT entry * will have 3 bundles (1 for inital entry and two for the PLT @@ -35,7 +62,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { unsigned long addr = lte->plt_addr + (4 * BUNDLE_SIZE) + (BUNDLE_SIZE * entries) + (2 * ndx * BUNDLE_SIZE); - debug(3, "Found PLT %d entry at %lx\n", ndx, addr); + debug(3, "Found PLT %zd entry at %lx", ndx, addr); return addr; } @@ -44,3 +71,29 @@ void * sym2addr(Process *proc, struct library_symbol *sym) { return sym->enter_addr; } + +int +arch_translate_address_dyn(struct Process *proc, + arch_addr_t addr, arch_addr_t *ret) +{ + errno = 0; + unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); + if (l == -1UL && errno) { + fprintf(stderr, "dynamic .opd translation of %p: %s\n", + addr, strerror(errno)); + return -1; + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + *ret = (arch_addr_t)(uintptr_t)l; + return 0; +} + +int +arch_translate_address(struct ltelf *lte, + arch_addr_t addr, arch_addr_t *ret) +{ + *ret = addr; + return 0; +} diff --git a/sysdeps/linux-gnu/ia64/ptrace.h b/sysdeps/linux-gnu/ia64/ptrace.h index c3cbcb6..ef63b4f 100644 --- a/sysdeps/linux-gnu/ia64/ptrace.h +++ b/sysdeps/linux-gnu/ia64/ptrace.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/ia64/regs.c b/sysdeps/linux-gnu/ia64/regs.c index d161d34..cbc2744 100644 --- a/sysdeps/linux-gnu/ia64/regs.c +++ b/sysdeps/linux-gnu/ia64/regs.c @@ -1,13 +1,36 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> #include <sys/ptrace.h> +#include <errno.h> #include <asm/ptrace_offsets.h> #include <asm/rse.h> #include <stddef.h> -#include "debug.h" +#include "proc.h" #include "common.h" void * @@ -37,12 +60,18 @@ set_instruction_pointer(Process *proc, void *addr) { void * get_stack_pointer(Process *proc) { - return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0); + long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0); + if (l == -1 && errno) + return NULL; + return (void *)l; } void * get_return_addr(Process *proc, void *stack_pointer) { - return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_B0, 0); + long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_B0, 0); + if (l == -1 && errno) + return NULL; + return (void *)l; } void diff --git a/sysdeps/linux-gnu/ia64/signalent.h b/sysdeps/linux-gnu/ia64/signalent.h index 5395f82..31699db 100644 --- a/sysdeps/linux-gnu/ia64/signalent.h +++ b/sysdeps/linux-gnu/ia64/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/ia64/syscallent.h b/sysdeps/linux-gnu/ia64/syscallent.h index 9bb4fb8..094cea2 100644 --- a/sysdeps/linux-gnu/ia64/syscallent.h +++ b/sysdeps/linux-gnu/ia64/syscallent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "0", /* 0 */ "1", /* 1 */ "2", /* 2 */ diff --git a/sysdeps/linux-gnu/ia64/trace.c b/sysdeps/linux-gnu/ia64/trace.c index 799e0ff..e608275 100644 --- a/sysdeps/linux-gnu/ia64/trace.c +++ b/sysdeps/linux-gnu/ia64/trace.c @@ -1,3 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Steve Fink + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <stdlib.h> @@ -9,8 +31,11 @@ #include <string.h> #include <asm/ptrace_offsets.h> #include <asm/rse.h> +#include <errno.h> +#include "proc.h" #include "common.h" +#include "type.h" /* What we think of as a bundle, ptrace thinks of it as two unsigned * longs */ @@ -48,9 +73,10 @@ int syscall_p(Process *proc, int status, int *sysnum) { if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { - unsigned long slot = - (ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & - 0x3; + long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0); + if (l == -1 && errno) + return -1; + unsigned long slot = ((unsigned long)l >> 41) & 0x3; unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0); @@ -114,155 +140,6 @@ syscall_p(Process *proc, int status, int *sysnum) { return 0; } -/* Stolen from David Mosberger's utrace tool, which he released under - the GPL - (http://www.gelato.unsw.edu.au/archives/linux-ia64/0104/1405.html) */ -static inline double -fpreg_to_double (struct ia64_fpreg *fp) { - double result; - - asm ("ldf.fill %0=%1" : "=f"(result) : "m"(*fp)); - return result; -} - -static long -gimme_long_arg(enum tof type, Process *proc, int arg_num) { - union cfm_t cfm; - unsigned long bsp; - - bsp = ptrace(PTRACE_PEEKUSER, proc->pid, PT_AR_BSP, 0); - cfm.value = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CFM, 0); - - if (arg_num == -1) /* return value */ - return ptrace(PTRACE_PEEKUSER, proc->pid, PT_R8, 0); - - /* First 8 arguments are passed in registers on the register - * stack, the following arguments are passed on the stack - * after a 16 byte scratch area - * - * If the function has returned, the ia64 register window has - * been reverted to the caller's configuration. So although in - * the callee, the first parameter is in R32, in the caller - * the first parameter comes in the registers after the local - * registers (really, input parameters plus locals, but the - * hardware doesn't track the distinction.) So we have to add - * in the size of the local area (sol) to find the first - * parameter passed to the callee. */ - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - if (arg_num < 8) { - if (type == LT_TOF_FUNCTIONR) - arg_num += cfm.cfm.sol; - - return ptrace(PTRACE_PEEKDATA, proc->pid, - (long)ia64_rse_skip_regs((unsigned long *)bsp, - -cfm.cfm.sof + arg_num), - 0); - } else { - unsigned long sp = - ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0) + 16; - return ptrace(PTRACE_PEEKDATA, proc->pid, - sp + (8 * (arg_num - 8))); - } - } - - if (type == LT_TOF_SYSCALL || LT_TOF_SYSCALLR) - return ptrace(PTRACE_PEEKDATA, proc->pid, - (long)ia64_rse_skip_regs((unsigned long *)bsp, arg_num), - 0); - - /* error if we get here */ - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); -} - -static long float_regs[8] = { PT_F8, PT_F9, PT_F10, PT_F11, - PT_F12, PT_F13, PT_F14, PT_F15 }; -static double -gimme_float_arg(enum tof type, Process *proc, int arg_num) { - union cfm_t cfm; - unsigned long bsp; - struct ia64_fpreg reg; - - if (arg_num == -1) { /* return value */ - reg.u.bits[0] = ptrace(PTRACE_PEEKUSER, proc->pid, - PT_F8, 0); - reg.u.bits[1] = ptrace(PTRACE_PEEKUSER, proc->pid, - PT_F8 + 0x8, 0); - return fpreg_to_double(®); - } - - bsp = ptrace(PTRACE_PEEKUSER, proc->pid, PT_AR_BSP, 0); - cfm.value = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CFM, 0); - - /* The first 8 arguments are passed in regular registers - * (counting from R32), unless they are floating point values - * (the case in question here). In that case, up to the first - * 8 regular registers are still "allocated" for each of the - * first 8 parameters, but if a parameter is floating point, - * then the register is left unset and the parameter is passed - * in the first available floating-point register, counting - * from F8. - * - * Take func(int a, float f, int b, double d), for example. - * a - passed in R32 - * f - R33 left unset, value passed in F8 - * b - passed in R34 - * d - R35 left unset, value passed in F9 - * - * ltrace handles this by counting floating point arguments - * while parsing declarations. The "arg_num" in this routine - * (which is only called for floating point values) really - * means which floating point parameter we're looking for, - * ignoring everything else. - * - * Following the first 8 arguments, the remaining arguments - * are passed on the stack after a 16 byte scratch area - */ - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - if (arg_num < 8) { - reg.u.bits[0] = ptrace(PTRACE_PEEKUSER, proc->pid, - float_regs[arg_num], 0); - reg.u.bits[1] = ptrace(PTRACE_PEEKUSER, proc->pid, - float_regs[arg_num] + 0x8, 0); - return fpreg_to_double(®); - } else { - unsigned long sp = - ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0) + 16; - reg.u.bits[0] = ptrace(PTRACE_PEEKDATA, proc->pid, - sp + (8 * (arg_num - 8))); - reg.u.bits[0] = ptrace(PTRACE_PEEKDATA, proc->pid, - sp + (8 * (arg_num - 8)) + 0x8); - return fpreg_to_double(®); - } - } - - /* error if we get here */ - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); -} - -long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { - union { - long l; - float f; - double d; - } cvt; - - if (info->type == ARGTYPE_FLOAT) - cvt.f = gimme_float_arg(type, proc, info->u.float_info.float_index); - else if (info->type == ARGTYPE_DOUBLE) - cvt.d = gimme_float_arg(type, proc, info->u.double_info.float_index); - else - cvt.l = gimme_long_arg(type, proc, arg_num); - - return cvt.l; -} - -void -save_register_args(enum tof type, Process *proc) { -} - void get_arch_dep(Process *proc) { } diff --git a/sysdeps/linux-gnu/m68k/Makefile b/sysdeps/linux-gnu/m68k/Makefile deleted file mode 100644 index 60d7531..0000000 --- a/sysdeps/linux-gnu/m68k/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OBJ = trace.o regs.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o - diff --git a/sysdeps/linux-gnu/m68k/Makefile.am b/sysdeps/linux-gnu/m68k/Makefile.am new file mode 100644 index 0000000..aa63e15 --- /dev/null +++ b/sysdeps/linux-gnu/m68k/Makefile.am @@ -0,0 +1,35 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/m68k/Makefile.in b/sysdeps/linux-gnu/m68k/Makefile.in new file mode 100644 index 0000000..45eebd3 --- /dev/null +++ b/sysdeps/linux-gnu/m68k/Makefile.in @@ -0,0 +1,530 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/m68k +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/m68k/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/m68k/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/m68k/arch.h b/sysdeps/linux-gnu/m68k/arch.h index 1790d09..3829901 100644 --- a/sysdeps/linux-gnu/m68k/arch.h +++ b/sysdeps/linux-gnu/m68k/arch.h @@ -1,6 +1,29 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2002,2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#define ARCH_HAVE_FETCH_ARG + #define BREAKPOINT_VALUE { 0x4e, 0x4f } #define BREAKPOINT_LENGTH 2 #define DECR_PC_AFTER_BREAK 2 +#define ARCH_ENDIAN_BIG #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_68K diff --git a/sysdeps/linux-gnu/m68k/fetch.c b/sysdeps/linux-gnu/m68k/fetch.c new file mode 100644 index 0000000..f6d8a0b --- /dev/null +++ b/sysdeps/linux-gnu/m68k/fetch.c @@ -0,0 +1,239 @@ +/* + * This file is part of ltrace. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <sys/types.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <sys/procfs.h> +#include <sys/reg.h> + +#include "backend.h" +#include "expr.h" +#include "fetch.h" +#include "proc.h" +#include "ptrace.h" +#include "type.h" +#include "value.h" + +struct fetch_context +{ + elf_gregset_t regs; + elf_fpregset_t fpregs; + + int arg_num; + arch_addr_t stack_pointer; + struct value retval; +}; + +static int +fetch_register_banks(struct Process *proc, struct fetch_context *context, + int floating) +{ + if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0) + return -1; + + if (floating + && ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0) + return -1; + + return 0; +} + +struct fetch_context * +arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + struct fetch_context *context = malloc(sizeof(*context)); + if (context == NULL) + return NULL; + + assert(type != LT_TOF_FUNCTIONR && type != LT_TOF_SYSCALLR); + if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTION) < 0) { + fail: + free(context); + return NULL; + } + + context->arg_num = 0; + context->stack_pointer = (arch_addr_t)context->regs[PT_USP] + 4; + + size_t sz = type_sizeof(proc, ret_info); + if (sz == (size_t)-1) + goto fail; + + if (ret_info->type == ARGTYPE_STRUCT && !(sz <= 4 || sz == 8)) { + value_init(&context->retval, proc, NULL, ret_info, 0); + + if (value_pass_by_reference(&context->retval) < 0) + goto fail; + value_set_word(&context->retval, context->regs[PT_A1]); + } else { + value_init_detached(&context->retval, NULL, NULL, 0); + } + + return context; +} + +struct fetch_context * +arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) +{ + struct fetch_context *ret = malloc(sizeof(*ret)); + if (ret == NULL) + return NULL; + *ret = *context; + return ret; +} + +int +arch_fetch_arg_next(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + + if (type == LT_TOF_SYSCALL) { + int reg; + + switch (context->arg_num++) { + case 0: reg = PT_D1; break; + case 1: reg = PT_D2; break; + case 2: reg = PT_D3; break; + case 3: reg = PT_D4; break; + case 4: reg = PT_D5; break; + case 5: reg = PT_A0; break; + default: + assert(!"More than six syscall arguments???"); + abort(); + } + value_set_word(valuep, context->regs[reg]); + } else { + size_t a = type_alignof(valuep->inferior, valuep->type); + if (a < 4) + a = 4; + context->stack_pointer = (arch_addr_t) + align((unsigned long)context->stack_pointer, a); + if (sz < 4) + context->stack_pointer += 4 - sz; + + value_in_inferior(valuep, context->stack_pointer); + context->stack_pointer += sz; + } + + return 0; +} + +int +arch_fetch_retval(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0) + return -1; + + if (context->retval.type != NULL) { + /* Struct return value was extracted when in fetch + * init. */ + *valuep = context->retval; + return 0; + } + + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + if (value_reserve(valuep, sz) == NULL) + return -1; + + switch (info->type) { + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_POINTER: + { + unsigned char *buf = value_get_raw_data(valuep); + int reg = info->type == ARGTYPE_POINTER ? PT_A0 : PT_D0; + unsigned char *val + = (unsigned char *)&context->regs[reg]; + if (sz < 4) val += 4 - sz; + memcpy(buf, val, sz); + } + return 0; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + { + union { + long double ld; + double d; + float f; + char buf[0]; + } u; + + unsigned long *reg = &context->fpregs.fpregs[0]; + memcpy (&u.ld, reg, sizeof (u.ld)); + if (valuep->type->type == ARGTYPE_FLOAT) + u.f = (float)u.ld; + else if (valuep->type->type == ARGTYPE_DOUBLE) + u.d = (double)u.ld; + else { + assert(!"Unexpected floating type!"); + abort(); + } + unsigned char *buf = value_get_raw_data (valuep); + memcpy (buf, u.buf, sz); + } + return 0; + + case ARGTYPE_STRUCT: + { + unsigned char *buf = value_get_raw_data(valuep); + unsigned char *val + = (unsigned char *)&context->regs[PT_D0]; + + assert(sz <= 4 || sz == 8); + if (sz < 4) val += 4 - sz; + memcpy(buf, val, sz <= 4 ? sz : 4); + if (sz == 8) + memcpy(buf + 4, &context->regs[PT_D1], 4); + } + return 0; + + default: + assert(!"Unexpected m68k retval type!"); + abort(); + } + + abort(); +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + if (context != NULL) + free(context); +} diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c index 508d7fc..c1b37dd 100644 --- a/sysdeps/linux-gnu/m68k/plt.c +++ b/sysdeps/linux-gnu/m68k/plt.c @@ -1,10 +1,32 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <gelf.h> +#include "proc.h" #include "common.h" +#include "library.h" GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { return lte->plt_addr + (ndx + 1) - * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12); + * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 20); } void * diff --git a/sysdeps/linux-gnu/m68k/ptrace.h b/sysdeps/linux-gnu/m68k/ptrace.h index c3cbcb6..ad7e0d6 100644 --- a/sysdeps/linux-gnu/m68k/ptrace.h +++ b/sysdeps/linux-gnu/m68k/ptrace.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/m68k/regs.c b/sysdeps/linux-gnu/m68k/regs.c index 959a60e..4afdfbb 100644 --- a/sysdeps/linux-gnu/m68k/regs.c +++ b/sysdeps/linux-gnu/m68k/regs.c @@ -1,9 +1,30 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2002,2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) diff --git a/sysdeps/linux-gnu/m68k/signalent.h b/sysdeps/linux-gnu/m68k/signalent.h index 5395f82..31699db 100644 --- a/sysdeps/linux-gnu/m68k/signalent.h +++ b/sysdeps/linux-gnu/m68k/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/m68k/syscallent.h b/sysdeps/linux-gnu/m68k/syscallent.h index 4d65b39..ceafd2e 100644 --- a/sysdeps/linux-gnu/m68k/syscallent.h +++ b/sysdeps/linux-gnu/m68k/syscallent.h @@ -1,4 +1,25 @@ - "0", /* 0 */ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Andreas Schwab + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + "restart_syscall", /* 0 */ "exit", /* 1 */ "fork", /* 2 */ "read", /* 3 */ @@ -15,7 +36,7 @@ "mknod", /* 14 */ "chmod", /* 15 */ "chown", /* 16 */ - "break", /* 17 */ + "17", /* 17 */ "oldstat", /* 18 */ "lseek", /* 19 */ "getpid", /* 20 */ @@ -29,11 +50,11 @@ "oldfstat", /* 28 */ "pause", /* 29 */ "utime", /* 30 */ - "stty", /* 31 */ - "gtty", /* 32 */ + "31", /* 31 */ + "32", /* 32 */ "access", /* 33 */ "nice", /* 34 */ - "ftime", /* 35 */ + "35", /* 35 */ "sync", /* 36 */ "kill", /* 37 */ "rename", /* 38 */ @@ -42,7 +63,7 @@ "dup", /* 41 */ "pipe", /* 42 */ "times", /* 43 */ - "prof", /* 44 */ + "44", /* 44 */ "brk", /* 45 */ "setgid", /* 46 */ "getgid", /* 47 */ @@ -51,13 +72,13 @@ "getegid", /* 50 */ "acct", /* 51 */ "umount2", /* 52 */ - "lock", /* 53 */ + "53", /* 53 */ "ioctl", /* 54 */ "fcntl", /* 55 */ - "mpx", /* 56 */ + "56", /* 56 */ "setpgid", /* 57 */ - "ulimit", /* 58 */ - "oldolduname", /* 59 */ + "58", /* 58 */ + "59", /* 59 */ "umask", /* 60 */ "chroot", /* 61 */ "ustat", /* 62 */ @@ -96,10 +117,10 @@ "fchown", /* 95 */ "getpriority", /* 96 */ "setpriority", /* 97 */ - "profil", /* 98 */ + "98", /* 98 */ "statfs", /* 99 */ "fstatfs", /* 100 */ - "ioperm", /* 101 */ + "101", /* 101 */ "socketcall", /* 102 */ "syslog", /* 103 */ "setitimer", /* 104 */ @@ -107,7 +128,7 @@ "stat", /* 106 */ "lstat", /* 107 */ "fstat", /* 108 */ - "olduname", /* 109 */ + "109", /* 109 */ "110", /* 110 */ "vhangup", /* 111 */ "112", /* 112 */ @@ -135,7 +156,7 @@ "bdflush", /* 134 */ "sysfs", /* 135 */ "personality", /* 136 */ - "afs_syscall", /* 137 */ + "137", /* 137 */ "setfsuid", /* 138 */ "setfsgid", /* 139 */ "_llseek", /* 140 */ @@ -276,7 +297,72 @@ "mq_notify", /* 275 */ "mq_getsetattr", /* 276 */ "waitid", /* 277 */ - "vserver", /* 278 */ + "278", /* 278 */ "add_key", /* 279 */ "request_key", /* 280 */ "keyctl", /* 281 */ + "ioprio_set", /* 282 */ + "ioprio_get", /* 283 */ + "inotify_init", /* 284 */ + "inotify_add_watch", /* 285 */ + "inotify_rm_watch", /* 286 */ + "migrate_pages", /* 287 */ + "openat", /* 288 */ + "mkdirat", /* 289 */ + "mknodat", /* 290 */ + "fchownat", /* 291 */ + "futimesat", /* 292 */ + "fstatat64", /* 293 */ + "unlinkat", /* 294 */ + "renameat", /* 295 */ + "linkat", /* 296 */ + "symlinkat", /* 297 */ + "readlinkat", /* 298 */ + "fchmodat", /* 299 */ + "faccessat", /* 300 */ + "pselect6", /* 301 */ + "ppoll", /* 302 */ + "unshare", /* 303 */ + "set_robust_list", /* 304 */ + "get_robust_list", /* 305 */ + "splice", /* 306 */ + "sync_file_range", /* 307 */ + "tee", /* 308 */ + "vmsplice", /* 309 */ + "move_pages", /* 310 */ + "sched_setaffinity", /* 311 */ + "sched_getaffinity", /* 312 */ + "kexec_load", /* 313 */ + "getcpu", /* 314 */ + "epoll_pwait", /* 315 */ + "utimensat", /* 316 */ + "signalfd", /* 317 */ + "timerfd_create", /* 318 */ + "eventfd", /* 319 */ + "fallocate", /* 320 */ + "timerfd_settime", /* 321 */ + "timerfd_gettime", /* 322 */ + "signalfd4", /* 323 */ + "eventfd2", /* 324 */ + "epoll_create1", /* 325 */ + "dup3", /* 326 */ + "pipe2", /* 327 */ + "inotify_init1", /* 328 */ + "preadv", /* 329 */ + "pwritev", /* 330 */ + "rt_tgsigqueueinfo", /* 331 */ + "perf_event_open", /* 332 */ + "get_thread_area", /* 333 */ + "set_thread_area", /* 334 */ + "atomic_cmpxchg_32", /* 335 */ + "atomic_barrier", /* 336 */ + "fanotify_init", /* 337 */ + "fanotify_mark", /* 338 */ + "prlimit64", /* 339 */ + "name_to_handle_at", /* 340 */ + "open_by_handle_at", /* 341 */ + "clock_adjtime", /* 342 */ + "syncfs", /* 343 */ + "setns", /* 344 */ + "process_vm_readv", /* 345 */ + "process_vm_writev", /* 346 */ diff --git a/sysdeps/linux-gnu/m68k/trace.c b/sysdeps/linux-gnu/m68k/trace.c index 2f89fdf..311ffd5 100644 --- a/sysdeps/linux-gnu/m68k/trace.c +++ b/sysdeps/linux-gnu/m68k/trace.c @@ -1,3 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 1998,2001,2004,2008,2009 Juan Cespedes + * Copyright (C) 2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> @@ -6,6 +28,7 @@ #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) @@ -44,46 +67,3 @@ syscall_p(Process *proc, int status, int *sysnum) { } return 0; } - -long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { - if (arg_num == -1) { /* return value */ - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D0, 0); - } - - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - return ptrace(PTRACE_PEEKTEXT, proc->pid, - proc->stack_pointer + 4 * (arg_num + 1), 0); - } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { -#if 0 - switch (arg_num) { - case 0: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D1, 0); - case 1: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D2, 0); - case 2: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D3, 0); - case 3: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D4, 0); - case 4: - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D5, 0); - default: - fprintf(stderr, - "gimme_arg called with wrong arguments\n"); - exit(2); - } -#else - /* That hack works on m68k, too */ - return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 0); -#endif - } else { - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); - } - - return 0; -} - -void -save_register_args(enum tof type, Process *proc) { -} diff --git a/sysdeps/linux-gnu/mipsel/Doxyfile b/sysdeps/linux-gnu/mipsel/Doxyfile index b4f5eb2..165f929 100644 --- a/sysdeps/linux-gnu/mipsel/Doxyfile +++ b/sysdeps/linux-gnu/mipsel/Doxyfile @@ -1,3 +1,21 @@ +# This file is part of ltrace. +# Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + # Doxyfile 1.5.1 #--------------------------------------------------------------------------- diff --git a/sysdeps/linux-gnu/mipsel/Makefile b/sysdeps/linux-gnu/mipsel/Makefile deleted file mode 100644 index 44f4aae..0000000 --- a/sysdeps/linux-gnu/mipsel/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -.PHONY: all deps clean docs - -OBJ = trace.o regs.o plt.o -SRC=$(OBJ:.o=.c) - -all: arch.o - -deps: - $(CC) $(CFLAGS) $(CPPFLAGS) -M $(SRC) > .depends - -arch.o: $(OBJ) arch.h - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - -rm -f $(OBJ) arch.o - -rm -rf html - -docs: - doxygen - - --include .depends diff --git a/sysdeps/linux-gnu/mipsel/Makefile.am b/sysdeps/linux-gnu/mipsel/Makefile.am new file mode 100644 index 0000000..9cf8f19 --- /dev/null +++ b/sysdeps/linux-gnu/mipsel/Makefile.am @@ -0,0 +1,38 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + mipsel.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +EXTRA_DIST = \ + Doxyfile + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/mipsel/Makefile.in b/sysdeps/linux-gnu/mipsel/Makefile.in new file mode 100644 index 0000000..f0a1b06 --- /dev/null +++ b/sysdeps/linux-gnu/mipsel/Makefile.in @@ -0,0 +1,532 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/mipsel +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + mipsel.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +EXTRA_DIST = \ + Doxyfile + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/mipsel/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/mipsel/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h index dd0ca35..684b546 100644 --- a/sysdeps/linux-gnu/mipsel/arch.h +++ b/sysdeps/linux-gnu/mipsel/arch.h @@ -1,9 +1,67 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Eric Vaitl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LTRACE_MIPS_ARCH_H +#define LTRACE_MIPS_ARCH_H + +#include <stddef.h> +#include <gelf.h> + #define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 } #define BREAKPOINT_LENGTH 4 #define DECR_PC_AFTER_BREAK 0 +#define ARCH_ENDIAN_LITTLE #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_MIPS -#define PLTs_INIT_BY_HERE "_start" -#define E_ENTRY_NAME "_start" +#define ARCH_HAVE_LTELF_DATA +struct arch_ltelf_data { + size_t pltgot_addr; + size_t mips_local_gotno; + size_t mips_gotsym; +}; + +#define ARCH_HAVE_FIND_DL_DEBUG +#define ARCH_HAVE_GET_SYMINFO +#define ARCH_HAVE_DYNLINK_DONE +#define ARCH_HAVE_ADD_PLT_ENTRY +#define ARCH_HAVE_ATOMIC_SINGLESTEP +#define ARCH_HAVE_SYMBOL_RET + +#define ARCH_HAVE_LIBRARY_SYMBOL_DATA +enum mips_plt_type +{ + MIPS_PLT_UNRESOLVED, + MIPS_PLT_RESOLVED, +}; + +struct arch_library_symbol_data { + enum mips_plt_type type; + GElf_Addr resolved_addr; + GElf_Addr stub_addr; + + /* Set for FUNCs that have GOT entries but not PLT entries. */ + int gotonly : 1; + /* Set for FUNCs that have PLT entries that are always used. */ + int pltalways : 1; +}; + +#endif /* LTRACE_MIPS_ARCH_H */ diff --git a/sysdeps/linux-gnu/mipsel/mipsel.h b/sysdeps/linux-gnu/mipsel/mipsel.h index a63cafd..a2dbda2 100644 --- a/sysdeps/linux-gnu/mipsel/mipsel.h +++ b/sysdeps/linux-gnu/mipsel/mipsel.h @@ -1,11 +1,33 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Arnaud Patard, Mandriva SA + * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #ifndef MIPSEL_h #define MIPSEL_h -// linux-2.4.30/arch/mips/kernel/ptrace.c for these offsets. +// asm/ptrace.h for these offsets. #define off_v0 2 #define off_pc 64 #define off_a0 4 #define off_a3 7 #define off_lr 31 +#define off_fpr0 32 #define off_sp 29 #endif // MIPSEL_h diff --git a/sysdeps/linux-gnu/mipsel/plt.c b/sysdeps/linux-gnu/mipsel/plt.c index 003171b..b277fbc 100644 --- a/sysdeps/linux-gnu/mipsel/plt.c +++ b/sysdeps/linux-gnu/mipsel/plt.c @@ -1,13 +1,51 @@ -#include <debug.h> +/* + * This file is part of ltrace. + * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <string.h> +#include <error.h> +#include <errno.h> #include <gelf.h> #include <sys/ptrace.h> + #include "common.h" +#include "debug.h" +#include "proc.h" +#include "library.h" +#include "breakpoint.h" +#include "backend.h" /** \addtogroup mipsel @{ */ +/* Are we in pure CPIC mode (the non-PIC ABI extension)? */ +static inline int +mips_elf_is_cpic(unsigned int elf_flags) +{ + return (elf_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC; +} + /** \param lte Structure containing link table entry information \param ndx Index into .dynsym @@ -32,10 +70,19 @@ */ GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - debug(1,"plt_addr %x ndx %#x",lte->pltgot_addr, ndx); - return lte->pltgot_addr + - sizeof(void *) * (lte->mips_local_gotno + (ndx - lte->mips_gotsym)); +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) +{ + debug(1,"plt_addr %zx ndx %#zx",lte->arch.pltgot_addr, ndx); + + if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + /* Return a pointer into the PLT. */ + return lte->plt_addr + 16 * 2 + (ndx * 16); + } + + /* Return a pointer to a GOT entry. */ + return lte->arch.pltgot_addr + + sizeof(void *) * (lte->arch.mips_local_gotno + + (ndx - lte->arch.mips_gotsym)); } /** \param proc The process to work on. @@ -59,6 +106,12 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { void * sym2addr(Process *proc, struct library_symbol *sym) { long ret; + + if (sym->arch.pltalways + || (!sym->arch.gotonly && sym->plt_type == LS_TOPLT_NONE)) { + return sym->enter_addr; + } + if(!proc->pid){ return 0; } @@ -69,4 +122,304 @@ sym2addr(Process *proc, struct library_symbol *sym) { return (void *)ret;; } +/* Address of run time loader map, used for debugging. */ +#define DT_MIPS_RLD_MAP 0x70000016 +int +arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr, + arch_addr_t *ret) +{ + arch_addr_t rld_addr; + int r; + + /* MIPS puts the address of the r_debug structure into the + * DT_MIPS_RLD_MAP entry instead of into the DT_DEBUG entry. */ + r = proc_find_dynamic_entry_addr(proc, dyn_addr, + DT_MIPS_RLD_MAP, &rld_addr); + if (r == 0) { + if (umovebytes(proc, rld_addr, + ret, sizeof *ret) != sizeof *ret) { + r = -1; + } + } + return r; +} + + +/* + * MIPS doesn't have traditional got.plt entries with corresponding + * relocations. + * + * sym_index is an offset into the external GOT entries. Filter out + * stuff that are not functions. + */ +int +arch_get_sym_info(struct ltelf *lte, const char *filename, + size_t sym_index, GElf_Rela *rela, GElf_Sym *sym) +{ + const char *name; + + if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + return elf_get_sym_info(lte, filename, sym_index, rela, sym); + } + + /* Fixup the offset. */ + sym_index += lte->arch.mips_gotsym; + + if (gelf_getsym(lte->dynsym, sym_index, sym) == NULL){ + error(EXIT_FAILURE, 0, + "Couldn't get relocation from \"%s\"", filename); + } + + name = lte->dynstr + sym->st_name; + if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC) { + debug(2, "sym %s not a function", name); + return -1; + } + + return 0; +} + +/** + MIPS ABI Supplement: + + DT_PLTGOT This member holds the address of the .got section. + + DT_MIPS_SYMTABNO This member holds the number of entries in the + .dynsym section. + + DT_MIPS_LOCAL_GOTNO This member holds the number of local global + offset table entries. + + DT_MIPS_GOTSYM This member holds the index of the first dyamic + symbol table entry that corresponds to an entry in the gobal offset + table. + + */ +int +arch_elf_init(struct ltelf *lte, struct library *lib) +{ + Elf_Scn *scn; + GElf_Shdr shdr; + + /* FIXME: for CPIC we should really scan both GOT tables + * to pick up relocations to external functions. Right now + * function pointers from the main binary to external functions + * can't be traced in CPIC mode. */ + if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + return 0; /* We are already done. */ + } + + if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 + || scn == NULL) { + fail: + error(0, 0, "Couldn't get SHT_DYNAMIC: %s", + elf_errmsg(-1)); + return -1; + } + + Elf_Data *data = elf_loaddata(scn, &shdr); + if (data == NULL) + goto fail; + + size_t j; + for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { + GElf_Dyn dyn; + if (gelf_getdyn(data, j, &dyn) == NULL) + goto fail; + + if(dyn.d_tag == DT_PLTGOT) { + lte->arch.pltgot_addr = dyn.d_un.d_ptr; + } + if(dyn.d_tag == DT_MIPS_LOCAL_GOTNO){ + lte->arch.mips_local_gotno = dyn.d_un.d_val; + } + if(dyn.d_tag == DT_MIPS_GOTSYM){ + lte->arch.mips_gotsym = dyn.d_un.d_val; + } + } + + /* Tell the generic code how many dynamic trace:able symbols + * we've got. */ + lte->relplt_count = lte->dynsym_count - lte->arch.mips_gotsym; + return 0; +} + +void +arch_elf_destroy(struct ltelf *lte) +{ +} + +/* When functions return we check if the symbol needs an updated + breakpoint with the resolved address. */ +void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym) +{ + struct breakpoint *bp; + arch_addr_t resolved_addr; + struct Process *leader = proc->leader; + + /* Only deal with unresolved symbols. */ + if (libsym->arch.type != MIPS_PLT_UNRESOLVED) + return; + + /* Get out if we are always using the PLT. */ + if (libsym->arch.pltalways) + return; + + resolved_addr = sym2addr(proc, libsym); + libsym->arch.resolved_addr = (uintptr_t) resolved_addr; + libsym->arch.type = MIPS_PLT_RESOLVED; + + if (libsym->arch.stub_addr == libsym->arch.resolved_addr) { + /* Prelinked symbol. No need to add new breakpoint. */ + return; + } + + bp = malloc(sizeof (*bp)); + if (bp == NULL) { + fprintf(stderr, "Failed to allocate bp for %s\n", + libsym->name); + return; + } + + if (breakpoint_init(bp, leader, resolved_addr, libsym) < 0) + goto err; + + if (proc_add_breakpoint(leader, bp) < 0) { + breakpoint_destroy(bp); + goto err; + } + + if (breakpoint_turn_on(bp, leader) < 0) { + proc_remove_breakpoint(leader, bp); + breakpoint_destroy(bp); + goto err; + } + return; +err: + free(bp); +} + +static enum callback_status +cb_enable_breakpoint_sym(struct library_symbol *libsym, void *data) +{ + struct Process *proc = data; + arch_addr_t bp_addr; + + if (!libsym->arch.gotonly) + return CBS_CONT; + + /* Update state. */ + bp_addr = sym2addr(proc, libsym); + /* XXX The cast to uintptr_t should be removed when + * arch_addr_t becomes integral type. keywords: double cast. */ + libsym->arch.resolved_addr = (uintptr_t) bp_addr; + + if (libsym->arch.resolved_addr == 0) + /* FIXME: What does this mean? */ + return CBS_CONT; + + libsym->arch.type = MIPS_PLT_RESOLVED; + + /* Now, activate the symbol causing a breakpoint to be added. */ + if (proc_activate_delayed_symbol(proc, libsym) < 0) { + fprintf(stderr, "Failed to activate delayed sym %s\n", + libsym->name); + } + return CBS_CONT; +} + +static enum callback_status +cb_enable_breakpoint_lib(struct Process *proc, struct library *lib, void *data) +{ + library_each_symbol(lib, NULL, cb_enable_breakpoint_sym, proc); + return CBS_CONT; +} + +void arch_dynlink_done(struct Process *proc) +{ + proc_each_library(proc->leader, NULL, cb_enable_breakpoint_lib, NULL); +} + +enum plt_status +arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + char *name = NULL; + int sym_index = ndx + lte->arch.mips_gotsym; + + struct library_symbol *libsym = malloc(sizeof(*libsym)); + if (libsym == NULL) + return plt_fail; + + GElf_Addr addr = arch_plt_sym_val(lte, sym_index, 0); + + name = strdup(a_name); + if (name == NULL) { + fprintf(stderr, "%s: failed %s(%#llx): %s\n", __func__, + name, addr, strerror(errno)); + goto fail; + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + if (library_symbol_init(libsym, + (arch_addr_t) (uintptr_t) addr, + name, 1, LS_TOPLT_EXEC) < 0) { + fprintf(stderr, "%s: failed %s : %llx\n", __func__, name, addr); + goto fail; + } + + arch_addr_t bp_addr = sym2addr(proc, libsym); + /* XXX This cast should be removed when + * arch_addr_t becomes integral type. keywords: double cast. */ + libsym->arch.stub_addr = (uintptr_t) bp_addr; + + if (bp_addr == 0) { + /* Function pointers without PLT entries. */ + libsym->plt_type = LS_TOPLT_NONE; + libsym->arch.gotonly = 1; + libsym->arch.type = MIPS_PLT_UNRESOLVED; + + /* Delay breakpoint activation until the symbol gets + * resolved. */ + libsym->delayed = 1; + } else if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + libsym->arch.pltalways = 1; + } + + *ret = libsym; + return plt_ok; + +fail: + free(name); + free(libsym); + return plt_fail; +} + +int +arch_library_symbol_init(struct library_symbol *libsym) +{ + libsym->arch.pltalways = 0; + libsym->arch.gotonly = 0; + libsym->arch.type = MIPS_PLT_UNRESOLVED; + if (libsym->plt_type == LS_TOPLT_NONE) { + libsym->arch.type = MIPS_PLT_RESOLVED; + } + return 0; +} + +void +arch_library_symbol_destroy(struct library_symbol *libsym) +{ +} + +int +arch_library_symbol_clone(struct library_symbol *retp, + struct library_symbol *libsym) +{ + retp->arch = libsym->arch; + return 0; +} + /**@}*/ diff --git a/sysdeps/linux-gnu/mipsel/ptrace.h b/sysdeps/linux-gnu/mipsel/ptrace.h index c3cbcb6..00c8673 100644 --- a/sysdeps/linux-gnu/mipsel/ptrace.h +++ b/sysdeps/linux-gnu/mipsel/ptrace.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/mipsel/regs.c b/sysdeps/linux-gnu/mipsel/regs.c index a7a6de1..8731ac5 100644 --- a/sysdeps/linux-gnu/mipsel/regs.c +++ b/sysdeps/linux-gnu/mipsel/regs.c @@ -1,11 +1,32 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <stddef.h> #include <sys/types.h> #include <sys/ptrace.h> #include <asm/ptrace.h> -#include <linux/user.h> +#include "proc.h" #include "common.h" #include "mipsel.h" diff --git a/sysdeps/linux-gnu/mipsel/signalent.h b/sysdeps/linux-gnu/mipsel/signalent.h index 6bb1ff6..d779af5 100644 --- a/sysdeps/linux-gnu/mipsel/signalent.h +++ b/sysdeps/linux-gnu/mipsel/signalent.h @@ -1,32 +1,52 @@ -"SIG_0", /* 0 */ - "SIGHUP", // 1 /* Hangup (POSIX). */ - "SIGINT", // 2 /* Interrupt (ANSI). */ - "SIGQUIT", // 3 /* Quit (POSIX). */ - "SIGILL", // 4 /* Illegal instruction (ANSI). */ - "SIGTRAP", // 5 /* Trace trap (POSIX). */ - "SIGIOT", // 6 /* IOT trap (4.2 BSD). */ - "SIGEMT", // 7 - "SIGFPE", // 8 /* Floating-point exception (ANSI). */ - "SIGKILL", // 9 /* Kill, unblockable (POSIX). */ - "SIGBUS", // 10 /* BUS error (4.2 BSD). */ - "SIGSEGV", // 11 /* Segmentation violation (ANSI). */ - "SIGSYS", // 12 - "SIGPIPE", // 13 /* Broken pipe (POSIX). */ - "SIGALRM", // 14 /* Alarm clock (POSIX). */ - "SIGTERM", // 15 /* Termination (ANSI). */ - "SIGUSR1", // 16 /* User-defined signal 1 (POSIX). */ - "SIGUSR2", // 17 /* User-defined signal 2 (POSIX). */ - "SIGCHLD", // 18 /* Child status has changed (POSIX). */ - "SIGPWR", // 19 /* Power failure restart (System V). */ - "SIGWINCH", // 20 /* Window size change (4.3 BSD, Sun). */ - "SIGURG", // 21 /* Urgent condition on socket (4.2 BSD). */ - "SIGIO", // 22 /* I/O now possible (4.2 BSD). */ - "SIGSTOP", // 23 /* Stop, unblockable (POSIX). */ - "SIGTSTP", // 24 /* Keyboard stop (POSIX). */ - "SIGCONT", // 25 /* Continue (POSIX). */ - "SIGTTIN", // 26 /* Background read from tty (POSIX). */ - "SIGTTOU", // 27 /* Background write to tty (POSIX). */ - "SIGVTALRM", // 28 /* Virtual alarm clock (4.2 BSD). */ - "SIGPROF", // 29 /* Profiling alarm clock (4.2 BSD). */ - "SIGXCPU", // 30 /* CPU limit exceeded (4.2 BSD). */ - "SIGXFSZ", // 31 /* File size limit exceeded (4.2 BSD). */ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Arnaud Patard, Mandriva SA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + "SIG_0", /* 0 */ + "SIGHUP", /* 1 */ + "SIGINT", /* 2 */ + "SIGQUIT", /* 3 */ + "SIGILL", /* 4 */ + "SIGTRAP", /* 5 */ + "SIGIOT", /* 6 */ + "SIGEMT", /* 7 */ + "SIGFPE", /* 8 */ + "SIGKILL", /* 9 */ + "SIGBUS", /* 10 */ + "SIGSEGV", /* 11 */ + "SIGSYS", /* 12 */ + "SIGPIPE", /* 13 */ + "SIGALRM", /* 14 */ + "SIGTERM", /* 15 */ + "SIGUSR1", /* 16 */ + "SIGUSR2", /* 17 */ + "SIGCHLD", /* 18 */ + "SIGPWR", /* 19 */ + "SIGWINCH", /* 20 */ + "SIGURG", /* 21 */ + "SIGIO", /* 22 */ + "SIGSTOP", /* 23 */ + "SIGTSTP", /* 24 */ + "SIGCONT", /* 25 */ + "SIGTTIN", /* 26 */ + "SIGTTOU", /* 27 */ + "SIGVTALRM", /* 28 */ + "SIGPROF", /* 29 */ + "SIGXCPU", /* 30 */ + "SIGXFSZ", /* 31 */ diff --git a/sysdeps/linux-gnu/mipsel/syscallent.h b/sysdeps/linux-gnu/mipsel/syscallent.h index bed43fe..c0e5dd6 100644 --- a/sysdeps/linux-gnu/mipsel/syscallent.h +++ b/sysdeps/linux-gnu/mipsel/syscallent.h @@ -1,241 +1,368 @@ - "0", /*Linux + 0*/ - "exit", /*Linux + 1*/ - "fork", /*Linux + 2*/ - "read", /*Linux + 3*/ - "write", /*Linux + 4*/ - "open", /*Linux + 5*/ - "close", /*Linux + 6*/ - "waitpid", /*Linux + 7*/ - "creat", /*Linux + 8*/ - "link", /*Linux + 9*/ - "unlink", /*Linux + 10*/ - "execve", /*Linux + 11*/ - "chdir", /*Linux + 12*/ - "time", /*Linux + 13*/ - "mknod", /*Linux + 14*/ - "chmod", /*Linux + 15*/ - "lchown", /*Linux + 16*/ - "break", /*Linux + 17*/ - "unused18", /*Linux + 18*/ - "lseek", /*Linux + 19*/ - "getpid", /*Linux + 20*/ - "mount", /*Linux + 21*/ - "umount", /*Linux + 22*/ - "setuid", /*Linux + 23*/ - "getuid", /*Linux + 24*/ - "stime", /*Linux + 25*/ - "ptrace", /*Linux + 26*/ - "alarm", /*Linux + 27*/ - "unused28", /*Linux + 28*/ - "pause", /*Linux + 29*/ - "utime", /*Linux + 30*/ - "stty", /*Linux + 31*/ - "gtty", /*Linux + 32*/ - "access", /*Linux + 33*/ - "nice", /*Linux + 34*/ - "ftime", /*Linux + 35*/ - "sync", /*Linux + 36*/ - "kill", /*Linux + 37*/ - "rename", /*Linux + 38*/ - "mkdir", /*Linux + 39*/ - "rmdir", /*Linux + 40*/ - "dup", /*Linux + 41*/ - "pipe", /*Linux + 42*/ - "times", /*Linux + 43*/ - "prof", /*Linux + 44*/ - "brk", /*Linux + 45*/ - "setgid", /*Linux + 46*/ - "getgid", /*Linux + 47*/ - "signal", /*Linux + 48*/ - "geteuid", /*Linux + 49*/ - "getegid", /*Linux + 50*/ - "acct", /*Linux + 51*/ - "umount2", /*Linux + 52*/ - "lock", /*Linux + 53*/ - "ioctl", /*Linux + 54*/ - "fcntl", /*Linux + 55*/ - "mpx", /*Linux + 56*/ - "setpgid", /*Linux + 57*/ - "ulimit", /*Linux + 58*/ - "unused59", /*Linux + 59*/ - "umask", /*Linux + 60*/ - "chroot", /*Linux + 61*/ - "ustat", /*Linux + 62*/ - "dup2", /*Linux + 63*/ - "getppid", /*Linux + 64*/ - "getpgrp", /*Linux + 65*/ - "setsid", /*Linux + 66*/ - "sigaction", /*Linux + 67*/ - "sgetmask", /*Linux + 68*/ - "ssetmask", /*Linux + 69*/ - "setreuid", /*Linux + 70*/ - "setregid", /*Linux + 71*/ - "sigsuspend", /*Linux + 72*/ - "sigpending", /*Linux + 73*/ - "sethostname", /*Linux + 74*/ - "setrlimit", /*Linux + 75*/ - "getrlimit", /*Linux + 76*/ - "getrusage", /*Linux + 77*/ - "gettimeofday", /*Linux + 78*/ - "settimeofday", /*Linux + 79*/ - "getgroups", /*Linux + 80*/ - "setgroups", /*Linux + 81*/ - "reserved82", /*Linux + 82*/ - "symlink", /*Linux + 83*/ - "unused84", /*Linux + 84*/ - "readlink", /*Linux + 85*/ - "uselib", /*Linux + 86*/ - "swapon", /*Linux + 87*/ - "reboot", /*Linux + 88*/ - "readdir", /*Linux + 89*/ - "mmap", /*Linux + 90*/ - "munmap", /*Linux + 91*/ - "truncate", /*Linux + 92*/ - "ftruncate", /*Linux + 93*/ - "fchmod", /*Linux + 94*/ - "fchown", /*Linux + 95*/ - "getpriority", /*Linux + 96*/ - "setpriority", /*Linux + 97*/ - "profil", /*Linux + 98*/ - "statfs", /*Linux + 99*/ - "fstatfs", /*Linux + 100*/ - "ioperm", /*Linux + 101*/ - "socketcall", /*Linux + 102*/ - "syslog", /*Linux + 103*/ - "setitimer", /*Linux + 104*/ - "getitimer", /*Linux + 105*/ - "stat", /*Linux + 106*/ - "lstat", /*Linux + 107*/ - "fstat", /*Linux + 108*/ - "unused109", /*Linux + 109*/ - "iopl", /*Linux + 110*/ - "vhangup", /*Linux + 111*/ - "idle", /*Linux + 112*/ - "vm86", /*Linux + 113*/ - "wait4", /*Linux + 114*/ - "swapoff", /*Linux + 115*/ - "sysinfo", /*Linux + 116*/ - "ipc", /*Linux + 117*/ - "fsync", /*Linux + 118*/ - "sigreturn", /*Linux + 119*/ - "clone", /*Linux + 120*/ - "setdomainname", /*Linux + 121*/ - "uname", /*Linux + 122*/ - "modify_ldt", /*Linux + 123*/ - "adjtimex", /*Linux + 124*/ - "mprotect", /*Linux + 125*/ - "sigprocmask", /*Linux + 126*/ - "create_module", /*Linux + 127*/ - "init_module", /*Linux + 128*/ - "delete_module", /*Linux + 129*/ - "get_kernel_syms", /*Linux + 130*/ - "quotactl", /*Linux + 131*/ - "getpgid", /*Linux + 132*/ - "fchdir", /*Linux + 133*/ - "bdflush", /*Linux + 134*/ - "sysfs", /*Linux + 135*/ - "personality", /*Linux + 136*/ - "afs_syscall", /*Linux + 137*/ /* Syscall for Andrew File System */ - "setfsuid", /*Linux + 138*/ - "setfsgid", /*Linux + 139*/ - "_llseek", /*Linux + 140*/ - "getdents", /*Linux + 141*/ - "_newselect", /*Linux + 142*/ - "flock", /*Linux + 143*/ - "msync", /*Linux + 144*/ - "readv", /*Linux + 145*/ - "writev", /*Linux + 146*/ - "cacheflush", /*Linux + 147*/ - "cachectl", /*Linux + 148*/ - "sysmips", /*Linux + 149*/ - "unused150", /*Linux + 150*/ - "getsid", /*Linux + 151*/ - "fdatasync", /*Linux + 152*/ - "_sysctl", /*Linux + 153*/ - "mlock", /*Linux + 154*/ - "munlock", /*Linux + 155*/ - "mlockall", /*Linux + 156*/ - "munlockall", /*Linux + 157*/ - "sched_setparam", /*Linux + 158*/ - "sched_getparam", /*Linux + 159*/ - "sched_setscheduler", /*Linux + 160*/ - "sched_getscheduler", /*Linux + 161*/ - "sched_yield", /*Linux + 162*/ - "sched_get_priority_max", /*Linux + 163*/ - "sched_get_priority_min", /*Linux + 164*/ - "sched_rr_get_interval", /*Linux + 165*/ - "nanosleep", /*Linux + 166*/ - "mremap", /*Linux + 167*/ - "accept", /*Linux + 168*/ - "bind", /*Linux + 169*/ - "connect", /*Linux + 170*/ - "getpeername", /*Linux + 171*/ - "getsockname", /*Linux + 172*/ - "getsockopt", /*Linux + 173*/ - "listen", /*Linux + 174*/ - "recv", /*Linux + 175*/ - "recvfrom", /*Linux + 176*/ - "recvmsg", /*Linux + 177*/ - "send", /*Linux + 178*/ - "sendmsg", /*Linux + 179*/ - "sendto", /*Linux + 180*/ - "setsockopt", /*Linux + 181*/ - "shutdown", /*Linux + 182*/ - "socket", /*Linux + 183*/ - "socketpair", /*Linux + 184*/ - "setresuid", /*Linux + 185*/ - "getresuid", /*Linux + 186*/ - "query_module", /*Linux + 187*/ - "poll", /*Linux + 188*/ - "nfsservctl", /*Linux + 189*/ - "setresgid", /*Linux + 190*/ - "getresgid", /*Linux + 191*/ - "prctl", /*Linux + 192*/ - "rt_sigreturn", /*Linux + 193*/ - "rt_sigaction", /*Linux + 194*/ - "rt_sigprocmask", /*Linux + 195*/ - "rt_sigpending", /*Linux + 196*/ - "rt_sigtimedwait", /*Linux + 197*/ - "rt_sigqueueinfo", /*Linux + 198*/ - "rt_sigsuspend", /*Linux + 199*/ - "pread", /*Linux + 200*/ - "pwrite", /*Linux + 201*/ - "chown", /*Linux + 202*/ - "getcwd", /*Linux + 203*/ - "capget", /*Linux + 204*/ - "capset", /*Linux + 205*/ - "sigaltstack", /*Linux + 206*/ - "sendfile", /*Linux + 207*/ - "getpmsg", /*Linux + 208*/ - "putpmsg", /*Linux + 209*/ - "mmap2", /*Linux + 210*/ - "truncate64", /*Linux + 211*/ - "ftruncate64", /*Linux + 212*/ - "stat64", /*Linux + 213*/ - "lstat64", /*Linux + 214*/ - "fstat64", /*Linux + 215*/ - "pivot_root", /*Linux + 216*/ - "mincore", /*Linux + 217*/ - "madvise", /*Linux + 218*/ - "getdents64", /*Linux + 219*/ - "fcntl64", /*Linux + 220*/ - "security", /*Linux + 221*/ - "gettid", /*Linux + 222*/ - "readahead", /*Linux + 223*/ - "setxattr", /*Linux + 224*/ - "lsetxattr", /*Linux + 225*/ - "fsetxattr", /*Linux + 226*/ - "getxattr", /*Linux + 227*/ - "lgetxattr", /*Linux + 228*/ - "fgetxattr", /*Linux + 229*/ - "listxattr", /*Linux + 230*/ - "llistxattr", /*Linux + 231*/ - "flistxattr", /*Linux + 232*/ - "removexattr", /*Linux + 233*/ - "lremovexattr", /*Linux + 234*/ - "fremovexattr", /*Linux + 235*/ - "tkill", /*Linux + 236*/ - "sendfile64", /*Linux + 237*/ - "futex", /*Linux + 238*/ - "sched_setaffinity", /*Linux + 239*/ - "sched_getaffinity", /*Linux + 240*/ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Arnaud Patard, Mandriva SA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + "syscall", /* 0 */ + "exit", /* 1 */ + "fork", /* 2 */ + "read", /* 3 */ + "write", /* 4 */ + "open", /* 5 */ + "close", /* 6 */ + "waitpid", /* 7 */ + "creat", /* 8 */ + "link", /* 9 */ + "unlink", /* 10 */ + "execve", /* 11 */ + "chdir", /* 12 */ + "time", /* 13 */ + "mknod", /* 14 */ + "chmod", /* 15 */ + "lchown", /* 16 */ + "break", /* 17 */ + "unused18", /* 18 */ + "lseek", /* 19 */ + "getpid", /* 20 */ + "mount", /* 21 */ + "umount", /* 22 */ + "setuid", /* 23 */ + "getuid", /* 24 */ + "stime", /* 25 */ + "ptrace", /* 26 */ + "alarm", /* 27 */ + "unused28", /* 28 */ + "pause", /* 29 */ + "utime", /* 30 */ + "stty", /* 31 */ + "gtty", /* 32 */ + "access", /* 33 */ + "nice", /* 34 */ + "ftime", /* 35 */ + "sync", /* 36 */ + "kill", /* 37 */ + "rename", /* 38 */ + "mkdir", /* 39 */ + "rmdir", /* 40 */ + "dup", /* 41 */ + "pipe", /* 42 */ + "times", /* 43 */ + "prof", /* 44 */ + "brk", /* 45 */ + "setgid", /* 46 */ + "getgid", /* 47 */ + "signal", /* 48 */ + "geteuid", /* 49 */ + "getegid", /* 50 */ + "acct", /* 51 */ + "umount2", /* 52 */ + "lock", /* 53 */ + "ioctl", /* 54 */ + "fcntl", /* 55 */ + "mpx", /* 56 */ + "setpgid", /* 57 */ + "ulimit", /* 58 */ + "unused59", /* 59 */ + "umask", /* 60 */ + "chroot", /* 61 */ + "ustat", /* 62 */ + "dup2", /* 63 */ + "getppid", /* 64 */ + "getpgrp", /* 65 */ + "setsid", /* 66 */ + "sigaction", /* 67 */ + "sgetmask", /* 68 */ + "ssetmask", /* 69 */ + "setreuid", /* 70 */ + "setregid", /* 71 */ + "sigsuspend", /* 72 */ + "sigpending", /* 73 */ + "sethostname", /* 74 */ + "setrlimit", /* 75 */ + "getrlimit", /* 76 */ + "getrusage", /* 77 */ + "gettimeofday", /* 78 */ + "settimeofday", /* 79 */ + "getgroups", /* 80 */ + "setgroups", /* 81 */ + "reserved82", /* 82 */ + "symlink", /* 83 */ + "unused84", /* 84 */ + "readlink", /* 85 */ + "uselib", /* 86 */ + "swapon", /* 87 */ + "reboot", /* 88 */ + "readdir", /* 89 */ + "mmap", /* 90 */ + "munmap", /* 91 */ + "truncate", /* 92 */ + "ftruncate", /* 93 */ + "fchmod", /* 94 */ + "fchown", /* 95 */ + "getpriority", /* 96 */ + "setpriority", /* 97 */ + "profil", /* 98 */ + "statfs", /* 99 */ + "fstatfs", /* 100 */ + "ioperm", /* 101 */ + "socketcall", /* 102 */ + "syslog", /* 103 */ + "setitimer", /* 104 */ + "getitimer", /* 105 */ + "stat", /* 106 */ + "lstat", /* 107 */ + "fstat", /* 108 */ + "unused109", /* 109 */ + "iopl", /* 110 */ + "vhangup", /* 111 */ + "idle", /* 112 */ + "vm86", /* 113 */ + "wait4", /* 114 */ + "swapoff", /* 115 */ + "sysinfo", /* 116 */ + "ipc", /* 117 */ + "fsync", /* 118 */ + "sigreturn", /* 119 */ + "clone", /* 120 */ + "setdomainname", /* 121 */ + "uname", /* 122 */ + "modify_ldt", /* 123 */ + "adjtimex", /* 124 */ + "mprotect", /* 125 */ + "sigprocmask", /* 126 */ + "create_module", /* 127 */ + "init_module", /* 128 */ + "delete_module", /* 129 */ + "get_kernel_syms", /* 130 */ + "quotactl", /* 131 */ + "getpgid", /* 132 */ + "fchdir", /* 133 */ + "bdflush", /* 134 */ + "sysfs", /* 135 */ + "personality", /* 136 */ + "afs_syscall", /* 137 */ + "setfsuid", /* 138 */ + "setfsgid", /* 139 */ + "_llseek", /* 140 */ + "getdents", /* 141 */ + "_newselect", /* 142 */ + "flock", /* 143 */ + "msync", /* 144 */ + "readv", /* 145 */ + "writev", /* 146 */ + "cacheflush", /* 147 */ + "cachectl", /* 148 */ + "sysmips", /* 149 */ + "unused150", /* 150 */ + "getsid", /* 151 */ + "fdatasync", /* 152 */ + "_sysctl", /* 153 */ + "mlock", /* 154 */ + "munlock", /* 155 */ + "mlockall", /* 156 */ + "munlockall", /* 157 */ + "sched_setparam", /* 158 */ + "sched_getparam", /* 159 */ + "sched_setscheduler", /* 160 */ + "sched_getscheduler", /* 161 */ + "sched_yield", /* 162 */ + "sched_get_priority_max", /* 163 */ + "sched_get_priority_min", /* 164 */ + "sched_rr_get_interval", /* 165 */ + "nanosleep", /* 166 */ + "mremap", /* 167 */ + "accept", /* 168 */ + "bind", /* 169 */ + "connect", /* 170 */ + "getpeername", /* 171 */ + "getsockname", /* 172 */ + "getsockopt", /* 173 */ + "listen", /* 174 */ + "recv", /* 175 */ + "recvfrom", /* 176 */ + "recvmsg", /* 177 */ + "send", /* 178 */ + "sendmsg", /* 179 */ + "sendto", /* 180 */ + "setsockopt", /* 181 */ + "shutdown", /* 182 */ + "socket", /* 183 */ + "socketpair", /* 184 */ + "setresuid", /* 185 */ + "getresuid", /* 186 */ + "query_module", /* 187 */ + "poll", /* 188 */ + "nfsservctl", /* 189 */ + "setresgid", /* 190 */ + "getresgid", /* 191 */ + "prctl", /* 192 */ + "rt_sigreturn", /* 193 */ + "rt_sigaction", /* 194 */ + "rt_sigprocmask", /* 195 */ + "rt_sigpending", /* 196 */ + "rt_sigtimedwait", /* 197 */ + "rt_sigqueueinfo", /* 198 */ + "rt_sigsuspend", /* 199 */ + "pread64", /* 200 */ + "pwrite64", /* 201 */ + "chown", /* 202 */ + "getcwd", /* 203 */ + "capget", /* 204 */ + "capset", /* 205 */ + "sigaltstack", /* 206 */ + "sendfile", /* 207 */ + "getpmsg", /* 208 */ + "putpmsg", /* 209 */ + "mmap2", /* 210 */ + "truncate64", /* 211 */ + "ftruncate64", /* 212 */ + "stat64", /* 213 */ + "lstat64", /* 214 */ + "fstat64", /* 215 */ + "pivot_root", /* 216 */ + "mincore", /* 217 */ + "madvise", /* 218 */ + "getdents64", /* 219 */ + "fcntl64", /* 220 */ + "reserved221", /* 221 */ + "gettid", /* 222 */ + "readahead", /* 223 */ + "setxattr", /* 224 */ + "lsetxattr", /* 225 */ + "fsetxattr", /* 226 */ + "getxattr", /* 227 */ + "lgetxattr", /* 228 */ + "fgetxattr", /* 229 */ + "listxattr", /* 230 */ + "llistxattr", /* 231 */ + "flistxattr", /* 232 */ + "removexattr", /* 233 */ + "lremovexattr", /* 234 */ + "fremovexattr", /* 235 */ + "tkill", /* 236 */ + "sendfile64", /* 237 */ + "futex", /* 238 */ + "sched_setaffinity", /* 239 */ + "sched_getaffinity", /* 240 */ + "io_setup", /* 241 */ + "io_destroy", /* 242 */ + "io_getevents", /* 243 */ + "io_submit", /* 244 */ + "io_cancel", /* 245 */ + "exit_group", /* 246 */ + "lookup_dcookie", /* 247 */ + "epoll_create", /* 248 */ + "epoll_ctl", /* 249 */ + "epoll_wait", /* 250 */ + "remap_file_pages", /* 251 */ + "set_tid_address", /* 252 */ + "restart_syscall", /* 253 */ + "fadvise64", /* 254 */ + "statfs64", /* 255 */ + "fstatfs64", /* 256 */ + "timer_create", /* 257 */ + "timer_settime", /* 258 */ + "timer_gettime", /* 259 */ + "timer_getoverrun", /* 260 */ + "timer_delete", /* 261 */ + "clock_settime", /* 262 */ + "clock_gettime", /* 263 */ + "clock_getres", /* 264 */ + "clock_nanosleep", /* 265 */ + "tgkill", /* 266 */ + "utimes", /* 267 */ + "mbind", /* 268 */ + "get_mempolicy", /* 269 */ + "set_mempolicy", /* 270 */ + "mq_open", /* 271 */ + "mq_unlink", /* 272 */ + "mq_timedsend", /* 273 */ + "mq_timedreceive", /* 274 */ + "mq_notify", /* 275 */ + "mq_getsetattr", /* 276 */ + "vserver", /* 277 */ + "waitid", /* 278 */ + "279", /* 279 */ + "add_key", /* 280 */ + "request_key", /* 281 */ + "keyctl", /* 282 */ + "set_thread_area", /* 283 */ + "inotify_init", /* 284 */ + "inotify_add_watch", /* 285 */ + "inotify_rm_watch", /* 286 */ + "migrate_pages", /* 287 */ + "openat", /* 288 */ + "mkdirat", /* 289 */ + "mknodat", /* 290 */ + "fchownat", /* 291 */ + "futimesat", /* 292 */ + "fstatat64", /* 293 */ + "unlinkat", /* 294 */ + "renameat", /* 295 */ + "linkat", /* 296 */ + "symlinkat", /* 297 */ + "readlinkat", /* 298 */ + "fchmodat", /* 299 */ + "faccessat", /* 300 */ + "pselect6", /* 301 */ + "ppoll", /* 302 */ + "unshare", /* 303 */ + "splice", /* 304 */ + "sync_file_range", /* 305 */ + "tee", /* 306 */ + "vmsplice", /* 307 */ + "move_pages", /* 308 */ + "set_robust_list", /* 309 */ + "get_robust_list", /* 310 */ + "kexec_load", /* 311 */ + "getcpu", /* 312 */ + "epoll_pwait", /* 313 */ + "ioprio_set", /* 314 */ + "ioprio_get", /* 315 */ + "utimensat", /* 316 */ + "signalfd", /* 317 */ + "timerfd", /* 318 */ + "eventfd", /* 319 */ + "fallocate", /* 320 */ + "timerfd_create", /* 321 */ + "timerfd_gettime", /* 322 */ + "timerfd_settime", /* 323 */ + "signalfd4", /* 324 */ + "eventfd2", /* 325 */ + "epoll_create1", /* 326 */ + "dup3", /* 327 */ + "pipe2", /* 328 */ + "inotify_init1", /* 329 */ + "preadv", /* 330 */ + "pwritev", /* 331 */ + "rt_tgsigqueueinfo", /* 332 */ + "perf_event_open", /* 333 */ + "accept4", /* 334 */ + "recvmmsg", /* 335 */ + "fanotify_init", /* 336 */ + "fanotify_mark", /* 337 */ + "prlimit64", /* 338 */ + "name_to_handle_at", /* 339 */ + "open_by_handle_at", /* 340 */ + "clock_adjtime", /* 341 */ + "syncfs", /* 342 */ + "sendmmsg", /* 343 */ + "setns", /* 344 */ + "process_vm_readv", /* 345 */ + "process_vm_writev", /* 346 */ diff --git a/sysdeps/linux-gnu/mipsel/trace.c b/sysdeps/linux-gnu/mipsel/trace.c index ff94930..db9ec21 100644 --- a/sysdeps/linux-gnu/mipsel/trace.c +++ b/sysdeps/linux-gnu/mipsel/trace.c @@ -1,3 +1,26 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications + * Copyright (C) 2010 Arnaud Patard, Mandriva SA + * Copyright (C) 2008,2009 Juan Cespedes + * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> @@ -5,9 +28,15 @@ #include <signal.h> #include <sys/ptrace.h> #include <asm/ptrace.h> -#include "debug.h" +#include <assert.h> + +#include "backend.h" #include "common.h" +#include "debug.h" #include "mipsel.h" +#include "proc.h" +#include "type.h" + #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR #endif @@ -88,6 +117,177 @@ syscall_p(Process *proc, int status, int *sysnum) { } return 0; } + +/* Based on GDB code. */ +#define mips32_op(x) (x >> 26) +#define itype_op(x) (x >> 26) +#define itype_rs(x) ((x >> 21) & 0x1f) +#define itype_rt(x) ((x >> 16) & 0x1f) +#define itype_immediate(x) (x & 0xffff) + +#define jtype_op(x) (x >> 26) +#define jtype_target(x) (x & 0x03ffffff) + +#define rtype_op(x) (x >> 26) +#define rtype_rs(x) ((x >> 21) & 0x1f) +#define rtype_rt(x) ((x >> 16) & 0x1f) +#define rtype_rd(x) ((x >> 11) & 0x1f) +#define rtype_shamt(x) ((x >> 6) & 0x1f) +#define rtype_funct(x) (x & 0x3f) + +static int32_t +mips32_relative_offset (uint32_t inst) +{ + return ((itype_immediate(inst) ^ 0x8000) - 0x8000) << 2; +} + +int mips_next_pcs(struct Process *proc, uint32_t pc, uint32_t *newpc) +{ + uint32_t inst, rx; + int op; + int rn; + int nr = 0; + + inst = ptrace(PTRACE_PEEKTEXT, proc->pid, pc, 0); + + if ((inst & 0xe0000000) != 0) { + /* Check for branches. */ + if (itype_op(inst) >> 2 == 5) { + /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */ + op = (itype_op(inst) & 0x03); + switch (op) + { + case 0: /* BEQL */ + case 1: /* BNEL */ + case 2: /* BLEZL */ + case 3: /* BGTZL */ + newpc[nr++] = pc + 8; + newpc[nr++] = pc + 4 + + mips32_relative_offset(inst); + break; + default: + newpc[nr++] = pc + 4; + break; + } + } else if (itype_op(inst) == 17 && itype_rs(inst) == 8) { + /* Step over the branch. */ + newpc[nr++] = pc + 8; + newpc[nr++] = pc + mips32_relative_offset(inst) + 4; + } else { + newpc[nr++] = pc + 4; + } + } else { + /* Further subdivide into SPECIAL, REGIMM and other. */ + switch (op = itype_op(inst) & 0x07) + { + case 0: + op = rtype_funct(inst); + switch (op) + { + case 8: /* JR */ + case 9: /* JALR */ + rn = rtype_rs(inst); + + rx = ptrace(PTRACE_PEEKUSER,proc->pid, rn, 0); + newpc[nr++] = rx; + break; + default: + case 12: /* SYSCALL */ + newpc[nr++] = pc + 4; + break; + } + break; + case 1: + op = itype_rt(inst); + switch (op) + { + case 0: + case 1: + case 2: + case 3: + case 16: + case 17: + case 18: + case 19: + newpc[nr++] = pc + 8; + newpc[nr++] = pc + 4 + + mips32_relative_offset(inst); + break; + default: + newpc[nr++] = pc + 4; + break; + } + break; + case 2: /* J */ + case 3: /* JAL */ + rx = jtype_target(inst) << 2; + /* Upper four bits get never changed... */ + newpc[nr++] = rx + ((pc + 4) & ~0x0fffffff); + break; + case 4: /* BEQ */ + if (itype_rs(inst) == itype_rt(inst)) { + /* Compare the same reg for equality, always + * follow the branch. */ + newpc[nr++] = pc + 4 + + mips32_relative_offset(inst); + break; + } + /* Fall through. */ + default: + case 5: + case 6: + case 7: + /* Step over the branch. */ + newpc[nr++] = pc + 8; + newpc[nr++] = pc + mips32_relative_offset(inst) + 4; + break; + } + } + if (nr <= 0 || nr > 2) + goto fail; + if (nr == 2) { + if (newpc[1] == 0) + goto fail; + } + if (newpc[0] == 0) + goto fail; + + assert(nr == 1 || nr == 2); + return nr; + +fail: + printf("nr=%d pc=%x\n", nr, pc); + printf("pc=%x %x\n", newpc[0], newpc[1]); + return 0; +} + +int +arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, + int (*add_cb)(void *addr, void *data), + void *add_cb_data) +{ + uint32_t pc = (uint32_t) get_instruction_pointer(proc); + uint32_t newpcs[2]; + int nr; + + nr = mips_next_pcs(proc, pc, newpcs); + + while (nr-- > 0) { + arch_addr_t baddr = (arch_addr_t) newpcs[nr]; + /* Not sure what to do here. We've already got a bp? */ + if (dict_find_entry(proc->leader->breakpoints, baddr) != NULL) { + fprintf(stderr, "skip %p %p\n", baddr, add_cb_data); + continue; + } + + if (add_cb(baddr, add_cb_data) < 0) + return -1; + } + + ptrace(PTRACE_SYSCALL, proc->pid, 0, 0); + return 0; +} + /** \param type Function/syscall call or return. \param proc The process that had an event. @@ -117,51 +317,61 @@ I'm not doing any floating point support here. */ long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { +gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +{ long ret; + long addr; debug(2,"type %d arg %d",type,arg_num); - if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL){ + if (arg_num == -1) { + if(type == LT_TOF_FUNCTIONR) { + return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0); + } + if (type == LT_TOF_SYSCALLR) { + unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0); + unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0); + if(!a3){ + return v0; + } + return -1; + } + } + if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL) { + /* o32: float args are in f12 and f14 */ + if ((info->type == ARGTYPE_FLOAT) && (arg_num < 2)) { + ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_fpr0+12+arg_num*2,0); + debug(2,"ret = %#lx",ret); + return ret; + } if(arg_num <4){ ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_a0+arg_num,0); debug(2,"ret = %#lx",ret); return ret; } else { - // If we need this, I think we can look at [sp+16] for arg_num==4. - CP; - return 0; + /* not sure it's going to work for something else than syscall */ + addr=ptrace(PTRACE_PEEKUSER,proc->pid,off_sp,0); + if (addr == -1) { + debug(2,"ret = %#lx",addr); + return addr; + } + ret = addr + 4*arg_num; + ret=ptrace(PTRACE_PEEKTEXT,proc->pid,addr,0); + debug(2,"ret = %#lx",ret); + return ret; } } - if(arg_num>=0){ - fprintf(stderr,"args on return?"); - } - if(type == LT_TOF_FUNCTIONR) { - return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0); - } - if (type == LT_TOF_SYSCALLR) { - unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0); - unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0); - if(!a3){ - return v0; + if (type == LT_TOF_FUNCTIONR || type == LT_TOF_SYSCALLR){ + addr=ptrace(PTRACE_PEEKUSER,proc->pid,off_sp,0); + if (addr == -1) { + debug(2,"ret = %#lx",addr); + return addr; } - return -1; + ret = addr + 4*arg_num; + ret=ptrace(PTRACE_PEEKTEXT,proc->pid,addr,0); + debug(2,"ret = %#lx",ret); + return ret; } fprintf(stderr, "gimme_arg called with wrong arguments\n"); return 0; } -/** - \param type Type of call/return - \param proc Process to work with. - - Called by \c output_left(), which is called on a syscall or - function. - - The other architectures stub this out, but seems to be the place to - stash off the arguments on a call so we have them on the return. - -*/ -void -save_register_args(enum tof type, Process *proc) { -} - /**@}*/ diff --git a/sysdeps/linux-gnu/mksignalent b/sysdeps/linux-gnu/mksignalent index 316d81f..b78b692 100755 --- a/sysdeps/linux-gnu/mksignalent +++ b/sysdeps/linux-gnu/mksignalent @@ -1,4 +1,21 @@ #!/usr/bin/awk -f +# This file is part of ltrace. +# Copyright (C) 1999 Juan Cespedes +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA # hack expression to generate arch/signalent.h from <asm/signal.h> # It reads from stdin and writes to stdout diff --git a/sysdeps/linux-gnu/mksyscallent b/sysdeps/linux-gnu/mksyscallent index e0c3ec7..615ff06 100755 --- a/sysdeps/linux-gnu/mksyscallent +++ b/sysdeps/linux-gnu/mksyscallent @@ -1,4 +1,22 @@ #!/usr/bin/awk -f +# This file is part of ltrace. +# Copyright (C) 2006 Ian Wienand +# Copyright (C) 1999 Juan Cespedes +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA # hack expression to generate arch/syscallent.h from <asm/unistd.h> # It reads from stdin and writes to stdout diff --git a/sysdeps/linux-gnu/mksyscallent_s390 b/sysdeps/linux-gnu/mksyscallent_s390 index 73416d9..1964d14 100644 --- a/sysdeps/linux-gnu/mksyscallent_s390 +++ b/sysdeps/linux-gnu/mksyscallent_s390 @@ -1,4 +1,22 @@ #!/usr/bin/perl +# This file is part of ltrace. +# Copyright (C) 2006 Heiko Carstens, IBM Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + # # Generate syscall table for s390/s390x # diff --git a/sysdeps/linux-gnu/os.h b/sysdeps/linux-gnu/os.h new file mode 100644 index 0000000..62bf38b --- /dev/null +++ b/sysdeps/linux-gnu/os.h @@ -0,0 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#define OS_HAVE_PROCESS_DATA +struct os_process_data { + arch_addr_t debug_addr; + int debug_state; +}; diff --git a/sysdeps/linux-gnu/ppc/Makefile b/sysdeps/linux-gnu/ppc/Makefile deleted file mode 100644 index 60d7531..0000000 --- a/sysdeps/linux-gnu/ppc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -OBJ = trace.o regs.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o - diff --git a/sysdeps/linux-gnu/ppc/Makefile.am b/sysdeps/linux-gnu/ppc/Makefile.am new file mode 100644 index 0000000..2239ae3 --- /dev/null +++ b/sysdeps/linux-gnu/ppc/Makefile.am @@ -0,0 +1,36 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + insn.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/ppc/Makefile.in b/sysdeps/linux-gnu/ppc/Makefile.in new file mode 100644 index 0000000..bcc9d84 --- /dev/null +++ b/sysdeps/linux-gnu/ppc/Makefile.in @@ -0,0 +1,531 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/ppc +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + insn.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/ppc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/ppc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h index 711b4a3..fb8768a 100644 --- a/sysdeps/linux-gnu/ppc/arch.h +++ b/sysdeps/linux-gnu/ppc/arch.h @@ -1,3 +1,29 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata + * Copyright (C) 2006 Paul Gilliam + * Copyright (C) 2002,2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef LTRACE_PPC_ARCH_H +#define LTRACE_PPC_ARCH_H + +#include <gelf.h> + #define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 } #define BREAKPOINT_LENGTH 4 #define DECR_PC_AFTER_BREAK 0 @@ -11,14 +37,72 @@ #define ARCH_SUPPORTS_OPD #endif -#define PLT_REINITALISATION_BP "_start" +#define ARCH_HAVE_ATOMIC_SINGLESTEP +#define ARCH_HAVE_ADD_PLT_ENTRY +#define ARCH_HAVE_TRANSLATE_ADDRESS +#define ARCH_HAVE_DYNLINK_DONE +#define ARCH_HAVE_FETCH_ARG +#define ARCH_ENDIAN_BIG +#define ARCH_HAVE_SIZEOF +#define ARCH_HAVE_ALIGNOF -/* Start of arch-specific functions. */ -#define ARCH_HAVE_UMOVELONG +struct library_symbol; -#define PPC_NOP { 0x60, 0x00, 0x00, 0x00 } -#define PPC_NOP_LENGTH 4 +#define ARCH_HAVE_LTELF_DATA +struct arch_ltelf_data { + GElf_Addr plt_stub_vma; + struct library_symbol *stubs; + Elf_Data *opd_data; + GElf_Addr opd_base; + GElf_Xword opd_size; + int secure_plt; +}; -#if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH) -#error "Length of the breakpoint value not equal to the length of a nop instruction" -#endif +#define ARCH_HAVE_LIBRARY_DATA +struct arch_library_data { + GElf_Addr pltgot_addr; + int bss_plt_prelinked; +}; + +enum ppc64_plt_type { + /* Either a non-PLT symbol, or PPC32 symbol. */ + PPC_DEFAULT = 0, + + /* PPC64 STUB, never resolved. */ + PPC64_PLT_STUB, + + /* Unresolved PLT symbol (.plt contains PLT address). */ + PPC_PLT_UNRESOLVED, + + /* Resolved PLT symbol. The corresponding .plt slot contained + * target address, which was changed to the address of + * corresponding PLT entry. The original is now saved in + * RESOLVED_VALUE. */ + PPC_PLT_RESOLVED, +}; + +#define ARCH_HAVE_LIBRARY_SYMBOL_DATA +struct arch_library_symbol_data { + enum ppc64_plt_type type; + GElf_Addr resolved_value; + + /* Address of corresponding slot in .plt. */ + GElf_Addr plt_slot_addr; +}; + +#define ARCH_HAVE_BREAKPOINT_DATA +struct arch_breakpoint_data { + /* We need this just for arch_breakpoint_init. */ +}; + +#define ARCH_HAVE_PROCESS_DATA +struct arch_process_data { + /* Breakpoint that hits when the dynamic linker is about to + * update a .plt slot. NULL before that address is known. */ + struct breakpoint *dl_plt_update_bp; + + /* PLT update breakpoint looks here for the handler. */ + struct process_stopping_handler *handler; +}; + +#endif /* LTRACE_PPC_ARCH_H */ diff --git a/sysdeps/linux-gnu/ppc/fetch.c b/sysdeps/linux-gnu/ppc/fetch.c new file mode 100644 index 0000000..9963a1e --- /dev/null +++ b/sysdeps/linux-gnu/ppc/fetch.c @@ -0,0 +1,436 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ucontext.h> + +#include "backend.h" +#include "fetch.h" +#include "type.h" +#include "ptrace.h" +#include "proc.h" +#include "value.h" + +static int allocate_gpr(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep); + +/* Floating point registers have the same width on 32-bit as well as + * 64-bit PPC, but <ucontext.h> presents a different API depending on + * whether ltrace is PPC32 or PPC64. + * + * This is PPC64 definition. The PPC32 is simply an array of 33 + * doubles, and doesn't contain the terminating pad. Both seem + * compatible enough. */ +struct fpregs_t +{ + double fpregs[32]; + double fpscr; + unsigned int _pad[2]; +}; + +typedef uint32_t gregs32_t[48]; +typedef uint64_t gregs64_t[48]; + +struct fetch_context { + arch_addr_t stack_pointer; + int greg; + int freg; + int ret_struct; + + union { + gregs32_t r32; + gregs64_t r64; + } regs; + struct fpregs_t fpregs; + +}; + +static int +fetch_context_init(struct Process *proc, struct fetch_context *context) +{ + context->greg = 3; + context->freg = 1; + + if (proc->e_machine == EM_PPC) + context->stack_pointer = proc->stack_pointer + 8; + else + context->stack_pointer = proc->stack_pointer + 112; + + /* When ltrace is 64-bit, we might use PTRACE_GETREGS to + * obtain 64-bit as well as 32-bit registers. But if we do it + * this way, 32-bit ltrace can obtain 64-bit registers. + * + * XXX this direction is not supported as of this writing, but + * should be eventually. */ + if (proc->e_machine == EM_PPC64) { + if (ptrace(PTRACE_GETREGS64, proc->pid, 0, + &context->regs.r64) < 0) + return -1; + } else { +#ifdef __powerpc64__ + if (ptrace(PTRACE_GETREGS, proc->pid, 0, + &context->regs.r64) < 0) + return -1; + unsigned i; + for (i = 0; i < sizeof(context->regs.r64)/8; ++i) + context->regs.r32[i] = context->regs.r64[i]; +#else + if (ptrace(PTRACE_GETREGS, proc->pid, 0, + &context->regs.r32) < 0) + return -1; +#endif + } + + if (ptrace(PTRACE_GETFPREGS, proc->pid, 0, &context->fpregs) < 0) + return -1; + + return 0; +} + +struct fetch_context * +arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + struct fetch_context *context = malloc(sizeof(*context)); + if (context == NULL + || fetch_context_init(proc, context) < 0) { + free(context); + return NULL; + } + + /* Aggregates or unions of any length, and character strings + * of length longer than 8 bytes, will be returned in a + * storage buffer allocated by the caller. The caller will + * pass the address of this buffer as a hidden first argument + * in r3, causing the first explicit argument to be passed in + * r4. */ + context->ret_struct = ret_info->type == ARGTYPE_STRUCT; + if (context->ret_struct) + context->greg++; + + return context; +} + +struct fetch_context * +arch_fetch_arg_clone(struct Process *proc, + struct fetch_context *context) +{ + struct fetch_context *clone = malloc(sizeof(*context)); + if (clone == NULL) + return NULL; + *clone = *context; + return clone; +} + +static int +allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + + size_t a = type_alignof(proc, info); + size_t off = 0; + if (proc->e_machine == EM_PPC && a < 4) + a = 4; + else if (proc->e_machine == EM_PPC64 && a < 8) + a = 8; + + /* XXX Remove the two double casts when arch_addr_t + * becomes integral type. */ + uintptr_t tmp = align((uint64_t)(uintptr_t)ctx->stack_pointer, a); + ctx->stack_pointer = (arch_addr_t)tmp; + + if (valuep != NULL) + value_in_inferior(valuep, ctx->stack_pointer + off); + ctx->stack_pointer += sz; + + return 0; +} + +static uint64_t +read_gpr(struct fetch_context *ctx, struct Process *proc, int reg_num) +{ + if (proc->e_machine == EM_PPC) + return ctx->regs.r32[reg_num]; + else + return ctx->regs.r64[reg_num]; +} + +/* The support for little endian PowerPC is in upstream Linux and BFD, + * and Unix-like Solaris, which we might well support at some point, + * runs PowerPC in little endian as well. This code moves SZ-sized + * value to the beginning of W-sized BUF regardless of + * endian. */ +static void +align_small_int(unsigned char *buf, size_t w, size_t sz) +{ + assert(w == 4 || w == 8); + union { + uint64_t i64; + uint32_t i32; + uint16_t i16; + uint8_t i8; + char buf[0]; + } u; + memcpy(u.buf, buf, w); + if (w == 4) + u.i64 = u.i32; + + switch (sz) { + case 1: + u.i8 = u.i64; + break; + case 2: + u.i16 = u.i64; + break; + case 4: + u.i32 = u.i64; + case 8: + break; + } + + memcpy(buf, u.buf, sz); +} + +static int +allocate_gpr(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + if (ctx->greg > 10) + return allocate_stack_slot(ctx, proc, info, valuep); + + int reg_num = ctx->greg++; + if (valuep == NULL) + return 0; + + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + assert(sz == 1 || sz == 2 || sz == 4 || sz == 8); + if (value_reserve(valuep, sz) == NULL) + return -1; + + union { + uint64_t i64; + unsigned char buf[0]; + } u; + + u.i64 = read_gpr(ctx, proc, reg_num); + if (proc->e_machine == EM_PPC) + align_small_int(u.buf, 8, sz); + memcpy(value_get_raw_data(valuep), u.buf, sz); + return 0; +} + +static int +allocate_float(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + int pool = proc->e_machine == EM_PPC64 ? 13 : 8; + if (ctx->freg <= pool) { + union { + double d; + float f; + char buf[0]; + } u = { .d = ctx->fpregs.fpregs[ctx->freg] }; + + ctx->freg++; + if (proc->e_machine == EM_PPC64) + allocate_gpr(ctx, proc, info, NULL); + + size_t sz = sizeof(double); + if (info->type == ARGTYPE_FLOAT) { + sz = sizeof(float); + u.f = (float)u.d; + } + + if (value_reserve(valuep, sz) == NULL) + return -1; + + memcpy(value_get_raw_data(valuep), u.buf, sz); + return 0; + } + return allocate_stack_slot(ctx, proc, info, valuep); +} + +static int +allocate_argument(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + /* Floating point types and void are handled specially. */ + switch (info->type) { + case ARGTYPE_VOID: + value_set_word(valuep, 0); + return 0; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + return allocate_float(ctx, proc, info, valuep); + + case ARGTYPE_STRUCT: + if (proc->e_machine == EM_PPC) { + if (value_pass_by_reference(valuep) < 0) + return -1; + } else { + /* PPC64: Fixed size aggregates and unions passed by + * value are mapped to as many doublewords of the + * parameter save area as the value uses in memory. + * [...] The first eight doublewords mapped to the + * parameter save area correspond to the registers r3 + * through r10. */ + } + /* fall through */ + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + break; + + case ARGTYPE_ARRAY: + /* Arrays decay into pointers. XXX Fortran? */ + default: + assert(info->type != info->type); + abort(); + } + + unsigned width = proc->e_machine == EM_PPC64 ? 8 : 4; + + /* For other cases (integral types and aggregates), read the + * eightbytes comprising the data. */ + size_t sz = type_sizeof(proc, valuep->type); + if (sz == (size_t)-1) + return -1; + size_t slots = (sz + width - 1) / width; /* Round up. */ + unsigned char *buf = value_reserve(valuep, slots * width); + if (buf == NULL) + return -1; + struct arg_type_info *long_info = type_get_simple(ARGTYPE_LONG); + + unsigned char *ptr = buf; + while (slots-- > 0) { + struct value val; + value_init(&val, proc, NULL, long_info, 0); + + /* Floating point registers [...] are used [...] to + pass [...] one member aggregates passed by value + containing a floating point value[.] Note that for + one member aggregates, "containing" extends to + aggregates within aggregates ad infinitum. */ + int rc; + struct arg_type_info *fp_info + = type_get_fp_equivalent(valuep->type); + if (fp_info != NULL) + rc = allocate_float(ctx, proc, fp_info, &val); + else + rc = allocate_gpr(ctx, proc, long_info, &val); + + if (rc >= 0) { + memcpy(ptr, value_get_data(&val, NULL), width); + ptr += width; + } + value_destroy(&val); + + /* Bail out if we failed or if we are dealing with + * FP-equivalent. Those don't need the adjustments + * made below. */ + if (rc < 0 || fp_info != NULL) + return rc; + } + + /* Small values need post-processing. */ + if (sz < width) { + switch (info->type) { + default: + abort(); + + /* Simple integer types (char, short, int, long, enum) + * are mapped to a single doubleword. Values shorter + * than a doubleword are sign or zero extended as + * necessary. */ + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_INT: + case ARGTYPE_USHORT: + case ARGTYPE_UINT: + align_small_int(buf, width, sz); + break; + + /* Single precision floating point values are mapped + * to the second word in a single doubleword. + * + * An aggregate or union smaller than one doubleword + * in size is padded so that it appears in the least + * significant bits of the doubleword. */ + case ARGTYPE_FLOAT: + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + memmove(buf, buf + width - sz, sz); + break; + } + } + + return 0; +} + +int +arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + return allocate_argument(ctx, proc, info, valuep); +} + +int +arch_fetch_retval(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (ctx->ret_struct) { + assert(info->type == ARGTYPE_STRUCT); + + uint64_t addr = read_gpr(ctx, proc, 3); + value_init(valuep, proc, NULL, info, 0); + + valuep->where = VAL_LOC_INFERIOR; + /* XXX Remove the double cast when arch_addr_t + * becomes integral type. */ + valuep->u.address = (arch_addr_t)(uintptr_t)addr; + return 0; + } + + if (fetch_context_init(proc, ctx) < 0) + return -1; + return allocate_argument(ctx, proc, info, valuep); +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + free(context); +} diff --git a/sysdeps/linux-gnu/ppc/insn.h b/sysdeps/linux-gnu/ppc/insn.h new file mode 100644 index 0000000..cd94b5e --- /dev/null +++ b/sysdeps/linux-gnu/ppc/insn.h @@ -0,0 +1,45 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* Instruction masks used during single-stepping of atomic + * sequences. This was lifted from GDB. */ +#define LWARX_MASK 0xfc0007fe +#define LWARX_INSTRUCTION 0x7c000028 +#define LDARX_INSTRUCTION 0x7c0000A8 +#define STWCX_MASK 0xfc0007ff +#define STWCX_INSTRUCTION 0x7c00012d +#define STDCX_INSTRUCTION 0x7c0001ad +#define BRANCH_MASK 0xfc000000 +#define BC_MASK 0xfc000000 +#define BC_INSN 0x40000000 +#define B_INSN 0x48000000 + +static inline arch_addr_t +ppc_branch_dest(arch_addr_t addr, uint32_t insn) +{ + int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000; + int absolute = insn & 2; + + /* XXX drop the following double casts. */ + if (absolute) + return (arch_addr_t)(uintptr_t)immediate; + else + return addr + (uintptr_t)immediate; +} diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c index 31830fb..f83f087 100644 --- a/sysdeps/linux-gnu/ppc/plt.c +++ b/sysdeps/linux-gnu/ppc/plt.c @@ -1,54 +1,1038 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Paul Gilliam + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <gelf.h> +#include <sys/ptrace.h> +#include <errno.h> +#include <inttypes.h> +#include <assert.h> +#include <string.h> + +#include "proc.h" #include "common.h" +#include "insn.h" +#include "library.h" +#include "breakpoint.h" +#include "linux-gnu/trace.h" +#include "backend.h" + +/* There are two PLT types on 32-bit PPC: old-style, BSS PLT, and + * new-style "secure" PLT. We can tell one from the other by the + * flags on the .plt section. If it's +X (executable), it's BSS PLT, + * otherwise it's secure. + * + * BSS PLT works the same way as most architectures: the .plt section + * contains trampolines and we put breakpoints to those. If not + * prelinked, .plt contains zeroes, and dynamic linker fills in the + * initial set of trampolines, which means that we need to delay + * enabling breakpoints until after binary entry point is hit. + * Additionally, after first call, dynamic linker updates .plt with + * branch to resolved address. That means that on first hit, we must + * do something similar to the PPC64 gambit described below. + * + * With secure PLT, the .plt section doesn't contain instructions but + * addresses. The real PLT table is stored in .text. Addresses of + * those PLT entries can be computed, and apart from the fact that + * they are in .text, they are ordinary PLT entries. + * + * 64-bit PPC is more involved. Program linker creates for each + * library call a _stub_ symbol named xxxxxxxx.plt_call.<callee> + * (where xxxxxxxx is a hexadecimal number). That stub does the call + * dispatch: it loads an address of a function to call from the + * section .plt, and branches. PLT entries themselves are essentially + * a curried call to the resolver. When the symbol is resolved, the + * resolver updates the value stored in .plt, and the next time + * around, the stub calls the library function directly. So we make + * at most one trip (none if the binary is prelinked) through each PLT + * entry, and correspondingly that is useless as a breakpoint site. + * + * Note the three confusing terms: stubs (that play the role of PLT + * entries), PLT entries, .plt section. + * + * We first check symbol tables and see if we happen to have stub + * symbols available. If yes we just put breakpoints to those, and + * treat them as usual breakpoints. The only tricky part is realizing + * that there can be more than one breakpoint per symbol. + * + * The case that we don't have the stub symbols available is harder. + * The following scheme uses two kinds of PLT breakpoints: unresolved + * and resolved (to some address). When the process starts (or when + * we attach), we distribute unresolved PLT breakpoints to the PLT + * entries (not stubs). Then we look in .plt, and for each entry + * whose value is different than the corresponding PLT entry address, + * we assume it was already resolved, and convert the breakpoint to + * resolved. We also rewrite the resolved value in .plt back to the + * PLT address. + * + * When a PLT entry hits a resolved breakpoint (which happens because + * we rewrite .plt with the original unresolved addresses), we move + * the instruction pointer to the corresponding address and continue + * the process as if nothing happened. + * + * When unresolved PLT entry is called for the first time, we need to + * catch the new value that the resolver will write to a .plt slot. + * We also need to prevent another thread from racing through and + * taking the branch without ltrace noticing. So when unresolved PLT + * entry hits, we have to stop all threads. We then single-step + * through the resolver, until the .plt slot changes. When it does, + * we treat it the same way as above: convert the PLT breakpoint to + * resolved, and rewrite the .plt value back to PLT address. We then + * start all threads again. + * + * As an optimization, we remember the address where the address was + * resolved, and put a breakpoint there. The next time around (when + * the next PLT entry is to be resolved), instead of single-stepping + * through half the dynamic linker, we just let the thread run and hit + * this breakpoint. When it hits, we know the PLT entry was resolved. + * + * XXX TODO If we have hardware watch point, we might put a read watch + * on .plt slot, and discover the offenders this way. I don't know + * the details, but I assume at most a handful (like, one or two, if + * available at all) addresses may be watched at a time, and thus this + * would be used as an amendment of the above rather than full-on + * solution to PLT tracing on PPC. + */ + +#define PPC_PLT_STUB_SIZE 16 +#define PPC64_PLT_STUB_SIZE 8 //xxx + +static inline int +host_powerpc64() +{ +#ifdef __powerpc64__ + return 1; +#else + return 0; +#endif +} + +int +read_target_4(struct Process *proc, arch_addr_t addr, uint32_t *lp) +{ + unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); + if (l == -1UL && errno) + return -1; +#ifdef __powerpc64__ + l >>= 32; +#endif + *lp = l; + return 0; +} + +static int +read_target_8(struct Process *proc, arch_addr_t addr, uint64_t *lp) +{ + unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); + if (l == -1UL && errno) + return -1; + if (host_powerpc64()) { + *lp = l; + } else { + unsigned long l2 = ptrace(PTRACE_PEEKTEXT, proc->pid, + addr + 4, 0); + if (l2 == -1UL && errno) + return -1; + *lp = ((uint64_t)l << 32) | l2; + } + return 0; +} + +int +read_target_long(struct Process *proc, arch_addr_t addr, uint64_t *lp) +{ + if (proc->e_machine == EM_PPC) { + uint32_t w; + int ret = read_target_4(proc, addr, &w); + if (ret >= 0) + *lp = (uint64_t)w; + return ret; + } else { + return read_target_8(proc, addr, lp); + } +} + +static void +mark_as_resolved(struct library_symbol *libsym, GElf_Addr value) +{ + libsym->arch.type = PPC_PLT_RESOLVED; + libsym->arch.resolved_value = value; +} + +void +arch_dynlink_done(struct Process *proc) +{ + /* On PPC32 with BSS PLT, we need to enable delayed symbols. */ + struct library_symbol *libsym = NULL; + while ((libsym = proc_each_symbol(proc, libsym, + library_symbol_delayed_cb, NULL))) { + if (read_target_8(proc, libsym->enter_addr, + &libsym->arch.resolved_value) < 0) { + fprintf(stderr, + "couldn't read PLT value for %s(%p): %s\n", + libsym->name, libsym->enter_addr, + strerror(errno)); + return; + } + + /* arch_dynlink_done is called on attach as well. In + * that case some slots will have been resolved + * already. Unresolved PLT looks like this: + * + * <sleep@plt>: li r11,0 + * <sleep@plt+4>: b "resolve" + * + * "resolve" is another address in PLTGOT (the same + * block that all the PLT slots are it). When + * resolved, it looks either this way: + * + * <sleep@plt>: b 0xfea88d0 <sleep> + * + * Which is easy to detect. It can also look this + * way: + * + * <sleep@plt>: li r11,0 + * <sleep@plt+4>: b "dispatch" + * + * The "dispatch" address lies in PLTGOT as well. In + * current GNU toolchain, "dispatch" address is the + * same as PLTGOT address. We rely on this to figure + * out whether the address is resolved or not. */ + uint32_t insn1 = libsym->arch.resolved_value >> 32; + uint32_t insn2 = (uint32_t)libsym->arch.resolved_value; + if ((insn1 & BRANCH_MASK) == B_INSN + || ((insn2 & BRANCH_MASK) == B_INSN + /* XXX double cast */ + && (ppc_branch_dest(libsym->enter_addr + 4, insn2) + == (void*)(long)libsym->lib->arch.pltgot_addr))) + mark_as_resolved(libsym, libsym->arch.resolved_value); + + if (proc_activate_delayed_symbol(proc, libsym) < 0) + return; + + /* XXX double cast */ + libsym->arch.plt_slot_addr + = (GElf_Addr)(uintptr_t)libsym->enter_addr; + } +} GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - return rela->r_offset; +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) +{ + if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) { + assert(lte->arch.plt_stub_vma != 0); + return lte->arch.plt_stub_vma + PPC_PLT_STUB_SIZE * ndx; + + } else if (lte->ehdr.e_machine == EM_PPC) { + return rela->r_offset; + + } else { + /* If we get here, we don't have stub symbols. In + * that case we put brakpoints to PLT entries the same + * as the PPC32 secure PLT case does. */ + assert(lte->arch.plt_stub_vma != 0); + return lte->arch.plt_stub_vma + PPC64_PLT_STUB_SIZE * ndx; + } +} + +/* This entry point is called when ltelf is not available + * anymore--during runtime. At that point we don't have to concern + * ourselves with bias, as the values in OPD have been resolved + * already. */ +int +arch_translate_address_dyn(struct Process *proc, + arch_addr_t addr, arch_addr_t *ret) +{ + if (proc->e_machine == EM_PPC64) { + uint64_t value; + if (read_target_8(proc, addr, &value) < 0) { + fprintf(stderr, + "dynamic .opd translation of %p: %s\n", + addr, strerror(errno)); + return -1; + } + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + *ret = (arch_addr_t)(uintptr_t)value; + return 0; + } + + *ret = addr; + return 0; +} + +int +arch_translate_address(struct ltelf *lte, + arch_addr_t addr, arch_addr_t *ret) +{ + if (lte->ehdr.e_machine == EM_PPC64) { + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + GElf_Xword offset + = (GElf_Addr)(uintptr_t)addr - lte->arch.opd_base; + uint64_t value; + if (elf_read_u64(lte->arch.opd_data, offset, &value) < 0) { + fprintf(stderr, "static .opd translation of %p: %s\n", + addr, elf_errmsg(-1)); + return -1; + } + *ret = (arch_addr_t)(uintptr_t)(value + lte->bias); + return 0; + } + + *ret = addr; + return 0; +} + +static int +load_opd_data(struct ltelf *lte, struct library *lib) +{ + Elf_Scn *sec; + GElf_Shdr shdr; + if (elf_get_section_named(lte, ".opd", &sec, &shdr) < 0) { + fail: + fprintf(stderr, "couldn't find .opd data\n"); + return -1; + } + + lte->arch.opd_data = elf_rawdata(sec, NULL); + if (lte->arch.opd_data == NULL) + goto fail; + + lte->arch.opd_base = shdr.sh_addr + lte->bias; + lte->arch.opd_size = shdr.sh_size; + + return 0; } void * -sym2addr(Process *proc, struct library_symbol *sym) { - void *addr = sym->enter_addr; - long pt_ret; +sym2addr(struct Process *proc, struct library_symbol *sym) +{ + return sym->enter_addr; +} - debug(3, 0); +static GElf_Addr +get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data) +{ + Elf_Scn *ppcgot_sec = NULL; + GElf_Shdr ppcgot_shdr; + if (ppcgot != 0 + && elf_get_section_covering(lte, ppcgot, + &ppcgot_sec, &ppcgot_shdr) < 0) + fprintf(stderr, + "DT_PPC_GOT=%#"PRIx64", but no such section found\n", + ppcgot); - if (sym->plt_type != LS_TOPLT_POINT) { - return addr; + if (ppcgot_sec != NULL) { + Elf_Data *data = elf_loaddata(ppcgot_sec, &ppcgot_shdr); + if (data == NULL || data->d_size < 8 ) { + fprintf(stderr, "couldn't read GOT data\n"); + } else { + // where PPCGOT begins in .got + size_t offset = ppcgot - ppcgot_shdr.sh_addr; + assert(offset % 4 == 0); + uint32_t glink_vma; + if (elf_read_u32(data, offset + 4, &glink_vma) < 0) { + fprintf(stderr, "couldn't read glink VMA" + " address at %zd@GOT\n", offset); + return 0; + } + if (glink_vma != 0) { + debug(1, "PPC GOT glink_vma address: %#" PRIx32, + glink_vma); + return (GElf_Addr)glink_vma; + } + } } - if (proc->pid == 0) { + if (plt_data != NULL) { + uint32_t glink_vma; + if (elf_read_u32(plt_data, 0, &glink_vma) < 0) { + fprintf(stderr, "couldn't read glink VMA address\n"); + return 0; + } + debug(1, ".plt glink_vma address: %#" PRIx32, glink_vma); + return (GElf_Addr)glink_vma; + } + + return 0; +} + +static int +load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep) +{ + Elf_Scn *scn; + GElf_Shdr shdr; + if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 + || scn == NULL) { + fail: + fprintf(stderr, "Couldn't get SHT_DYNAMIC: %s\n", + elf_errmsg(-1)); + return -1; + } + + Elf_Data *data = elf_loaddata(scn, &shdr); + if (data == NULL) + goto fail; + + size_t j; + for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { + GElf_Dyn dyn; + if (gelf_getdyn(data, j, &dyn) == NULL) + goto fail; + + if(dyn.d_tag == tag) { + *valuep = dyn.d_un.d_ptr; + return 0; + } + } + + return -1; +} + +static int +nonzero_data(Elf_Data *data) +{ + /* We are not supposed to get here if there's no PLT. */ + assert(data != NULL); + + unsigned char *buf = data->d_buf; + if (buf == NULL) return 0; + + size_t i; + for (i = 0; i < data->d_size; ++i) + if (buf[i] != 0) + return 1; + return 0; +} + +int +arch_elf_init(struct ltelf *lte, struct library *lib) +{ + if (lte->ehdr.e_machine == EM_PPC64 + && load_opd_data(lte, lib) < 0) + return -1; + + lte->arch.secure_plt = !(lte->plt_flags & SHF_EXECINSTR); + + /* For PPC32 BSS, it is important whether the binary was + * prelinked. If .plt section is NODATA, or if it contains + * zeroes, then this library is not prelinked, and we need to + * delay breakpoints. */ + if (lte->ehdr.e_machine == EM_PPC && !lte->arch.secure_plt) + lib->arch.bss_plt_prelinked = nonzero_data(lte->plt_data); + else + /* For cases where it's irrelevant, initialize the + * value to something conspicuous. */ + lib->arch.bss_plt_prelinked = -1; + + if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) { + GElf_Addr ppcgot; + if (load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) { + fprintf(stderr, "couldn't find DT_PPC_GOT\n"); + return -1; + } + GElf_Addr glink_vma = get_glink_vma(lte, ppcgot, lte->plt_data); + + assert(lte->relplt_size % 12 == 0); + size_t count = lte->relplt_size / 12; // size of RELA entry + lte->arch.plt_stub_vma = glink_vma + - (GElf_Addr)count * PPC_PLT_STUB_SIZE; + debug(1, "stub_vma is %#" PRIx64, lte->arch.plt_stub_vma); + + } else if (lte->ehdr.e_machine == EM_PPC64) { + GElf_Addr glink_vma; + if (load_dynamic_entry(lte, DT_PPC64_GLINK, &glink_vma) < 0) { + fprintf(stderr, "couldn't find DT_PPC64_GLINK\n"); + return -1; + } + + /* The first glink stub starts at offset 32. */ + lte->arch.plt_stub_vma = glink_vma + 32; + + } else { + /* By exhaustion--PPC32 BSS. */ + if (load_dynamic_entry(lte, DT_PLTGOT, + &lib->arch.pltgot_addr) < 0) { + fprintf(stderr, "couldn't find DT_PLTGOT\n"); + return -1; + } + } + + /* On PPC64, look for stub symbols in symbol table. These are + * called: xxxxxxxx.plt_call.callee_name@version+addend. */ + if (lte->ehdr.e_machine == EM_PPC64 + && lte->symtab != NULL && lte->strtab != NULL) { + + /* N.B. We can't simply skip the symbols that we fail + * to read or malloc. There may be more than one stub + * per symbol name, and if we failed in one but + * succeeded in another, the PLT enabling code would + * have no way to tell that something is missing. We + * could work around that, of course, but it doesn't + * seem worth the trouble. So if anything fails, we + * just pretend that we don't have stub symbols at + * all, as if the binary is stripped. */ + + size_t i; + for (i = 0; i < lte->symtab_count; ++i) { + GElf_Sym sym; + if (gelf_getsym(lte->symtab, i, &sym) == NULL) { + struct library_symbol *sym, *next; + fail: + for (sym = lte->arch.stubs; sym != NULL; ) { + next = sym->next; + library_symbol_destroy(sym); + free(sym); + sym = next; + } + lte->arch.stubs = NULL; + break; + } + + const char *name = lte->strtab + sym.st_name; + +#define STUBN ".plt_call." + if ((name = strstr(name, STUBN)) == NULL) + continue; + name += sizeof(STUBN) - 1; +#undef STUBN + + size_t len; + const char *ver = strchr(name, '@'); + if (ver != NULL) { + len = ver - name; + + } else { + /* If there is "+" at all, check that + * the symbol name ends in "+0". */ + const char *add = strrchr(name, '+'); + if (add != NULL) { + assert(strcmp(add, "+0") == 0); + len = add - name; + } else { + len = strlen(name); + } + } + + char *sym_name = strndup(name, len); + struct library_symbol *libsym = malloc(sizeof(*libsym)); + if (sym_name == NULL || libsym == NULL) { + fail2: + free(sym_name); + free(libsym); + goto fail; + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t addr = (arch_addr_t) + (uintptr_t)sym.st_value + lte->bias; + if (library_symbol_init(libsym, addr, sym_name, 1, + LS_TOPLT_EXEC) < 0) + goto fail2; + libsym->arch.type = PPC64_PLT_STUB; + libsym->next = lte->arch.stubs; + lte->arch.stubs = libsym; + } + } + + return 0; +} + +static int +read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp) +{ + /* On PPC64, we read from .plt, which contains 8 byte + * addresses. On PPC32 we read from .plt, which contains 4 + * byte instructions, but the PLT is two instructions, and + * either can change. */ + uint64_t l; + /* XXX double cast. */ + if (read_target_8(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) { + fprintf(stderr, "ptrace .plt slot value @%#" PRIx64": %s\n", + addr, strerror(errno)); + return -1; + } + + *valp = (GElf_Addr)l; + return 0; +} + +static int +unresolve_plt_slot(struct Process *proc, GElf_Addr addr, GElf_Addr value) +{ + /* We only modify plt_entry[0], which holds the resolved + * address of the routine. We keep the TOC and environment + * pointers intact. Hence the only adjustment that we need to + * do is to IP. */ + if (ptrace(PTRACE_POKETEXT, proc->pid, addr, value) < 0) { + fprintf(stderr, "failed to unresolve .plt slot: %s\n", + strerror(errno)); + return -1; + } + return 0; +} + +enum plt_status +arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + if (lte->ehdr.e_machine == EM_PPC) { + if (lte->arch.secure_plt) + return plt_default; + + struct library_symbol *libsym = NULL; + if (default_elf_add_plt_entry(proc, lte, a_name, rela, ndx, + &libsym) < 0) + return plt_fail; + + /* On PPC32 with BSS PLT, delay the symbol until + * dynamic linker is done. */ + assert(!libsym->delayed); + libsym->delayed = 1; + + *ret = libsym; + return plt_ok; + } + + /* PPC64. If we have stubs, we return a chain of breakpoint + * sites, one for each stub that corresponds to this PLT + * entry. */ + struct library_symbol *chain = NULL; + struct library_symbol **symp; + for (symp = <e->arch.stubs; *symp != NULL; ) { + struct library_symbol *sym = *symp; + if (strcmp(sym->name, a_name) != 0) { + symp = &(*symp)->next; + continue; + } + + /* Re-chain the symbol from stubs to CHAIN. */ + *symp = sym->next; + sym->next = chain; + chain = sym; } - if (options.debug >= 3) { - xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0), - sizeof(void*)*8); + if (chain != NULL) { + *ret = chain; + return plt_ok; } - // On a PowerPC-64 system, a plt is three 64-bit words: the first is the - // 64-bit address of the routine. Before the PLT has been initialized, - // this will be 0x0. In fact, the symbol table won't have the plt's - // address even. Ater the PLT has been initialized, but before it has - // been resolved, the first word will be the address of the function in - // the dynamic linker that will reslove the PLT. After the PLT is - // resolved, this will will be the address of the routine whose symbol - // is in the symbol table. + /* We don't have stub symbols. Find corresponding .plt slot, + * and check whether it contains the corresponding PLT address + * (or 0 if the dynamic linker hasn't run yet). N.B. we don't + * want read this from ELF file, but from process image. That + * makes a difference if we are attaching to a running + * process. */ - // On a PowerPC-32 system, there are two types of PLTs: secure (new) and - // non-secure (old). For the secure case, the PLT is simply a pointer - // and we can treat it much as we do for the PowerPC-64 case. For the - // non-secure case, the PLT is executable code and we can put the - // break-point right in the PLT. + GElf_Addr plt_entry_addr = arch_plt_sym_val(lte, ndx, rela); + GElf_Addr plt_slot_addr = rela->r_offset; + assert(plt_slot_addr >= lte->plt_addr + || plt_slot_addr < lte->plt_addr + lte->plt_size); - pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); + GElf_Addr plt_slot_value; + if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0) + return plt_fail; + + char *name = strdup(a_name); + struct library_symbol *libsym = malloc(sizeof(*libsym)); + if (name == NULL || libsym == NULL) { + fprintf(stderr, "allocation for .plt slot: %s\n", + strerror(errno)); + fail: + free(name); + free(libsym); + return plt_fail; + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + if (library_symbol_init(libsym, + (arch_addr_t)(uintptr_t)plt_entry_addr, + name, 1, LS_TOPLT_EXEC) < 0) + goto fail; + libsym->arch.plt_slot_addr = plt_slot_addr; + + if (plt_slot_value == plt_entry_addr || plt_slot_value == 0) { + libsym->arch.type = PPC_PLT_UNRESOLVED; + libsym->arch.resolved_value = plt_entry_addr; - if (proc->mask_32bit) { - // Assume big-endian. - addr = (void *)((pt_ret >> 32) & 0xffffffff); } else { - addr = (void *)pt_ret; + /* Unresolve the .plt slot. If the binary was + * prelinked, this makes the code invalid, because in + * case of prelinked binary, the dynamic linker + * doesn't update .plt[0] and .plt[1] with addresses + * of the resover. But we don't care, we will never + * need to enter the resolver. That just means that + * we have to un-un-resolve this back before we + * detach. */ + + if (unresolve_plt_slot(proc, plt_slot_addr, plt_entry_addr) < 0) { + library_symbol_destroy(libsym); + goto fail; + } + mark_as_resolved(libsym, plt_slot_value); + } + + *ret = libsym; + return plt_ok; +} + +void +arch_elf_destroy(struct ltelf *lte) +{ + struct library_symbol *sym; + for (sym = lte->arch.stubs; sym != NULL; ) { + struct library_symbol *next = sym->next; + library_symbol_destroy(sym); + free(sym); + sym = next; + } +} + +static void +dl_plt_update_bp_on_hit(struct breakpoint *bp, struct Process *proc) +{ + debug(DEBUG_PROCESS, "pid=%d dl_plt_update_bp_on_hit %s(%p)", + proc->pid, breakpoint_name(bp), bp->addr); + struct process_stopping_handler *self = proc->arch.handler; + assert(self != NULL); + + struct library_symbol *libsym = self->breakpoint_being_enabled->libsym; + GElf_Addr value; + if (read_plt_slot_value(proc, libsym->arch.plt_slot_addr, &value) < 0) + return; + + /* On PPC64, we rewrite the slot value. */ + if (proc->e_machine == EM_PPC64) + unresolve_plt_slot(proc, libsym->arch.plt_slot_addr, + libsym->arch.resolved_value); + /* We mark the breakpoint as resolved on both arches. */ + mark_as_resolved(libsym, value); + + /* cb_on_all_stopped looks if HANDLER is set to NULL as a way + * to check that this was run. It's an error if it + * wasn't. */ + proc->arch.handler = NULL; + + breakpoint_turn_off(bp, proc); +} + +static void +cb_on_all_stopped(struct process_stopping_handler *self) +{ + /* Put that in for dl_plt_update_bp_on_hit to see. */ + assert(self->task_enabling_breakpoint->arch.handler == NULL); + self->task_enabling_breakpoint->arch.handler = self; + + linux_ptrace_disable_and_continue(self); +} + +static enum callback_status +cb_keep_stepping_p(struct process_stopping_handler *self) +{ + struct Process *proc = self->task_enabling_breakpoint; + struct library_symbol *libsym = self->breakpoint_being_enabled->libsym; + + GElf_Addr value; + if (read_plt_slot_value(proc, libsym->arch.plt_slot_addr, &value) < 0) + return CBS_FAIL; + + /* In UNRESOLVED state, the RESOLVED_VALUE in fact contains + * the PLT entry value. */ + if (value == libsym->arch.resolved_value) + return CBS_CONT; + + debug(DEBUG_PROCESS, "pid=%d PLT got resolved to value %#"PRIx64, + proc->pid, value); + + /* The .plt slot got resolved! We can migrate the breakpoint + * to RESOLVED and stop single-stepping. */ + if (proc->e_machine == EM_PPC64 + && unresolve_plt_slot(proc, libsym->arch.plt_slot_addr, + libsym->arch.resolved_value) < 0) + return CBS_FAIL; + + /* Resolving on PPC64 consists of overwriting a doubleword in + * .plt. That doubleword is than read back by a stub, and + * jumped on. Hopefully we can assume that double word update + * is done on a single place only, as it contains a final + * address. We still need to look around for any sync + * instruction, but essentially it is safe to optimize away + * the single stepping next time and install a post-update + * breakpoint. + * + * The situation on PPC32 BSS is more complicated. The + * dynamic linker here updates potentially several + * instructions (XXX currently we assume two) and the rules + * are more complicated. Sometimes it's enough to adjust just + * one of the addresses--the logic for generating optimal + * dispatch depends on relative addresses of the .plt entry + * and the jump destination. We can't assume that the some + * instruction block does the update every time. So on PPC32, + * we turn the optimization off and just step through it each + * time. */ + if (proc->e_machine == EM_PPC) + goto done; + + /* Install breakpoint to the address where the change takes + * place. If we fail, then that just means that we'll have to + * singlestep the next time around as well. */ + struct Process *leader = proc->leader; + if (leader == NULL || leader->arch.dl_plt_update_bp != NULL) + goto done; + + /* We need to install to the next instruction. ADDR points to + * a store instruction, so moving the breakpoint one + * instruction forward is safe. */ + arch_addr_t addr = get_instruction_pointer(proc) + 4; + leader->arch.dl_plt_update_bp = insert_breakpoint(proc, addr, NULL); + if (leader->arch.dl_plt_update_bp == NULL) + goto done; + + static struct bp_callbacks dl_plt_update_cbs = { + .on_hit = dl_plt_update_bp_on_hit, + }; + leader->arch.dl_plt_update_bp->cbs = &dl_plt_update_cbs; + + /* Turn it off for now. We will turn it on again when we hit + * the PLT entry that needs this. */ + breakpoint_turn_off(leader->arch.dl_plt_update_bp, proc); + +done: + mark_as_resolved(libsym, value); + + return CBS_STOP; +} + +static void +jump_to_entry_point(struct Process *proc, struct breakpoint *bp) +{ + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t rv = (arch_addr_t) + (uintptr_t)bp->libsym->arch.resolved_value; + set_instruction_pointer(proc, rv); +} + +static void +ppc_plt_bp_continue(struct breakpoint *bp, struct Process *proc) +{ + switch (bp->libsym->arch.type) { + struct Process *leader; + void (*on_all_stopped)(struct process_stopping_handler *); + enum callback_status (*keep_stepping_p) + (struct process_stopping_handler *); + + case PPC_DEFAULT: + assert(proc->e_machine == EM_PPC); + assert(bp->libsym != NULL); + assert(bp->libsym->lib->arch.bss_plt_prelinked == 0); + /* Fall through. */ + + case PPC_PLT_UNRESOLVED: + on_all_stopped = NULL; + keep_stepping_p = NULL; + leader = proc->leader; + + if (leader != NULL && leader->arch.dl_plt_update_bp != NULL + && breakpoint_turn_on(leader->arch.dl_plt_update_bp, + proc) >= 0) + on_all_stopped = cb_on_all_stopped; + else + keep_stepping_p = cb_keep_stepping_p; + + if (process_install_stopping_handler + (proc, bp, on_all_stopped, keep_stepping_p, NULL) < 0) { + fprintf(stderr, "ppc_plt_bp_continue: " + "couldn't install event handler\n"); + continue_after_breakpoint(proc, bp); + } + return; + + case PPC_PLT_RESOLVED: + if (proc->e_machine == EM_PPC) { + continue_after_breakpoint(proc, bp); + return; + } + + jump_to_entry_point(proc, bp); + continue_process(proc->pid); + return; + + case PPC64_PLT_STUB: + /* These should never hit here. */ + break; + } + + assert(bp->libsym->arch.type != bp->libsym->arch.type); + abort(); +} + +/* When a process is in a PLT stub, it may have already read the data + * in .plt that we changed. If we detach now, it will jump to PLT + * entry and continue to the dynamic linker, where it will SIGSEGV, + * because zeroth .plt slot is not filled in prelinked binaries, and + * the dynamic linker needs that data. Moreover, the process may + * actually have hit the breakpoint already. This functions tries to + * detect both cases and do any fix-ups necessary to mend this + * situation. */ +static enum callback_status +detach_task_cb(struct Process *task, void *data) +{ + struct breakpoint *bp = data; + + if (get_instruction_pointer(task) == bp->addr) { + debug(DEBUG_PROCESS, "%d at %p, which is PLT slot", + task->pid, bp->addr); + jump_to_entry_point(task, bp); + return CBS_CONT; } - return addr; + /* XXX There's still a window of several instructions where we + * might catch the task inside a stub such that it has already + * read destination address from .plt, but hasn't jumped yet, + * thus avoiding the breakpoint. */ + + return CBS_CONT; +} + +static void +ppc_plt_bp_retract(struct breakpoint *bp, struct Process *proc) +{ + /* On PPC64, we rewrite .plt with PLT entry addresses. This + * needs to be undone. Unfortunately, the program may have + * made decisions based on that value */ + if (proc->e_machine == EM_PPC64 + && bp->libsym != NULL + && bp->libsym->arch.type == PPC_PLT_RESOLVED) { + each_task(proc->leader, NULL, detach_task_cb, bp); + unresolve_plt_slot(proc, bp->libsym->arch.plt_slot_addr, + bp->libsym->arch.resolved_value); + } +} + +void +arch_library_init(struct library *lib) +{ +} + +void +arch_library_destroy(struct library *lib) +{ +} + +void +arch_library_clone(struct library *retp, struct library *lib) +{ +} + +int +arch_library_symbol_init(struct library_symbol *libsym) +{ + /* We set type explicitly in the code above, where we have the + * necessary context. This is for calls from ltrace-elf.c and + * such. */ + libsym->arch.type = PPC_DEFAULT; + return 0; +} + +void +arch_library_symbol_destroy(struct library_symbol *libsym) +{ +} + +int +arch_library_symbol_clone(struct library_symbol *retp, + struct library_symbol *libsym) +{ + retp->arch = libsym->arch; + return 0; +} + +/* For some symbol types, we need to set up custom callbacks. XXX we + * don't need PROC here, we can store the data in BP if it is of + * interest to us. */ +int +arch_breakpoint_init(struct Process *proc, struct breakpoint *bp) +{ + /* Artificial and entry-point breakpoints are plain. */ + if (bp->libsym == NULL || bp->libsym->plt_type != LS_TOPLT_EXEC) + return 0; + + /* On PPC, secure PLT and prelinked BSS PLT are plain. */ + if (proc->e_machine == EM_PPC + && bp->libsym->lib->arch.bss_plt_prelinked != 0) + return 0; + + /* On PPC64, stub PLT breakpoints are plain. */ + if (proc->e_machine == EM_PPC64 + && bp->libsym->arch.type == PPC64_PLT_STUB) + return 0; + + static struct bp_callbacks cbs = { + .on_continue = ppc_plt_bp_continue, + .on_retract = ppc_plt_bp_retract, + }; + breakpoint_set_callbacks(bp, &cbs); + return 0; +} + +void +arch_breakpoint_destroy(struct breakpoint *bp) +{ +} + +int +arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) +{ + retp->arch = sbp->arch; + return 0; +} + +int +arch_process_init(struct Process *proc) +{ + proc->arch.dl_plt_update_bp = NULL; + proc->arch.handler = NULL; + return 0; +} + +void +arch_process_destroy(struct Process *proc) +{ +} + +int +arch_process_clone(struct Process *retp, struct Process *proc) +{ + retp->arch = proc->arch; + return 0; +} + +int +arch_process_exec(struct Process *proc) +{ + return arch_process_init(proc); } diff --git a/sysdeps/linux-gnu/ppc/ptrace.h b/sysdeps/linux-gnu/ppc/ptrace.h index c3cbcb6..57c230c 100644 --- a/sysdeps/linux-gnu/ppc/ptrace.h +++ b/sysdeps/linux-gnu/ppc/ptrace.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c index eca58ff..37f89a4 100644 --- a/sysdeps/linux-gnu/ppc/regs.c +++ b/sysdeps/linux-gnu/ppc/regs.c @@ -1,9 +1,34 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2002,2008,2009 Juan Cespedes + * Copyright (C) 2009 Juan Cespedes + * Copyright (C) 2008 Luis Machado, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> #include <sys/ptrace.h> #include <asm/ptrace.h> +#include <errno.h> +#include <error.h> +#include "proc.h" #include "common.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) @@ -20,8 +45,10 @@ get_instruction_pointer(Process *proc) { } void -set_instruction_pointer(Process *proc, void *addr) { - ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr); +set_instruction_pointer(Process *proc, void *addr) +{ + if (ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr) != 0) + error(0, errno, "set_instruction_pointer"); } void * diff --git a/sysdeps/linux-gnu/ppc/signalent.h b/sysdeps/linux-gnu/ppc/signalent.h index d58a36c..9b8baa0 100644 --- a/sysdeps/linux-gnu/ppc/signalent.h +++ b/sysdeps/linux-gnu/ppc/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/ppc/syscallent.h b/sysdeps/linux-gnu/ppc/syscallent.h index 5ce5739..6989e81 100644 --- a/sysdeps/linux-gnu/ppc/syscallent.h +++ b/sysdeps/linux-gnu/ppc/syscallent.h @@ -1,4 +1,25 @@ -"0", /* 0 */ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + + "restart_syscall", /* 0 */ "exit", /* 1 */ "fork", /* 2 */ "read", /* 3 */ @@ -177,8 +198,8 @@ "rt_sigtimedwait", /* 176 */ "rt_sigqueueinfo", /* 177 */ "rt_sigsuspend", /* 178 */ - "pread", /* 179 */ - "pwrite", /* 180 */ + "pread64", /* 179 */ + "pwrite64", /* 180 */ "chown", /* 181 */ "getcwd", /* 182 */ "capget", /* 183 */ @@ -254,6 +275,12 @@ "fstatfs64", /* 253 */ "fadvise64_64", /* 254 */ "rtas", /* 255 */ + "sys_debug_setcontext", /* 256 */ + "server", /* 257 */ + "migrate_pages", /* 258 */ + "mbind", /* 259 */ + "get_mempolicy", /* 260 */ + "set_mempolicy", /* 261 */ "mq_open", /* 262 */ "mq_unlink", /* 263 */ "mq_timedsend", /* 264 */ @@ -270,3 +297,78 @@ "inotify_init", /* 275 */ "inotify_add_watch", /* 276 */ "inotify_rm_watch", /* 277 */ + "spu_run", /* 278 */ + "spu_create", /* 279 */ + "pselect6", /* 280 */ + "ppoll", /* 281 */ + "unshare", /* 282 */ + "splice", /* 283 */ + "tee", /* 284 */ + "vmsplice", /* 285 */ + "openat", /* 286 */ + "mkdirat", /* 287 */ + "mknodat", /* 288 */ + "fchownat", /* 289 */ + "futimesat", /* 290 */ + "fstatat64", /* 291 */ + "unlinkat", /* 292 */ + "renameat", /* 293 */ + "linkat", /* 294 */ + "symlinkat", /* 295 */ + "readlinkat", /* 296 */ + "fchmodat", /* 297 */ + "faccessat", /* 298 */ + "get_robust_list", /* 299 */ + "set_robust_list", /* 300 */ + "move_pages", /* 301 */ + "getcpu", /* 302 */ + "epoll_pwait", /* 303 */ + "utimensat", /* 304 */ + "signalfd", /* 305 */ + "timerfd_create", /* 306 */ + "eventfd", /* 307 */ + "sync_file_range2", /* 308 */ + "fallocate", /* 309 */ + "subpage_prot", /* 310 */ + "timerfd_settime", /* 311 */ + "timerfd_gettime", /* 312 */ + "signalfd4", /* 313 */ + "eventfd2", /* 314 */ + "epoll_create1", /* 315 */ + "dup3", /* 316 */ + "pipe2", /* 317 */ + "inotify_init1", /* 318 */ + "perf_event_open", /* 319 */ + "preadv", /* 320 */ + "pwritev", /* 321 */ + "rt_tgsigqueueinfo", /* 322 */ + "fanotify_init", /* 323 */ + "fanotify_mark", /* 324 */ + "prlimit64", /* 325 */ + "socket", /* 326 */ + "bind", /* 327 */ + "connect", /* 328 */ + "listen", /* 329 */ + "accept", /* 330 */ + "getsockname", /* 331 */ + "getpeername", /* 332 */ + "socketpair", /* 333 */ + "send", /* 334 */ + "sendto", /* 335 */ + "recv", /* 336 */ + "recvfrom", /* 337 */ + "shutdown", /* 338 */ + "setsockopt", /* 339 */ + "getsockopt", /* 340 */ + "sendmsg", /* 341 */ + "recvmsg", /* 342 */ + "recvmmsg", /* 343 */ + "accept4", /* 344 */ + "name_to_handle_at", /* 345 */ + "open_by_handle_at", /* 346 */ + "clock_adjtime", /* 347 */ + "syncfs", /* 348 */ + "sendmmsg", /* 349 */ + "setns", /* 350 */ + "process_vm_readv", /* 351 */ + "process_writev", /* 352 */ diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c index 81fb71d..4357a1e 100644 --- a/sysdeps/linux-gnu/ppc/trace.c +++ b/sysdeps/linux-gnu/ppc/trace.c @@ -1,14 +1,44 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2011 Andreas Schwab + * Copyright (C) 2002,2004,2008,2009 Juan Cespedes + * Copyright (C) 2008 Luis Machado, IBM Corporation + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <sys/ptrace.h> -#include <asm/ptrace.h> +#include <assert.h> #include <elf.h> #include <errno.h> +#include <signal.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include "backend.h" +#include "breakpoint.h" #include "common.h" +#include "insn.h" +#include "proc.h" +#include "ptrace.h" +#include "type.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR @@ -21,20 +51,13 @@ void get_arch_dep(Process *proc) { #ifdef __powerpc64__ - if (proc->arch_ptr) - return; proc->mask_32bit = (proc->e_machine == EM_PPC); - proc->arch_ptr = (void *)1; #endif } -/* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ #define SYSCALL_INSN 0x44000002 -unsigned int greg = 3; -unsigned int freg = 1; -unsigned int vreg = 2; - +/* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int syscall_p(Process *proc, int status, int *sysnum) { if (WIFSTOPPED(status) @@ -59,97 +82,167 @@ syscall_p(Process *proc, int status, int *sysnum) { return 0; } -/* Grab functions arguments based on the PPC64 ABI. */ -long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { - long data; - - if (type == LT_TOF_FUNCTIONR) { - if (info->type == ARGTYPE_FLOAT || info->type == ARGTYPE_DOUBLE) - return ptrace (PTRACE_PEEKUSER, proc->pid, - sizeof (long) * (PT_FPR0 + 1), 0); - else - return ptrace (PTRACE_PEEKUSER, proc->pid, - sizeof (long) * PT_R3, 0); - } +/* The atomic skip code is mostly taken from GDB. */ - /* Check if we're entering a new function call to list parameters. If - so, initialize the register control variables to keep track of where - the parameters were stored. */ - if (type == LT_TOF_FUNCTION && arg_num == 0) { - /* Initialize the set of registrers for parameter passing. */ - greg = 3; - freg = 1; - vreg = 2; +/* In plt.h. XXX make this official interface. */ +int read_target_4(struct Process *proc, arch_addr_t addr, uint32_t *lp); + +int +arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, + int (*add_cb)(void *addr, void *data), + void *add_cb_data) +{ + arch_addr_t ip = get_instruction_pointer(proc); + struct breakpoint *other = address2bpstruct(proc->leader, ip); + + debug(1, "arch_atomic_singlestep pid=%d addr=%p %s(%p)", + proc->pid, ip, breakpoint_name(sbp), sbp->addr); + + /* If the original instruction was lwarx/ldarx, we can't + * single-step over it, instead we have to execute the whole + * atomic block at once. */ + union { + uint32_t insn; + char buf[BREAKPOINT_LENGTH]; + } u; + if (other != NULL) { + memcpy(u.buf, sbp->orig_value, BREAKPOINT_LENGTH); + } else if (read_target_4(proc, ip, &u.insn) < 0) { + fprintf(stderr, "couldn't read instruction at IP %p\n", ip); + /* Do the normal singlestep. */ + return 1; } - if (info->type == ARGTYPE_FLOAT || info->type == ARGTYPE_DOUBLE) { - if (freg <= 13 || (proc->mask_32bit && freg <= 8)) { - data = ptrace (PTRACE_PEEKUSER, proc->pid, - sizeof (long) * (PT_FPR0 + freg), 0); - - if (info->type == ARGTYPE_FLOAT) { - /* float values passed in FP registers are automatically - promoted to double. We need to convert it back to float - before printing. */ - union { long val; float fval; double dval; } cvt; - cvt.val = data; - cvt.fval = (float) cvt.dval; - data = cvt.val; - } + if ((u.insn & LWARX_MASK) != LWARX_INSTRUCTION + && (u.insn & LWARX_MASK) != LDARX_INSTRUCTION) + return 1; + + debug(1, "singlestep over atomic block at %p", ip); + + int insn_count; + arch_addr_t addr = ip; + for (insn_count = 0; ; ++insn_count) { + addr += 4; + unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); + if (l == (unsigned long)-1 && errno) + return -1; + uint32_t insn; +#ifdef __powerpc64__ + insn = l >> 32; +#else + insn = l; +#endif - freg++; - greg++; + /* If a conditional branch is found, put a breakpoint + * in its destination address. */ + if ((insn & BRANCH_MASK) == BC_INSN) { + arch_addr_t branch_addr = ppc_branch_dest(addr, insn); + debug(1, "pid=%d, branch in atomic block from %p to %p", + proc->pid, addr, branch_addr); + if (add_cb(branch_addr, add_cb_data) < 0) + return -1; + } - return data; + /* Assume that the atomic sequence ends with a + * stwcx/stdcx instruction. */ + if ((insn & STWCX_MASK) == STWCX_INSTRUCTION + || (insn & STWCX_MASK) == STDCX_INSTRUCTION) { + debug(1, "pid=%d, found end of atomic block %p at %p", + proc->pid, ip, addr); + break; } - } - else if (greg <= 10) { - data = ptrace (PTRACE_PEEKUSER, proc->pid, - sizeof (long) * greg, 0); - greg++; - return data; + /* Arbitrary cut-off. If we didn't find the + * terminating instruction by now, just give up. */ + if (insn_count > 16) { + fprintf(stderr, "[%d] couldn't find end of atomic block" + " at %p\n", proc->pid, ip); + return -1; + } } - else - return ptrace (PTRACE_PEEKDATA, proc->pid, - proc->stack_pointer + sizeof (long) * - (arg_num - 8), 0); + /* Put the breakpoint to the next instruction. */ + addr += 4; + if (add_cb(addr, add_cb_data) < 0) + return -1; + + debug(1, "PTRACE_CONT"); + ptrace(PTRACE_CONT, proc->pid, 0, 0); return 0; } -void -save_register_args(enum tof type, Process *proc) { +size_t +arch_type_sizeof(struct Process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_CHAR: + return 1; + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 2; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + return 4; + + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return proc->e_machine == EM_PPC64 ? 8 : 4; + + case ARGTYPE_FLOAT: + return 4; + case ARGTYPE_DOUBLE: + return 8; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; + + default: + assert(info->type != info->type); + abort(); + break; + } } -/* Read a single long from the process's memory address 'addr'. */ -int -arch_umovelong (Process *proc, void *addr, long *result, arg_type_info *info) { - long pointed_to; - - errno = 0; - - pointed_to = ptrace (PTRACE_PEEKTEXT, proc->pid, addr, 0); - - if (pointed_to == -1 && errno) - return -errno; - - /* Since int's are 4-bytes (long is 8-bytes) in length for ppc64, we - need to shift the long values returned by ptrace to end up with - the correct value. */ - - if (info) { - if (info->type == ARGTYPE_INT || (proc->mask_32bit && (info->type == ARGTYPE_POINTER - || info->type == ARGTYPE_STRING))) { - pointed_to = pointed_to >> 32; - - /* Make sure we have nothing in the upper word so we can - do a explicit cast from long to int later in the code. */ - pointed_to &= 0x00000000ffffffff; - } +size_t +arch_type_alignof(struct Process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + default: + assert(info->type != info->type); + abort(); + break; + + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + /* On both PPC and PPC64, fundamental types have the + * same alignment as size. */ + return arch_type_sizeof(proc, info); + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; } - - *result = pointed_to; - return 0; } diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c index 4251c1d..5adfb16 100644 --- a/sysdeps/linux-gnu/proc.c +++ b/sysdeps/linux-gnu/proc.c @@ -1,11 +1,53 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Zachary T Welch, CodeSourcery + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1998,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#define _GNU_SOURCE /* For getline. */ #include "config.h" +#include <sys/stat.h> +#include <sys/syscall.h> #include <sys/types.h> +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <link.h> +#include <signal.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include <signal.h> #include <unistd.h> +#include "backend.h" +#include "breakpoint.h" +#include "config.h" +#include "debug.h" +#include "events.h" +#include "library.h" +#include "ltrace-elf.h" +#include "proc.h" + /* /proc/pid doesn't exist just after the fork, and sometimes `ltrace' * couldn't open it to find the executable. So it may be necessary to * have a bit delay @@ -13,17 +55,19 @@ #define MAX_DELAY 100000 /* 100000 microseconds = 0.1 seconds */ +#define PROC_PID_FILE(VAR, FORMAT, PID) \ + char VAR[strlen(FORMAT) + 6]; \ + sprintf(VAR, FORMAT, PID) + /* * Returns a (malloc'd) file name corresponding to a running pid */ char * pid2name(pid_t pid) { - char proc_exe[1024]; - if (!kill(pid, 0)) { int delay = 0; - sprintf(proc_exe, "/proc/%d/exe", pid); + PROC_PID_FILE(proc_exe, "/proc/%d/exe", pid); while (delay < MAX_DELAY) { if (!access(proc_exe, F_OK)) { @@ -34,3 +78,655 @@ pid2name(pid_t pid) { } return NULL; } + +static FILE * +open_status_file(pid_t pid) +{ + PROC_PID_FILE(fn, "/proc/%d/status", pid); + /* Don't complain if we fail. This would typically happen + when the process is about to terminate, and these files are + not available anymore. This function is called from the + event loop, and we don't want to clutter the output just + because the process terminates. */ + return fopen(fn, "r"); +} + +static char * +find_line_starting(FILE * file, const char * prefix, size_t len) +{ + char * line = NULL; + size_t line_len = 0; + while (!feof(file)) { + if (getline(&line, &line_len, file) < 0) + return NULL; + if (strncmp(line, prefix, len) == 0) + return line; + } + return NULL; +} + +static void +each_line_starting(FILE *file, const char *prefix, + enum callback_status (*cb)(const char *line, + const char *prefix, + void *data), + void *data) +{ + size_t len = strlen(prefix); + char * line; + while ((line = find_line_starting(file, prefix, len)) != NULL) { + enum callback_status st = (*cb)(line, prefix, data); + free(line); + if (st == CBS_STOP) + return; + } +} + +static enum callback_status +process_leader_cb(const char *line, const char *prefix, void *data) +{ + pid_t * pidp = data; + *pidp = atoi(line + strlen(prefix)); + return CBS_STOP; +} + +pid_t +process_leader(pid_t pid) +{ + pid_t tgid = 0; + FILE * file = open_status_file(pid); + if (file != NULL) { + each_line_starting(file, "Tgid:\t", &process_leader_cb, &tgid); + fclose(file); + } + + return tgid; +} + +static enum callback_status +process_stopped_cb(const char *line, const char *prefix, void *data) +{ + char c = line[strlen(prefix)]; + // t:tracing stop, T:job control stop + *(int *)data = (c == 't' || c == 'T'); + return CBS_STOP; +} + +int +process_stopped(pid_t pid) +{ + int is_stopped = -1; + FILE * file = open_status_file(pid); + if (file != NULL) { + each_line_starting(file, "State:\t", &process_stopped_cb, + &is_stopped); + fclose(file); + } + return is_stopped; +} + +static enum callback_status +process_status_cb(const char *line, const char *prefix, void *data) +{ + const char * status = line + strlen(prefix); + const char c = *status; + +#define RETURN(C) do { \ + *(enum process_status *)data = C; \ + return CBS_STOP; \ + } while (0) + + switch (c) { + case 'Z': RETURN(ps_zombie); + case 't': RETURN(ps_tracing_stop); + case 'T': + /* This can be either "T (stopped)" or, for older + * kernels, "T (tracing stop)". */ + if (!strcmp(status, "T (stopped)\n")) + RETURN(ps_stop); + else if (!strcmp(status, "T (tracing stop)\n")) + RETURN(ps_tracing_stop); + else { + fprintf(stderr, "Unknown process status: %s", + status); + RETURN(ps_stop); /* Some sort of stop + * anyway. */ + } + case 'D': + case 'S': RETURN(ps_sleeping); + } + + RETURN(ps_other); +#undef RETURN +} + +enum process_status +process_status(pid_t pid) +{ + enum process_status ret = ps_invalid; + FILE * file = open_status_file(pid); + if (file != NULL) { + each_line_starting(file, "State:\t", &process_status_cb, &ret); + fclose(file); + if (ret == ps_invalid) + fprintf(stderr, "process_status %d: %s", pid, + strerror(errno)); + } else + /* If the file is not present, the process presumably + * exited already. */ + ret = ps_zombie; + + return ret; +} + +static int +all_digits(const char *str) +{ + while (isdigit(*str)) + str++; + return !*str; +} + +int +process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n) +{ + PROC_PID_FILE(fn, "/proc/%d/task", pid); + DIR * d = opendir(fn); + if (d == NULL) + return -1; + + pid_t *tasks = NULL; + size_t n = 0; + size_t alloc = 0; + + while (1) { + struct dirent entry; + struct dirent *result; + if (readdir_r(d, &entry, &result) != 0) { + free(tasks); + return -1; + } + if (result == NULL) + break; + if (result->d_type == DT_DIR && all_digits(result->d_name)) { + pid_t npid = atoi(result->d_name); + if (n >= alloc) { + alloc = alloc > 0 ? (2 * alloc) : 8; + pid_t *ntasks = realloc(tasks, + sizeof(*tasks) * alloc); + if (ntasks == NULL) { + free(tasks); + return -1; + } + tasks = ntasks; + } + if (n >= alloc) + abort(); + tasks[n++] = npid; + } + } + + closedir(d); + + *ret_tasks = tasks; + *ret_n = n; + return 0; +} + +/* On native 64-bit system, we need to be careful when handling cross + * tracing. This select appropriate pointer depending on host and + * target architectures. XXX Really we should abstract this into the + * ABI object, as theorized about somewhere on pmachata/revamp + * branch. */ +static void * +select_32_64(struct Process *proc, void *p32, void *p64) +{ + if (sizeof(long) == 4 || proc->mask_32bit) + return p32; + else + return p64; +} + +static int +fetch_dyn64(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret) +{ + if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret)) + return -1; + *addr += sizeof(*ret); + return 0; +} + +static int +fetch_dyn32(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret) +{ + Elf32_Dyn dyn; + if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn)) + return -1; + + *addr += sizeof(dyn); + ret->d_tag = dyn.d_tag; + ret->d_un.d_val = dyn.d_un.d_val; + + return 0; +} + +static int (* +dyn_fetcher(struct Process *proc))(struct Process *, + arch_addr_t *, Elf64_Dyn *) +{ + return select_32_64(proc, fetch_dyn32, fetch_dyn64); +} + +int +proc_find_dynamic_entry_addr(struct Process *proc, arch_addr_t src_addr, + int d_tag, arch_addr_t *ret) +{ + debug(DEBUG_FUNCTION, "find_dynamic_entry()"); + + if (ret == NULL || src_addr == 0 || d_tag < 0) + return -1; + + int i = 0; + while (1) { + Elf64_Dyn entry; + if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0 + || entry.d_tag == DT_NULL + || i++ > 100) { /* Arbitrary cut-off so that we + * don't loop forever if the + * binary is corrupted. */ + debug(2, "Couldn't find address for dtag!"); + return -1; + } + + if (entry.d_tag == d_tag) { + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + *ret = (arch_addr_t)(uintptr_t)entry.d_un.d_val; + debug(2, "found address: %p in dtag %d", *ret, d_tag); + return 0; + } + } +} + +/* Our own type for representing 32-bit linkmap. We can't rely on the + * definition in link.h, because that's only accurate for our host + * architecture, not for target architecture (where the traced process + * runs). */ +#define LT_LINK_MAP(BITS) \ + { \ + Elf##BITS##_Addr l_addr; \ + Elf##BITS##_Addr l_name; \ + Elf##BITS##_Addr l_ld; \ + Elf##BITS##_Addr l_next; \ + Elf##BITS##_Addr l_prev; \ + } +struct lt_link_map_32 LT_LINK_MAP(32); +struct lt_link_map_64 LT_LINK_MAP(64); + +static int +fetch_lm64(struct Process *proc, arch_addr_t addr, + struct lt_link_map_64 *ret) +{ + if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret)) + return -1; + return 0; +} + +static int +fetch_lm32(struct Process *proc, arch_addr_t addr, + struct lt_link_map_64 *ret) +{ + struct lt_link_map_32 lm; + if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm)) + return -1; + + ret->l_addr = lm.l_addr; + ret->l_name = lm.l_name; + ret->l_ld = lm.l_ld; + ret->l_next = lm.l_next; + ret->l_prev = lm.l_prev; + + return 0; +} + +static int (* +lm_fetcher(struct Process *proc))(struct Process *, + arch_addr_t, struct lt_link_map_64 *) +{ + return select_32_64(proc, fetch_lm32, fetch_lm64); +} + +/* The same as above holds for struct r_debug. */ +#define LT_R_DEBUG(BITS) \ + { \ + int r_version; \ + Elf##BITS##_Addr r_map; \ + Elf##BITS##_Addr r_brk; \ + int r_state; \ + Elf##BITS##_Addr r_ldbase; \ + } + +struct lt_r_debug_32 LT_R_DEBUG(32); +struct lt_r_debug_64 LT_R_DEBUG(64); + +static int +fetch_rd64(struct Process *proc, arch_addr_t addr, + struct lt_r_debug_64 *ret) +{ + if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret)) + return -1; + return 0; +} + +static int +fetch_rd32(struct Process *proc, arch_addr_t addr, + struct lt_r_debug_64 *ret) +{ + struct lt_r_debug_32 rd; + if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd)) + return -1; + + ret->r_version = rd.r_version; + ret->r_map = rd.r_map; + ret->r_brk = rd.r_brk; + ret->r_state = rd.r_state; + ret->r_ldbase = rd.r_ldbase; + + return 0; +} + +static int (* +rdebug_fetcher(struct Process *proc))(struct Process *, + arch_addr_t, struct lt_r_debug_64 *) +{ + return select_32_64(proc, fetch_rd32, fetch_rd64); +} + +static int +fetch_auxv64_entry(int fd, Elf64_auxv_t *ret) +{ + /* Reaching EOF is as much problem as not reading whole + * entry. */ + return read(fd, ret, sizeof(*ret)) == sizeof(*ret) ? 0 : -1; +} + +static int +fetch_auxv32_entry(int fd, Elf64_auxv_t *ret) +{ + Elf32_auxv_t auxv; + if (read(fd, &auxv, sizeof(auxv)) != sizeof(auxv)) + return -1; + + ret->a_type = auxv.a_type; + ret->a_un.a_val = auxv.a_un.a_val; + return 0; +} + +static int (* +auxv_fetcher(struct Process *proc))(int, Elf64_auxv_t *) +{ + return select_32_64(proc, fetch_auxv32_entry, fetch_auxv64_entry); +} + +static void +crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) +{ + debug (DEBUG_FUNCTION, "crawl_linkmap()"); + + if (!dbg || !dbg->r_map) { + debug(2, "Debug structure or it's linkmap are NULL!"); + return; + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t addr = (arch_addr_t)(uintptr_t)dbg->r_map; + + while (addr != 0) { + struct lt_link_map_64 rlm; + if (lm_fetcher(proc)(proc, addr, &rlm) < 0) { + debug(2, "Unable to read link map"); + return; + } + + arch_addr_t key = addr; + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + addr = (arch_addr_t)(uintptr_t)rlm.l_next; + if (rlm.l_name == 0) { + debug(2, "Name of mapped library is NULL"); + return; + } + + char lib_name[BUFSIZ]; + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + umovebytes(proc, (arch_addr_t)(uintptr_t)rlm.l_name, + lib_name, sizeof(lib_name)); + + /* Library name can be an empty string, in which case + * the entry represents either the main binary, or a + * VDSO. Unfortunately we can't rely on that, as in + * recent glibc, that entry is initialized to VDSO + * SONAME. + * + * It's not clear how to detect VDSO in this case. We + * can't assume that l_name of real DSOs will be + * either absolute or relative (for LD_LIBRARY_PATH=: + * it will be neither). We can't compare l_addr with + * AT_SYSINFO_EHDR either, as l_addr is bias (which + * also means it's not unique, and therefore useless + * for this). We could load VDSO from process image + * and at least compare actual SONAMEs. For now, this + * kludge is about the best that we can do. */ + if (*lib_name == 0 + || strcmp(lib_name, "linux-vdso.so.1") == 0 + || strcmp(lib_name, "linux-gate.so.1") == 0 + || strcmp(lib_name, "linux-vdso32.so.1") == 0 + || strcmp(lib_name, "linux-vdso64.so.1") == 0) + continue; + + /* Do we have that library already? */ + if (proc_each_library(proc, NULL, library_with_key_cb, &key)) + continue; + + struct library *lib = malloc(sizeof(*lib)); + if (lib == NULL) { + fail: + if (lib != NULL) + library_destroy(lib); + fprintf(stderr, "Couldn't load ELF object %s: %s\n", + lib_name, strerror(errno)); + continue; + } + library_init(lib, LT_LIBTYPE_DSO); + + if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0) + goto fail; + + lib->key = key; + proc_add_library(proc, lib); + } + return; +} + +static int +load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret) +{ + debug(DEBUG_FUNCTION, "load_debug_struct"); + + if (rdebug_fetcher(proc)(proc, proc->os.debug_addr, ret) < 0) { + debug(2, "This process does not have a debug structure!"); + return -1; + } + + return 0; +} + +static void +rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc) +{ + debug(DEBUG_FUNCTION, "arch_check_dbg"); + + struct lt_r_debug_64 rdbg; + if (load_debug_struct(proc, &rdbg) < 0) { + debug(2, "Unable to load debug structure!"); + return; + } + + if (rdbg.r_state == RT_CONSISTENT) { + debug(2, "Linkmap is now consistent"); + switch (proc->os.debug_state) { + case RT_ADD: + debug(2, "Adding DSO to linkmap"); + crawl_linkmap(proc, &rdbg); + break; + case RT_DELETE: + debug(2, "Removing DSO from linkmap"); + // XXX unload that library + break; + default: + debug(2, "Unexpected debug state!"); + } + } + + proc->os.debug_state = rdbg.r_state; +} + +#ifndef ARCH_HAVE_FIND_DL_DEBUG +int +arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr, + arch_addr_t *ret) +{ + return proc_find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, ret); +} +#endif + +int +linkmap_init(struct Process *proc, arch_addr_t dyn_addr) +{ + debug(DEBUG_FUNCTION, "linkmap_init(%d, dyn_addr=%p)", proc->pid, dyn_addr); + + if (arch_find_dl_debug(proc, dyn_addr, &proc->os.debug_addr) == -1) { + debug(2, "Couldn't find debug structure!"); + return -1; + } + + int status; + struct lt_r_debug_64 rdbg; + if ((status = load_debug_struct(proc, &rdbg)) < 0) { + debug(2, "No debug structure or no memory to allocate one!"); + return status; + } + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t addr = (arch_addr_t)(uintptr_t)rdbg.r_brk; + if (arch_translate_address_dyn(proc, addr, &addr) < 0) + return -1; + + struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL); + static struct bp_callbacks rdebug_callbacks = { + .on_hit = rdebug_bp_on_hit, + }; + rdebug_bp->cbs = &rdebug_callbacks; + + crawl_linkmap(proc, &rdbg); + + return 0; +} + +int +task_kill (pid_t pid, int sig) +{ + // Taken from GDB + int ret; + + errno = 0; + ret = syscall (__NR_tkill, pid, sig); + return ret; +} + +void +process_removed(struct Process *proc) +{ + delete_events_for(proc); +} + +int +process_get_entry(struct Process *proc, + arch_addr_t *entryp, + arch_addr_t *interp_biasp) +{ + PROC_PID_FILE(fn, "/proc/%d/auxv", proc->pid); + int fd = open(fn, O_RDONLY); + int ret = 0; + if (fd == -1) { + fail: + fprintf(stderr, "couldn't read %s: %s", fn, strerror(errno)); + ret = -1; + done: + if (fd != -1) + close(fd); + return ret; + } + + arch_addr_t at_entry = 0; + arch_addr_t at_bias = 0; + while (1) { + Elf64_auxv_t entry = {}; + if (auxv_fetcher(proc)(fd, &entry) < 0) + goto fail; + + switch (entry.a_type) { + case AT_BASE: + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + at_bias = (arch_addr_t)(uintptr_t)entry.a_un.a_val; + continue; + + case AT_ENTRY: + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + at_entry = (arch_addr_t)(uintptr_t)entry.a_un.a_val; + default: + continue; + + case AT_NULL: + break; + } + break; + } + + if (entryp != NULL) + *entryp = at_entry; + if (interp_biasp != NULL) + *interp_biasp = at_bias; + goto done; +} + +int +os_process_init(struct Process *proc) +{ + proc->os.debug_addr = 0; + proc->os.debug_state = 0; + return 0; +} + +void +os_process_destroy(struct Process *proc) +{ +} + +int +os_process_clone(struct Process *retp, struct Process *proc) +{ + retp->os = proc->os; + return 0; +} + +int +os_process_exec(struct Process *proc) +{ + return 0; +} diff --git a/sysdeps/linux-gnu/s390/Makefile b/sysdeps/linux-gnu/s390/Makefile deleted file mode 100644 index cea1b45..0000000 --- a/sysdeps/linux-gnu/s390/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# S/390 version -# Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation -# -OBJ = trace.o regs.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o diff --git a/sysdeps/linux-gnu/s390/Makefile.am b/sysdeps/linux-gnu/s390/Makefile.am new file mode 100644 index 0000000..22741bd --- /dev/null +++ b/sysdeps/linux-gnu/s390/Makefile.am @@ -0,0 +1,39 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent1.h \ + signalent.h \ + syscallent1.h \ + syscallent.h \ + syscalls31.h \ + syscalls64.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/s390/Makefile.in b/sysdeps/linux-gnu/s390/Makefile.in new file mode 100644 index 0000000..0f55ef5 --- /dev/null +++ b/sysdeps/linux-gnu/s390/Makefile.in @@ -0,0 +1,534 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/s390 +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent1.h \ + signalent.h \ + syscallent1.h \ + syscallent.h \ + syscalls31.h \ + syscalls64.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/s390/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/s390/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/s390/arch.h b/sysdeps/linux-gnu/s390/arch.h index 03690b8..0d412dc 100644 --- a/sysdeps/linux-gnu/s390/arch.h +++ b/sysdeps/linux-gnu/s390/arch.h @@ -1,18 +1,35 @@ /* -** S/390 version -** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation -*/ + * This file is part of ltrace. + * Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #define BREAKPOINT_VALUE { 0x00, 0x01 } #define BREAKPOINT_LENGTH 2 #define DECR_PC_AFTER_BREAK 2 +#define ARCH_ENDIAN_BIG +#define ARCH_HAVE_FETCH_ARG +#define ARCH_HAVE_SIZEOF +#define ARCH_HAVE_ALIGNOF -#ifdef __s390x__ -#define LT_ELFCLASS ELFCLASS64 -#define LT_ELF_MACHINE EM_S390 -#define LT_ELFCLASS2 ELFCLASS32 -#define LT_ELF_MACHINE2 EM_S390 -#else #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_S390 + +#ifdef __s390x__ +#define LT_ELFCLASS2 ELFCLASS64 +#define LT_ELF_MACHINE2 EM_S390 #endif diff --git a/sysdeps/linux-gnu/s390/fetch.c b/sysdeps/linux-gnu/s390/fetch.c new file mode 100644 index 0000000..fa8f42d --- /dev/null +++ b/sysdeps/linux-gnu/s390/fetch.c @@ -0,0 +1,289 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <asm/ptrace.h> +#include <sys/ptrace.h> +#include <sys/ucontext.h> +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "backend.h" +#include "fetch.h" +#include "type.h" +#include "proc.h" +#include "value.h" + +struct fetch_context { + struct user_regs_struct regs; + arch_addr_t stack_pointer; + int greg; + int freg; +}; + +static int +s390x(struct fetch_context *ctx) +{ + /* +--------+--------+--------+ + * | PSW.31 | PSW.32 | mode | + * +--------+--------+--------+ + * | 0 | 0 | 24-bit | Not supported in Linux + * | 0 | 1 | 31-bit | s390 compatible mode + * | 1 | 1 | 64-bit | z/Architecture, "s390x" + * +--------+--------+--------+ + * (Note: The leftmost bit is PSW.0, rightmost PSW.63.) + */ + +#ifdef __s390x__ + if ((ctx->regs.psw.mask & 0x180000000UL) == 0x180000000UL) + return 1; +#endif + return 0; +} + +static int +fetch_register_banks(struct Process *proc, struct fetch_context *ctx) +{ + ptrace_area parea; + parea.len = sizeof(ctx->regs); + parea.process_addr = (uintptr_t)&ctx->regs; + parea.kernel_addr = 0; + if (ptrace(PTRACE_PEEKUSR_AREA, proc->pid, &parea, NULL) < 0) { + fprintf(stderr, "fetch_register_banks GPR: %s\n", + strerror(errno)); + return -1; + } + return 0; +} + +static int +fetch_context_init(struct Process *proc, struct fetch_context *context) +{ + context->greg = 2; + context->freg = 0; + return fetch_register_banks(proc, context); +} + +struct fetch_context * +arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + struct fetch_context *context = malloc(sizeof(*context)); + if (context == NULL + || fetch_context_init(proc, context) < 0) { + fprintf(stderr, "arch_fetch_arg_init: %s\n", + strerror(errno)); + free(context); + return NULL; + } + + context->stack_pointer = get_stack_pointer(proc) + + (s390x(context) ? 160 : 96); + if (ret_info->type == ARGTYPE_STRUCT) + ++context->greg; + + return context; +} + +struct fetch_context * +arch_fetch_arg_clone(struct Process *proc, + struct fetch_context *context) +{ + struct fetch_context *clone = malloc(sizeof(*context)); + if (clone == NULL) + return NULL; + *clone = *context; + return clone; +} + +static int +allocate_stack_slot(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep, + size_t sz) +{ + /* Note: here we shouldn't see large composite types, those + * are passed by reference, which is handled below. Here we + * only deal with integers, floats, small structs, etc. */ + + size_t a; + if (s390x(ctx)) { + assert(sz <= 8); + a = 8; + } else { + /* Note: double is 8 bytes. */ + assert(sz <= 8); + a = 4; + } + + size_t off = sz < a ? a - sz : 0; + value_in_inferior(valuep, ctx->stack_pointer + off); + + ctx->stack_pointer += sz > a ? sz : a; + return 0; +} + +static void +copy_gpr(struct fetch_context *ctx, struct value *valuep, int regno) +{ + value_set_word(valuep, ctx->regs.gprs[regno]); +} + +static int +allocate_gpr(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep, + size_t sz) +{ + if (ctx->greg > 6) + return allocate_stack_slot(ctx, proc, info, valuep, sz); + + copy_gpr(ctx, valuep, ctx->greg++); + return 0; +} + +static int +allocate_gpr_pair(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep, + size_t sz) +{ + assert(!s390x(ctx)); + assert(sz <= 8); + + if (ctx->greg > 5) { + ctx->greg = 7; + return allocate_stack_slot(ctx, proc, info, valuep, sz); + } + + if (value_reserve(valuep, sz) == NULL) + return -1; + + unsigned char *ptr = value_get_raw_data(valuep); + union { + struct { + uint32_t a; + uint32_t b; + }; + unsigned char buf[8]; + } u; + u.a = ctx->regs.gprs[ctx->greg++]; + u.b = ctx->regs.gprs[ctx->greg++]; + memcpy(ptr, u.buf, sz); + + return 0; +} + +static int +allocate_fpr(struct fetch_context *ctx, struct Process *proc, + struct arg_type_info *info, struct value *valuep, + size_t sz) +{ + int pool = s390x(ctx) ? 6 : 2; + + if (ctx->freg > pool) + return allocate_stack_slot(ctx, proc, info, valuep, sz); + + if (value_reserve(valuep, sz) == NULL) + return -1; + + memcpy(value_get_raw_data(valuep), + &ctx->regs.fp_regs.fprs[ctx->freg], sz); + ctx->freg += 2; + + return 0; +} + +int +arch_fetch_arg_next(struct fetch_context *ctx, enum tof type, + struct Process *proc, + struct arg_type_info *info, struct value *valuep) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + + switch (info->type) { + case ARGTYPE_VOID: + value_set_word(valuep, 0); + return 0; + + case ARGTYPE_STRUCT: + if (type_get_fp_equivalent(info) != NULL) + /* fall through */ + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + return allocate_fpr(ctx, proc, info, valuep, sz); + + /* Structures<4 bytes on s390 and structures<8 bytes + * on s390x are passed in register. On s390, long + * long and structures<8 bytes are passed in two + * consecutive registers (if two are available). */ + + if (sz <= (s390x(ctx) ? 8 : 4)) + return allocate_gpr(ctx, proc, info, valuep, sz); + else if (sz <= 8) + return allocate_gpr_pair(ctx, proc, info, valuep, sz); + + /* fall through */ + + case ARGTYPE_ARRAY: + if (value_pass_by_reference(valuep) < 0) + return -1; + /* fall through */ + + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_POINTER: + return allocate_gpr(ctx, proc, info, valuep, sz); + + default: + assert(info->type != info->type); + abort(); + } + return -1; +} + +int +arch_fetch_retval(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (info->type == ARGTYPE_STRUCT) { + if (value_pass_by_reference(valuep) < 0) + return -1; + copy_gpr(ctx, valuep, 2); + return 0; + } + + if (fetch_context_init(proc, ctx) < 0) + return -1; + return arch_fetch_arg_next(ctx, type, proc, info, valuep); +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + free(context); +} diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c index 85a1dd1..5f612e5 100644 --- a/sysdeps/linux-gnu/s390/plt.c +++ b/sysdeps/linux-gnu/s390/plt.c @@ -1,5 +1,27 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <gelf.h> +#include "proc.h" #include "common.h" +#include "library.h" GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { diff --git a/sysdeps/linux-gnu/s390/ptrace.h b/sysdeps/linux-gnu/s390/ptrace.h index c3cbcb6..ad7e0d6 100644 --- a/sysdeps/linux-gnu/s390/ptrace.h +++ b/sysdeps/linux-gnu/s390/ptrace.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c index 169893e..0592ccd 100644 --- a/sysdeps/linux-gnu/s390/regs.c +++ b/sysdeps/linux-gnu/s390/regs.c @@ -1,7 +1,25 @@ /* -** S/390 version -** Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation -*/ + * This file is part of ltrace. + * Copyright (C) 2002,2004,2008,2009 Juan Cespedes + * Copyright (C) 2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #include "config.h" @@ -9,6 +27,7 @@ #include <sys/ptrace.h> #include <asm/ptrace.h> +#include "proc.h" #include "common.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) diff --git a/sysdeps/linux-gnu/s390/signalent.h b/sysdeps/linux-gnu/s390/signalent.h index 35b74f1..218b057 100644 --- a/sysdeps/linux-gnu/s390/signalent.h +++ b/sysdeps/linux-gnu/s390/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/s390/signalent1.h b/sysdeps/linux-gnu/s390/signalent1.h index b5b6ca8..0f529bb 100644 --- a/sysdeps/linux-gnu/s390/signalent1.h +++ b/sysdeps/linux-gnu/s390/signalent1.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "s390/signalent.h" diff --git a/sysdeps/linux-gnu/s390/syscallent.h b/sysdeps/linux-gnu/s390/syscallent.h index 5a35d93..03d0541 100644 --- a/sysdeps/linux-gnu/s390/syscallent.h +++ b/sysdeps/linux-gnu/s390/syscallent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #ifdef __s390x__ #include "s390/syscalls64.h" #else diff --git a/sysdeps/linux-gnu/s390/syscallent1.h b/sysdeps/linux-gnu/s390/syscallent1.h index c9fdc81..8d80a54 100644 --- a/sysdeps/linux-gnu/s390/syscallent1.h +++ b/sysdeps/linux-gnu/s390/syscallent1.h @@ -1 +1,21 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "s390/syscalls31.h" diff --git a/sysdeps/linux-gnu/s390/syscalls31.h b/sysdeps/linux-gnu/s390/syscalls31.h index 42631eb..46f4cf3 100644 --- a/sysdeps/linux-gnu/s390/syscalls31.h +++ b/sysdeps/linux-gnu/s390/syscalls31.h @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Heiko Carstens, IBM Corporation + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "0", /* 0 */ "exit", /* 1 */ "fork", /* 2 */ diff --git a/sysdeps/linux-gnu/s390/syscalls64.h b/sysdeps/linux-gnu/s390/syscalls64.h index 97be52c..f2ec7f4 100644 --- a/sysdeps/linux-gnu/s390/syscalls64.h +++ b/sysdeps/linux-gnu/s390/syscalls64.h @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Heiko Carstens, IBM Corporation + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "0", /* 0 */ "exit", /* 1 */ "fork", /* 2 */ diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c index 9df2437..b9e05ff 100644 --- a/sysdeps/linux-gnu/s390/trace.c +++ b/sysdeps/linux-gnu/s390/trace.c @@ -1,23 +1,38 @@ /* -** S390 specific part of trace.c -** -** Other routines are in ../trace.c and need to be combined -** at link time with this code. -** -** Copyright (C) 2001,2005 IBM Corp. -*/ + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2001,2005 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #include "config.h" -#include <errno.h> -#include <stdlib.h> +#include <asm/ptrace.h> +#include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> +#include <assert.h> +#include <errno.h> #include <signal.h> -#include <sys/ptrace.h> -#include <asm/ptrace.h> +#include <stdlib.h> #include "common.h" +#include "proc.h" +#include "type.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR @@ -159,40 +174,84 @@ syscall_p(Process *proc, int status, int *sysnum) { return 0; } -long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { - long ret; +size_t +arch_type_sizeof(struct Process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_CHAR: + return 1; + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 2; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + return 4; + + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return proc->e_class == ELFCLASS64 ? 8 : 4; + + case ARGTYPE_FLOAT: + return 4; + case ARGTYPE_DOUBLE: + return 8; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; - switch (arg_num) { - case -1: /* return value */ - ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0); - break; - case 0: - ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0); - break; - case 1: - ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0); - break; - case 2: - ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0); - break; - case 3: - ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0); - break; - case 4: - ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0); - break; default: - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(2); + assert(info->type != info->type); + abort(); } -#ifdef __s390x__ - if (proc->mask_32bit) - ret &= 0xffffffff; -#endif - return ret; } -void -save_register_args(enum tof type, Process *proc) { +size_t +arch_type_alignof(struct Process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + default: + assert(info->type != info->type); + break; + + case ARGTYPE_CHAR: + return 1; + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 2; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + return 4; + + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return proc->e_class == ELFCLASS64 ? 8 : 4; + + case ARGTYPE_FLOAT: + return 4; + case ARGTYPE_DOUBLE: + return 8; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; + } + abort(); } diff --git a/sysdeps/linux-gnu/signalent1.h b/sysdeps/linux-gnu/signalent1.h new file mode 100644 index 0000000..74d8e19 --- /dev/null +++ b/sysdeps/linux-gnu/signalent1.h @@ -0,0 +1 @@ +/* This file is intentionally left blank */ diff --git a/sysdeps/linux-gnu/sparc/Makefile b/sysdeps/linux-gnu/sparc/Makefile deleted file mode 100644 index b3914e5..0000000 --- a/sysdeps/linux-gnu/sparc/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -OBJ = regs.o trace.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o diff --git a/sysdeps/linux-gnu/sparc/Makefile.am b/sysdeps/linux-gnu/sparc/Makefile.am new file mode 100644 index 0000000..5c6ecc2 --- /dev/null +++ b/sysdeps/linux-gnu/sparc/Makefile.am @@ -0,0 +1,34 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/sparc/Makefile.in b/sysdeps/linux-gnu/sparc/Makefile.in new file mode 100644 index 0000000..d94a1d8 --- /dev/null +++ b/sysdeps/linux-gnu/sparc/Makefile.in @@ -0,0 +1,528 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/sparc +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + syscallent.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/sparc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/sparc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/sparc/arch.h b/sysdeps/linux-gnu/sparc/arch.h index 75251b8..9685d13 100644 --- a/sysdeps/linux-gnu/sparc/arch.h +++ b/sysdeps/linux-gnu/sparc/arch.h @@ -1,6 +1,27 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #define BREAKPOINT_VALUE {0x91, 0xd0, 0x20, 0x01} #define BREAKPOINT_LENGTH 4 #define DECR_PC_AFTER_BREAK 0 +#define ARCH_ENDIAN_BIG #define LT_ELFCLASS ELFCLASS32 #define LT_ELF_MACHINE EM_SPARC diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c index f9e6d80..40bbabc 100644 --- a/sysdeps/linux-gnu/sparc/plt.c +++ b/sysdeps/linux-gnu/sparc/plt.c @@ -1,4 +1,25 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include <gelf.h> +#include "proc.h" #include "common.h" GElf_Addr diff --git a/sysdeps/linux-gnu/sparc/ptrace.h b/sysdeps/linux-gnu/sparc/ptrace.h index bbaf01a..cbc35a6 100644 --- a/sysdeps/linux-gnu/sparc/ptrace.h +++ b/sysdeps/linux-gnu/sparc/ptrace.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #undef PTRACE_GETREGS #undef PTRACE_SETREGS #undef PTRACE_GETFPREGS diff --git a/sysdeps/linux-gnu/sparc/regs.c b/sysdeps/linux-gnu/sparc/regs.c index 49d2729..5e5ad20 100644 --- a/sysdeps/linux-gnu/sparc/regs.c +++ b/sysdeps/linux-gnu/sparc/regs.c @@ -1,7 +1,29 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <sys/types.h> #include "ptrace.h" +#include "proc.h" #include "common.h" void * diff --git a/sysdeps/linux-gnu/sparc/signalent.h b/sysdeps/linux-gnu/sparc/signalent.h index d30f69e..8555456 100644 --- a/sysdeps/linux-gnu/sparc/signalent.h +++ b/sysdeps/linux-gnu/sparc/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/sparc/syscallent.h b/sysdeps/linux-gnu/sparc/syscallent.h index 96eeec9..bb309c6 100644 --- a/sysdeps/linux-gnu/sparc/syscallent.h +++ b/sysdeps/linux-gnu/sparc/syscallent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "0", /* 0 */ "exit", /* 1 */ "fork", /* 2 */ diff --git a/sysdeps/linux-gnu/sparc/trace.c b/sysdeps/linux-gnu/sparc/trace.c index 7f05b55..e1725ff 100644 --- a/sysdeps/linux-gnu/sparc/trace.c +++ b/sysdeps/linux-gnu/sparc/trace.c @@ -1,3 +1,24 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + #include "config.h" #include <stdlib.h> @@ -6,6 +27,7 @@ #include <signal.h> #include <string.h> #include "ptrace.h" +#include "proc.h" #include "common.h" void @@ -44,7 +66,8 @@ syscall_p(Process *proc, int status, int *sysnum) { } long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { +gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info) +{ proc_archdep *a = (proc_archdep *) proc->arch_ptr; if (!a->valid) { fprintf(stderr, "Could not get child registers\n"); @@ -68,14 +91,3 @@ gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { } return 0; } - -void -save_register_args(enum tof type, Process *proc) { - proc_archdep *a = (proc_archdep *) proc->arch_ptr; - if (a->valid) { - if (type == LT_TOF_FUNCTION) - memcpy(a->func_arg, &a->regs.u_regs[UREG_G7], sizeof(a->func_arg)); - else - memcpy(a->sysc_arg, &a->regs.u_regs[UREG_G7], sizeof(a->sysc_arg)); - } -} diff --git a/sysdeps/linux-gnu/syscallent1.h b/sysdeps/linux-gnu/syscallent1.h new file mode 100644 index 0000000..74d8e19 --- /dev/null +++ b/sysdeps/linux-gnu/syscallent1.h @@ -0,0 +1 @@ +/* This file is intentionally left blank */ diff --git a/sysdeps/linux-gnu/trace-defs.h b/sysdeps/linux-gnu/trace-defs.h new file mode 100644 index 0000000..aa69b83 --- /dev/null +++ b/sysdeps/linux-gnu/trace-defs.h @@ -0,0 +1,92 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef _TRACE_DEFS_H_ +#define _TRACE_DEFS_H_ +#include <sys/ptrace.h> + +/* If the system headers did not provide the constants, hard-code the + * normal values. */ +#ifndef PTRACE_OLDSETOPTIONS +# define PTRACE_OLDSETOPTIONS 21 +#endif + +#ifndef PTRACE_SETOPTIONS +# define PTRACE_SETOPTIONS 0x4200 +#endif + +#ifndef PTRACE_GETEVENTMSG +# define PTRACE_GETEVENTMSG 0x4201 +#endif + +/* Options set using PTRACE_SETOPTIONS. */ +#ifndef PTRACE_O_TRACESYSGOOD +# define PTRACE_O_TRACESYSGOOD 0x00000001 +#endif + +#ifndef PTRACE_O_TRACEFORK +# define PTRACE_O_TRACEFORK 0x00000002 +#endif + +#ifndef PTRACE_O_TRACEVFORK +# define PTRACE_O_TRACEVFORK 0x00000004 +#endif + +#ifndef PTRACE_O_TRACECLONE +# define PTRACE_O_TRACECLONE 0x00000008 +#endif + +#ifndef PTRACE_O_TRACEEXEC +# define PTRACE_O_TRACEEXEC 0x00000010 +#endif + +#ifndef PTRACE_O_TRACEVFORKDONE +# define PTRACE_O_TRACEVFORKDONE 0x00000020 +#endif + +#ifndef PTRACE_O_TRACEEXIT +# define PTRACE_O_TRACEEXIT 0x00000040 +#endif + +/* Wait extended result codes for the above trace options. */ +#ifndef PTRACE_EVENT_FORK +# define PTRACE_EVENT_FORK 1 +#endif + +#ifndef PTRACE_EVENT_VFORK +# define PTRACE_EVENT_VFORK 2 +#endif + +#ifndef PTRACE_EVENT_CLONE +# define PTRACE_EVENT_CLONE 3 +#endif + +#ifndef PTRACE_EVENT_EXEC +# define PTRACE_EVENT_EXEC 4 +#endif + +#ifndef PTRACE_EVENT_VFORK_DONE +# define PTRACE_EVENT_VFORK_DONE 5 +#endif + +#ifndef PTRACE_EVENT_EXIT +# define PTRACE_EVENT_EXIT 6 +#endif + +#endif /* _TRACE_DEFS_H_ */ diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c index df5b090..e13b761 100644 --- a/sysdeps/linux-gnu/trace.c +++ b/sysdeps/linux-gnu/trace.c @@ -1,104 +1,129 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2007,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2010 Joe Damato + * Copyright (C) 1998,2002,2003,2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "config.h" + +#include <asm/unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <assert.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <errno.h> #include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include "ptrace.h" -#include <asm/unistd.h> -#include "common.h" - -/* If the system headers did not provide the constants, hard-code the normal - values. */ -#ifndef PTRACE_EVENT_FORK - -#define PTRACE_OLDSETOPTIONS 21 -#define PTRACE_SETOPTIONS 0x4200 -#define PTRACE_GETEVENTMSG 0x4201 - -/* options set using PTRACE_SETOPTIONS */ -#define PTRACE_O_TRACESYSGOOD 0x00000001 -#define PTRACE_O_TRACEFORK 0x00000002 -#define PTRACE_O_TRACEVFORK 0x00000004 -#define PTRACE_O_TRACECLONE 0x00000008 -#define PTRACE_O_TRACEEXEC 0x00000010 -#define PTRACE_O_TRACEVFORKDONE 0x00000020 -#define PTRACE_O_TRACEEXIT 0x00000040 - -/* Wait extended result codes for the above trace options. */ -#define PTRACE_EVENT_FORK 1 -#define PTRACE_EVENT_VFORK 2 -#define PTRACE_EVENT_CLONE 3 -#define PTRACE_EVENT_EXEC 4 -#define PTRACE_EVENT_VFORK_DONE 5 -#define PTRACE_EVENT_EXIT 6 - -#endif /* PTRACE_EVENT_FORK */ - -#ifdef ARCH_HAVE_UMOVELONG -extern int arch_umovelong (Process *, void *, long *, arg_type_info *); -int -umovelong (Process *proc, void *addr, long *result, arg_type_info *info) { - return arch_umovelong (proc, addr, result, info); -} -#else -/* Read a single long from the process's memory address 'addr' */ -int -umovelong (Process *proc, void *addr, long *result, arg_type_info *info) { - long pointed_to; +#ifdef HAVE_LIBSELINUX +# include <selinux/selinux.h> +#endif - errno = 0; - pointed_to = ptrace (PTRACE_PEEKTEXT, proc->pid, addr, 0); - if (pointed_to == -1 && errno) - return -errno; +#include "linux-gnu/trace.h" +#include "linux-gnu/trace-defs.h" +#include "backend.h" +#include "breakpoint.h" +#include "debug.h" +#include "events.h" +#include "options.h" +#include "proc.h" +#include "ptrace.h" +#include "type.h" - *result = pointed_to; - return 0; +void +trace_fail_warning(pid_t pid) +{ + /* This was adapted from GDB. */ +#ifdef HAVE_LIBSELINUX + static int checked = 0; + if (checked) + return; + checked = 1; + + /* -1 is returned for errors, 0 if it has no effect, 1 if + * PTRACE_ATTACH is forbidden. */ + if (security_get_boolean_active("deny_ptrace") == 1) + fprintf(stderr, +"The SELinux boolean 'deny_ptrace' is enabled, which may prevent ltrace from\n" +"tracing other processes. You can disable this process attach protection by\n" +"issuing 'setsebool deny_ptrace=0' in the superuser context.\n"); +#endif /* HAVE_LIBSELINUX */ } -#endif void -trace_me(void) { - debug(DEBUG_PROCESS, "trace_me: pid=%d\n", getpid()); - if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) { +trace_me(void) +{ + debug(DEBUG_PROCESS, "trace_me: pid=%d", getpid()); + if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { perror("PTRACE_TRACEME"); + trace_fail_warning(getpid()); exit(1); } } +/* There's a (hopefully) brief period of time after the child process + * forks when we can't trace it yet. Here we wait for kernel to + * prepare the process. */ int -trace_pid(pid_t pid) { - debug(DEBUG_PROCESS, "trace_pid: pid=%d\n", pid); - if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) { - return -1; - } - +wait_for_proc(pid_t pid) +{ /* man ptrace: PTRACE_ATTACH attaches to the process specified in pid. The child is sent a SIGSTOP, but will not necessarily have stopped by the completion of this call; use wait() to wait for the child to stop. */ - if (waitpid (pid, NULL, 0) != pid) { + if (waitpid(pid, NULL, __WALL) != pid) { perror ("trace_pid: waitpid"); - exit (1); + return -1; } return 0; } +int +trace_pid(pid_t pid) +{ + debug(DEBUG_PROCESS, "trace_pid: pid=%d", pid); + /* This shouldn't emit error messages, as there are legitimate + * reasons that the PID can't be attached: like it may have + * already ended. */ + if (ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) + return -1; + + return wait_for_proc(pid); +} + void -trace_set_options(Process *proc, pid_t pid) { +trace_set_options(struct Process *proc) +{ if (proc->tracesysgood & 0x80) return; - debug(DEBUG_PROCESS, "trace_set_options: pid=%d\n", pid); + pid_t pid = proc->pid; + debug(DEBUG_PROCESS, "trace_set_options: pid=%d", pid); long options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXEC; - if (ptrace(PTRACE_SETOPTIONS, pid, 0, options) < 0 && - ptrace(PTRACE_OLDSETOPTIONS, pid, 0, options) < 0) { + if (ptrace(PTRACE_SETOPTIONS, pid, 0, (void *)options) < 0 && + ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)options) < 0) { perror("PTRACE_SETOPTIONS"); return; } @@ -107,87 +132,1077 @@ trace_set_options(Process *proc, pid_t pid) { void untrace_pid(pid_t pid) { - debug(DEBUG_PROCESS, "untrace_pid: pid=%d\n", pid); - ptrace(PTRACE_DETACH, pid, 1, 0); + debug(DEBUG_PROCESS, "untrace_pid: pid=%d", pid); + ptrace(PTRACE_DETACH, pid, 0, 0); } void -continue_after_signal(pid_t pid, int signum) { - Process *proc; +continue_after_signal(pid_t pid, int signum) +{ + debug(DEBUG_PROCESS, "continue_after_signal: pid=%d, signum=%d", + pid, signum); + ptrace(PTRACE_SYSCALL, pid, 0, (void *)(uintptr_t)signum); +} - debug(DEBUG_PROCESS, "continue_after_signal: pid=%d, signum=%d", pid, signum); +static enum ecb_status +event_for_pid(Event *event, void *data) +{ + if (event->proc != NULL && event->proc->pid == (pid_t)(uintptr_t)data) + return ecb_yield; + return ecb_cont; +} - proc = pid2proc(pid); - if (proc && proc->breakpoint_being_enabled) { -#if defined __sparc__ || defined __ia64___ - ptrace(PTRACE_SYSCALL, pid, 0, signum); -#else - ptrace(PTRACE_SINGLESTEP, pid, 0, signum); -#endif +static int +have_events_for(pid_t pid) +{ + return each_qd_event(event_for_pid, (void *)(uintptr_t)pid) != NULL; +} + +void +continue_process(pid_t pid) +{ + debug(DEBUG_PROCESS, "continue_process: pid=%d", pid); + + /* Only really continue the process if there are no events in + the queue for this process. Otherwise just wait for the + other events to arrive. */ + if (!have_events_for(pid)) + /* We always trace syscalls to control fork(), + * clone(), execve()... */ + ptrace(PTRACE_SYSCALL, pid, 0, 0); + else + debug(DEBUG_PROCESS, + "putting off the continue, events in que."); +} + +static struct pid_task * +get_task_info(struct pid_set *pids, pid_t pid) +{ + assert(pid != 0); + size_t i; + for (i = 0; i < pids->count; ++i) + if (pids->tasks[i].pid == pid) + return &pids->tasks[i]; + + return NULL; +} + +static struct pid_task * +add_task_info(struct pid_set *pids, pid_t pid) +{ + if (pids->count == pids->alloc) { + size_t ns = (2 * pids->alloc) ?: 4; + struct pid_task *n = realloc(pids->tasks, + sizeof(*pids->tasks) * ns); + if (n == NULL) + return NULL; + pids->tasks = n; + pids->alloc = ns; + } + struct pid_task * task_info = &pids->tasks[pids->count++]; + memset(task_info, 0, sizeof(*task_info)); + task_info->pid = pid; + return task_info; +} + +static enum callback_status +task_stopped(struct Process *task, void *data) +{ + enum process_status st = process_status(task->pid); + if (data != NULL) + *(enum process_status *)data = st; + + /* If the task is already stopped, don't worry about it. + * Likewise if it managed to become a zombie or terminate in + * the meantime. This can happen when the whole thread group + * is terminating. */ + switch (st) { + case ps_invalid: + case ps_tracing_stop: + case ps_zombie: + return CBS_CONT; + case ps_sleeping: + case ps_stop: + case ps_other: + return CBS_STOP; + } + + abort (); +} + +/* Task is blocked if it's stopped, or if it's a vfork parent. */ +static enum callback_status +task_blocked(struct Process *task, void *data) +{ + struct pid_set *pids = data; + struct pid_task *task_info = get_task_info(pids, task->pid); + if (task_info != NULL + && task_info->vforked) + return CBS_CONT; + + return task_stopped(task, NULL); +} + +static Event *process_vfork_on_event(struct event_handler *super, Event *event); + +static enum callback_status +task_vforked(struct Process *task, void *data) +{ + if (task->event_handler != NULL + && task->event_handler->on_event == &process_vfork_on_event) + return CBS_STOP; + return CBS_CONT; +} + +static int +is_vfork_parent(struct Process *task) +{ + return each_task(task->leader, NULL, &task_vforked, NULL) != NULL; +} + +static enum callback_status +send_sigstop(struct Process *task, void *data) +{ + struct Process *leader = task->leader; + struct pid_set *pids = data; + + /* Look for pre-existing task record, or add new. */ + struct pid_task *task_info = get_task_info(pids, task->pid); + if (task_info == NULL) + task_info = add_task_info(pids, task->pid); + if (task_info == NULL) { + perror("send_sigstop: add_task_info"); + destroy_event_handler(leader); + /* Signal failure upwards. */ + return CBS_STOP; + } + + /* This task still has not been attached to. It should be + stopped by the kernel. */ + if (task->state == STATE_BEING_CREATED) + return CBS_CONT; + + /* Don't bother sending SIGSTOP if we are already stopped, or + * if we sent the SIGSTOP already, which happens when we are + * handling "onexit" and inherited the handler from breakpoint + * re-enablement. */ + enum process_status st; + if (task_stopped(task, &st) == CBS_CONT) + return CBS_CONT; + if (task_info->sigstopped) { + if (!task_info->delivered) + return CBS_CONT; + task_info->delivered = 0; + } + + /* Also don't attempt to stop the process if it's a parent of + * vforked process. We set up event handler specially to hint + * us. In that case parent is in D state, which we use to + * weed out unnecessary looping. */ + if (st == ps_sleeping + && is_vfork_parent (task)) { + task_info->vforked = 1; + return CBS_CONT; + } + + if (task_kill(task->pid, SIGSTOP) >= 0) { + debug(DEBUG_PROCESS, "send SIGSTOP to %d", task->pid); + task_info->sigstopped = 1; + } else + fprintf(stderr, + "Warning: couldn't send SIGSTOP to %d\n", task->pid); + + return CBS_CONT; +} + +/* On certain kernels, detaching right after a singlestep causes the + tracee to be killed with a SIGTRAP (that even though the singlestep + was properly caught by waitpid. The ugly workaround is to put a + breakpoint where IP points and let the process continue. After + this the breakpoint can be retracted and the process detached. */ +static void +ugly_workaround(struct Process *proc) +{ + void *ip = get_instruction_pointer(proc); + struct breakpoint *sbp = dict_find_entry(proc->leader->breakpoints, ip); + if (sbp != NULL) + enable_breakpoint(proc, sbp); + else + insert_breakpoint(proc, ip, NULL); + ptrace(PTRACE_CONT, proc->pid, 0, 0); +} + +static void +process_stopping_done(struct process_stopping_handler *self, + struct Process *leader) +{ + debug(DEBUG_PROCESS, "process stopping done %d", + self->task_enabling_breakpoint->pid); + + if (!self->exiting) { + size_t i; + for (i = 0; i < self->pids.count; ++i) + if (self->pids.tasks[i].pid != 0 + && (self->pids.tasks[i].delivered + || self->pids.tasks[i].sysret)) + continue_process(self->pids.tasks[i].pid); + continue_process(self->task_enabling_breakpoint->pid); + } + + if (self->exiting) { + ugly_workaround: + self->state = psh_ugly_workaround; + ugly_workaround(self->task_enabling_breakpoint); } else { - ptrace(PTRACE_SYSCALL, pid, 0, signum); + switch ((self->ugly_workaround_p)(self)) { + case CBS_FAIL: + /* xxx handle me */ + case CBS_STOP: + break; + case CBS_CONT: + goto ugly_workaround; + } + destroy_event_handler(leader); } } -void -continue_process(pid_t pid) { - /* We always trace syscalls to control fork(), clone(), execve()... */ +/* Before we detach, we need to make sure that task's IP is on the + * edge of an instruction. So for tasks that have a breakpoint event + * in the queue, we adjust the instruction pointer, just like + * continue_after_breakpoint does. */ +static enum ecb_status +undo_breakpoint(Event *event, void *data) +{ + if (event != NULL + && event->proc->leader == data + && event->type == EVENT_BREAKPOINT) + set_instruction_pointer(event->proc, event->e_un.brk_addr); + return ecb_cont; +} - debug(DEBUG_PROCESS, "continue_process: pid=%d", pid); +static enum callback_status +untrace_task(struct Process *task, void *data) +{ + if (task != data) + untrace_pid(task->pid); + return CBS_CONT; +} + +static enum callback_status +remove_task(struct Process *task, void *data) +{ + /* Don't untrace leader just yet. */ + if (task != data) + remove_process(task); + return CBS_CONT; +} + +static enum callback_status +retract_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data) +{ + breakpoint_on_retract(bp, proc); + return CBS_CONT; +} + +static void +detach_process(struct Process *leader) +{ + each_qd_event(&undo_breakpoint, leader); + disable_all_breakpoints(leader); + proc_each_breakpoint(leader, NULL, retract_breakpoint_cb, NULL); + + /* Now untrace the process, if it was attached to by -p. */ + struct opt_p_t *it; + for (it = opt_p; it != NULL; it = it->next) { + struct Process *proc = pid2proc(it->pid); + if (proc == NULL) + continue; + if (proc->leader == leader) { + each_task(leader, NULL, &untrace_task, NULL); + break; + } + } + each_task(leader, NULL, &remove_task, leader); + destroy_event_handler(leader); + remove_task(leader, NULL); +} + +static void +handle_stopping_event(struct pid_task *task_info, Event **eventp) +{ + /* Mark all events, so that we know whom to SIGCONT later. */ + if (task_info != NULL) + task_info->got_event = 1; + + Event *event = *eventp; + + /* In every state, sink SIGSTOP events for tasks that it was + * sent to. */ + if (task_info != NULL + && event->type == EVENT_SIGNAL + && event->e_un.signum == SIGSTOP) { + debug(DEBUG_PROCESS, "SIGSTOP delivered to %d", task_info->pid); + if (task_info->sigstopped + && !task_info->delivered) { + task_info->delivered = 1; + *eventp = NULL; // sink the event + } else + fprintf(stderr, "suspicious: %d got SIGSTOP, but " + "sigstopped=%d and delivered=%d\n", + task_info->pid, task_info->sigstopped, + task_info->delivered); + } +} + +/* Some SIGSTOPs may have not been delivered to their respective tasks + * yet. They are still in the queue. If we have seen an event for + * that process, continue it, so that the SIGSTOP can be delivered and + * caught by ltrace. We don't mind that the process is after + * breakpoint (and therefore potentially doesn't have aligned IP), + * because the signal will be delivered without the process actually + * starting. */ +static void +continue_for_sigstop_delivery(struct pid_set *pids) +{ + size_t i; + for (i = 0; i < pids->count; ++i) { + if (pids->tasks[i].pid != 0 + && pids->tasks[i].sigstopped + && !pids->tasks[i].delivered + && pids->tasks[i].got_event) { + debug(DEBUG_PROCESS, "continue %d for SIGSTOP delivery", + pids->tasks[i].pid); + ptrace(PTRACE_SYSCALL, pids->tasks[i].pid, 0, 0); + } + } +} + +static int +event_exit_p(Event *event) +{ + return event != NULL && (event->type == EVENT_EXIT + || event->type == EVENT_EXIT_SIGNAL); +} - ptrace(PTRACE_SYSCALL, pid, 0, 0); +static int +event_exit_or_none_p(Event *event) +{ + return event == NULL || event_exit_p(event) + || event->type == EVENT_NONE; +} + +static int +await_sigstop_delivery(struct pid_set *pids, struct pid_task *task_info, + Event *event) +{ + /* If we still didn't get our SIGSTOP, continue the process + * and carry on. */ + if (event != NULL && !event_exit_or_none_p(event) + && task_info != NULL && task_info->sigstopped) { + debug(DEBUG_PROCESS, "continue %d for SIGSTOP delivery", + task_info->pid); + /* We should get the signal the first thing + * after this, so it should be OK to continue + * even if we are over a breakpoint. */ + ptrace(PTRACE_SYSCALL, task_info->pid, 0, 0); + + } else { + /* If all SIGSTOPs were delivered, uninstall the + * handler and continue everyone. */ + /* XXX I suspect that we should check tasks that are + * still around. Is things are now, there should be a + * race between waiting for everyone to stop and one + * of the tasks exiting. */ + int all_clear = 1; + size_t i; + for (i = 0; i < pids->count; ++i) + if (pids->tasks[i].pid != 0 + && pids->tasks[i].sigstopped + && !pids->tasks[i].delivered) { + all_clear = 0; + break; + } + return all_clear; + } + + return 0; +} + +static int +all_stops_accountable(struct pid_set *pids) +{ + size_t i; + for (i = 0; i < pids->count; ++i) + if (pids->tasks[i].pid != 0 + && !pids->tasks[i].got_event + && !have_events_for(pids->tasks[i].pid)) + return 0; + return 1; +} + +/* The protocol is: 0 for success, negative for failure, positive if + * default singlestep is to be used. */ +int arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, + int (*add_cb)(void *addr, void *data), + void *add_cb_data); + +#ifndef ARCH_HAVE_ATOMIC_SINGLESTEP +int +arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp, + int (*add_cb)(void *addr, void *data), + void *add_cb_data) +{ + return 1; +} +#endif + +static Event *process_stopping_on_event(struct event_handler *super, + Event *event); + +static void +remove_atomic_breakpoints(struct Process *proc) +{ + struct process_stopping_handler *self + = (void *)proc->leader->event_handler; + assert(self != NULL); + assert(self->super.on_event == process_stopping_on_event); + + int ct = sizeof(self->atomic_skip_bp_addrs) + / sizeof(*self->atomic_skip_bp_addrs); + int i; + for (i = 0; i < ct; ++i) + if (self->atomic_skip_bp_addrs[i] != 0) { + delete_breakpoint(proc, self->atomic_skip_bp_addrs[i]); + self->atomic_skip_bp_addrs[i] = 0; + } +} + +static void +atomic_singlestep_bp_on_hit(struct breakpoint *bp, struct Process *proc) +{ + remove_atomic_breakpoints(proc); +} + +static int +atomic_singlestep_add_bp(void *addr, void *data) +{ + struct process_stopping_handler *self = data; + struct Process *proc = self->task_enabling_breakpoint; + + int ct = sizeof(self->atomic_skip_bp_addrs) + / sizeof(*self->atomic_skip_bp_addrs); + int i; + for (i = 0; i < ct; ++i) + if (self->atomic_skip_bp_addrs[i] == 0) { + self->atomic_skip_bp_addrs[i] = addr; + static struct bp_callbacks cbs = { + .on_hit = atomic_singlestep_bp_on_hit, + }; + struct breakpoint *bp + = insert_breakpoint(proc, addr, NULL); + breakpoint_set_callbacks(bp, &cbs); + return 0; + } + + assert(!"Too many atomic singlestep breakpoints!"); + abort(); +} + +static int +singlestep(struct process_stopping_handler *self) +{ + struct Process *proc = self->task_enabling_breakpoint; + + int status = arch_atomic_singlestep(self->task_enabling_breakpoint, + self->breakpoint_being_enabled, + &atomic_singlestep_add_bp, self); + + /* Propagate failure and success. */ + if (status <= 0) + return status; + + /* Otherwise do the default action: singlestep. */ + debug(1, "PTRACE_SINGLESTEP"); + if (ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0)) { + perror("PTRACE_SINGLESTEP"); + return -1; + } + return 0; +} + +static void +post_singlestep(struct process_stopping_handler *self, + struct Event **eventp) +{ + continue_for_sigstop_delivery(&self->pids); + + if (*eventp != NULL && (*eventp)->type == EVENT_BREAKPOINT) + *eventp = NULL; // handled + + struct Process *proc = self->task_enabling_breakpoint; + + remove_atomic_breakpoints(proc); + self->breakpoint_being_enabled = NULL; +} + +static void +singlestep_error(struct process_stopping_handler *self) +{ + struct Process *teb = self->task_enabling_breakpoint; + struct breakpoint *sbp = self->breakpoint_being_enabled; + fprintf(stderr, "%d couldn't continue when handling %s (%p) at %p\n", + teb->pid, breakpoint_name(sbp), sbp->addr, + get_instruction_pointer(teb)); + delete_breakpoint(teb->leader, sbp->addr); +} + +static void +pt_continue(struct process_stopping_handler *self) +{ + struct Process *teb = self->task_enabling_breakpoint; + debug(1, "PTRACE_CONT"); + ptrace(PTRACE_CONT, teb->pid, 0, 0); +} + +static void +pt_singlestep(struct process_stopping_handler *self) +{ + if (singlestep(self) < 0) + singlestep_error(self); +} + +static void +disable_and(struct process_stopping_handler *self, + void (*do_this)(struct process_stopping_handler *self)) +{ + struct Process *teb = self->task_enabling_breakpoint; + debug(DEBUG_PROCESS, "all stopped, now singlestep/cont %d", teb->pid); + if (self->breakpoint_being_enabled->enabled) + disable_breakpoint(teb, self->breakpoint_being_enabled); + (do_this)(self); + self->state = psh_singlestep; +} + +void +linux_ptrace_disable_and_singlestep(struct process_stopping_handler *self) +{ + disable_and(self, &pt_singlestep); } void -continue_enabling_breakpoint(pid_t pid, Breakpoint *sbp) { - enable_breakpoint(pid, sbp); - continue_process(pid); +linux_ptrace_disable_and_continue(struct process_stopping_handler *self) +{ + disable_and(self, &pt_continue); +} + +/* This event handler is installed when we are in the process of + * stopping the whole thread group to do the pointer re-enablement for + * one of the threads. We pump all events to the queue for later + * processing while we wait for all the threads to stop. When this + * happens, we let the re-enablement thread to PTRACE_SINGLESTEP, + * re-enable, and continue everyone. */ +static Event * +process_stopping_on_event(struct event_handler *super, Event *event) +{ + struct process_stopping_handler *self = (void *)super; + struct Process *task = event->proc; + struct Process *leader = task->leader; + struct Process *teb = self->task_enabling_breakpoint; + + debug(DEBUG_PROCESS, + "process_stopping_on_event: pid %d; event type %d; state %d", + task->pid, event->type, self->state); + + struct pid_task *task_info = get_task_info(&self->pids, task->pid); + if (task_info == NULL) + fprintf(stderr, "new task??? %d\n", task->pid); + handle_stopping_event(task_info, &event); + + int state = self->state; + int event_to_queue = !event_exit_or_none_p(event); + + /* Deactivate the entry if the task exits. */ + if (event_exit_p(event) && task_info != NULL) + task_info->pid = 0; + + /* Always handle sysrets. Whether sysret occurred and what + * sys it rets from may need to be determined based on process + * stack, so we need to keep that in sync with reality. Note + * that we don't continue the process after the sysret is + * handled. See continue_after_syscall. */ + if (event != NULL && event->type == EVENT_SYSRET) { + debug(1, "%d LT_EV_SYSRET", event->proc->pid); + event_to_queue = 0; + task_info->sysret = 1; + } + + switch (state) { + case psh_stopping: + /* If everyone is stopped, singlestep. */ + if (each_task(leader, NULL, &task_blocked, + &self->pids) == NULL) { + (self->on_all_stopped)(self); + state = self->state; + } + break; + + case psh_singlestep: + /* In singlestep state, breakpoint signifies that we + * have now stepped, and can re-enable the breakpoint. */ + if (event != NULL && task == teb) { + + /* If this was caused by a real breakpoint, as + * opposed to a singlestep, assume that it's + * an artificial breakpoint installed for some + * reason for the re-enablement. In that case + * handle it. */ + if (event->type == EVENT_BREAKPOINT) { + arch_addr_t ip + = get_instruction_pointer(task); + struct breakpoint *other + = address2bpstruct(leader, ip); + if (other != NULL) + breakpoint_on_hit(other, task); + } + + /* If we got SIGNAL instead of BREAKPOINT, + * then this is not singlestep at all. */ + if (event->type == EVENT_SIGNAL) { + do_singlestep: + if (singlestep(self) < 0) { + singlestep_error(self); + post_singlestep(self, &event); + goto psh_sinking; + } + break; + } else { + switch ((self->keep_stepping_p)(self)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + break; + case CBS_CONT: + /* Sink singlestep event. */ + if (event->type == EVENT_BREAKPOINT) + event = NULL; + goto do_singlestep; + } + } + + /* Re-enable the breakpoint that we are + * stepping over. */ + struct breakpoint *sbp = self->breakpoint_being_enabled; + if (sbp->enabled) + enable_breakpoint(teb, sbp); + + post_singlestep(self, &event); + goto psh_sinking; + } + break; + + psh_sinking: + state = self->state = psh_sinking; + case psh_sinking: + if (await_sigstop_delivery(&self->pids, task_info, event)) + process_stopping_done(self, leader); + break; + + case psh_ugly_workaround: + if (event == NULL) + break; + if (event->type == EVENT_BREAKPOINT) { + undo_breakpoint(event, leader); + if (task == teb) + self->task_enabling_breakpoint = NULL; + } + if (self->task_enabling_breakpoint == NULL + && all_stops_accountable(&self->pids)) { + undo_breakpoint(event, leader); + detach_process(leader); + event = NULL; // handled + } + } + + if (event != NULL && event_to_queue) { + enque_event(event); + event = NULL; // sink the event + } + + return event; +} + +static void +process_stopping_destroy(struct event_handler *super) +{ + struct process_stopping_handler *self = (void *)super; + free(self->pids.tasks); +} + +static enum callback_status +no(struct process_stopping_handler *self) +{ + return CBS_STOP; +} + +int +process_install_stopping_handler(struct Process *proc, struct breakpoint *sbp, + void (*as)(struct process_stopping_handler *), + enum callback_status (*ks) + (struct process_stopping_handler *), + enum callback_status (*uw) + (struct process_stopping_handler *)) +{ + debug(DEBUG_FUNCTION, + "process_install_stopping_handler: pid=%d", proc->pid); + + struct process_stopping_handler *handler = calloc(sizeof(*handler), 1); + if (handler == NULL) + return -1; + + if (as == NULL) + as = &linux_ptrace_disable_and_singlestep; + if (ks == NULL) + ks = &no; + if (uw == NULL) + uw = &no; + + handler->super.on_event = process_stopping_on_event; + handler->super.destroy = process_stopping_destroy; + handler->task_enabling_breakpoint = proc; + handler->breakpoint_being_enabled = sbp; + handler->on_all_stopped = as; + handler->keep_stepping_p = ks; + handler->ugly_workaround_p = uw; + + install_event_handler(proc->leader, &handler->super); + + if (each_task(proc->leader, NULL, &send_sigstop, + &handler->pids) != NULL) { + destroy_event_handler(proc); + return -1; + } + + /* And deliver the first fake event, in case all the + * conditions are already fulfilled. */ + Event ev = { + .type = EVENT_NONE, + .proc = proc, + }; + process_stopping_on_event(&handler->super, &ev); + + return 0; } void -continue_after_breakpoint(Process *proc, Breakpoint *sbp) { - if (sbp->enabled) - disable_breakpoint(proc->pid, sbp); +continue_after_breakpoint(Process *proc, struct breakpoint *sbp) +{ + debug(DEBUG_PROCESS, + "continue_after_breakpoint: pid=%d, addr=%p", + proc->pid, sbp->addr); + set_instruction_pointer(proc, sbp->addr); + if (sbp->enabled == 0) { continue_process(proc->pid); } else { - debug(DEBUG_PROCESS, "continue_after_breakpoint: pid=%d, addr=%p", proc->pid, sbp->addr); - proc->breakpoint_being_enabled = sbp; #if defined __sparc__ || defined __ia64___ /* we don't want to singlestep here */ continue_process(proc->pid); #else - ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0); + if (process_install_stopping_handler + (proc, sbp, NULL, NULL, NULL) < 0) { + perror("process_stopping_handler_create"); + /* Carry on not bothering to re-enable. */ + continue_process(proc->pid); + } #endif } } -/* Read a series of bytes starting at the process's memory address - 'addr' and continuing until a NUL ('\0') is seen or 'len' bytes - have been read. -*/ +/** + * Ltrace exit. When we are about to exit, we have to go through all + * the processes, stop them all, remove all the breakpoints, and then + * detach the processes that we attached to using -p. If we left the + * other tasks running, they might hit stray return breakpoints and + * produce artifacts, so we better stop everyone, even if it's a bit + * of extra work. + */ +struct ltrace_exiting_handler +{ + struct event_handler super; + struct pid_set pids; +}; + +static Event * +ltrace_exiting_on_event(struct event_handler *super, Event *event) +{ + struct ltrace_exiting_handler *self = (void *)super; + struct Process *task = event->proc; + struct Process *leader = task->leader; + + debug(DEBUG_PROCESS, + "ltrace_exiting_on_event: pid %d; event type %d", + task->pid, event->type); + + struct pid_task *task_info = get_task_info(&self->pids, task->pid); + handle_stopping_event(task_info, &event); + + if (event != NULL && event->type == EVENT_BREAKPOINT) + undo_breakpoint(event, leader); + + if (await_sigstop_delivery(&self->pids, task_info, event) + && all_stops_accountable(&self->pids)) + detach_process(leader); + + /* Sink all non-exit events. We are about to exit, so we + * don't bother with queuing them. */ + if (event_exit_or_none_p(event)) + return event; + + return NULL; +} + +static void +ltrace_exiting_destroy(struct event_handler *super) +{ + struct ltrace_exiting_handler *self = (void *)super; + free(self->pids.tasks); +} + +static int +ltrace_exiting_install_handler(struct Process *proc) +{ + /* Only install to leader. */ + if (proc->leader != proc) + return 0; + + /* Perhaps we are already installed, if the user passed + * several -p options that are tasks of one process. */ + if (proc->event_handler != NULL + && proc->event_handler->on_event == <race_exiting_on_event) + return 0; + + /* If stopping handler is already present, let it do the + * work. */ + if (proc->event_handler != NULL) { + assert(proc->event_handler->on_event + == &process_stopping_on_event); + struct process_stopping_handler *other + = (void *)proc->event_handler; + other->exiting = 1; + return 0; + } + + struct ltrace_exiting_handler *handler + = calloc(sizeof(*handler), 1); + if (handler == NULL) { + perror("malloc exiting handler"); + fatal: + /* XXXXXXXXXXXXXXXXXXX fixme */ + return -1; + } + + handler->super.on_event = ltrace_exiting_on_event; + handler->super.destroy = ltrace_exiting_destroy; + install_event_handler(proc->leader, &handler->super); + + if (each_task(proc->leader, NULL, &send_sigstop, + &handler->pids) != NULL) + goto fatal; + + return 0; +} + +/* + * When the traced process vforks, it's suspended until the child + * process calls _exit or exec*. In the meantime, the two share the + * address space. + * + * The child process should only ever call _exit or exec*, but we + * can't count on that (it's not the role of ltrace to policy, but to + * observe). In any case, we will _at least_ have to deal with + * removal of vfork return breakpoint (which we have to smuggle back + * in, so that the parent can see it, too), and introduction of exec* + * return breakpoint. Since we already have both breakpoint actions + * to deal with, we might as well support it all. + * + * The gist is that we pretend that the child is in a thread group + * with its parent, and handle it as a multi-threaded case, with the + * exception that we know that the parent is blocked, and don't + * attempt to stop it. When the child execs, we undo the setup. + */ + +struct process_vfork_handler +{ + struct event_handler super; + void *bp_addr; +}; + +static Event * +process_vfork_on_event(struct event_handler *super, Event *event) +{ + debug(DEBUG_PROCESS, + "process_vfork_on_event: pid %d; event type %d", + event->proc->pid, event->type); + + struct process_vfork_handler *self = (void *)super; + struct breakpoint *sbp; + assert(self != NULL); + + switch (event->type) { + case EVENT_BREAKPOINT: + /* Remember the vfork return breakpoint. */ + if (self->bp_addr == 0) + self->bp_addr = event->e_un.brk_addr; + break; + + case EVENT_EXIT: + case EVENT_EXIT_SIGNAL: + case EVENT_EXEC: + /* Smuggle back in the vfork return breakpoint, so + * that our parent can trip over it once again. */ + if (self->bp_addr != 0) { + sbp = dict_find_entry(event->proc->leader->breakpoints, + self->bp_addr); + if (sbp != NULL) + assert(sbp->libsym == NULL); + /* We don't mind failing that, it's not a big + * deal to not display one extra vfork return. */ + insert_breakpoint(event->proc->parent, + self->bp_addr, NULL); + } + + continue_process(event->proc->parent->pid); + + /* Remove the leader that we artificially set up + * earlier. */ + change_process_leader(event->proc, event->proc); + destroy_event_handler(event->proc); + + default: + ; + } + + return event; +} + +void +continue_after_vfork(struct Process *proc) +{ + debug(DEBUG_PROCESS, "continue_after_vfork: pid=%d", proc->pid); + struct process_vfork_handler *handler = calloc(sizeof(*handler), 1); + if (handler == NULL) { + perror("malloc vfork handler"); + /* Carry on not bothering to treat the process as + * necessary. */ + continue_process(proc->parent->pid); + return; + } + + /* We must set up custom event handler, so that we see + * exec/exit events for the task itself. */ + handler->super.on_event = process_vfork_on_event; + install_event_handler(proc, &handler->super); + + /* Make sure that the child is sole thread. */ + assert(proc->leader == proc); + assert(proc->next == NULL || proc->next->leader != proc); + + /* Make sure that the child's parent is properly set up. */ + assert(proc->parent != NULL); + assert(proc->parent->leader != NULL); + + change_process_leader(proc, proc->parent->leader); +} + +static int +is_mid_stopping(Process *proc) +{ + return proc != NULL + && proc->event_handler != NULL + && proc->event_handler->on_event == &process_stopping_on_event; +} + +void +continue_after_syscall(struct Process *proc, int sysnum, int ret_p) +{ + /* Don't continue if we are mid-stopping. */ + if (ret_p && (is_mid_stopping(proc) || is_mid_stopping(proc->leader))) { + debug(DEBUG_PROCESS, + "continue_after_syscall: don't continue %d", + proc->pid); + return; + } + continue_process(proc->pid); +} + +/* If ltrace gets SIGINT, the processes directly or indirectly run by + * ltrace get it too. We just have to wait long enough for the signal + * to be delivered and the process terminated, which we notice and + * exit ltrace, too. So there's not much we need to do there. We + * want to keep tracing those processes as usual, in case they just + * SIG_IGN the SIGINT to do their shutdown etc. + * + * For processes ran on the background, we want to install an exit + * handler that stops all the threads, removes all breakpoints, and + * detaches. + */ +void +os_ltrace_exiting(void) +{ + struct opt_p_t *it; + for (it = opt_p; it != NULL; it = it->next) { + struct Process *proc = pid2proc(it->pid); + if (proc == NULL || proc->leader == NULL) + continue; + if (ltrace_exiting_install_handler(proc->leader) < 0) + fprintf(stderr, + "Couldn't install exiting handler for %d.\n", + proc->pid); + } +} + int -umovestr(Process *proc, void *addr, int len, void *laddr) { +os_ltrace_exiting_sighandler(void) +{ + extern int linux_in_waitpid; + if (linux_in_waitpid) { + os_ltrace_exiting(); + return 1; + } + return 0; +} + +size_t +umovebytes(Process *proc, void *addr, void *laddr, size_t len) { + union { long a; char c[sizeof(long)]; } a; - int i; - int offset = 0; + int started = 0; + size_t offset = 0, bytes_read = 0; while (offset < len) { a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr + offset, 0); - for (i = 0; i < sizeof(long); i++) { - if (a.c[i] && offset + (signed)i < len) { - *(char *)(laddr + offset + i) = a.c[i]; - } else { - *(char *)(laddr + offset + i) = '\0'; - return 0; - } + if (a.a == -1 && errno) { + if (started && errno == EIO) + return bytes_read; + else + return -1; + } + started = 1; + + if (len - offset >= sizeof(long)) { + memcpy(laddr + offset, &a.c[0], sizeof(long)); + bytes_read += sizeof(long); + } + else { + memcpy(laddr + offset, &a.c[0], len - offset); + bytes_read += (len - offset); } offset += sizeof(long); } - *(char *)(laddr + offset) = '\0'; - return 0; + + return bytes_read; } diff --git a/sysdeps/linux-gnu/trace.h b/sysdeps/linux-gnu/trace.h new file mode 100644 index 0000000..88ac33d --- /dev/null +++ b/sysdeps/linux-gnu/trace.h @@ -0,0 +1,121 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef _LTRACE_LINUX_TRACE_H_ +#define _LTRACE_LINUX_TRACE_H_ + +#include "proc.h" + +/* This publishes some Linux-specific data structures used for process + * handling. */ + +/** + * This is used for bookkeeping related to PIDs that the event + * handlers work with. + */ +struct pid_task { + pid_t pid; /* This may be 0 for tasks that exited + * mid-handling. */ + int sigstopped : 1; + int got_event : 1; + int delivered : 1; + int vforked : 1; + int sysret : 1; +}; + +struct pid_set { + struct pid_task *tasks; + size_t count; + size_t alloc; +}; + +/** + * Breakpoint re-enablement. When we hit a breakpoint, we must + * disable it, single-step, and re-enable it. That single-step can be + * done only by one task in a task group, while others are stopped, + * otherwise the processes would race for who sees the breakpoint + * disabled and who doesn't. The following is to keep track of it + * all. + */ +struct process_stopping_handler +{ + struct event_handler super; + + /* The task that is doing the re-enablement. */ + struct Process *task_enabling_breakpoint; + + /* The pointer being re-enabled. */ + struct breakpoint *breakpoint_being_enabled; + + /* Artificial atomic skip breakpoint, if any needed. */ + void *atomic_skip_bp_addrs[2]; + + /* When all tasks are stopped, this callback gets called. */ + void (*on_all_stopped)(struct process_stopping_handler *); + + /* When we get a singlestep event, this is called to decide + * whether to stop stepping, or whether to enable the + * brakpoint, sink remaining signals, and continue + * everyone. */ + enum callback_status (*keep_stepping_p) + (struct process_stopping_handler *); + + /* Whether we need to use ugly workaround to get around + * various problems with singlestepping. */ + enum callback_status (*ugly_workaround_p) + (struct process_stopping_handler *); + + enum { + /* We are waiting for everyone to land in t/T. */ + psh_stopping = 0, + + /* We are doing the PTRACE_SINGLESTEP. */ + psh_singlestep, + + /* We are waiting for all the SIGSTOPs to arrive so + * that we can sink them. */ + psh_sinking, + + /* This is for tracking the ugly workaround. */ + psh_ugly_workaround, + } state; + + int exiting; + + struct pid_set pids; +}; + +/* Allocate a process stopping handler, initialize it and install it. + * Return 0 on success or a negative value on failure. Pass NULL for + * each callback to use a default instead. The default for + * ON_ALL_STOPPED is LINUX_PTRACE_DISABLE_AND_SINGLESTEP, the default + * for KEEP_STEPPING_P and UGLY_WORKAROUND_P is "no". */ +int process_install_stopping_handler + (struct Process *proc, struct breakpoint *sbp, + void (*on_all_stopped)(struct process_stopping_handler *), + enum callback_status (*keep_stepping_p) + (struct process_stopping_handler *), + enum callback_status (*ugly_workaround_p) + (struct process_stopping_handler *)); + +void linux_ptrace_disable_and_singlestep(struct process_stopping_handler *self); +void linux_ptrace_disable_and_continue(struct process_stopping_handler *self); + +#endif /* _LTRACE_LINUX_TRACE_H_ */ diff --git a/sysdeps/linux-gnu/x86/Makefile.am b/sysdeps/linux-gnu/x86/Makefile.am new file mode 100644 index 0000000..ee45bab --- /dev/null +++ b/sysdeps/linux-gnu/x86/Makefile.am @@ -0,0 +1,37 @@ +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + signalent1.h \ + syscallent.h \ + syscallent1.h + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/sysdeps/linux-gnu/x86/Makefile.in b/sysdeps/linux-gnu/x86/Makefile.in new file mode 100644 index 0000000..bb7bc9f --- /dev/null +++ b/sysdeps/linux-gnu/x86/Makefile.in @@ -0,0 +1,532 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of ltrace. +# Copyright (C) 2010 Marc Kleine-Budde, Pengutronix +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = sysdeps/linux-gnu/x86 +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +___libcpu_la_LIBADD = +am____libcpu_la_OBJECTS = plt.lo regs.lo trace.lo fetch.lo +___libcpu_la_OBJECTS = $(am____libcpu_la_OBJECTS) +am__dirstamp = $(am__leading_dot)dirstamp +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/autoconf/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(___libcpu_la_SOURCES) +DIST_SOURCES = $(___libcpu_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = \ + ../libcpu.la + +___libcpu_la_SOURCES = \ + plt.c \ + regs.c \ + trace.c \ + fetch.c + +noinst_HEADERS = \ + arch.h \ + ptrace.h \ + signalent.h \ + signalent1.h \ + syscallent.h \ + syscallent1.h + +MAINTAINERCLEANFILES = \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sysdeps/linux-gnu/x86/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign sysdeps/linux-gnu/x86/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +../$(am__dirstamp): + @$(MKDIR_P) .. + @: > ../$(am__dirstamp) +../libcpu.la: $(___libcpu_la_OBJECTS) $(___libcpu_la_DEPENDENCIES) ../$(am__dirstamp) + $(LINK) $(___libcpu_la_OBJECTS) $(___libcpu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ../.libs ../_libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/sysdeps/linux-gnu/x86/arch.h b/sysdeps/linux-gnu/x86/arch.h new file mode 100644 index 0000000..329cfba --- /dev/null +++ b/sysdeps/linux-gnu/x86/arch.h @@ -0,0 +1,36 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011, 2012 Petr Machata + * Copyright (C) 2006 Ian Wienand + * Copyright (C) 2004 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#define BREAKPOINT_VALUE {0xcc} +#define BREAKPOINT_LENGTH 1 +#define DECR_PC_AFTER_BREAK 1 +#define ARCH_HAVE_FETCH_ARG +#define ARCH_HAVE_SIZEOF +#define ARCH_HAVE_ALIGNOF +#define ARCH_ENDIAN_LITTLE + +#ifdef __x86_64__ +#define LT_ELFCLASS ELFCLASS64 +#define LT_ELF_MACHINE EM_X86_64 +#endif +#define LT_ELFCLASS2 ELFCLASS32 +#define LT_ELF_MACHINE2 EM_386 diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c new file mode 100644 index 0000000..4dab4cc --- /dev/null +++ b/sysdeps/linux-gnu/x86/fetch.c @@ -0,0 +1,849 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "config.h" + +#include <sys/types.h> +#include <assert.h> +#include <gelf.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "backend.h" +#include "expr.h" +#include "fetch.h" +#include "proc.h" +#include "ptrace.h" +#include "type.h" +#include "value.h" + +enum arg_class { + CLASS_INTEGER, + CLASS_SSE, + CLASS_NO, + CLASS_MEMORY, + CLASS_X87, +}; + +enum reg_pool { + POOL_FUNCALL, + POOL_SYSCALL, + /* A common pool for system call and function call return is + * enough, the ABI is similar enough. */ + POOL_RETVAL, +}; + +struct fetch_context +{ + struct user_regs_struct iregs; + struct user_fpregs_struct fpregs; + + void *stack_pointer; + size_t ireg; /* Used-up integer registers. */ + size_t freg; /* Used-up floating registers. */ + + union { + struct { + /* Storage classes for return type. We need + * to compute them anyway, so let's keep them + * around. */ + enum arg_class ret_classes[2]; + ssize_t num_ret_classes; + } x86_64; + struct { + struct value retval; + } ix86; + } u; +}; + +#ifndef __x86_64__ +__attribute__((noreturn)) static void +i386_unreachable(void) +{ + abort(); +} +#endif + +static int +contains_unaligned_fields(struct arg_type_info *info) +{ + /* XXX currently we don't support structure alignment. */ + return 0; +} + +static int +has_nontrivial_ctor_dtor(struct arg_type_info *info) +{ + /* XXX another unsupported aspect of type info. We might call + * these types "class" instead of "struct" in the config + * file. */ + return 0; +} + +static void +copy_int_register(struct fetch_context *context, + struct value *valuep, unsigned long val, size_t offset) +{ + if (valuep != NULL) { + unsigned char *buf = value_get_raw_data(valuep); + memcpy(buf + offset, &val, sizeof(val)); + } + context->ireg++; +} + +static void +copy_sse_register(struct fetch_context *context, struct value *valuep, + int half, size_t sz, size_t offset) +{ +#ifdef __x86_64__ + union { + uint32_t sse[4]; + long halves[2]; + } u; + size_t off = 4 * context->freg++; + memcpy(u.sse, context->fpregs.xmm_space + off, sizeof(u.sse)); + + if (valuep != NULL) { + unsigned char *buf = value_get_raw_data(valuep); + memcpy(buf + offset, u.halves + half, sz); + } +#else + i386_unreachable(); +#endif +} + +static void +allocate_stack_slot(struct fetch_context *context, + struct value *valuep, size_t sz, size_t offset, + size_t archw) +{ + size_t a = type_alignof(valuep->inferior, valuep->type); + if (a < archw) + a = archw; + context->stack_pointer + = (void *)align((unsigned long)context->stack_pointer, a); + + if (valuep != NULL) + value_in_inferior(valuep, context->stack_pointer); + context->stack_pointer += sz; +} + +static enum arg_class +allocate_x87(struct fetch_context *context, struct value *valuep, + size_t sz, size_t offset, enum reg_pool pool, size_t archw) +{ + /* Both i386 and x86_64 ABI only ever really use x87 registers + * to return values. Otherwise, the parameter is treated as + * if it were CLASS_MEMORY. On x86_64 x87 registers are only + * used for returning long double values, which we currently + * don't support. */ + + if (pool != POOL_RETVAL) { + allocate_stack_slot(context, valuep, sz, offset, archw); + return CLASS_MEMORY; + + } + + /* If the class is X87, the value is returned on the X87 stack + * in %st0 as 80-bit x87 number. + * + * If the class is X87UP, the value is returned together with + * the previous X87 value in %st0. + * + * If the class is COMPLEX_X87, the real part of the value is + * returned in %st0 and the imaginary part in %st1. */ + + if (valuep != NULL) { + union { + long double ld; + double d; + float f; + char buf[0]; + } u; + + /* The x87 floating point value is in long double + * format, so we need to convert in to the right type. + * Alternatively we might just leave it as is and + * smuggle the long double type into the value (via + * value_set_type), but for that we first need to + * support long double in the first place. */ + +#ifdef __x86_64__ + unsigned int *reg; +#else + long int *reg; +#endif + reg = &context->fpregs.st_space[0]; + memcpy(&u.ld, reg, sizeof(u)); + if (valuep->type->type == ARGTYPE_FLOAT) + u.f = (float)u.ld; + else if (valuep->type->type == ARGTYPE_DOUBLE) + u.d = (double)u.ld; + else + assert(!"Unexpected floating type!"), abort(); + + unsigned char *buf = value_get_raw_data(valuep); + memcpy(buf + offset, u.buf, sz); + } + return CLASS_X87; +} + +static enum arg_class +allocate_integer(struct fetch_context *context, struct value *valuep, + size_t sz, size_t offset, enum reg_pool pool) +{ +#define HANDLE(NUM, WHICH) \ + case NUM: \ + copy_int_register(context, valuep, \ + context->iregs.WHICH, offset); \ + return CLASS_INTEGER + + switch (pool) { + case POOL_FUNCALL: +#ifdef __x86_64__ + switch (context->ireg) { + HANDLE(0, rdi); + HANDLE(1, rsi); + HANDLE(2, rdx); + HANDLE(3, rcx); + HANDLE(4, r8); + HANDLE(5, r9); + default: + allocate_stack_slot(context, valuep, sz, offset, 8); + return CLASS_MEMORY; + } +#else + i386_unreachable(); +#endif + + case POOL_SYSCALL: +#ifdef __x86_64__ + switch (context->ireg) { + HANDLE(0, rdi); + HANDLE(1, rsi); + HANDLE(2, rdx); + HANDLE(3, r10); + HANDLE(4, r8); + HANDLE(5, r9); + default: + assert(!"More than six syscall arguments???"); + abort(); + } +#else + i386_unreachable(); +#endif + + case POOL_RETVAL: + switch (context->ireg) { +#ifdef __x86_64__ + HANDLE(0, rax); + HANDLE(1, rdx); +#else + HANDLE(0, eax); +#endif + default: + assert(!"Too many return value classes."); + abort(); + } + } + + abort(); + +#undef HANDLE +} + +static enum arg_class +allocate_sse(struct fetch_context *context, struct value *valuep, + size_t sz, size_t offset, enum reg_pool pool) +{ + size_t num_regs = 0; + switch (pool) { + case POOL_FUNCALL: + num_regs = 8; + case POOL_SYSCALL: + break; + case POOL_RETVAL: + num_regs = 2; + } + + if (context->freg >= num_regs) { + /* We shouldn't see overflow for RETVAL or SYSCALL + * pool. */ + assert(pool == POOL_FUNCALL); + allocate_stack_slot(context, valuep, sz, offset, 8); + return CLASS_MEMORY; + } else { + copy_sse_register(context, valuep, 0, sz, offset); + return CLASS_SSE; + } +} + +/* This allocates registers or stack space for another argument of the + * class CLS. */ +static enum arg_class +allocate_class(enum arg_class cls, struct fetch_context *context, + struct value *valuep, size_t sz, size_t offset, enum reg_pool pool) +{ + switch (cls) { + case CLASS_MEMORY: + allocate_stack_slot(context, valuep, sz, offset, 8); + case CLASS_NO: + return cls; + + case CLASS_INTEGER: + return allocate_integer(context, valuep, sz, offset, pool); + + case CLASS_SSE: + return allocate_sse(context, valuep, sz, offset, pool); + + case CLASS_X87: + return allocate_x87(context, valuep, sz, offset, pool, 8); + } + abort(); +} + +static ssize_t +classify(struct Process *proc, struct fetch_context *context, + struct arg_type_info *info, struct value *valuep, enum arg_class classes[], + size_t sz, size_t eightbytes); + +/* This classifies one eightbyte part of an array or struct. */ +static ssize_t +classify_eightbyte(struct Process *proc, struct fetch_context *context, + struct arg_type_info *info, struct value *valuep, + enum arg_class *classp, size_t start, size_t end, + struct arg_type_info *(*getter)(struct arg_type_info *, + size_t)) +{ + size_t i; + enum arg_class cls = CLASS_NO; + for (i = start; i < end; ++i) { + enum arg_class cls2; + struct arg_type_info *info2 = getter(info, i); + size_t sz = type_sizeof(proc, info2); + if (sz == (size_t)-1) + return -1; + if (classify(proc, context, info2, valuep, &cls2, sz, 1) < 0) + return -1; + + if (cls == CLASS_NO) + cls = cls2; + else if (cls2 == CLASS_NO || cls == cls2) + ; + else if (cls == CLASS_MEMORY || cls2 == CLASS_MEMORY) + cls = CLASS_MEMORY; + else if (cls == CLASS_INTEGER || cls2 == CLASS_INTEGER) + cls = CLASS_INTEGER; + else + cls = CLASS_SSE; + } + + *classp = cls; + return 1; +} + +/* This classifies small arrays and structs. */ +static ssize_t +classify_eightbytes(struct Process *proc, struct fetch_context *context, + struct arg_type_info *info, struct value *valuep, + enum arg_class classes[], size_t elements, + size_t eightbytes, + struct arg_type_info *(*getter)(struct arg_type_info *, + size_t)) +{ + if (eightbytes > 1) { + /* Where the second eightbyte starts. Number of the + * first element in the structure that belongs to the + * second eightbyte. */ + size_t start_2nd = 0; + size_t i; + for (i = 0; i < elements; ++i) + if (type_offsetof(proc, info, i) >= 8) { + start_2nd = i; + break; + } + + enum arg_class cls1, cls2; + if (classify_eightbyte(proc, context, info, valuep, &cls1, + 0, start_2nd, getter) < 0 + || classify_eightbyte(proc, context, info, valuep, &cls2, + start_2nd, elements, getter) < 0) + return -1; + + if (cls1 == CLASS_MEMORY || cls2 == CLASS_MEMORY) { + classes[0] = CLASS_MEMORY; + return 1; + } + + classes[0] = cls1; + classes[1] = cls2; + return 2; + } + + return classify_eightbyte(proc, context, info, valuep, classes, + 0, elements, getter); +} + +static struct arg_type_info * +get_array_field(struct arg_type_info *info, size_t emt) +{ + return info->u.array_info.elt_type; +} + +static int +flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info) +{ + size_t i; + for (i = 0; i < type_struct_size(info); ++i) { + struct arg_type_info *field = type_struct_get(info, i); + assert(field != NULL); + switch (field->type) { + case ARGTYPE_STRUCT: + if (flatten_structure(flattened, field) < 0) + return -1; + break; + + default: + if (type_struct_add(flattened, field, 0) < 0) + return -1; + } + } + return 0; +} + +static ssize_t +classify(struct Process *proc, struct fetch_context *context, + struct arg_type_info *info, struct value *valuep, enum arg_class classes[], + size_t sz, size_t eightbytes) +{ + switch (info->type) { + struct arg_type_info flattened; + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + + case ARGTYPE_POINTER: + /* and LONGLONG */ + /* CLASS_INTEGER */ + classes[0] = CLASS_INTEGER; + return 1; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + /* and DECIMAL, and _m64 */ + classes[0] = CLASS_SSE; + return 1; + + case ARGTYPE_ARRAY: + /* N.B. this cannot be top-level array, those decay to + * pointers. Therefore, it must be inside structure + * that's at most 2 eightbytes long. */ + + /* Structures with flexible array members can't be + * passed by value. */ + assert(expr_is_compile_constant(info->u.array_info.length)); + + long l; + if (expr_eval_constant(info->u.array_info.length, &l) < 0) + return -1; + + return classify_eightbytes(proc, context, info, valuep, classes, + (size_t)l, eightbytes, + get_array_field); + + case ARGTYPE_STRUCT: + /* N.B. "big" structs are dealt with in the caller. + * + * First, we need to flatten the structure. In + * struct(float,struct(float,float)), first two floats + * both belong to the same eightbyte. */ + type_init_struct(&flattened); + + ssize_t ret; + if (flatten_structure(&flattened, info) < 0) { + ret = -1; + goto done; + } + ret = classify_eightbytes(proc, context, &flattened, + valuep, classes, + type_struct_size(&flattened), + eightbytes, type_struct_get); + done: + type_destroy(&flattened); + return ret; + + default: + /* Unsupported type. */ + assert(info->type != info->type); + abort(); + } + abort(); +} + +static ssize_t +pass_by_reference(struct value *valuep, enum arg_class classes[]) +{ + if (valuep != NULL && value_pass_by_reference(valuep) < 0) + return -1; + classes[0] = CLASS_INTEGER; + return 1; +} + +static ssize_t +classify_argument(struct Process *proc, struct fetch_context *context, + struct arg_type_info *info, struct value *valuep, + enum arg_class classes[], size_t *sizep) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + *sizep = sz; + + size_t eightbytes = (sz + 7) / 8; /* Round up. */ + + /* Arrays decay into pointers. */ + assert(info->type != ARGTYPE_ARRAY); + + if (info->type == ARGTYPE_STRUCT) { + if (eightbytes > 2 || contains_unaligned_fields(info)) { + classes[0] = CLASS_MEMORY; + return 1; + } + + if (has_nontrivial_ctor_dtor(info)) + return pass_by_reference(valuep, classes); + } + + return classify(proc, context, info, valuep, classes, sz, eightbytes); +} + +static int +fetch_register_banks(struct Process *proc, struct fetch_context *context, + int floating) +{ + if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0) + return -1; + context->ireg = 0; + + if (floating) { + if (ptrace(PTRACE_GETFPREGS, proc->pid, + 0, &context->fpregs) < 0) + return -1; + context->freg = 0; + } else { + context->freg = -1; + } + + return 0; +} + +static int +arch_fetch_arg_next_32(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + + allocate_stack_slot(context, valuep, sz, 0, 4); + + return 0; +} + +static int +arch_fetch_retval_32(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0) + return -1; + + struct value *retval = &context->u.ix86.retval; + if (retval->type != NULL) { + /* Struct return value was extracted when in fetch + * init. */ + memcpy(valuep, &context->u.ix86.retval, sizeof(*valuep)); + return 0; + } + + size_t sz = type_sizeof(proc, info); + if (sz == (size_t)-1) + return -1; + if (value_reserve(valuep, sz) == NULL) + return -1; + + switch (info->type) { + enum arg_class cls; + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_POINTER: + cls = allocate_integer(context, valuep, sz, 0, POOL_RETVAL); + assert(cls == CLASS_INTEGER); + return 0; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + cls = allocate_x87(context, valuep, sz, 0, POOL_RETVAL, 4); + assert(cls == CLASS_X87); + return 0; + + case ARGTYPE_STRUCT: /* Handled above. */ + default: + assert(!"Unexpected i386 retval type!"); + abort(); + } + + abort(); +} + +static arch_addr_t +fetch_stack_pointer(struct fetch_context *context) +{ + arch_addr_t sp; +#ifdef __x86_64__ + sp = (arch_addr_t)context->iregs.rsp; +#else + sp = (arch_addr_t)context->iregs.esp; +#endif + return sp; +} + +struct fetch_context * +arch_fetch_arg_init_32(struct fetch_context *context, + enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + context->stack_pointer = fetch_stack_pointer(context) + 4; + + size_t sz = type_sizeof(proc, ret_info); + if (sz == (size_t)-1) + return NULL; + + struct value *retval = &context->u.ix86.retval; + if (ret_info->type == ARGTYPE_STRUCT) { + value_init(retval, proc, NULL, ret_info, 0); + + enum arg_class dummy[2]; + if (pass_by_reference(retval, dummy) < 0) + return NULL; + allocate_stack_slot(context, retval, 4, 0, 4); + + } else { + value_init_detached(retval, NULL, NULL, 0); + } + + return context; +} + +struct fetch_context * +arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type, + struct Process *proc, struct arg_type_info *ret_info) +{ + /* The first stack slot holds a return address. */ + ctx->stack_pointer = fetch_stack_pointer(ctx) + 8; + + size_t size; + ctx->u.x86_64.num_ret_classes + = classify_argument(proc, ctx, ret_info, NULL, + ctx->u.x86_64.ret_classes, &size); + if (ctx->u.x86_64.num_ret_classes == -1) + return NULL; + + /* If the class is MEMORY, then the first argument is a hidden + * pointer to the allocated storage. */ + if (ctx->u.x86_64.num_ret_classes > 0 + && ctx->u.x86_64.ret_classes[0] == CLASS_MEMORY) { + /* MEMORY should be the sole class. */ + assert(ctx->u.x86_64.num_ret_classes == 1); + allocate_integer(ctx, NULL, size, 0, POOL_FUNCALL); + } + + return ctx; +} + +struct fetch_context * +arch_fetch_arg_init(enum tof type, struct Process *proc, + struct arg_type_info *ret_info) +{ + struct fetch_context *ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + assert(type != LT_TOF_FUNCTIONR + && type != LT_TOF_SYSCALLR); + if (fetch_register_banks(proc, ctx, type == LT_TOF_FUNCTION) < 0) { + fail: + free(ctx); + return NULL; + } + + struct fetch_context *ret; + if (proc->e_machine == EM_386) + ret = arch_fetch_arg_init_32(ctx, type, proc, ret_info); + else + ret = arch_fetch_arg_init_64(ctx, type, proc, ret_info); + if (ret == NULL) + goto fail; + return ret; +} + +struct fetch_context * +arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context) +{ + struct fetch_context *ret = malloc(sizeof(*ret)); + if (ret == NULL) + return NULL; + return memcpy(ret, context, sizeof(*ret)); +} + +static int +arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep, enum reg_pool pool) +{ + enum arg_class classes[2]; + size_t sz, sz1; + ssize_t i; + ssize_t nclasses = classify_argument(proc, context, info, valuep, + classes, &sz); + if (nclasses == -1) + return -1; + if (value_reserve(valuep, sz) == NULL) + return -1; + + /* If there are no registers available for any eightbyte of an + * argument, the whole argument is passed on the stack. If + * registers have already been assigned for some eightbytes of + * such an argument, the assignments get reverted. */ + struct fetch_context tmp_context = *context; + int revert; + if (nclasses == 1) { + revert = allocate_class(classes[0], &tmp_context, + valuep, sz, 0, pool) != classes[0]; + } else { + revert = 0; + for (i = 0; i < nclasses; ++i) { + sz1 = (size_t)(8 * (i + 1)) > sz ? sz - 8 * i : 8; + if (allocate_class(classes[i], &tmp_context, valuep, + sz1, 8 * i, pool) != classes[i]) + revert = 1; + } + } + + if (nclasses > 1 && revert) + allocate_class(CLASS_MEMORY, context, valuep, sz, 0, pool); + else + *context = tmp_context; /* Commit. */ + + return 0; +} + +int +arch_fetch_fun_retval(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + assert(type != LT_TOF_FUNCTION + && type != LT_TOF_SYSCALL); + if (value_reserve(valuep, 8 * context->u.x86_64.num_ret_classes) == NULL + || fetch_register_banks(proc, context, + type == LT_TOF_FUNCTIONR) < 0) + return -1; + + if (context->u.x86_64.num_ret_classes == 1 + && context->u.x86_64.ret_classes[0] == CLASS_MEMORY) + pass_by_reference(valuep, context->u.x86_64.ret_classes); + + size_t sz = type_sizeof(proc, valuep->type); + if (sz == (size_t)-1) + return -1; + + ssize_t i; + size_t sz1 = context->u.x86_64.num_ret_classes == 1 ? sz : 8; + for (i = 0; i < context->u.x86_64.num_ret_classes; ++i) { + enum arg_class cls + = allocate_class(context->u.x86_64.ret_classes[i], + context, valuep, sz1, + 8 * i, POOL_RETVAL); + assert(cls == context->u.x86_64.ret_classes[i]); + } + return 0; +} + +int +arch_fetch_arg_next(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (proc->e_machine == EM_386) + return arch_fetch_arg_next_32(context, type, proc, + info, valuep); + + switch (type) { + case LT_TOF_FUNCTION: + case LT_TOF_FUNCTIONR: + return arch_fetch_pool_arg_next(context, type, proc, + info, valuep, POOL_FUNCALL); + + case LT_TOF_SYSCALL: + case LT_TOF_SYSCALLR: + return arch_fetch_pool_arg_next(context, type, proc, + info, valuep, POOL_SYSCALL); + } + + abort(); +} + +int +arch_fetch_retval(struct fetch_context *context, enum tof type, + struct Process *proc, struct arg_type_info *info, + struct value *valuep) +{ + if (proc->e_machine == EM_386) + return arch_fetch_retval_32(context, type, proc, info, valuep); + + return arch_fetch_fun_retval(context, type, proc, info, valuep); +} + +void +arch_fetch_arg_done(struct fetch_context *context) +{ + if (context != NULL) + free(context); +} diff --git a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c new file mode 100644 index 0000000..dc6f183 --- /dev/null +++ b/sysdeps/linux-gnu/x86/plt.c @@ -0,0 +1,34 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <gelf.h> +#include "proc.h" +#include "common.h" +#include "library.h" + +GElf_Addr +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { + return lte->plt_addr + (ndx + 1) * 16; +} + +void * +sym2addr(Process *proc, struct library_symbol *sym) { + return sym->enter_addr; +} diff --git a/sysdeps/linux-gnu/x86/ptrace.h b/sysdeps/linux-gnu/x86/ptrace.h new file mode 100644 index 0000000..dc4734a --- /dev/null +++ b/sysdeps/linux-gnu/x86/ptrace.h @@ -0,0 +1,21 @@ +/* + * This file is part of ltrace. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <sys/ptrace.h> +#include <sys/user.h> diff --git a/sysdeps/linux-gnu/x86/regs.c b/sysdeps/linux-gnu/x86/regs.c new file mode 100644 index 0000000..ca6470b --- /dev/null +++ b/sysdeps/linux-gnu/x86/regs.c @@ -0,0 +1,116 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1998,2002,2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include "config.h" + +#include <sys/types.h> +#include <sys/ptrace.h> +#include <sys/reg.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "backend.h" +#include "proc.h" + +#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) +# define PTRACE_PEEKUSER PTRACE_PEEKUSR +#endif + +#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) +# define PTRACE_POKEUSER PTRACE_POKEUSR +#endif + +#ifdef __x86_64__ +# define XIP (8 * RIP) +# define XSP (8 * RSP) +#else +# define XIP (4 * EIP) +# define XSP (4 * UESP) +#endif + +static arch_addr_t +conv_32(arch_addr_t val) +{ + /* XXX Drop the multiple double casts when arch_addr_t + * becomes integral. */ + return (arch_addr_t)(uintptr_t)(uint32_t)(uintptr_t)val; +} + +void * +get_instruction_pointer(struct Process *proc) +{ + long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, XIP, 0); + if (proc->e_machine == EM_386) + ret &= 0xffffffff; + return (void *)ret; +} + +void +set_instruction_pointer(struct Process *proc, arch_addr_t addr) +{ + if (proc->e_machine == EM_386) + addr = conv_32(addr); + ptrace(PTRACE_POKEUSER, proc->pid, XIP, addr); +} + +void * +get_stack_pointer(struct Process *proc) +{ + long sp = ptrace(PTRACE_PEEKUSER, proc->pid, XSP, 0); + if (sp == -1 && errno) { + fprintf(stderr, "Couldn't read SP register: %s\n", + strerror(errno)); + return NULL; + } + + /* XXX Drop the multiple double casts when arch_addr_t + * becomes integral. */ + arch_addr_t ret = (arch_addr_t)(uintptr_t)sp; + if (proc->e_machine == EM_386) + ret = conv_32(ret); + return ret; +} + +void * +get_return_addr(struct Process *proc, void *sp) +{ + long a = ptrace(PTRACE_PEEKTEXT, proc->pid, sp, 0); + if (a == -1 && errno) { + fprintf(stderr, "Couldn't read return value: %s\n", + strerror(errno)); + return NULL; + } + + /* XXX Drop the multiple double casts when arch_addr_t + * becomes integral. */ + arch_addr_t ret = (arch_addr_t)(uintptr_t)a; + if (proc->e_machine == EM_386) + ret = conv_32(ret); + return ret; +} + +void +set_return_addr(Process *proc, void *addr) { + if (proc->e_machine == EM_386) + addr = (void *)((long int)addr & 0xffffffff); + ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr); +} diff --git a/sysdeps/linux-gnu/x86_64/signalent.h b/sysdeps/linux-gnu/x86/signalent.h index d58a36c..9b8baa0 100644 --- a/sysdeps/linux-gnu/x86_64/signalent.h +++ b/sysdeps/linux-gnu/x86/signalent.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/i386/signalent.h b/sysdeps/linux-gnu/x86/signalent1.h index 5395f82..31699db 100644 --- a/sysdeps/linux-gnu/i386/signalent.h +++ b/sysdeps/linux-gnu/x86/signalent1.h @@ -1,3 +1,23 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + "SIG_0", /* 0 */ "SIGHUP", /* 1 */ "SIGINT", /* 2 */ diff --git a/sysdeps/linux-gnu/x86/syscallent.h b/sysdeps/linux-gnu/x86/syscallent.h new file mode 100644 index 0000000..345fe20 --- /dev/null +++ b/sysdeps/linux-gnu/x86/syscallent.h @@ -0,0 +1,370 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* This file is for i386 system call names. */ + "restart_syscall", /* 0 */ + "exit", /* 1 */ + "fork", /* 2 */ + "read", /* 3 */ + "write", /* 4 */ + "open", /* 5 */ + "close", /* 6 */ + "waitpid", /* 7 */ + "creat", /* 8 */ + "link", /* 9 */ + "unlink", /* 10 */ + "execve", /* 11 */ + "chdir", /* 12 */ + "time", /* 13 */ + "mknod", /* 14 */ + "chmod", /* 15 */ + "lchown", /* 16 */ + "break", /* 17 */ + "oldstat", /* 18 */ + "lseek", /* 19 */ + "getpid", /* 20 */ + "mount", /* 21 */ + "umount", /* 22 */ + "setuid", /* 23 */ + "getuid", /* 24 */ + "stime", /* 25 */ + "ptrace", /* 26 */ + "alarm", /* 27 */ + "oldfstat", /* 28 */ + "pause", /* 29 */ + "utime", /* 30 */ + "stty", /* 31 */ + "gtty", /* 32 */ + "access", /* 33 */ + "nice", /* 34 */ + "ftime", /* 35 */ + "sync", /* 36 */ + "kill", /* 37 */ + "rename", /* 38 */ + "mkdir", /* 39 */ + "rmdir", /* 40 */ + "dup", /* 41 */ + "pipe", /* 42 */ + "times", /* 43 */ + "prof", /* 44 */ + "brk", /* 45 */ + "setgid", /* 46 */ + "getgid", /* 47 */ + "signal", /* 48 */ + "geteuid", /* 49 */ + "getegid", /* 50 */ + "acct", /* 51 */ + "umount2", /* 52 */ + "lock", /* 53 */ + "ioctl", /* 54 */ + "fcntl", /* 55 */ + "mpx", /* 56 */ + "setpgid", /* 57 */ + "ulimit", /* 58 */ + "oldolduname", /* 59 */ + "umask", /* 60 */ + "chroot", /* 61 */ + "ustat", /* 62 */ + "dup2", /* 63 */ + "getppid", /* 64 */ + "getpgrp", /* 65 */ + "setsid", /* 66 */ + "sigaction", /* 67 */ + "sgetmask", /* 68 */ + "ssetmask", /* 69 */ + "setreuid", /* 70 */ + "setregid", /* 71 */ + "sigsuspend", /* 72 */ + "sigpending", /* 73 */ + "sethostname", /* 74 */ + "setrlimit", /* 75 */ + "getrlimit", /* 76 */ + "getrusage", /* 77 */ + "gettimeofday", /* 78 */ + "settimeofday", /* 79 */ + "getgroups", /* 80 */ + "setgroups", /* 81 */ + "select", /* 82 */ + "symlink", /* 83 */ + "oldlstat", /* 84 */ + "readlink", /* 85 */ + "uselib", /* 86 */ + "swapon", /* 87 */ + "reboot", /* 88 */ + "readdir", /* 89 */ + "mmap", /* 90 */ + "munmap", /* 91 */ + "truncate", /* 92 */ + "ftruncate", /* 93 */ + "fchmod", /* 94 */ + "fchown", /* 95 */ + "getpriority", /* 96 */ + "setpriority", /* 97 */ + "profil", /* 98 */ + "statfs", /* 99 */ + "fstatfs", /* 100 */ + "ioperm", /* 101 */ + "socketcall", /* 102 */ + "syslog", /* 103 */ + "setitimer", /* 104 */ + "getitimer", /* 105 */ + "stat", /* 106 */ + "lstat", /* 107 */ + "fstat", /* 108 */ + "olduname", /* 109 */ + "iopl", /* 110 */ + "vhangup", /* 111 */ + "idle", /* 112 */ + "vm86old", /* 113 */ + "wait4", /* 114 */ + "swapoff", /* 115 */ + "sysinfo", /* 116 */ + "ipc", /* 117 */ + "fsync", /* 118 */ + "sigreturn", /* 119 */ + "clone", /* 120 */ + "setdomainname", /* 121 */ + "uname", /* 122 */ + "modify_ldt", /* 123 */ + "adjtimex", /* 124 */ + "mprotect", /* 125 */ + "sigprocmask", /* 126 */ + "create_module", /* 127 */ + "init_module", /* 128 */ + "delete_module", /* 129 */ + "get_kernel_syms", /* 130 */ + "quotactl", /* 131 */ + "getpgid", /* 132 */ + "fchdir", /* 133 */ + "bdflush", /* 134 */ + "sysfs", /* 135 */ + "personality", /* 136 */ + "afs_syscall", /* 137 */ + "setfsuid", /* 138 */ + "setfsgid", /* 139 */ + "_llseek", /* 140 */ + "getdents", /* 141 */ + "_newselect", /* 142 */ + "flock", /* 143 */ + "msync", /* 144 */ + "readv", /* 145 */ + "writev", /* 146 */ + "getsid", /* 147 */ + "fdatasync", /* 148 */ + "_sysctl", /* 149 */ + "mlock", /* 150 */ + "munlock", /* 151 */ + "mlockall", /* 152 */ + "munlockall", /* 153 */ + "sched_setparam", /* 154 */ + "sched_getparam", /* 155 */ + "sched_setscheduler", /* 156 */ + "sched_getscheduler", /* 157 */ + "sched_yield", /* 158 */ + "sched_get_priority_max", /* 159 */ + "sched_get_priority_min", /* 160 */ + "sched_rr_get_interval", /* 161 */ + "nanosleep", /* 162 */ + "mremap", /* 163 */ + "setresuid", /* 164 */ + "getresuid", /* 165 */ + "vm86", /* 166 */ + "query_module", /* 167 */ + "poll", /* 168 */ + "nfsservctl", /* 169 */ + "setresgid", /* 170 */ + "getresgid", /* 171 */ + "prctl", /* 172 */ + "rt_sigreturn", /* 173 */ + "rt_sigaction", /* 174 */ + "rt_sigprocmask", /* 175 */ + "rt_sigpending", /* 176 */ + "rt_sigtimedwait", /* 177 */ + "rt_sigqueueinfo", /* 178 */ + "rt_sigsuspend", /* 179 */ + "pread64", /* 180 */ + "pwrite64", /* 181 */ + "chown", /* 182 */ + "getcwd", /* 183 */ + "capget", /* 184 */ + "capset", /* 185 */ + "sigaltstack", /* 186 */ + "sendfile", /* 187 */ + "getpmsg", /* 188 */ + "putpmsg", /* 189 */ + "vfork", /* 190 */ + "ugetrlimit", /* 191 */ + "mmap2", /* 192 */ + "truncate64", /* 193 */ + "ftruncate64", /* 194 */ + "stat64", /* 195 */ + "lstat64", /* 196 */ + "fstat64", /* 197 */ + "lchown32", /* 198 */ + "getuid32", /* 199 */ + "getgid32", /* 200 */ + "geteuid32", /* 201 */ + "getegid32", /* 202 */ + "setreuid32", /* 203 */ + "setregid32", /* 204 */ + "getgroups32", /* 205 */ + "setgroups32", /* 206 */ + "fchown32", /* 207 */ + "setresuid32", /* 208 */ + "getresuid32", /* 209 */ + "setresgid32", /* 210 */ + "getresgid32", /* 211 */ + "chown32", /* 212 */ + "setuid32", /* 213 */ + "setgid32", /* 214 */ + "setfsuid32", /* 215 */ + "setfsgid32", /* 216 */ + "pivot_root", /* 217 */ + "mincore", /* 218 */ + "madvise1", /* 219 */ + "getdents64", /* 220 */ + "fcntl64", /* 221 */ + "222", /* 222 */ + "223", /* 223 */ + "gettid", /* 224 */ + "readahead", /* 225 */ + "setxattr", /* 226 */ + "lsetxattr", /* 227 */ + "fsetxattr", /* 228 */ + "getxattr", /* 229 */ + "lgetxattr", /* 230 */ + "fgetxattr", /* 231 */ + "listxattr", /* 232 */ + "llistxattr", /* 233 */ + "flistxattr", /* 234 */ + "removexattr", /* 235 */ + "lremovexattr", /* 236 */ + "fremovexattr", /* 237 */ + "tkill", /* 238 */ + "sendfile64", /* 239 */ + "futex", /* 240 */ + "sched_setaffinity", /* 241 */ + "sched_getaffinity", /* 242 */ + "set_thread_area", /* 243 */ + "get_thread_area", /* 244 */ + "io_setup", /* 245 */ + "io_destroy", /* 246 */ + "io_getevents", /* 247 */ + "io_submit", /* 248 */ + "io_cancel", /* 249 */ + "fadvise64", /* 250 */ + "251", /* 251 */ + "exit_group", /* 252 */ + "lookup_dcookie", /* 253 */ + "epoll_create", /* 254 */ + "epoll_ctl", /* 255 */ + "epoll_wait", /* 256 */ + "remap_file_pages", /* 257 */ + "set_tid_address", /* 258 */ + "timer_create", /* 259 */ + "260", /* 260 */ + "261", /* 261 */ + "262", /* 262 */ + "263", /* 263 */ + "264", /* 264 */ + "265", /* 265 */ + "266", /* 266 */ + "267", /* 267 */ + "statfs64", /* 268 */ + "fstatfs64", /* 269 */ + "tgkill", /* 270 */ + "utimes", /* 271 */ + "fadvise64_64", /* 272 */ + "vserver", /* 273 */ + "mbind", /* 274 */ + "get_mempolicy", /* 275 */ + "set_mempolicy", /* 276 */ + "mq_open", /* 277 */ + "278", /* 278 */ + "279", /* 279 */ + "280", /* 280 */ + "281", /* 281 */ + "282", /* 282 */ + "kexec_load", /* 283 */ + "waitid", /* 284 */ + "285", /* 285 */ + "add_key", /* 286 */ + "request_key", /* 287 */ + "keyctl", /* 288 */ + "ioprio_set", /* 289 */ + "ioprio_get", /* 290 */ + "inotify_init", /* 291 */ + "inotify_add_watch", /* 292 */ + "inotify_rm_watch", /* 293 */ + "migrate_pages", /* 294 */ + "openat", /* 295 */ + "mkdirat", /* 296 */ + "mknodat", /* 297 */ + "fchownat", /* 298 */ + "futimesat", /* 299 */ + "fstatat64", /* 300 */ + "unlinkat", /* 301 */ + "renameat", /* 302 */ + "linkat", /* 303 */ + "symlinkat", /* 304 */ + "readlinkat", /* 305 */ + "fchmodat", /* 306 */ + "faccessat", /* 307 */ + "pselect6", /* 308 */ + "ppoll", /* 309 */ + "unshare", /* 310 */ + "set_robust_list", /* 311 */ + "get_robust_list", /* 312 */ + "splice", /* 313 */ + "sync_file_range", /* 314 */ + "tee", /* 315 */ + "vmsplice", /* 316 */ + "move_pages", /* 317 */ + "getcpu", /* 318 */ + "epoll_pwait", /* 319 */ + "utimensat", /* 320 */ + "signalfd", /* 321 */ + "timerfd_create", /* 322 */ + "eventfd", /* 323 */ + "fallocate", /* 324 */ + "timerfd_settime", /* 325 */ + "timerfd_gettime", /* 326 */ + "signalfd4", /* 327 */ + "eventfd2", /* 328 */ + "epoll_create1", /* 329 */ + "dup3", /* 330 */ + "pipe2", /* 331 */ + "inotify_init1", /* 332 */ + "preadv", /* 333 */ + "pwritev", /* 334 */ + "rt_tgsigqueueinfo", /* 335 */ + "perf_event_open", /* 336 */ + "recvmmsg", /* 337 */ + "fanotify_init", /* 338 */ + "fanotify_mark", /* 339 */ + "prlimit64", /* 340 */ + "name_to_handle_at", /* 341 */ + "open_by_handle_at", /* 342 */ + "clock_adjtime", /* 343 */ + "syncfs", /* 344 */ + "sendmmsg", /* 345 */ + "setns", /* 346 */ + "process_vm_readv", /* 347 */ + "process_vm_writev", /* 348 */ diff --git a/sysdeps/linux-gnu/x86/syscallent1.h b/sysdeps/linux-gnu/x86/syscallent1.h new file mode 100644 index 0000000..91ae8d6 --- /dev/null +++ b/sysdeps/linux-gnu/x86/syscallent1.h @@ -0,0 +1,333 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* This file is for x86_64 system call names. */ + "read", /* 0 */ + "write", /* 1 */ + "open", /* 2 */ + "close", /* 3 */ + "stat", /* 4 */ + "fstat", /* 5 */ + "lstat", /* 6 */ + "poll", /* 7 */ + "lseek", /* 8 */ + "mmap", /* 9 */ + "mprotect", /* 10 */ + "munmap", /* 11 */ + "brk", /* 12 */ + "rt_sigaction", /* 13 */ + "rt_sigprocmask", /* 14 */ + "rt_sigreturn", /* 15 */ + "ioctl", /* 16 */ + "pread", /* 17 */ + "pwrite", /* 18 */ + "readv", /* 19 */ + "writev", /* 20 */ + "access", /* 21 */ + "pipe", /* 22 */ + "select", /* 23 */ + "sched_yield", /* 24 */ + "mremap", /* 25 */ + "msync", /* 26 */ + "mincore", /* 27 */ + "madvise", /* 28 */ + "shmget", /* 29 */ + "shmat", /* 30 */ + "shmctl", /* 31 */ + "dup", /* 32 */ + "dup2", /* 33 */ + "pause", /* 34 */ + "nanosleep", /* 35 */ + "getitimer", /* 36 */ + "alarm", /* 37 */ + "setitimer", /* 38 */ + "getpid", /* 39 */ + "sendfile", /* 40 */ + "socket", /* 41 */ + "connect", /* 42 */ + "accept", /* 43 */ + "sendto", /* 44 */ + "recvfrom", /* 45 */ + "sendmsg", /* 46 */ + "recvmsg", /* 47 */ + "shutdown", /* 48 */ + "bind", /* 49 */ + "listen", /* 50 */ + "getsockname", /* 51 */ + "getpeername", /* 52 */ + "socketpair", /* 53 */ + "setsockopt", /* 54 */ + "getsockopt", /* 55 */ + "clone", /* 56 */ + "fork", /* 57 */ + "vfork", /* 58 */ + "execve", /* 59 */ + "exit", /* 60 */ + "wait4", /* 61 */ + "kill", /* 62 */ + "uname", /* 63 */ + "semget", /* 64 */ + "semop", /* 65 */ + "semctl", /* 66 */ + "shmdt", /* 67 */ + "msgget", /* 68 */ + "msgsnd", /* 69 */ + "msgrcv", /* 70 */ + "msgctl", /* 71 */ + "fcntl", /* 72 */ + "flock", /* 73 */ + "fsync", /* 74 */ + "fdatasync", /* 75 */ + "truncate", /* 76 */ + "ftruncate", /* 77 */ + "getdents", /* 78 */ + "getcwd", /* 79 */ + "chdir", /* 80 */ + "fchdir", /* 81 */ + "rename", /* 82 */ + "mkdir", /* 83 */ + "rmdir", /* 84 */ + "creat", /* 85 */ + "link", /* 86 */ + "unlink", /* 87 */ + "symlink", /* 88 */ + "readlink", /* 89 */ + "chmod", /* 90 */ + "fchmod", /* 91 */ + "chown", /* 92 */ + "fchown", /* 93 */ + "lchown", /* 94 */ + "umask", /* 95 */ + "gettimeofday", /* 96 */ + "getrlimit", /* 97 */ + "getrusage", /* 98 */ + "sysinfo", /* 99 */ + "times", /* 100 */ + "ptrace", /* 101 */ + "getuid", /* 102 */ + "syslog", /* 103 */ + "getgid", /* 104 */ + "setuid", /* 105 */ + "setgid", /* 106 */ + "geteuid", /* 107 */ + "getegid", /* 108 */ + "setpgid", /* 109 */ + "getppid", /* 110 */ + "getpgrp", /* 111 */ + "setsid", /* 112 */ + "setreuid", /* 113 */ + "setregid", /* 114 */ + "getgroups", /* 115 */ + "setgroups", /* 116 */ + "setresuid", /* 117 */ + "getresuid", /* 118 */ + "setresgid", /* 119 */ + "getresgid", /* 120 */ + "getpgid", /* 121 */ + "setfsuid", /* 122 */ + "setfsgid", /* 123 */ + "getsid", /* 124 */ + "capget", /* 125 */ + "capset", /* 126 */ + "rt_sigpending", /* 127 */ + "rt_sigtimedwait", /* 128 */ + "rt_sigqueueinfo", /* 129 */ + "rt_sigsuspend", /* 130 */ + "sigaltstack", /* 131 */ + "utime", /* 132 */ + "mknod", /* 133 */ + "uselib", /* 134 */ + "personality", /* 135 */ + "ustat", /* 136 */ + "statfs", /* 137 */ + "fstatfs", /* 138 */ + "sysfs", /* 139 */ + "getpriority", /* 140 */ + "setpriority", /* 141 */ + "sched_setparam", /* 142 */ + "sched_getparam", /* 143 */ + "sched_setscheduler", /* 144 */ + "sched_getscheduler", /* 145 */ + "sched_get_priority_max", /* 146 */ + "sched_get_priority_min", /* 147 */ + "sched_rr_get_interval", /* 148 */ + "mlock", /* 149 */ + "munlock", /* 150 */ + "mlockall", /* 151 */ + "munlockall", /* 152 */ + "vhangup", /* 153 */ + "modify_ldt", /* 154 */ + "pivot_root", /* 155 */ + "_sysctl", /* 156 */ + "prctl", /* 157 */ + "arch_prctl", /* 158 */ + "adjtimex", /* 159 */ + "setrlimit", /* 160 */ + "chroot", /* 161 */ + "sync", /* 162 */ + "acct", /* 163 */ + "settimeofday", /* 164 */ + "mount", /* 165 */ + "umount2", /* 166 */ + "swapon", /* 167 */ + "swapoff", /* 168 */ + "reboot", /* 169 */ + "sethostname", /* 170 */ + "setdomainname", /* 171 */ + "iopl", /* 172 */ + "ioperm", /* 173 */ + "create_module", /* 174 */ + "init_module", /* 175 */ + "delete_module", /* 176 */ + "get_kernel_syms", /* 177 */ + "query_module", /* 178 */ + "quotactl", /* 179 */ + "nfsservctl", /* 180 */ + "getpmsg", /* 181 */ + "putpmsg", /* 182 */ + "afs_syscall", /* 183 */ + "tuxcall", /* 184 */ + "security", /* 185 */ + "gettid", /* 186 */ + "readahead", /* 187 */ + "setxattr", /* 188 */ + "lsetxattr", /* 189 */ + "fsetxattr", /* 190 */ + "getxattr", /* 191 */ + "lgetxattr", /* 192 */ + "fgetxattr", /* 193 */ + "listxattr", /* 194 */ + "llistxattr", /* 195 */ + "flistxattr", /* 196 */ + "removexattr", /* 197 */ + "lremovexattr", /* 198 */ + "fremovexattr", /* 199 */ + "tkill", /* 200 */ + "time", /* 201 */ + "futex", /* 202 */ + "sched_setaffinity", /* 203 */ + "sched_getaffinity", /* 204 */ + "set_thread_area", /* 205 */ + "io_setup", /* 206 */ + "io_destroy", /* 207 */ + "io_getevents", /* 208 */ + "io_submit", /* 209 */ + "io_cancel", /* 210 */ + "get_thread_area", /* 211 */ + "lookup_dcookie", /* 212 */ + "epoll_create", /* 213 */ + "epoll_ctl", /* 214 */ + "epoll_wait", /* 215 */ + "remap_file_pages", /* 216 */ + "getdents64", /* 217 */ + "set_tid_address", /* 218 */ + "restart_syscall", /* 219 */ + "semtimedop", /* 220 */ + "fadvise64", /* 221 */ + "timer_create", /* 222 */ + "timer_settime", /* 223 */ + "timer_gettime", /* 224 */ + "timer_getoverrun", /* 225 */ + "timer_delete", /* 226 */ + "clock_settime", /* 227 */ + "clock_gettime", /* 228 */ + "clock_getres", /* 229 */ + "clock_nanosleep", /* 230 */ + "exit_group", /* 231 */ + "epoll_wait", /* 232 */ + "epoll_ctl", /* 233 */ + "tgkill", /* 234 */ + "utimes", /* 235 */ + "vserver", /* 236 */ + "mbind", /* 237 */ + "set_mempolicy", /* 238 */ + "get_mempolicy", /* 239 */ + "mq_open", /* 240 */ + "mq_unlink", /* 241 */ + "mq_timedsend", /* 242 */ + "mq_timedreceive", /* 243 */ + "mq_notify", /* 244 */ + "mq_getsetattr", /* 245 */ + "kexec_load", /* 246 */ + "waitid", /* 247 */ + "add_key", /* 248 */ + "request_key", /* 249 */ + "keyctl", /* 250 */ + "ioprio_set", /* 251 */ + "ioprio_get", /* 252 */ + "inotify_init", /* 253 */ + "inotify_add_watch", /* 254 */ + "inotify_rm_watch", /* 255 */ + "migrate_pages", /* 256 */ + "openat", /* 257 */ + "mkdirat", /* 258 */ + "mknodat", /* 259 */ + "fchownat", /* 260 */ + "futimesat", /* 261 */ + "newfstatat", /* 262 */ + "unlinkat", /* 263 */ + "renameat", /* 264 */ + "linkat", /* 265 */ + "symlinkat", /* 266 */ + "readlinkat", /* 267 */ + "fchmodat", /* 268 */ + "faccessat", /* 269 */ + "pselect6", /* 270 */ + "ppoll", /* 271 */ + "unshare", /* 272 */ + "set_robust_list", /* 273 */ + "get_robust_list", /* 274 */ + "splice", /* 275 */ + "tee", /* 276 */ + "sync_file_range", /* 277 */ + "vmsplice", /* 278 */ + "move_pages", /* 279 */ + "utimensat", /* 280 */ + "epoll_pwait", /* 281 */ + "signalfd", /* 282 */ + "timerfd_create", /* 283 */ + "eventfd", /* 284 */ + "fallocate", /* 285 */ + "timerfd_settime", /* 286 */ + "timerfd_gettime", /* 287 */ + "accept4", /* 288 */ + "signalfd4", /* 289 */ + "eventfd2", /* 290 */ + "epoll_create1", /* 291 */ + "dup3", /* 292 */ + "pipe2", /* 293 */ + "inotify_init1", /* 294 */ + "preadv", /* 295 */ + "pwritev", /* 296 */ + "rt_tgsigqueueinfo", /* 297 */ + "perf_event_open", /* 298 */ + "recvmmsg", /* 299 */ + "fanotify_init", /* 300 */ + "fanotify_mark", /* 301 */ + "prlimit64", /* 302 */ + "name_to_handle_at", /* 303 */ + "open_by_handle_at", /* 304 */ + "clock_adjtime", /* 305 */ + "syncfs", /* 306 */ + "sendmmsg", /* 307 */ + "setns", /* 308 */ + "getcpu", /* 309 */ + "process_vm_readv", /* 310 */ + "process_vm_writev", /* 311 */ diff --git a/sysdeps/linux-gnu/x86/trace.c b/sysdeps/linux-gnu/x86/trace.c new file mode 100644 index 0000000..ed8bdb4 --- /dev/null +++ b/sysdeps/linux-gnu/x86/trace.c @@ -0,0 +1,191 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2010,2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2004,2008,2009 Juan Cespedes + * Copyright (C) 2006 Ian Wienand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "config.h" + +#include <sys/reg.h> +#include <sys/wait.h> +#include <assert.h> +#include <errno.h> +#include <stdlib.h> + +#include "backend.h" +#include "debug.h" +#include "proc.h" +#include "ptrace.h" +#include "type.h" + +#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) +# define PTRACE_PEEKUSER PTRACE_PEEKUSR +#endif + +#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) +# define PTRACE_POKEUSER PTRACE_POKEUSR +#endif + +#ifdef __x86_64__ +# define ORIG_XAX (8 * ORIG_RAX) +#else +# define ORIG_XAX (4 * ORIG_EAX) +#endif + +#ifdef __x86_64__ +static const int x86_64 = 1; +#else +static const int x86_64 = 0; +#endif + +void +get_arch_dep(struct Process *proc) +{ + /* Unfortunately there are still remnants of mask_32bit uses + * around. */ + + if (proc->e_machine == EM_X86_64) { + proc->mask_32bit = 0; + proc->personality = 1; + } else if (x86_64) { /* x86_64/i386 */ + proc->mask_32bit = 1; + proc->personality = 0; + } else { + proc->mask_32bit = 0; + proc->personality = 0; + } +} + +/* Returns 1 if syscall, 2 if sysret, 0 otherwise. + */ +int +syscall_p(struct Process *proc, int status, int *sysnum) +{ + if (WIFSTOPPED(status) + && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { + struct callstack_element *elem = NULL; + if (proc->callstack_depth > 0) + elem = proc->callstack + proc->callstack_depth - 1; + + long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, ORIG_XAX, 0); + if (ret == -1) { + if (errno) + return -1; + /* Otherwise, ORIG_RAX == -1 means that the + * system call should not be restarted. In + * that case rely on what we have on + * stack. */ + if (elem != NULL && elem->is_syscall) + ret = elem->c_un.syscall; + } + + *sysnum = ret; + debug(DEBUG_FUNCTION, "sysnum=%ld %p %d", ret, + get_instruction_pointer(proc), errno); + if (elem != NULL && elem->is_syscall + && elem->c_un.syscall == *sysnum) + return 2; + + if (*sysnum >= 0) + return 1; + } + return 0; +} + +size_t +arch_type_sizeof(struct Process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + case ARGTYPE_VOID: + return 0; + + case ARGTYPE_CHAR: + return 1; + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 2; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + return 4; + + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return proc->e_machine == EM_X86_64 ? 8 : 4; + + case ARGTYPE_FLOAT: + return 4; + case ARGTYPE_DOUBLE: + return 8; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; + + default: + assert(info->type != info->type); + abort(); + } +} + +size_t +arch_type_alignof(struct Process *proc, struct arg_type_info *info) +{ + if (proc == NULL) + return (size_t)-2; + + switch (info->type) { + default: + assert(info->type != info->type); + abort(); + break; + + case ARGTYPE_CHAR: + return 1; + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 2; + + case ARGTYPE_INT: + case ARGTYPE_UINT: + return 4; + + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_POINTER: + return proc->e_machine == EM_X86_64 ? 8 : 4; + + case ARGTYPE_FLOAT: + return 4; + case ARGTYPE_DOUBLE: + return proc->e_machine == EM_X86_64 ? 8 : 4; + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + /* Use default value. */ + return (size_t)-2; + } +} diff --git a/sysdeps/linux-gnu/x86_64/Makefile b/sysdeps/linux-gnu/x86_64/Makefile deleted file mode 100644 index 0a19c97..0000000 --- a/sysdeps/linux-gnu/x86_64/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -OBJ = trace.o regs.o plt.o - -all: arch.o - -arch.o: $(OBJ) - $(CC) -nostdlib -r -o arch.o $(OBJ) - -clean: - $(RM) $(OBJ) arch.o diff --git a/sysdeps/linux-gnu/x86_64/arch.h b/sysdeps/linux-gnu/x86_64/arch.h deleted file mode 100644 index 255395c..0000000 --- a/sysdeps/linux-gnu/x86_64/arch.h +++ /dev/null @@ -1,12 +0,0 @@ -#define BREAKPOINT_VALUE {0xcc} -#define BREAKPOINT_LENGTH 1 -#define DECR_PC_AFTER_BREAK 1 - -#define LT_ELFCLASS ELFCLASS64 -#define LT_ELF_MACHINE EM_X86_64 -#define LT_ELFCLASS2 ELFCLASS32 -#define LT_ELF_MACHINE2 EM_386 - -/* __NR_fork, __NR_clone, __NR_clone2, __NR_vfork and __NR_execve - from asm-i386/unistd.h. */ -#define FORK_EXEC_SYSCALLS , { 2, 120, -1, 190, 11 } diff --git a/sysdeps/linux-gnu/x86_64/ffcheck.c b/sysdeps/linux-gnu/x86_64/ffcheck.c deleted file mode 100644 index e69de29..0000000 --- a/sysdeps/linux-gnu/x86_64/ffcheck.c +++ /dev/null diff --git a/sysdeps/linux-gnu/x86_64/plt.c b/sysdeps/linux-gnu/x86_64/plt.c deleted file mode 100644 index b53ff44..0000000 --- a/sysdeps/linux-gnu/x86_64/plt.c +++ /dev/null @@ -1,12 +0,0 @@ -#include <gelf.h> -#include "common.h" - -GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - return lte->plt_addr + (ndx + 1) * 16; -} - -void * -sym2addr(Process *proc, struct library_symbol *sym) { - return sym->enter_addr; -} diff --git a/sysdeps/linux-gnu/x86_64/ptrace.h b/sysdeps/linux-gnu/x86_64/ptrace.h deleted file mode 100644 index c3cbcb6..0000000 --- a/sysdeps/linux-gnu/x86_64/ptrace.h +++ /dev/null @@ -1 +0,0 @@ -#include <sys/ptrace.h> diff --git a/sysdeps/linux-gnu/x86_64/regs.c b/sysdeps/linux-gnu/x86_64/regs.c deleted file mode 100644 index ed1f118..0000000 --- a/sysdeps/linux-gnu/x86_64/regs.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "config.h" - -#include <sys/types.h> -#include <sys/ptrace.h> -#include <sys/reg.h> - -#include "common.h" - -#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) -# define PTRACE_PEEKUSER PTRACE_PEEKUSR -#endif - -#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) -# define PTRACE_POKEUSER PTRACE_POKEUSR -#endif - -void * -get_instruction_pointer(Process *proc) { - long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RIP, 0); - if (proc->mask_32bit) - ret &= 0xffffffff; - return (void *)ret; -} - -void -set_instruction_pointer(Process *proc, void *addr) { - if (proc->mask_32bit) - addr = (void *)((long int)addr & 0xffffffff); - ptrace(PTRACE_POKEUSER, proc->pid, 8 * RIP, addr); -} - -void * -get_stack_pointer(Process *proc) { - long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSP, 0); - if (proc->mask_32bit) - ret &= 0xffffffff; - return (void *)ret; -} - -void * -get_return_addr(Process *proc, void *stack_pointer) { - unsigned long int ret; - ret = ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0); - if (proc->mask_32bit) - ret &= 0xffffffff; - return (void *)ret; -} - -void -set_return_addr(Process *proc, void *addr) { - if (proc->mask_32bit) - addr = (void *)((long int)addr & 0xffffffff); - ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr); -} diff --git a/sysdeps/linux-gnu/x86_64/signalent1.h b/sysdeps/linux-gnu/x86_64/signalent1.h deleted file mode 100644 index 5ead946..0000000 --- a/sysdeps/linux-gnu/x86_64/signalent1.h +++ /dev/null @@ -1 +0,0 @@ -#include "i386/signalent.h" diff --git a/sysdeps/linux-gnu/x86_64/syscallent.h b/sysdeps/linux-gnu/x86_64/syscallent.h deleted file mode 100644 index 5e5f88a..0000000 --- a/sysdeps/linux-gnu/x86_64/syscallent.h +++ /dev/null @@ -1,256 +0,0 @@ -"read", /* 0 */ - "write", /* 1 */ - "open", /* 2 */ - "close", /* 3 */ - "stat", /* 4 */ - "fstat", /* 5 */ - "lstat", /* 6 */ - "poll", /* 7 */ - "lseek", /* 8 */ - "mmap", /* 9 */ - "mprotect", /* 10 */ - "munmap", /* 11 */ - "brk", /* 12 */ - "rt_sigaction", /* 13 */ - "rt_sigprocmask", /* 14 */ - "rt_sigreturn", /* 15 */ - "ioctl", /* 16 */ - "pread", /* 17 */ - "pwrite", /* 18 */ - "readv", /* 19 */ - "writev", /* 20 */ - "access", /* 21 */ - "pipe", /* 22 */ - "select", /* 23 */ - "sched_yield", /* 24 */ - "mremap", /* 25 */ - "msync", /* 26 */ - "mincore", /* 27 */ - "madvise", /* 28 */ - "shmget", /* 29 */ - "shmat", /* 30 */ - "shmctl", /* 31 */ - "dup", /* 32 */ - "dup2", /* 33 */ - "pause", /* 34 */ - "nanosleep", /* 35 */ - "getitimer", /* 36 */ - "alarm", /* 37 */ - "setitimer", /* 38 */ - "getpid", /* 39 */ - "sendfile", /* 40 */ - "socket", /* 41 */ - "connect", /* 42 */ - "accept", /* 43 */ - "sendto", /* 44 */ - "recvfrom", /* 45 */ - "sendmsg", /* 46 */ - "recvmsg", /* 47 */ - "shutdown", /* 48 */ - "bind", /* 49 */ - "listen", /* 50 */ - "getsockname", /* 51 */ - "getpeername", /* 52 */ - "socketpair", /* 53 */ - "setsockopt", /* 54 */ - "getsockopt", /* 55 */ - "clone", /* 56 */ - "fork", /* 57 */ - "vfork", /* 58 */ - "execve", /* 59 */ - "exit", /* 60 */ - "wait4", /* 61 */ - "kill", /* 62 */ - "uname", /* 63 */ - "semget", /* 64 */ - "semop", /* 65 */ - "semctl", /* 66 */ - "shmdt", /* 67 */ - "msgget", /* 68 */ - "msgsnd", /* 69 */ - "msgrcv", /* 70 */ - "msgctl", /* 71 */ - "fcntl", /* 72 */ - "flock", /* 73 */ - "fsync", /* 74 */ - "fdatasync", /* 75 */ - "truncate", /* 76 */ - "ftruncate", /* 77 */ - "getdents", /* 78 */ - "getcwd", /* 79 */ - "chdir", /* 80 */ - "fchdir", /* 81 */ - "rename", /* 82 */ - "mkdir", /* 83 */ - "rmdir", /* 84 */ - "creat", /* 85 */ - "link", /* 86 */ - "unlink", /* 87 */ - "symlink", /* 88 */ - "readlink", /* 89 */ - "chmod", /* 90 */ - "fchmod", /* 91 */ - "chown", /* 92 */ - "fchown", /* 93 */ - "lchown", /* 94 */ - "umask", /* 95 */ - "gettimeofday", /* 96 */ - "getrlimit", /* 97 */ - "getrusage", /* 98 */ - "sysinfo", /* 99 */ - "times", /* 100 */ - "ptrace", /* 101 */ - "getuid", /* 102 */ - "syslog", /* 103 */ - "getgid", /* 104 */ - "setuid", /* 105 */ - "setgid", /* 106 */ - "geteuid", /* 107 */ - "getegid", /* 108 */ - "setpgid", /* 109 */ - "getppid", /* 110 */ - "getpgrp", /* 111 */ - "setsid", /* 112 */ - "setreuid", /* 113 */ - "setregid", /* 114 */ - "getgroups", /* 115 */ - "setgroups", /* 116 */ - "setresuid", /* 117 */ - "getresuid", /* 118 */ - "setresgid", /* 119 */ - "getresgid", /* 120 */ - "getpgid", /* 121 */ - "setfsuid", /* 122 */ - "setfsgid", /* 123 */ - "getsid", /* 124 */ - "capget", /* 125 */ - "capset", /* 126 */ - "rt_sigpending", /* 127 */ - "rt_sigtimedwait", /* 128 */ - "rt_sigqueueinfo", /* 129 */ - "rt_sigsuspend", /* 130 */ - "sigaltstack", /* 131 */ - "utime", /* 132 */ - "mknod", /* 133 */ - "uselib", /* 134 */ - "personality", /* 135 */ - "ustat", /* 136 */ - "statfs", /* 137 */ - "fstatfs", /* 138 */ - "sysfs", /* 139 */ - "getpriority", /* 140 */ - "setpriority", /* 141 */ - "sched_setparam", /* 142 */ - "sched_getparam", /* 143 */ - "sched_setscheduler", /* 144 */ - "sched_getscheduler", /* 145 */ - "sched_get_priority_max", /* 146 */ - "sched_get_priority_min", /* 147 */ - "sched_rr_get_interval", /* 148 */ - "mlock", /* 149 */ - "munlock", /* 150 */ - "mlockall", /* 151 */ - "munlockall", /* 152 */ - "vhangup", /* 153 */ - "modify_ldt", /* 154 */ - "pivot_root", /* 155 */ - "_sysctl", /* 156 */ - "prctl", /* 157 */ - "arch_prctl", /* 158 */ - "adjtimex", /* 159 */ - "setrlimit", /* 160 */ - "chroot", /* 161 */ - "sync", /* 162 */ - "acct", /* 163 */ - "settimeofday", /* 164 */ - "mount", /* 165 */ - "umount2", /* 166 */ - "swapon", /* 167 */ - "swapoff", /* 168 */ - "reboot", /* 169 */ - "sethostname", /* 170 */ - "setdomainname", /* 171 */ - "iopl", /* 172 */ - "ioperm", /* 173 */ - "create_module", /* 174 */ - "init_module", /* 175 */ - "delete_module", /* 176 */ - "get_kernel_syms", /* 177 */ - "query_module", /* 178 */ - "quotactl", /* 179 */ - "nfsservctl", /* 180 */ - "getpmsg", /* 181 */ - "putpmsg", /* 182 */ - "afs_syscall", /* 183 */ - "tuxcall", /* 184 */ - "security", /* 185 */ - "gettid", /* 186 */ - "readahead", /* 187 */ - "setxattr", /* 188 */ - "lsetxattr", /* 189 */ - "fsetxattr", /* 190 */ - "getxattr", /* 191 */ - "lgetxattr", /* 192 */ - "fgetxattr", /* 193 */ - "listxattr", /* 194 */ - "llistxattr", /* 195 */ - "flistxattr", /* 196 */ - "removexattr", /* 197 */ - "lremovexattr", /* 198 */ - "fremovexattr", /* 199 */ - "tkill", /* 200 */ - "time", /* 201 */ - "futex", /* 202 */ - "sched_setaffinity", /* 203 */ - "sched_getaffinity", /* 204 */ - "set_thread_area", /* 205 */ - "io_setup", /* 206 */ - "io_destroy", /* 207 */ - "io_getevents", /* 208 */ - "io_submit", /* 209 */ - "io_cancel", /* 210 */ - "get_thread_area", /* 211 */ - "lookup_dcookie", /* 212 */ - "epoll_create", /* 213 */ - "epoll_ctl", /* 214 */ - "epoll_wait", /* 215 */ - "remap_file_pages", /* 216 */ - "getdents64", /* 217 */ - "set_tid_address", /* 218 */ - "restart_syscall", /* 219 */ - "semtimedop", /* 220 */ - "fadvise64", /* 221 */ - "timer_create", /* 222 */ - "timer_settime", /* 223 */ - "timer_gettime", /* 224 */ - "timer_getoverrun", /* 225 */ - "timer_delete", /* 226 */ - "clock_settime", /* 227 */ - "clock_gettime", /* 228 */ - "clock_getres", /* 229 */ - "clock_nanosleep", /* 230 */ - "exit_group", /* 231 */ - "epoll_wait", /* 232 */ - "epoll_ctl", /* 233 */ - "tgkill", /* 234 */ - "utimes", /* 235 */ - "vserver", /* 236 */ - "mbind", /* 237 */ - "set_mempolicy", /* 238 */ - "get_mempolicy", /* 239 */ - "mq_open", /* 240 */ - "mq_unlink", /* 241 */ - "mq_timedsend", /* 242 */ - "mq_timedreceive", /* 243 */ - "mq_notify", /* 244 */ - "mq_getsetattr", /* 245 */ - "kexec_load", /* 246 */ - "waitid", /* 247 */ - "add_key", /* 248 */ - "request_key", /* 249 */ - "keyctl", /* 250 */ - "ioprio_set", /* 251 */ - "ioprio_get", /* 252 */ - "inotify_init", /* 253 */ - "inotify_add_watch", /* 254 */ - "inotify_rm_watch", /* 255 */ diff --git a/sysdeps/linux-gnu/x86_64/syscallent1.h b/sysdeps/linux-gnu/x86_64/syscallent1.h deleted file mode 100644 index d8dd9f7..0000000 --- a/sysdeps/linux-gnu/x86_64/syscallent1.h +++ /dev/null @@ -1 +0,0 @@ -#include "i386/syscallent.h" diff --git a/sysdeps/linux-gnu/x86_64/trace.c b/sysdeps/linux-gnu/x86_64/trace.c deleted file mode 100644 index 189734d..0000000 --- a/sysdeps/linux-gnu/x86_64/trace.c +++ /dev/null @@ -1,144 +0,0 @@ -#include "config.h" - -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <stdlib.h> -#include <sys/ptrace.h> -#include <sys/reg.h> - -#include "common.h" - -#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) -# define PTRACE_PEEKUSER PTRACE_PEEKUSR -#endif - -#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) -# define PTRACE_POKEUSER PTRACE_POKEUSR -#endif - -void -get_arch_dep(Process *proc) { - unsigned long cs; - if (proc->arch_ptr) - return; - cs = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * CS, 0); - if (cs == 0x23) { - proc->mask_32bit = 1; - proc->personality = 1; - } - proc->arch_ptr = (void *)1; -} - -/* Returns 1 if syscall, 2 if sysret, 0 otherwise. - */ -int -syscall_p(Process *proc, int status, int *sysnum) { - if (WIFSTOPPED(status) - && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { - *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * ORIG_RAX, 0); - - if (proc->callstack_depth > 0 && - proc->callstack[proc->callstack_depth - 1].is_syscall && - proc->callstack[proc->callstack_depth - 1].c_un.syscall == *sysnum) { - return 2; - } - - if (*sysnum >= 0) { - return 1; - } - } - return 0; -} - -static unsigned int -gimme_arg32(enum tof type, Process *proc, int arg_num) { - if (arg_num == -1) { /* return value */ - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RAX, 0); - } - - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - return ptrace(PTRACE_PEEKTEXT, proc->pid, - proc->stack_pointer + 4 * (arg_num + 1), 0); - } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { - switch (arg_num) { - case 0: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RBX, 0); - case 1: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RCX, 0); - case 2: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0); - case 3: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0); - case 4: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0); - case 5: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RBP, 0); - default: - fprintf(stderr, - "gimme_arg32 called with wrong arguments\n"); - exit(2); - } - } - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); -} - -long -gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) { - if (proc->mask_32bit) - return (unsigned int)gimme_arg32(type, proc, arg_num); - - if (arg_num == -1) { /* return value */ - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RAX, 0); - } - - if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { - switch (arg_num) { - case 0: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0); - case 1: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0); - case 2: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0); - case 3: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RCX, 0); - case 4: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R8, 0); - case 5: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R9, 0); - default: - return ptrace(PTRACE_PEEKTEXT, proc->pid, - proc->stack_pointer + 8 * (arg_num - 6 + - 1), 0); - } - } else if (type == LT_TOF_SYSCALL || LT_TOF_SYSCALLR) { - switch (arg_num) { - case 0: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0); - case 1: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0); - case 2: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0); - case 3: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R10, 0); - case 4: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R8, 0); - case 5: - return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R9, 0); - default: - fprintf(stderr, - "gimme_arg called with wrong arguments\n"); - exit(2); - } - } else { - fprintf(stderr, "gimme_arg called with wrong arguments\n"); - exit(1); - } - - return 0; -} - -void -save_register_args(enum tof type, Process *proc) { -} diff --git a/sysdeps/sysdep.h b/sysdeps/sysdep.h new file mode 100644 index 0000000..e8e287f --- /dev/null +++ b/sysdeps/sysdep.h @@ -0,0 +1,66 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LTRACE_SYSDEP_H +#define LTRACE_SYSDEP_H + +#include <arch.h> +#ifndef ARCH_HAVE_ADDRESS_TYPES +/* We should in general be able to trace 64-bit processes with 32-bit + * ltrace. (At least PPC has several PTRACE requests related to + * tracing 64-on-32, so presumably it should be possible.) But ltrace + * is currently hopelessly infested with using void* for host address. + * So keep with it, for now. */ +typedef void *arch_addr_t; +#endif + +#include <os.h> + +#ifndef ARCH_HAVE_LTELF_DATA +struct arch_ltelf_data { +}; +#endif + +#ifndef ARCH_HAVE_BREAKPOINT_DATA +struct arch_breakpoint_data { +}; +#endif + +#ifndef ARCH_HAVE_LIBRARY_SYMBOL_DATA +struct arch_library_symbol_data { +}; +#endif + +#ifndef ARCH_HAVE_LIBRARY_DATA +struct arch_library_data { +}; +#endif + +#ifndef OS_HAVE_PROCESS_DATA +struct os_process_data { +}; +#endif + +#ifndef ARCH_HAVE_PROCESS_DATA +struct arch_process_data { +}; +#endif + +#endif /* LTRACE_SYSDEP_H */ diff --git a/testsuite/Makefile b/testsuite/Makefile deleted file mode 100644 index b78807e..0000000 --- a/testsuite/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (C) 1992 - 2001 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 1, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -AUTOMAKE_OPTIONS = dejagnu -EXPECT = expect -RUNTEST = runtest -CC = @CC@ - -srcdir = . -RUNTESTDEFAULTFLAGS = --srcdir $(srcdir) - -CLEANFILES = *.log *.sum site.bak setval.tmp site.exp - -SUBDIRS = ltrace.main ltrace.minor ltrace.torture - -#all: all-recursive - -.SUFFIXES: - -check-DEJAGNU: site.exp - EXPECT=$(EXPECT); export EXPECT; - @$(RUNTEST) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); - -site.exp: - @echo 'Making a new site.exp file...' - @echo '## these variables are automatically generated by make ##' >site.tmp - @echo '# Do not edit here. If you wish to override these values' >>site.tmp - @echo '# edit the last section' >>site.tmp - @echo 'set srcdir $(srcdir)' >>site.tmp - @echo "set objdir `pwd`" >>site.tmp - @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp - @test ! -f site.exp || \ - sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp - @-rm -f site.bak - @test ! -f site.exp || mv site.exp site.bak - @mv site.tmp site.exp - -check: check-DEJAGNU - -clean: - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making clean in $$subdir"; \ - (cd $$subdir && $(MAKE) clean ) done; - - -rm -f $(CLEANFILES) - -distclean: - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making clean in $$subdir"; \ - (cd $$subdir && $(MAKE) distclean ) done; - -rm -f $(CLEANFILES) - -.PHONY: $(RECURSIVE_TARGETS) check clean distclean realclean - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/testsuite/ltrace.minor/Makefile b/testsuite/Makefile.am index cd4914f..f9b6c0d 100644 --- a/testsuite/ltrace.minor/Makefile +++ b/testsuite/Makefile.am @@ -15,22 +15,31 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -CLEANFILES = *.log *.sum site.bak setval.tmp site.exp +AUTOMAKE_OPTIONS = dejagnu -.SUFFIXES: -clean: - -rm -f demangle trace-fork trace-clone trace-exec trace-exec1 - -rm -f time-record-tt time-record-ttt time-record-T - -rm -f attach-process count-record - -rm -f print-instruction-pointer - -rm -f *.o *.so - -rm -f *.ltrace - -rm -f $(CLEANFILES) -distclean: clean +if USE_VALGRIND +valgrind_cmd="VALGRIND=valgrind -q --error-exitcode=1 --leak-check=full" +endif +RUNTESTDEFAULTFLAGS = --srcdir $(srcdir) $(valgrind_cmd) -.PHONY: $(RECURSIVE_TARGETS) check clean distclean realclean +SUBDIRS = ltrace.main ltrace.minor ltrace.torture -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: +EXTRA_DIST = \ + README \ + config/unix.exp \ + lib/compiler.c \ + lib/compiler.cc \ + lib/ltrace.exp \ + run-my-tests.sh + +BUILT_SOURCES = env.exp + +env.exp: Makefile + rm -f env.exp + echo set libelf_LD_LIBRARY_PATH '"$(libelf_LD_LIBRARY_PATH)"' >> $@ + echo set libunwind_LD_LIBRARY_PATH '"$(libunwind_LD_LIBRARY_PATH)"' >> $@ + +CLEANFILES = *.o *.so *.log *.sum *.ltrace site.bak setval.tmp site.exp env.exp + +MAINTAINERCLEANFILES = Makefile.in diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in new file mode 100644 index 0000000..1c0ae49 --- /dev/null +++ b/testsuite/Makefile.in @@ -0,0 +1,654 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 1992 - 2001 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = testsuite +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DEJATOOL = $(PACKAGE) +EXPECT = expect +RUNTEST = runtest +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = dejagnu +@USE_VALGRIND_TRUE@valgrind_cmd = "VALGRIND=valgrind -q --error-exitcode=1 --leak-check=full" +RUNTESTDEFAULTFLAGS = --srcdir $(srcdir) $(valgrind_cmd) +SUBDIRS = ltrace.main ltrace.minor ltrace.torture +EXTRA_DIST = \ + README \ + config/unix.exp \ + lib/compiler.c \ + lib/compiler.cc \ + lib/ltrace.exp \ + run-my-tests.sh + +BUILT_SOURCES = env.exp +CLEANFILES = *.o *.so *.log *.sum *.ltrace site.bak setval.tmp site.exp env.exp +MAINTAINERCLEANFILES = Makefile.in +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-DEJAGNU: site.exp + srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \ + EXPECT=$(EXPECT); export EXPECT; \ + runtest=$(RUNTEST); \ + if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \ + if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ + then :; else exit_status=1; fi; \ + done; \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi; \ + exit $$exit_status +site.exp: Makefile + @echo 'Making a new site.exp file...' + @echo '## these variables are automatically generated by make ##' >site.tmp + @echo '# Do not edit here. If you wish to override these values' >>site.tmp + @echo '# edit the last section' >>site.tmp + @echo 'set srcdir $(srcdir)' >>site.tmp + @echo "set objdir `pwd`" >>site.tmp + @echo 'set build_alias "$(build_alias)"' >>site.tmp + @echo 'set build_triplet $(build_triplet)' >>site.tmp + @echo 'set host_alias "$(host_alias)"' >>site.tmp + @echo 'set host_triplet $(host_triplet)' >>site.tmp + @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp + @test ! -f site.exp || \ + sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp + @-rm -f site.bak + @test ! -f site.exp || mv site.exp site.bak + @mv site.tmp site.exp + +distclean-DEJAGNU: + -rm -f site.exp site.bak + -l='$(DEJATOOL)'; for tool in $$l; do \ + rm -f $$tool.sum $$tool.log; \ + done + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-DEJAGNU distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + check-am ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-DEJAGNU check-am clean clean-generic \ + clean-libtool ctags ctags-recursive distclean \ + distclean-DEJAGNU distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am + + +env.exp: Makefile + rm -f env.exp + echo set libelf_LD_LIBRARY_PATH '"$(libelf_LD_LIBRARY_PATH)"' >> $@ + echo set libunwind_LD_LIBRARY_PATH '"$(libunwind_LD_LIBRARY_PATH)"' >> $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/testsuite/lib/ltrace.exp b/testsuite/lib/ltrace.exp index b56d50d..cbb5602 100644 --- a/testsuite/lib/ltrace.exp +++ b/testsuite/lib/ltrace.exp @@ -1,19 +1,42 @@ -# This file was written by Yao Qi. (qiyao@cn.ibm.com) +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# Copyright (C) 2006 Yao Qi, IBM Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA # Generic ltrace test subroutines that should work for any target. If these # need to be modified for any target, it can be done with a variable # or by passing arguments. +source $objdir/env.exp -global LTRACE if [info exists TOOL_EXECUTABLE] { set LTRACE $TOOL_EXECUTABLE } else { set LTRACE $objdir/../ltrace } -global LTRACE_OPTIONS -set LTRACE_OPTIONS ""; +if {[info exists VALGRIND] && ![string equal $VALGRIND {}]} { + verbose "Running under valgrind command: `$VALGRIND'" + set LTRACE "$VALGRIND $LTRACE" +} + +set LTRACE_OPTIONS {} +set LTRACE_ARGS {} +set LTRACE_TEMP_FILES {} # ltrace_compile SOURCE DEST TYPE OPTIONS # @@ -29,42 +52,50 @@ set LTRACE_OPTIONS ""; # OPTIONS is option to compiler in this compilation. proc ltrace_compile {source dest type options} { global LTRACE_TESTCASE_OPTIONS; - - # Add platform-specific options if a shared library was specified using - # "shlib=librarypath" in OPTIONS. - set new_options "" - set shlib_found 0 - - foreach opt $options { - if [regexp {^shlib=(.*)} $opt dummy_var shlib_name] { - if [test_compiler_info "xlc*"] { - # IBM xlc compiler doesn't accept shared library named other - # than .so: use "-Wl," to bypass this - lappend source "-Wl,$shlib_name" - } else { - lappend source $shlib_name - } - - if {$shlib_found == 0} { - set shlib_found 1 - - if { ([test_compiler_info "gcc-*"]&& ([istarget "powerpc*-*-aix*"]|| [istarget "rs6000*-*-aix*"] ))} { - lappend options "additional_flags=-L${objdir}/${subdir}" - } elseif { [istarget "mips-sgi-irix*"] } { - lappend options "additional_flags=-rpath ${objdir}/${subdir}" - } - } - - } else { - lappend new_options $opt - } - } - #end of for loop - set options $new_options + + if {![string equal "object" $type]} { + # Add platform-specific options if a shared library was specified using + # "shlib=librarypath" in OPTIONS. + set new_options "" + set shlib_found 0 + + foreach opt $options { + if [regexp {^shlib=(.*)} $opt dummy_var shlib_name] { + if [test_compiler_info "xlc*"] { + # IBM xlc compiler doesn't accept shared library named other + # than .so: use "-Wl," to bypass this + lappend source "-Wl,$shlib_name" + } else { + lappend source $shlib_name + } + + if {$shlib_found == 0} { + set shlib_found 1 + + if { ([test_compiler_info "gcc-*"]&& ([istarget "powerpc*-*-aix*"]|| [istarget "rs6000*-*-aix*"] ))} { + lappend options "additional_flags=-L${objdir}/${subdir}" + } elseif { [istarget "mips-sgi-irix*"] } { + lappend options "additional_flags=-rpath ${objdir}/${subdir}" + } + } + + } else { + lappend new_options $opt + } + } + + #end of for loop + set options $new_options + } + # dump some information for debug purpose. verbose "options are $options" verbose "source is $source $dest $type $options" - + + # Wipe the DEST file, so that we don't end up running an obsolete + # version of the binary. + exec rm -f $dest + set result [target_compile $source $dest $type $options]; verbose "result is $result" regsub "\[\r\n\]*$" "$result" "" result; @@ -128,11 +159,11 @@ proc get_compiler_info {binfile args} { proc test_compiler_info { {compiler ""} } { global compiler_info - verbose "compiler_info=$compiler_info" - # if no arg, return the compiler_info string if [string match "" $compiler] { if [info exists compiler_info] { + verbose "compiler_info=$compiler_info" + # if no arg, return the compiler_info string return $compiler_info } else { perror "No compiler info found." @@ -163,15 +194,9 @@ proc ltrace_compile_shlib {sources dest options} { fail "Bad compiler!" } } - - set outdir [file dirname $dest] - set objects "" - foreach source $sources { - set sourcebase [file tail $source] - if {[ltrace_compile $source "${outdir}/${sourcebase}.o" object $obj_options] != ""} { - return -1 - } - lappend objects ${outdir}/${sourcebase}.o + + if {![LtraceCompileObjects $sources $obj_options objects]} { + return -1 } set link_options $options @@ -183,6 +208,416 @@ proc ltrace_compile_shlib {sources dest options} { if {[ltrace_compile "${objects}" "${dest}" executable $link_options] != ""} { return -1 } + + return +} + +# WipeFiles -- +# +# Delete each file in the list. +# +# Arguments: +# files List of files to delete. +# Results: +# Each of the files is deleted. Returns nothing. + +proc WipeFiles {files} { + verbose "WipeFiles: $files\n" + foreach f $files { + file delete $f + } +} + +# LtraceTmpDir -- +# +# Guess what directory to use for temporary files. +# This was adapted from http://wiki.tcl.tk/772 +# +# Results: +# A temporary directory to use. The current directory if no +# other seems to be available. + +proc LtraceTmpDir {} { + set tmpdir [pwd] + + if {[file exists "/tmp"]} { + set tmpdir "/tmp" + } + + catch {set tmpdir $::env(TMP)} + catch {set tmpdir $::env(TEMP)} + catch {set tmpdir $::env(TMPDIR)} + + return $tmpdir +} + +set LTRACE_TEMP_DIR [LtraceTmpDir] + +# LtraceTempFile -- +# +# Create a temporary file according to a pattern, and return its +# name. This behaves similar to mktemp. We don't use mktemp +# directly, because on older systems, mktemp requires that the +# array of X's be at the very end of the string, while ltrace +# temporary files need to have suffixes. +# +# Arguments: +# pat Pattern to use. See mktemp for description of its format. +# +# Results: +# Creates the temporary file and returns its name. The name is +# also appended to LTRACE_TEMP_FILES. + +proc LtraceTempFile {pat} { + global LTRACE_TEMP_FILES + global LTRACE_TEMP_DIR + + set letters "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + set numLetters [string length $letters] + + if {![regexp -indices {(X{3,})} $pat m]} { + send_error -- "Pattern $pat contains insufficient number of X's." + return {} + } + + set start [lindex $m 0] + set end [lindex $m 1] + set len [expr {$end - $start + 1}] + + for {set j 0} {$j < 10} {incr j} { + + # First, generate a random name. + + set randstr {} + for {set i 0} {$i < $len} {incr i} { + set r [expr {int(rand() * $numLetters)}] + append randstr [string index $letters $r] + } + set prefix [string range $pat 0 [expr {$start - 1}]] + set suffix [string range $pat [expr {$end + 1}] end] + set name [file join $LTRACE_TEMP_DIR "$prefix$randstr$suffix"] + + # Now check that it's free. This is of course racy, but this + # is a test suite, not anything used in actual production. + + if {[file exists $name]} { + continue + } + + # We don't bother attempting to open the file. Downstream + # code can do it itself. + + lappend LTRACE_TEMP_FILES $name + return $name + } + + send_error -- "Couldn't create a temporary file for pattern $pat." + return +} + +# ltraceSource -- +# +# Create a temporary file with a given suffix and prime it with +# contents given in text. +# +# Arguments: +# suffix Suffix of the temp file to be created. +# +# text Contents of the new file. +# +# Results: +# Returns file name of created file. + +proc ltraceSource {suffix text} { + set ret [LtraceTempFile "lt-XXXXXXXXXX.$suffix"] + + set chan [open $ret w] + puts $chan $text + close $chan + + return $ret +} + +# LtraceCompileObjects -- +# +# Compile each source file into an object file. ltrace_compile +# is called to perform actual compilation. +# +# Arguments: +# sources List of source files. +# +# options Options for ltrace_compile. +# +# retName Variable where the resulting list of object names is +# to be placed. +# Results: +# Returns true or false depending on whether there were any +# errors. If it returns true, then variable referenced by +# retName contains list of object files, produced by compiling +# files in sources list. + +proc LtraceCompileObjects {sources options retName} { + global LTRACE_TEMP_FILES + upvar $retName ret + set ret {} + + foreach source $sources { + set sourcebase [file tail $source] + set dest $source.o + lappend LTRACE_TEMP_FILES $dest + verbose "LtraceCompileObjects: $source -> $dest" + if {[ltrace_compile $source $dest object $options] != ""} { + return false + } + lappend ret $dest + } + + return true +} + +# ltraceCompile -- +# +# This attempts to compile a binary from sources given in ARGS. +# +# Arguments: +# dest A binary to be produced. If this is called lib*.so, then +# the resulting binary will be a library, if *.pie, it +# will be a PIE, otherwise it will be an executable. In +# theory this could also be *.o for "object" and *.i for +# "preprocess" for cases with one source file, but that +# is not supported at the moment. The binary will be +# placed in $objdir/$subdir. +# +# args List of options and source files. +# +# Options are arguments that start with a dash. Options +# (sans the dash) are passed to ltrace_compile. +# +# Source files named lib*.so are libraries. Those are +# passed to ltrace_compile as options shlib=X. Source +# files named *.o are objects. The remaining source +# files are first compiled (by LtraceCompileObjects) and +# then together with other objects passed to +# ltrace_compile to produce resulting binary. +# +# Any argument that is empty string prompts the function +# to fail. This is done so that errors caused by +# ltraceSource (or similar) distribute naturally +# upwards. +# +# Results: +# This compiles given source files into a binary. Full file name +# of that binary is returned. Empty string is returned in case +# of a failure. + +proc ltraceCompile {dest args} { + global objdir + global subdir + + get_compiler_info {} c + get_compiler_info {} c++ + + if {[string match "lib*.so" $dest]} { + set type "library" + set extraObjOptions "additional_flags=-fpic" + set extraOptions "additional_flags=-shared" + } elseif {[string match "*.pie" $dest]} { + set type "executable" + set extraObjOptions "additional_flags=-fpic" + set extraOptions "additional_flags=-pie" + } else { + set type "executable" + set extraObjOptions {} + set extraOptions {} + } + + set options {} + set sources {} + set objects {} + foreach a $args { + if {[string match "-?*" $a]} { + lappend options [string range $a 1 end] + } elseif {[string match "*.so" $a]} { + lappend options "shlib=$a" + } elseif {[string match "*.o" $a]} { + lappend objects $a + } else { + lappend sources $a + } + } + + if {[string equal $dest {}]} { + set dest [LtraceTempFile "exe-XXXXXXXXXX"] + } elseif {[string equal $dest ".pie"]} { + set dest [LtraceTempFile "pie-XXXXXXXXXX"] + } else { + set dest $objdir/$subdir/$dest + } + + verbose "ltraceCompile: dest $dest" + verbose " : options $options" + verbose " : sources $sources" + verbose " : objects $objects" + + if {![LtraceCompileObjects $sources \ + [concat $options $extraObjOptions] newObjects]} { + return {} + } + set objects [concat $objects $newObjects] + + verbose "ltraceCompile: objects $objects" + + if {[ltrace_compile $objects $dest $type \ + [concat $options $extraOptions]] != ""} { + return {} + } + + return $dest +} + +# ltraceRun -- +# +# Invoke command identified by LTRACE global variable with given +# ARGS. A logfile redirection is automatically ordered by +# passing -o and a temporary file name. +# +# Arguments: +# args Arguments to ltrace binary. +# +# Results: +# Returns name of logfile. The "exec" command that it uses +# under the hood fails loudly if the process exits with a +# non-zero exit status, or uses stderr in any way. + +proc ltraceRun {args} { + global LTRACE + global objdir + global subdir + + set LdPath [ld_library_path $objdir/$subdir] + set logfile [ltraceSource ltrace {}] + + # Run ltrace. expect will show an error if this doesn't exit with + # zero exit status (i.e. ltrace fails, valgrind finds errors, + # etc.). + + set command "exec env LD_LIBRARY_PATH=$LdPath $LTRACE -o $logfile $args" + verbose $command + if {[catch {eval $command}] } { + fail "test case execution failed" + send_error -- $command + send_error -- $::errorInfo + } + + return $logfile +} + +# ltraceDone -- +# +# Wipes or dumps all temporary files after a test suite has +# finished. +# +# Results: +# Doesn't return anything. Wipes all files gathered in +# LTRACE_TEMP_FILES. If SAVE_TEMPS is defined and true, the +# temporary files are not wiped, but their names are dumped +# instead. Contents of LTRACE_TEMP_FILES are deleted in any +# case. + +proc ltraceDone {} { + global SAVE_TEMPS + global LTRACE_TEMP_FILES + + if {[info exists SAVE_TEMPS] && $SAVE_TEMPS} { + foreach tmp $LTRACE_TEMP_FILES { + send_user "$tmp\n" + } + } else { + WipeFiles $LTRACE_TEMP_FILES + } + + set LTRACE_TEMP_FILES {} + return +} + +# Grep -- +# +# Return number of lines in a given file, matching a given +# regular expression. +# +# Arguments: +# logfile File to search through. +# +# re Regular expression to match. +# +# Results: +# Returns number of matching lines. + +proc Grep {logfile re} { + set count 0 + set fp [open $logfile] + while {[gets $fp line] >= 0} { + if [regexp -- $re $line] { + incr count + } + } + close $fp + return $count +} + +# ltraceMatch1 -- +# +# Look for a pattern in a given logfile, comparing number of +# occurences of the pattern with expectation. +# +# Arguments: +# logfile The name of file where to look for patterns. +# +# pattern Regular expression pattern to look for. +# +# op Operator to compare number of occurences. +# +# expect Second operand to op, the first being number of +# occurences of pattern. +# +# Results: +# Doesn't return anything, but calls fail or pass depending on +# whether the patterns matches expectation. + +proc ltraceMatch1 {logfile pattern {op ==} {expect 1}} { + set count [Grep $logfile $pattern] + set msgMain "$pattern appears in $logfile $count times" + set msgExpect ", expected $op $expect" + + if {[eval expr $count $op $expect]} { + pass $msgMain + } else { + fail $msgMain$msgExpect + } + return +} + +# ltraceMatch -- +# +# Look for series of patterns in a given logfile, comparing +# number of occurences of each pattern with expectations. +# +# Arguments: +# logfile The name of file where to look for patterns. +# +# patterns List of patterns to look for. ltraceMatch1 is called +# on each of these in turn. +# +# Results: +# +# Doesn't return anything, but calls fail or pass depending on +# whether each of the patterns holds. + +proc ltraceMatch {logfile patterns} { + foreach pat $patterns { + eval ltraceMatch1 [linsert $pat 0 $logfile] + } + return } # @@ -196,6 +631,37 @@ proc ltrace_options { args } { } # +# ltrace_args ARGS_LIST +# Pass ltrace'd program its own commandline options. +# +proc ltrace_args { args } { + + global LTRACE_ARGS + set LTRACE_ARGS $args +} + +# +# handle run-time library paths +# +proc ld_library_path { args } { + + set ALL_LIBRARY_PATHS { } + if [info exists LD_LIBRARY_PATH] { + lappend ALL_LIBRARY_PATHS $LD_LIBRARY_PATH + } + global libelf_LD_LIBRARY_PATH + if {[string length $libelf_LD_LIBRARY_PATH] > 0} { + lappend ALL_LIBRARY_PATHS $libelf_LD_LIBRARY_PATH + } + global libunwind_LD_LIBRARY_PATH + if {[string length $libunwind_LD_LIBRARY_PATH] > 0} { + lappend ALL_LIBRARY_PATHS $libunwind_LD_LIBRARY_PATH + } + lappend ALL_LIBRARY_PATHS $args + join $ALL_LIBRARY_PATHS ":" +} + +# # ltrace_runtest LD_LIBRARY_PATH BIN FILE # Trace the execution of BIN and return result. # @@ -208,10 +674,11 @@ proc ltrace_runtest { args } { global LTRACE global LTRACE_OPTIONS + global LTRACE_ARGS verbose "LTRACE = $LTRACE" - set LD_LIBRARY_PATH_ [lindex $args 0] + set LD_LIBRARY_PATH_ [ld_library_path [lindex $args 0]] set BIN [lindex $args 1] # specify the output file, the default one is $BIN.ltrace @@ -220,35 +687,29 @@ proc ltrace_runtest { args } { } else { set file $BIN.ltrace } + + # Remove the file first. If ltrace fails to overwrite it, we + # would be comparing output to an obsolete run. + exec rm -f $file + # append this option to LTRACE_OPTIONS. lappend LTRACE_OPTIONS "-o" lappend LTRACE_OPTIONS "$file" verbose "LTRACE_OPTIONS = $LTRACE_OPTIONS" + set command "exec sh -c {export LD_LIBRARY_PATH=$LD_LIBRARY_PATH_; \ + $LTRACE $LTRACE_OPTIONS $BIN $LTRACE_ARGS;exit}" #ltrace the PUT. - catch "exec sh -c {export LD_LIBRARY_PATH=$LD_LIBRARY_PATH_; $LTRACE $LTRACE_OPTIONS $BIN;exit}" output - + if {[catch $command output]} { + fail "test case execution failed" + send_error -- $command + send_error -- $::errorInfo + } + # return output from ltrace. return $output } # -# ltrace_saveoutput OUTPUT FILE -# Save OUTPUT from ltrace to file FILE. -# OUTPUT is output from ltrace or return value of ltrace_runtest. -# FILE is file save output. -# -proc ltrace_saveoutput { args } { - - set output [lindex $args 0] - set file [lindex $args 1] - - set fd [open $file w] - puts $fd $output - close $fd -} - - -# # ltrace_verify_output FILE_TO_SEARCH PATTERN MAX_LINE # Verify the ltrace output by comparing the number of PATTERN in # FILE_TO_SEARCH with INSTANCE_NO. Do not specify INSTANCE_NO if @@ -257,10 +718,10 @@ proc ltrace_saveoutput { args } { # 0 = number of PATTERN in FILE_TO_SEARCH inqual to INSTANCE_NO. # 1 = number of PATTERN in FILE_TO_SEARCH qual to INSTANCE_NO. # -proc ltrace_verify_output { file_to_search pattern {instance_no 0}} { +proc ltrace_verify_output { file_to_search pattern {instance_no 0} {grep_command "grep"}} { # compute the number of PATTERN in FILE_TO_SEARCH by grep and wc. - catch "exec sh -c {grep \"$pattern\" $file_to_search | wc -l ;exit}" output + catch "exec sh -c {$grep_command \"$pattern\" $file_to_search | wc -l ;exit}" output verbose "output = $output" if [ regexp "syntax error" $output ] then { @@ -274,6 +735,6 @@ proc ltrace_verify_output { file_to_search pattern {instance_no 0}} { } elseif { $output >= $instance_no } then { pass "$pattern in $file_to_search for $output times" } else { - fail "$pattern in $file_to_search for $output times ,should be $instance_no" + fail "$pattern in $file_to_search for $output times, should be $instance_no" } } diff --git a/testsuite/ltrace.main/Makefile b/testsuite/ltrace.main/Makefile.am index 449214a..ade68d6 100644 --- a/testsuite/ltrace.main/Makefile +++ b/testsuite/ltrace.main/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 1992 - 2001 Free Software Foundation, Inc. +# Copyright (C) 1992 - 2001, 2012 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,19 +15,31 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -CLEANFILES = *.log *.sum site.bak setval.tmp site.exp +EXTRA_DIST = \ + branch_func.c \ + branch_func.exp \ + filters.exp \ + hello-vfork.c \ + hello-vfork.exp \ + main.c \ + main.exp \ + main-internal.exp \ + main-lib.c \ + main-threaded.c \ + main-threaded.exp \ + main-vfork.c \ + main-vfork.exp \ + parameters.c \ + parameters.conf \ + parameters.exp \ + parameters-lib.c \ + parameters2.exp \ + signals.c \ + signals.exp \ + system_calls.c \ + system_calls.exp -.SUFFIXES: -clean: - -rm -f main main-internal system_calls signals parameters - -rm -f *.o *.so - -rm -f *.ltrace - -rm -f $(CLEANFILES) -distclean: clean +CLEANFILES = *.o *.so *.log *.sum *.ltrace setval.tmp \ + main main-internal parameters signals system_calls - -.PHONY: $(RECURSIVE_TARGETS) check clean distclean realclean - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: +MAINTAINERCLEANFILES = Makefile.in diff --git a/testsuite/ltrace.main/Makefile.in b/testsuite/ltrace.main/Makefile.in new file mode 100644 index 0000000..6a490c8 --- /dev/null +++ b/testsuite/ltrace.main/Makefile.in @@ -0,0 +1,414 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 1992 - 2001, 2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = testsuite/ltrace.main +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + branch_func.c \ + branch_func.exp \ + filters.exp \ + hello-vfork.c \ + hello-vfork.exp \ + main.c \ + main.exp \ + main-internal.exp \ + main-lib.c \ + main-threaded.c \ + main-threaded.exp \ + main-vfork.c \ + main-vfork.exp \ + parameters.c \ + parameters.conf \ + parameters.exp \ + parameters-lib.c \ + parameters2.exp \ + signals.c \ + signals.exp \ + system_calls.c \ + system_calls.exp + +CLEANFILES = *.o *.so *.log *.sum *.ltrace setval.tmp \ + main main-internal parameters signals system_calls + +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/ltrace.main/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/ltrace.main/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/testsuite/ltrace.main/branch_func.c b/testsuite/ltrace.main/branch_func.c new file mode 100644 index 0000000..0ce311d --- /dev/null +++ b/testsuite/ltrace.main/branch_func.c @@ -0,0 +1,51 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +/* This is specially made to produce tail calls. We then trace them + * and see if ltrace handles it well, or whether its internal stack + * overflows. */ + +__attribute__((noinline, optimize(3))) int +func3(int i) +{ + return i + 1; +} + +__attribute__((noinline, optimize(3))) int +func2(int i) +{ + return func3(i * 3); +} + +__attribute__((noinline, optimize(3))) int +func1(int i) +{ + return func2(i + 2); +} + +__attribute__((optimize(0))) int +main(int argc, char **argv) +{ + int counter = 0; + int i; + for (i = 0; i < 100; ++i) + counter += func1(i); + return counter; +} diff --git a/testsuite/ltrace.main/branch_func.exp b/testsuite/ltrace.main/branch_func.exp new file mode 100644 index 0000000..fec5700 --- /dev/null +++ b/testsuite/ltrace.main/branch_func.exp @@ -0,0 +1,57 @@ +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +set testfile "branch_func" +set srcfile ${testfile}.c +set binfile ${testfile} + +if [get_compiler_info $binfile] { + return -1 +} + +verbose "compiling source file now....." +if { [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable {debug} ] != "" } { + send_user "Testcase compile failed, so all tests in this file will automatically fail\n." +} + +# set options for ltrace. +ltrace_options "-x" "func1" "-x" "func2" "-x" "func3" + +# Run PUT for ltarce. +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] + +# Check the output of this program. +verbose "ltrace runtest output: $exec_output\n" +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +set pattern "func1(.*unfinished" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 100 +set pattern "func2(.*unfinished" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 100 +set pattern "func3(.*)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 100 +set pattern "func2.resumed" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 100 +set pattern "func1.resumed" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 100 diff --git a/testsuite/ltrace.main/filters.exp b/testsuite/ltrace.main/filters.exp new file mode 100644 index 0000000..988346f --- /dev/null +++ b/testsuite/ltrace.main/filters.exp @@ -0,0 +1,85 @@ +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +set libfilt1 [ltraceCompile libfilt1.so [ltraceSource c { + void func2(void); + void func1(void) { func2(); } +}]] + +set libfilt2 [ltraceCompile libfilt2.so [ltraceSource c { + void func2(void) { puts("func2"); } +}]] + +foreach ext {{} .pie} { + set filt [ltraceCompile filt$ext $libfilt1 $libfilt2 [ltraceSource c { + void func1(void); + int main(int argc, char *argv[]) { func1(); return 0; } + }]] + + ltraceMatch [ltraceRun -e* $filt] { + {{filt(\.pie)?->func1} == 1} + {{libfilt1.so->func2} == 1} + {{libfilt2.so->puts} == 1} + {{func2 resumed} == 1} + {{func1 resumed} == 1} + } + + ltraceMatch1 [ltraceRun $filt] \ + {^func1\(.*\)} == 1 + + ltraceMatch1 [ltraceRun -e@MAIN $filt] \ + {filt(\.pie)?->func1\(.*\)} == 1 + + ltraceMatch1 [ltraceRun -e@libfilt1.so $filt] \ + {libfilt1.so->func2\(.*\)} == 1 + + ltraceMatch1 [ltraceRun -e@libfilt2.so $filt] \ + {libfilt2.so->puts\(.*\)} == 1 + + ltraceMatch [ltraceRun -e@libfilt* $filt] { + {{libfilt1.so->func2\(} == 1} + {{libfilt2.so->puts\(.*\)} == 1} + {{func2 resumed} == 1} + } + + ltraceMatch [ltraceRun -efunc* $filt] { + {{filt(\.pie)?->func1\(} == 1} + {{libfilt1.so->func2\(.*\)} == 1} + {{func1 resumed} == 1} + } + + # Check that we handle breakpoint on both PLT entry and entry point + ltraceMatch [ltraceRun -efunc1 -xfunc1 $filt] { + {{filt(\.pie)?->func1\(} == 1} + {{func1@libfilt1.so\(.*\)} == 1} + {{func1 resumed} == 1} + } + + # Check that when given -l, we don't trace symbols from other + # libraries. + ltraceMatch1 [ltraceRun -llibfilt1.so -- $filt] \ + {filt(\.pie)?->func1\(.*\)} == 1 + + ltraceMatch [ltraceRun -llibfilt1.so -llibfilt2.so $filt] { + {{filt(\.pie)?->func1\(} == 1} + {{libfilt1.so->func2\(.*\)} == 1} + {{func1 resumed} == 1} + } +} + +ltraceDone diff --git a/testsuite/ltrace.main/hello-vfork.c b/testsuite/ltrace.main/hello-vfork.c new file mode 100644 index 0000000..81e426f --- /dev/null +++ b/testsuite/ltrace.main/hello-vfork.c @@ -0,0 +1,11 @@ +/* Copyright (C) 2008, Red Hat, Inc. + * Written by Denys Vlasenko */ +#include <stdio.h> +#include <unistd.h> + +int main() { + int r = vfork(); + fprintf(stdout, "vfork():%d\n", r); + _exit(0); +} + diff --git a/testsuite/ltrace.main/hello-vfork.exp b/testsuite/ltrace.main/hello-vfork.exp new file mode 100644 index 0000000..12c9ca3 --- /dev/null +++ b/testsuite/ltrace.main/hello-vfork.exp @@ -0,0 +1,35 @@ +# This file was written by Yao Qi <qiyao@cn.ibm.com>. + +set testfile "hello-vfork" +set srcfile ${testfile}.c +set binfile ${testfile} + + +if [get_compiler_info $binfile] { + return -1 +} + +verbose "compiling source file now....." +if { [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable debug ] != ""} { + send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +} + +# set options for ltrace. +ltrace_options "-f" + +# Run PUT for ltarce. +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] + +# Check the output of this program. +verbose "ltrace runtest output: $exec_output\n" +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +# Verify the output by checking numbers of print in main-vfork.ltrace. +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "_exit" 2 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "vfork resumed" 2 diff --git a/testsuite/ltrace.main/main-internal-1.c b/testsuite/ltrace.main/main-internal-1.c deleted file mode 100644 index 2a5cd0c..0000000 --- a/testsuite/ltrace.main/main-internal-1.c +++ /dev/null @@ -1,8 +0,0 @@ -#include<stdio.h> - -void -display ( char* s ) -{ - printf("%s\n",s); -} - diff --git a/testsuite/ltrace.main/main-internal.c b/testsuite/ltrace.main/main-internal.c deleted file mode 100644 index 7508d06..0000000 --- a/testsuite/ltrace.main/main-internal.c +++ /dev/null @@ -1,19 +0,0 @@ - /* Ltrace Test : main-internal.c. - Objectives : Verify that ltrace can trace call from main - executable within it. - This file was written by Yao Qi <qiyao@cn.ibm.com>. */ -#include<stdio.h> - -extern void display ( char* ); - -#define DISPLAY_LOOP 12 - -int -main () -{ - int i; - printf ("should not show up if '-X display' is used.\n"); - for (i=0; i< DISPLAY_LOOP; i++) - display ("Function call within executable."); -} - diff --git a/testsuite/ltrace.main/main-internal.exp b/testsuite/ltrace.main/main-internal.exp index f3f0015..0ca5e14 100644 --- a/testsuite/ltrace.main/main-internal.exp +++ b/testsuite/ltrace.main/main-internal.exp @@ -1,33 +1,35 @@ -# This file was written by Yao Qi <qiyao@cn.ibm.com>. +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA -set testfile "main-internal" -set srcfile ${testfile}.c -set binfile ${testfile} +set bin [ltraceCompile {} [ltraceSource c { + __attribute__((noinline)) void this(void) {} + __attribute__((noinline)) void that(void) {} + int main(int i) { + for (i = 0; i < 12; ++i) { + this(); + that(); + } + } +}]] -verbose "compiling source file now....." -# Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c ${srcdir}/${subdir}/${testfile}-1.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { - send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +ltraceMatch [ltraceRun -L -xthis -- $bin] { + {{this\(.*\)} == 12} + {that == 0} } -# set options for ltrace. -ltrace_options "-x" "display" - -# Run PUT for ltarce. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] - -# Check the output of this program. -verbose "ltrace runtest output: $exec_output\n" -if [regexp {ELF from incompatible architecture} $exec_output] { - fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" - return -} elseif [ regexp {Couldn't do static plt2addr} $exec_output ] { - fail "Couldn't do static plt2addr!" - return -} elseif [regexp {Couldn't get .hash data from} $exec_output ] { - fail "Couldn't get .hash data!" - return -} - -set pattern "display" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 12 +ltraceDone diff --git a/testsuite/ltrace.main/main-threaded.c b/testsuite/ltrace.main/main-threaded.c new file mode 100644 index 0000000..a183966 --- /dev/null +++ b/testsuite/ltrace.main/main-threaded.c @@ -0,0 +1,29 @@ +#include <pthread.h> + +extern void print (char *); + +#define PRINT_LOOP 10 + +void * +th_main (void *arg) +{ + int i; + for (i=0; i<PRINT_LOOP; i++) + print (arg); +} + +int +main () +{ + pthread_t thread1; + pthread_t thread2; + pthread_t thread3; + pthread_create (&thread1, NULL, th_main, "aaa"); + pthread_create (&thread2, NULL, th_main, "bbb"); + pthread_create (&thread3, NULL, th_main, "ccc"); + pthread_join (thread1, NULL); + pthread_join (thread2, NULL); + pthread_join (thread3, NULL); + return 0; +} + diff --git a/testsuite/ltrace.main/main-threaded.exp b/testsuite/ltrace.main/main-threaded.exp new file mode 100644 index 0000000..4f6c25d --- /dev/null +++ b/testsuite/ltrace.main/main-threaded.exp @@ -0,0 +1,39 @@ +# This file was written by Yao Qi <qiyao@cn.ibm.com>. + +set testfile "main-threaded" +set srcfile ${testfile}.c +set binfile ${testfile} +set libfile "main-lib" +set libsrc $srcdir/$subdir/$libfile.c +set lib_sl $objdir/$subdir/lib$testfile.so + + +if [get_compiler_info $binfile] { + return -1 +} + +verbose "compiling source file now....." +if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" + || [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable [list debug shlib=$lib_sl ldflags=-pthread] ] != ""} { + send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +} + +# set options for ltrace. +ltrace_options "-l" "lib$testfile.so" "-f" + +# Run PUT for ltarce. +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] + +# Check the output of this program. +verbose "ltrace runtest output: $exec_output\n" +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +# Verify the output by checking numbers of print in main-threaded.ltrace. +set pattern "print" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 30 diff --git a/testsuite/ltrace.main/main-vfork.c b/testsuite/ltrace.main/main-vfork.c new file mode 100644 index 0000000..a5f6c40 --- /dev/null +++ b/testsuite/ltrace.main/main-vfork.c @@ -0,0 +1,28 @@ +#include <unistd.h> + +extern void print (char *); + +#define PRINT_LOOP 10 + +void +th_main (char * arg) +{ + int i; + for (i=0; i<PRINT_LOOP; i++) + print (arg); +} + +int main (int argc, char ** argv) +{ + if (argc != 1) + { + th_main ("aaa"); + return 0; + } + + if (!vfork ()) + execlp (argv[0], argv[0], "", NULL); + th_main ("bbb"); + + return 0; +} diff --git a/testsuite/ltrace.main/main-vfork.exp b/testsuite/ltrace.main/main-vfork.exp new file mode 100644 index 0000000..989012d --- /dev/null +++ b/testsuite/ltrace.main/main-vfork.exp @@ -0,0 +1,39 @@ +# This file was written by Yao Qi <qiyao@cn.ibm.com>. + +set testfile "main-vfork" +set srcfile ${testfile}.c +set binfile ${testfile} +set libfile "main-lib" +set libsrc $srcdir/$subdir/$libfile.c +set lib_sl $objdir/$subdir/lib$testfile.so + + +if [get_compiler_info $binfile] { + return -1 +} + +verbose "compiling source file now....." +if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" + || [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable [list debug shlib=$lib_sl] ] != ""} { + send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +} + +# set options for ltrace. +ltrace_options "-l" "lib$testfile.so" "-f" "-evfork" + +# Run PUT for ltarce. +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] + +# Check the output of this program. +verbose "ltrace runtest output: $exec_output\n" +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +# Verify the output by checking numbers of print in main-vfork.ltrace. +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "print" 20 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "vfork resumed" 2 diff --git a/testsuite/ltrace.main/main.exp b/testsuite/ltrace.main/main.exp index ca66deb..50c5353 100644 --- a/testsuite/ltrace.main/main.exp +++ b/testsuite/ltrace.main/main.exp @@ -5,7 +5,7 @@ set srcfile ${testfile}.c set binfile ${testfile} set libfile "main-lib" set libsrc $srcdir/$subdir/$libfile.c -set lib_sl $srcdir/$subdir/lib$testfile.so +set lib_sl $objdir/$subdir/lib$testfile.so if [get_compiler_info $binfile] { @@ -14,15 +14,15 @@ if [get_compiler_info $binfile] { verbose "compiling source file now....." if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" - || [ltrace_compile $srcdir/$subdir/$srcfile $srcdir/$subdir/$binfile executable [list debug shlib=$lib_sl] ] != ""} { + || [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable [list debug shlib=$lib_sl] ] != ""} { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } # set options for ltrace. -ltrace_options "-l" "$srcdir/$subdir/libmain.so" +ltrace_options "-l" "libmain.so" # Run PUT for ltarce. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -36,4 +36,4 @@ if [regexp {ELF from incompatible architecture} $exec_output] { # Verify the output by checking numbers of print in main.ltrace. set pattern "print" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 10 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 10 diff --git a/testsuite/ltrace.main/parameters-lib.c b/testsuite/ltrace.main/parameters-lib.c index 26e4c3b..bf8cdfe 100644 --- a/testsuite/ltrace.main/parameters-lib.c +++ b/testsuite/ltrace.main/parameters-lib.c @@ -22,11 +22,22 @@ int func_strlen(char* p) return strlen(p); } +int func_arg0(char *p) +{ + strcpy(p, "Hello another world!"); + return strlen(p); +} + void func_strfixed(char* p) { strcpy(p, "Hello world"); } +void func_string(char* p) +{ + printf("%s\n", p); +} + void func_ppp(int*** ppp) { printf("%d\n", ***ppp); @@ -52,9 +63,16 @@ void func_ushort(unsigned short x1, unsigned short x2) printf("ushort: %hu %hu\n", x1, x2); } -void func_float(float f1, float f2) +float func_float(float f1, float f2) +{ + printf("%f %f\n", f1, f2); + return f1; +} + +double func_double(double f1, double f2) { printf("%f %f\n", f1, f2); + return f2; } void func_typedef(int x) @@ -115,3 +133,351 @@ void func_struct(struct test_struct* x) buf[x->slen] = '\0'; printf("%s\n", buf); } + +void func_work (char *x) +{ + *x = 'x'; +} + +void func_call (char *x, char* y, void (*cb) (char *)) +{ + cb (y); + *x = (*y)++; +} + +struct S2 { + float f; + char a; + char b; +}; + +struct S3 { + char a[6]; + float f; +}; + +struct S2 +func_struct_2(int i, struct S3 s3, double d) +{ + return (struct S2){ s3.f, s3.a[1], s3.a[2] }; +} + +struct S4 { + long a; + long b; + long c; + long d; +}; + +struct S4 +func_struct_large(struct S4 a, struct S4 b) +{ + return (struct S4){ a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d }; +} + +struct S5 { + char a; + char b; + long c; + long d; +}; + +struct S5 +func_struct_large2(struct S5 a, struct S5 b) +{ + return (struct S5){ a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d }; +} + +struct S6 { + long a; + long b; + char c; + char d; +}; + +struct S6 +func_struct_large3(struct S6 a, struct S6 b) +{ + return (struct S6){ a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d }; +} + +void +func_many_args(int a, int b, long c, double d, char e, int f, float g, char h, + int i, double j, int k, double l, char m, int n, short o, int p, + char q, float r, float s, double t, long u, float v, float w, + float x, float y) +{ +} + +void +func_lens(int a, long b, short c, long d) +{ +} + +int +func_bool(int a, int b) +{ + return !b; +} + +void +func_hide(int a, int b, int c, int d, int e, int f) +{ +} + +struct func_hide_struct { + int a; int b; int c; int d; int e; int f; int g; int h; +}; + +void +func_hide_struct(struct func_hide_struct s) +{ +} + +long * +func_short_enums(short values[]) +{ + static long retvals[4]; + retvals[0] = values[0]; + retvals[1] = values[1]; + retvals[2] = values[2]; + retvals[3] = values[3]; + return retvals; +} + +long +func_negative_enum(short a, unsigned short b, int c, unsigned d, + long e, unsigned long f) +{ + return -1; +} + +void +func_charp_string(char *p) +{ +} + +struct dbl_eqv1 { double d; }; +struct dbl_eqv2 { struct dbl_eqv1 d; }; +struct dbl_eqv3 { struct dbl_eqv2 d; }; +struct dbl_eqv4 { struct dbl_eqv3 d; }; + +struct flt_eqv1 { float d; }; +struct flt_eqv2 { struct flt_eqv1 d; }; +struct flt_eqv3 { struct flt_eqv2 d; }; +struct flt_eqv4 { struct flt_eqv3 d; }; + +struct dbl_eqv1 +func_dbl_eqv(struct dbl_eqv1 a, struct dbl_eqv2 b, + struct dbl_eqv3 c, struct dbl_eqv4 d) +{ + return (struct dbl_eqv1){ a.d + b.d.d + c.d.d.d + d.d.d.d.d }; +} + +struct flt_eqv1 +func_flt_eqv(struct flt_eqv1 a, struct flt_eqv2 b, + struct flt_eqv3 c, struct flt_eqv4 d) +{ + return (struct flt_eqv1){ a.d + b.d.d + c.d.d.d + d.d.d.d.d }; +} + +struct struct_empty {}; +struct struct_size1 { char a; }; +struct struct_size2 { short a; }; +struct struct_size4 { int a; }; +struct struct_size8 { int a; int b; }; + +struct struct_empty +func_struct_empty(struct struct_empty e) +{ + return e; +} + +struct struct_size1 +func_struct_size1(struct struct_size1 e) +{ + return e; +} + +struct struct_size2 +func_struct_size2(struct struct_size2 e) +{ + return e; +} + +struct struct_size4 +func_struct_size4(struct struct_size4 e) +{ + return e; +} + +struct struct_size8 +func_struct_size8(struct struct_size8 e) +{ + return e; +} + +struct struct_hfa_f2 { float a; struct flt_eqv1 b; }; +struct struct_hfa_f2 +func_hfa_f2(struct struct_hfa_f2 e) +{ + return e; +} + +struct struct_hfa_f3 { float a; struct struct_hfa_f2 b; }; +struct struct_hfa_f3 +func_hfa_f3(struct struct_hfa_f3 e) +{ + return e; +} + +struct struct_hfa_f4 { float a; struct struct_hfa_f3 b; }; +struct struct_hfa_f4 +func_hfa_f4(struct struct_hfa_f4 e) +{ + return e; +} + +struct struct_hfa_f5 { float a; struct struct_hfa_f4 b; }; +struct struct_hfa_f5 +func_hfa_f5(struct struct_hfa_f5 e) +{ + return e; +} + +struct struct_hfa_f6 { float a; struct struct_hfa_f5 b; }; +struct struct_hfa_f6 +func_hfa_f6(struct struct_hfa_f6 e) +{ + return e; +} + +struct struct_hfa_f7 { float a; struct struct_hfa_f6 b; }; +struct struct_hfa_f7 +func_hfa_f7(struct struct_hfa_f7 e) +{ + return e; +} + +struct struct_hfa_f8 { float a; struct struct_hfa_f7 b; }; +struct struct_hfa_f8 +func_hfa_f8(struct struct_hfa_f8 e) +{ + return e; +} + +struct struct_hfa_f9 { float a; struct struct_hfa_f8 b; }; +struct struct_hfa_f9 +func_hfa_f9(struct struct_hfa_f9 e) +{ + return e; +} + +struct struct_hfa_f10 { float a; struct struct_hfa_f9 b; }; +struct struct_hfa_f10 +func_hfa_f10(struct struct_hfa_f10 e) +{ + return e; +} + +struct struct_hfa_f11 { float a; struct struct_hfa_f10 b; }; +struct struct_hfa_f11 +func_hfa_f11(struct struct_hfa_f11 e) +{ + return e; +} + +struct struct_hfa_f12 { float a; struct struct_hfa_f11 b; }; +struct struct_hfa_f12 +func_hfa_f12(struct struct_hfa_f12 e) +{ + return e; +} + + +struct struct_hfa_d2 { double a; struct dbl_eqv1 b; }; +struct struct_hfa_d2 +func_hfa_d2(struct struct_hfa_d2 e) +{ + return e; +} + +struct struct_hfa_d3 { double a; struct struct_hfa_d2 b; }; +struct struct_hfa_d3 +func_hfa_d3(struct struct_hfa_d3 e) +{ + return e; +} + +struct struct_hfa_d4 { double a; struct struct_hfa_d3 b; }; +struct struct_hfa_d4 +func_hfa_d4(struct struct_hfa_d4 e) +{ + return e; +} + +struct struct_hfa_d5 { double a; struct struct_hfa_d4 b; }; +struct struct_hfa_d5 +func_hfa_d5(struct struct_hfa_d5 e) +{ + return e; +} + +struct struct_hfa_d6 { double a; struct struct_hfa_d5 b; }; +struct struct_hfa_d6 +func_hfa_d6(struct struct_hfa_d6 e) +{ + return e; +} + +struct struct_hfa_d7 { double a; struct struct_hfa_d6 b; }; +struct struct_hfa_d7 +func_hfa_d7(struct struct_hfa_d7 e) +{ + return e; +} + +struct struct_hfa_d8 { double a; struct struct_hfa_d7 b; }; +struct struct_hfa_d8 +func_hfa_d8(struct struct_hfa_d8 e) +{ + return e; +} + +struct struct_hfa_d9 { double a; struct struct_hfa_d8 b; }; +struct struct_hfa_d9 +func_hfa_d9(struct struct_hfa_d9 e) +{ + return e; +} + +struct struct_hfa_d10 { double a; struct struct_hfa_d9 b; }; +struct struct_hfa_d10 +func_hfa_d10(struct struct_hfa_d10 e) +{ + return e; +} + +struct struct_hfa_d11 { double a; struct struct_hfa_d10 b; }; +struct struct_hfa_d11 +func_hfa_d11(struct struct_hfa_d11 e) +{ + return e; +} + +struct struct_hfa_d12 { double a; struct struct_hfa_d11 b; }; +struct struct_hfa_d12 +func_hfa_d12(struct struct_hfa_d12 e) +{ + return e; +} + +void +func_printf(char *format, ...) +{ +} + +void +func_sprintf(char *str, char *format, ...) +{ +} diff --git a/testsuite/ltrace.main/parameters.c b/testsuite/ltrace.main/parameters.c index dd63612..ff24a38 100644 --- a/testsuite/ltrace.main/parameters.c +++ b/testsuite/ltrace.main/parameters.c @@ -20,7 +20,8 @@ void func_ppp(int***); void func_stringp(char**); void func_short(short, short); void func_ushort(unsigned short, unsigned short); -void func_float(float, float); +float func_float(float, float); +double func_double(double, double); void func_arrayi(int*, int); void func_arrayf(float*, int); void func_struct(void*); @@ -35,7 +36,16 @@ typedef enum { void func_enum(color_t); void func_typedef(color_t); -int +void func_work(char *x); +void func_call(char *x, char *y, void (*cb)(char *)); + +void +call_func_work (char *x) +{ + func_work(x); +} + +int main () { int x = 17; @@ -49,7 +59,12 @@ main () func_intptr_ret(&x); + func_string("zero\0xxxxxxxxxxxxxx"); func_strlen(buf); + + extern int func_arg0(char *); + func_arg0(buf); + printf("%s\n", buf); func_strfixed(buf); @@ -68,7 +83,8 @@ main () func_short(-8, -9); func_ushort(33, 34); - func_float(3.4, -3.4); + float f = func_float(3.4, -3.4); + double d = func_double(3.4, -3.4); func_typedef(BLUE); @@ -116,5 +132,240 @@ main () func_struct(&x); } + { + char x[10] = {}; + char y[10] = {}; + func_call(x, y, call_func_work); + } + + struct S2 { + float f; + char a; + char b; + }; + struct S3 { + char a[6]; + float f; + }; + struct S2 func_struct_2(int, struct S3 s3, double d); + func_struct_2(17, (struct S3){ "ABCDE", 0.25 }, 0.5); + + struct S4 { + long a; + long b; + long c; + long d; + }; + struct S4 func_struct_large(struct S4 a, struct S4 b); + func_struct_large((struct S4){ 1, 2, 3, 4 }, (struct S4){ 5, 6, 7, 8 }); + + struct S5 { + char a; + char b; + long c; + long d; + }; + struct S5 func_struct_large2(struct S5 a, struct S5 b); + func_struct_large2((struct S5){ '0', '1', 3, 4 }, (struct S5){ '2', '3', 7, 8 }); + + struct S6 { + long a; + long b; + char c; + char d; + }; + struct S6 func_struct_large3(struct S6 a, struct S6 b); + func_struct_large3((struct S6){ 3, 4, '0', '1' }, (struct S6){ 7, 8 ,'2', '3' }); + + void func_many_args(int a, int b, long c, double d, char e, int f, float g, + char h, int i, double j, int k, double l, char m, int n, + short o, int p, char q, float r, float s, double t, + long u, float v, float w, float x, float y); + func_many_args(1, 2, 3, 4.0, '5', 6, 7.0, + '8', 9, 10.0, 11, 12.0, 'A', 14, + 15, 16, 'B', 18.0, 19.0, 20.0, + 21, 22.0, 23.0, 24.0, 25.0); + + void func_printf(char *format, ...); + func_printf("sotnuh %d %ld %g %c\n", 5, 6L, 1.5, 'X'); + func_printf("sotnuh1 %d %ld %hd\n", 5, 6L, (short)7); + func_printf("sotnuh2 %s %10s %10s\n", "a string", "a trimmed string", "short"); + func_printf("many_args" + "%d %d %ld %g %c %d %g " + "%c %d %g %d %g %c %d " + "%hd %d %c %g %g %g " + "%ld %g %g %g %g", + 1, 2, 3L, 4.0, '5', 6, 7.0, + '8', 9, 10.0, 11, 12.0, 'A', 14, + (short)15, 16, 'B', 18.0, 19.0, 20.0, + 21L, 22.0, 23.0, 24.0, 25.0); + + func_printf("sotnuh3 %*s\n", 4, "a trimmed string"); + + void func_sprintf(char *str, char *format, ...); + func_sprintf(NULL, "test %d %d %d %d\n", 1, 2, 3, 4); + + void func_lens(int, long, short, long); + func_lens(22, 23, 24, 25); + + int func_bool(int a, int b); + func_bool(1, 10); + func_bool(2, 0); + + void func_hide(int a, int b, int c, int d, int e, int f, int g, int h); + func_hide(1, 2, 3, 4, 5, 6, 7, 8); + + struct func_hide_struct { + int a; int b; int c; int d; int e; int f; int g; int h; + }; + void func_hide_struct(struct func_hide_struct hs); + func_hide_struct((struct func_hide_struct){1, 2, 3, 4, 5, 6, 7, 8}); + + enum ab { A, B }; + long *func_short_enums(short abs[]); + func_short_enums((short[]){ A, B, A, A }); + + long func_negative_enum(short a, unsigned short b, int c, unsigned d, + long e, unsigned long f); + func_negative_enum(-1, -1, -1, -1, -1, -1); + + void func_charp_string(char *p); + func_charp_string("null-terminated string"); + + struct dbl_eqv1 { double d; }; + struct dbl_eqv2 { struct dbl_eqv1 d; }; + struct dbl_eqv3 { struct dbl_eqv2 d; }; + struct dbl_eqv4 { struct dbl_eqv3 d; }; + + struct flt_eqv1 { float d; }; + struct flt_eqv2 { struct flt_eqv1 d; }; + struct flt_eqv3 { struct flt_eqv2 d; }; + struct flt_eqv4 { struct flt_eqv3 d; }; + + struct dbl_eqv1 func_dbl_eqv(struct dbl_eqv1 a, struct dbl_eqv2 b, + struct dbl_eqv3 c, struct dbl_eqv4 d); + func_dbl_eqv((struct dbl_eqv1){ 2.5 }, + (struct dbl_eqv2){ { 1.5 } }, + (struct dbl_eqv3){ { { 0.5 } } }, + (struct dbl_eqv4){ { { { -0.5 } } } }); + + struct flt_eqv1 func_flt_eqv(struct flt_eqv1 a, struct flt_eqv2 b, + struct flt_eqv3 c, struct flt_eqv4 d); + func_flt_eqv((struct flt_eqv1){ 2.5 }, + (struct flt_eqv2){ { 1.5 } }, + (struct flt_eqv3){ { { 0.5 } } }, + (struct flt_eqv4){ { { { -0.5 } } } }); + + struct struct_empty {}; + struct struct_empty func_struct_empty(struct struct_empty e); + func_struct_empty((struct struct_empty) {}); + + struct struct_size1 { char a; }; + struct struct_size1 func_struct_size1(struct struct_size1 e); + func_struct_size1((struct struct_size1){ '5' }); + + struct struct_size2 { short a; }; + struct struct_size2 func_struct_size2(struct struct_size2 e); + func_struct_size2((struct struct_size2){ 5 }); + + struct struct_size4 { int a; }; + struct struct_size4 func_struct_size4(struct struct_size4 e); + func_struct_size4((struct struct_size4){ 5 }); + + struct struct_size8 { int a; int b; }; + struct struct_size8 func_struct_size8(struct struct_size8 e); + func_struct_size8((struct struct_size8){ 5, 6 }); + + /* Test Itanium Homogeneous Floating-point Aggregates. */ + + struct struct_hfa_f2 { float a; struct flt_eqv1 b; }; + struct struct_hfa_f2 func_hfa_f2(struct struct_hfa_f2 e); + func_hfa_f2((struct struct_hfa_f2){ 1, { 2 } }); + + struct struct_hfa_f3 { float a; struct struct_hfa_f2 b; }; + struct struct_hfa_f3 func_hfa_f3(struct struct_hfa_f3 e); + func_hfa_f3((struct struct_hfa_f3){ 3, { 1, { 2 } } }); + + struct struct_hfa_f4 { float a; struct struct_hfa_f3 b; }; + struct struct_hfa_f4 func_hfa_f4(struct struct_hfa_f4 e); + func_hfa_f4((struct struct_hfa_f4){ 4, { 3, { 1, { 2 } } } }); + + struct struct_hfa_f5 { float a; struct struct_hfa_f4 b; }; + struct struct_hfa_f5 func_hfa_f5(struct struct_hfa_f5 e); + func_hfa_f5((struct struct_hfa_f5){ 5, { 4, { 3, { 1, { 2 } } } } }); + + struct struct_hfa_f6 { float a; struct struct_hfa_f5 b; }; + struct struct_hfa_f6 func_hfa_f6(struct struct_hfa_f6 e); + func_hfa_f6((struct struct_hfa_f6){ 6, { 5, { 4, { 3, { 1, { 2 } } } } } }); + + struct struct_hfa_f7 { float a; struct struct_hfa_f6 b; }; + struct struct_hfa_f7 func_hfa_f7(struct struct_hfa_f7 e); + func_hfa_f7((struct struct_hfa_f7){ 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } }); + + struct struct_hfa_f8 { float a; struct struct_hfa_f7 b; }; + struct struct_hfa_f8 func_hfa_f8(struct struct_hfa_f8 e); + func_hfa_f8((struct struct_hfa_f8){ 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } }); + + struct struct_hfa_f9 { float a; struct struct_hfa_f8 b; }; + struct struct_hfa_f9 func_hfa_f9(struct struct_hfa_f9 e); + func_hfa_f9((struct struct_hfa_f9){ 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } }); + + struct struct_hfa_f10 { float a; struct struct_hfa_f9 b; }; + struct struct_hfa_f10 func_hfa_f10(struct struct_hfa_f10 e); + func_hfa_f10((struct struct_hfa_f10){ 10, { 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } } }); + + struct struct_hfa_f11 { float a; struct struct_hfa_f10 b; }; + struct struct_hfa_f11 func_hfa_f11(struct struct_hfa_f11 e); + func_hfa_f11((struct struct_hfa_f11){ 11, { 10, { 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } } } }); + + struct struct_hfa_f12 { float a; struct struct_hfa_f11 b; }; + struct struct_hfa_f12 func_hfa_f12(struct struct_hfa_f12 e); + func_hfa_f12((struct struct_hfa_f12){ 12, { 11, { 10, { 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } } } } }); + + + struct struct_hfa_d2 { double a; struct dbl_eqv1 b; }; + struct struct_hfa_d2 func_hfa_d2(struct struct_hfa_d2 e); + func_hfa_d2((struct struct_hfa_d2){ 1, { 2 } }); + + struct struct_hfa_d3 { double a; struct struct_hfa_d2 b; }; + struct struct_hfa_d3 func_hfa_d3(struct struct_hfa_d3 e); + func_hfa_d3((struct struct_hfa_d3){ 3, { 1, { 2 } } }); + + struct struct_hfa_d4 { double a; struct struct_hfa_d3 b; }; + struct struct_hfa_d4 func_hfa_d4(struct struct_hfa_d4 e); + func_hfa_d4((struct struct_hfa_d4){ 4, { 3, { 1, { 2 } } } }); + + struct struct_hfa_d5 { double a; struct struct_hfa_d4 b; }; + struct struct_hfa_d5 func_hfa_d5(struct struct_hfa_d5 e); + func_hfa_d5((struct struct_hfa_d5){ 5, { 4, { 3, { 1, { 2 } } } } }); + + struct struct_hfa_d6 { double a; struct struct_hfa_d5 b; }; + struct struct_hfa_d6 func_hfa_d6(struct struct_hfa_d6 e); + func_hfa_d6((struct struct_hfa_d6){ 6, { 5, { 4, { 3, { 1, { 2 } } } } } }); + + struct struct_hfa_d7 { double a; struct struct_hfa_d6 b; }; + struct struct_hfa_d7 func_hfa_d7(struct struct_hfa_d7 e); + func_hfa_d7((struct struct_hfa_d7){ 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } }); + + struct struct_hfa_d8 { double a; struct struct_hfa_d7 b; }; + struct struct_hfa_d8 func_hfa_d8(struct struct_hfa_d8 e); + func_hfa_d8((struct struct_hfa_d8){ 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } }); + + struct struct_hfa_d9 { double a; struct struct_hfa_d8 b; }; + struct struct_hfa_d9 func_hfa_d9(struct struct_hfa_d9 e); + func_hfa_d9((struct struct_hfa_d9){ 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } }); + + struct struct_hfa_d10 { double a; struct struct_hfa_d9 b; }; + struct struct_hfa_d10 func_hfa_d10(struct struct_hfa_d10 e); + func_hfa_d10((struct struct_hfa_d10){ 10, { 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } } }); + + struct struct_hfa_d11 { double a; struct struct_hfa_d10 b; }; + struct struct_hfa_d11 func_hfa_d11(struct struct_hfa_d11 e); + func_hfa_d11((struct struct_hfa_d11){ 11, { 10, { 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } } } }); + + struct struct_hfa_d12 { double a; struct struct_hfa_d11 b; }; + struct struct_hfa_d12 func_hfa_d12(struct struct_hfa_d12 e); + func_hfa_d12((struct struct_hfa_d12){ 12, { 11, { 10, { 9, { 8, { 7, { 6, { 5, { 4, { 3, { 1, { 2 } } } } } } } } } } } }); + return 0; } diff --git a/testsuite/ltrace.main/parameters.conf b/testsuite/ltrace.main/parameters.conf index 33c1a1e..066c012 100644 --- a/testsuite/ltrace.main/parameters.conf +++ b/testsuite/ltrace.main/parameters.conf @@ -1,15 +1,65 @@ void func_intptr(int*) void func_intptr_ret(+int*) +void func_string(string[10]) int func_strlen(+string[retval]) +int func_arg0(+string[arg0]) void func_strfixed(string[4]) -void func_ppp(int***) +void func_ppp(int * **) void func_stringp(string*) void func_enum(enum (RED=0,GREEN=1,BLUE=2,CHARTREUSE=3,PETUNIA=4)) void func_short(short,short) void func_ushort(ushort, ushort) -void func_float(float,float) +float func_float(float,float) +double func_double(double,double) typedef color = enum (RED=0,GREEN=1,BLUE=2,CHARTREUSE=3,PETUNIA=4) void func_typedef(color) -void func_arrayi(array(int,arg2)*,void) -void func_arrayf(array(float,arg2)*,void) +void func_arrayi(array(int,arg2)*,int) +void func_arrayf(array(float,arg2)*,int) void func_struct(struct(int,int,int,array(struct(int,int),elt2)*,array(struct(int,int),3),string[elt3])*) +void func_work(+string); +void func_call(+string, string); +struct(float,char,char) func_struct_2(int, struct(string(array(char, 6)),float), double); +struct(long,long,long,long) func_struct_large(struct(long,long,long,long), struct(long,long,long,long)); +struct(char,char,long,long) func_struct_large2(struct(char,char,long,long), struct(char,char,long,long)); +struct(long,long,char,char) func_struct_large3(struct(long,long,char,char), struct(long,long,char,char)); +void func_many_args(int, int, long, double, char, int, float, char, int, double, int, double, char, int, short, int, char, float, float, double, long, float, float, float, float); +void func_printf(format); +void func_sprintf(+string,format); +void func_lens(octal, octal(long), hex(short), hex(long)); +bool(int) func_bool(int, bool(int)); +void func_hide(hide(int), int, hide(int), hide(int), int, hide(int), int, hide(int)); +void func_hide_struct(struct(hide(int), int, hide(int), hide(int), int, hide(int), int, hide(int))); +array(enum[long](A,B), 4) *func_short_enums(array(enum[short](A,B), 4)*); +enum[long](A=-1) func_negative_enum(enum[short](A=-1), enum[ushort](A=-1), enum[int](A=-1), enum[uint](A=-1), enum[long](A=-1), enum[ulong](A=-1)); +void func_charp_string(string(char *)); +struct(double) func_dbl_eqv(struct(double), struct(struct(double)), struct(struct(struct(double))), struct(struct(struct(struct(double))))); +struct(float) func_flt_eqv(struct(float), struct(struct(float)), struct(struct(struct(float))), struct(struct(struct(struct(float))))); +struct() func_struct_empty(struct()); +struct(char) func_struct_size1(struct(char)); +struct(short) func_struct_size2(struct(short)); +struct(int) func_struct_size4(struct(int)); +struct(int,int) func_struct_size8(struct(int,int)); + +struct(float,struct(float)) func_hfa_f2(struct(float,struct(float))); +struct(float,struct(float,struct(float))) func_hfa_f3(struct(float,struct(float,struct(float)))); +struct(float,struct(float,struct(float,struct(float)))) func_hfa_f4(struct(float,struct(float,struct(float,struct(float))))); +struct(float,struct(float,struct(float,struct(float,struct(float))))) func_hfa_f5(struct(float,struct(float,struct(float,struct(float,struct(float)))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))) func_hfa_f6(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))) func_hfa_f7(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))))) func_hfa_f8(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))))) func_hfa_f9(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))))))) func_hfa_f10(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))))))) func_hfa_f11(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))))))))); +struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float)))))))))))) func_hfa_f12(struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float,struct(float))))))))))))); + +struct(double,struct(double)) func_hfa_d2(struct(double,struct(double))); +struct(double,struct(double,struct(double))) func_hfa_d3(struct(double,struct(double,struct(double)))); +struct(double,struct(double,struct(double,struct(double)))) func_hfa_d4(struct(double,struct(double,struct(double,struct(double))))); +struct(double,struct(double,struct(double,struct(double,struct(double))))) func_hfa_d5(struct(double,struct(double,struct(double,struct(double,struct(double)))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))) func_hfa_d6(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))) func_hfa_d7(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))))) func_hfa_d8(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))))) func_hfa_d9(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))))))) func_hfa_d10(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))))))) func_hfa_d11(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))))))))); +struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double)))))))))))) func_hfa_d12(struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double,struct(double))))))))))))); diff --git a/testsuite/ltrace.main/parameters.exp b/testsuite/ltrace.main/parameters.exp index bb55e03..e54086f 100644 --- a/testsuite/ltrace.main/parameters.exp +++ b/testsuite/ltrace.main/parameters.exp @@ -6,7 +6,7 @@ set srcfile ${testfile}.c set binfile ${testfile} set libfile "parameters-lib" set libsrc $srcdir/$subdir/$libfile.c -set lib_sl $srcdir/$subdir/lib$testfile.so +set lib_sl $objdir/$subdir/lib$testfile.so if [get_compiler_info $binfile] { @@ -15,15 +15,15 @@ if [get_compiler_info $binfile] { verbose "compiling source file now....." if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" - || [ltrace_compile $srcdir/$subdir/$srcfile $srcdir/$subdir/$binfile executable [list debug shlib=$lib_sl] ] != ""} { + || [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable [list debug shlib=$lib_sl] ] != ""} { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } # set options for ltrace. -ltrace_options "-l" "$srcdir/$subdir/libparameters.so" "-F" "$srcdir/$subdir/parameters.conf" +ltrace_options "-l" "libparameters.so" "-F" "$srcdir/$subdir/parameters.conf" # Run PUT for ltarce. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -35,38 +35,198 @@ if [regexp {ELF from incompatible architecture} $exec_output] { return } +set xfail_spec {"arm*-*" } +set xfail_spec_arm {"arm*-*"} + # Verify the output set pattern "func_intptr(17)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_intptr_ret(42)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_strlen(\\\"Hello world\\\") *= *11" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_arg0(\\\"Hello another world!\\\") *= *20" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_strfixed(\\\"Hell\\\")" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_ppp(80)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_stringp(\\\"Dude\\\")" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_string(\\\"zero\\\")" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_enum(BLUE)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_short(-8, -9)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_ushort(33, 34)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "func_float(3.40*, -3.40*)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_float(3.40*, -3.40*).*= 3.40*" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +eval "setup_xfail $xfail_spec" +set pattern "func_double(3.40*, -3.40*).*= -3.40*" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_typedef(BLUE)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "func_arrayi(. 10, 11, 12, 13\\.\\.\\. ., )" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "func_arrayi(. 10, 11 ., )" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "func_arrayf(. 10.10*, 11.10*, 12.10*, 13.10*\\.\\.\\. ., )" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "func_arrayf(. 10.10*, 11.10* ., )" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_arrayi(. 10, 11, 12, 13\\.\\.\\. ., 8)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_arrayi(. 10, 11 ., 2)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_arrayf(. 10.10*, 11.10*, 12.10*, 13.10*\\.\\.\\. ., 8)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_arrayf(. 10.10*, 11.10* ., 2)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "exited (status 0)" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_struct({ 89, 2, 3, . { 1, 10 }, { 3, 30 } ., . { 4, 40 }, { 5, 50 }, { 6, 60 } ., \\\"123\\\" })" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_call( <unfinished ...>" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_work(\\\"x\\\")" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "func_struct_2(17, { \\\"ABCDE\\\\\\\\0\\\", 0.250* }, 0.50*).*= { 0.250*, 'B', 'C' }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +eval "setup_xfail $xfail_spec_arm" +set pattern "<... func_call resumed> \\\"x\\\", \\\"y\\\")" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_large({ 1, 2, 3, 4 }, { 5, 6, 7, 8 }).*= { 6, 8, 10, 12 }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_large2({ '0', '1', 3, 4 }, { '2', '3', 7, 8 }).*= { 'b', 'd', 10, 12 }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_large3({ 3, 4, '0', '1' }, { 7, 8, '2', '3' }).*= { 10, 12, 'b', 'd' }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_many_args(1, 2, 3, 4.00*, '5', 6, 7.00*, '8', 9, 10.00*, 11, 12.00*, 'A', 14, 15, 16, 'B', 18.00*, 19.00*, 20.00*, 21, 22.00*, 23.00*, 24.00*, 25.00*)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_printf(\\\"sotnuh %d %ld %g %c.n\\\", 5, 6, 1.500*, 'X')" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_printf(\\\"sotnuh1 %d %ld %hd.n\\\", 5, 6, 7)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_printf(\\\"sotnuh2 %s %10s %10s.n\\\", \\\"a string\\\", \\\"a trimmed \\\", \\\"short\\\")" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_printf(\\\"sotnuh3 %.s.n\\\", 4, \\\"a tr\\\")" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_printf(\\\"many_args%d %d %ld %g %c %d %g .*, 1, 2, 3, 4.00*, '5', 6, 7.00*, '8', 9, 10.00*, 11, 12.00*, 'A', 14, 15, 16, 'B', 18.00*, 19.00*, 20.00*, 21, 22.00*, 23.00*, 24.00*, 25.00*)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_sprintf(nil, \\\"test %d %d %d %d.n\\\", 1, 2, 3, 4)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_lens(026, 027, 0x18, 0x19)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_bool(1, true).*= false" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_bool(2, false).*= true" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hide(2, 5, 7)" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hide_struct({ 2, 5, 7 })" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_short_enums(. A, B, A, A .).*= . A, B, A, A ." +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_negative_enum(A, A, A, A, A, A).*= A" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_charp_string(\\\"null-terminated string\\\")" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_dbl_eqv({ 2.500* }, { { 1.50* } }, { { { 0.50* } } }, { { { { -0.50* } } } }).*= { 4.00* }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_flt_eqv({ 2.500* }, { { 1.50* } }, { { { 0.50* } } }, { { { { -0.50* } } } }).*= { 4.00* }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_empty({ *}).*= { *}" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_size1({ '5' }).*= { '5' }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_size2({ 5 }).*= { 5 }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_size4({ 5 }).*= { 5 }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_struct_size8({ 5, 6 }).*= { 5, 6 }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f2({ 1.000*, { 2.000* } }).*= { 1.000*, { 2.000* } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f3({ 3.000*, { 1.000*, { 2.000* } } }).*= { 3.000*, { 1.000*, { 2.000* } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f4({ 4.000*, { 3.000*, { 1.000*, { 2.000* } } } }).*= { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f5({ 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } }).*= { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f6({ 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } }).*= { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f7({ 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } }).*= { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f8({ 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } }).*= { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f9({ 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } }).*= { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f10({ 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } }).*= { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f11({ 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } }).*= { 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_f12({ 12.000*, { 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } } }).*= { 12.000*, { 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d2({ 1.000*, { 2.000* } }).*= { 1.000*, { 2.000* } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d3({ 3.000*, { 1.000*, { 2.000* } } }).*= { 3.000*, { 1.000*, { 2.000* } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d4({ 4.000*, { 3.000*, { 1.000*, { 2.000* } } } }).*= { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d5({ 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } }).*= { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d6({ 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } }).*= { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d7({ 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } }).*= { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d8({ 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } }).*= { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d9({ 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } }).*= { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d10({ 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } }).*= { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d11({ 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } }).*= { 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern "func_hfa_d12({ 12.000*, { 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } } }).*= { 12.000*, { 11.000*, { 10.000*, { 9.000*, { 8.000*, { 7.000*, { 6.000*, { 5.000*, { 4.000*, { 3.000*, { 1.000*, { 2.000* } } } } } } } } } } } }" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 diff --git a/testsuite/ltrace.main/parameters2.exp b/testsuite/ltrace.main/parameters2.exp new file mode 100644 index 0000000..8443fb6 --- /dev/null +++ b/testsuite/ltrace.main/parameters2.exp @@ -0,0 +1,215 @@ +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +set trivial [ltraceCompile {} [ltraceSource c { + int main(void) {} +}]] + +ltraceMatch1 [ltraceRun -L -F [ltraceSource conf { + typedef aa = int; + typedef aaa = int; + typedef bbb = struct(aa); +}] -- $trivial] "error" == 0 + +ltraceMatch1 [ltraceRun -L -F [ltraceSource conf { + typedef aa = int; + typedef aa = int; +}] -- $trivial] "error" != 0 + +ltraceMatch1 [ltraceRun -L -F [ltraceSource conf { + typedef aa = struct; + typedef aa = int; +}] -- $trivial] "error" != 0 + +ltraceMatch1 [ltraceRun -L -F [ltraceSource conf { + typedef aa = struct; + typedef aa = struct(int); + typedef aa = struct(int); +}] -- $trivial] "error" != 0 + +ltraceMatch1 [ltraceRun -L -F [ltraceSource conf { + typedef aa = struct; + typedef aa = struct(); + typedef aa = struct(); +}] -- $trivial] "error" != 0 + +ltraceMatch1 [ltraceRun -L -F [ltraceSource conf { + typedef aa = struct(int, struct;); +}] -- $trivial] "error" != 0 + +set libll [ltraceCompile libll.so [ltraceSource c { + struct xxx; + void ll(struct xxx *xxx) {} +}]] + +set conf [ltraceSource conf { + typedef xxx = struct; + typedef xxx = struct(int, xxx*); + void ll(xxx*); +}] + +ltraceMatch [ltraceRun -F $conf -e ll [ltraceCompile {} $libll [ltraceSource c { + struct xxx { + int i; + struct xxx *next; + }; + + void ll (struct xxx *xxx); + int main (int argc, char *argv[]) + { + struct xxx a = { 1, 0 }; + struct xxx b = { 2, &a }; + struct xxx c = { 3, &b }; + struct xxx d = { 4, &c }; + ll (&d); + + struct xxx e = { 1, 0 }; + struct xxx f = { 2, &e }; + e.next = &f; + ll (&f); + + struct xxx g = { 1, &g }; + ll (&g); + + return 0; + } +}]]] { + {{->ll\({ 4, { 3, { 2, { 1, nil } } } }\) *= <void>} == 1} + {{->ll\({ 2, { 1, recurse\^ } }\) *= <void>} == 1} + {{->ll\({ 1, recurse }\) *= <void>} == 1} +} + +ltraceMatch1 [ltraceRun -F $conf -e ll -A 5 \ +-- [ltraceCompile ll $libll [ltraceSource c { + #include <stdlib.h> + struct ble { + int i; + struct ble *next; + }; + + void ll (struct ble *ble); + int main (int argc, char *argv[]) + { + struct ble *b = NULL; + int i; + for (i = 0; i < 10; ++i) { + struct ble *n = malloc(sizeof(*n)); + n->i = i; + n->next = b; + b = n; + } + ll (b); + + return 0; + } +}]]] {->ll\({ 9, { 8, { 7, { 6, { 5, \.\.\. } } } } }\) *= <void>} == 1 + +proc ltraceParamTest {conf cdecl libcode maincode match {params ""}} { + set conffile [ltraceSource conf $conf] + set lib [ltraceCompile liblib.so [ltraceSource c [concat $cdecl $libcode]]] + set bin [ltraceCompile {} $lib \ + [ltraceSource c \ + [concat $cdecl "int main(void) {" $maincode "}"]]] + + set command [concat "ltraceRun -F $conffile " $params "-- $bin"] + return [ltraceMatch [eval $command] $match] +} + +# Test using lens in typedef. + +ltraceParamTest { + typedef hexptr = hex(uint*); + void fun(hexptr); +} { + void fun(unsigned *arg); +} { + void fun(unsigned *arg) {} +} { + unsigned u = 0x123; + fun(&u); +} { + {{fun\(0x123\) *= <void>} == 1} +} + +# Test support for bitvec lens. + +ltraceParamTest { + void fun(bitvec(uint)); + void fun2(bitvec(array(char, 32)*)); +} { + void fun(unsigned i); + void fun2(unsigned char *arr); +} { + void fun(unsigned i) {} + void fun2(unsigned char *arr) {} +} { + fun(0); + fun(0x123); + fun(0xfffffffe); + fun(0xffffffff); + + unsigned char bytes[32] = {0x00}; + bytes[1] = 0xff; + bytes[31] = 0x80; + fun2(bytes); +} { + {{fun\(<>\) *= <void>} == 1} + {{fun\(<0-1,5,8>\) *= <void>} == 1} + {{fun\(~<0>\) *= <void>} == 1} + {{fun\(~<>\) *= <void>} == 1} + {{fun2\(<8-15,255>\) *= <void>} == 1} +} + +# Test support for hex(float), hex(double). + +ltraceParamTest { + hex(float) hex_float(hex(float)); + hex(double) hex_double(hex(double)); +} { + float hex_float(float f); + double hex_double(double d); +} { + float hex_float(float f) { return f + 1; } + double hex_double(double d) { return d + 1; } +} { + hex_float(1.5); + hex_double(1.5); +} { + {{hex_float\(0x1.8p\+0\) *= 0x1.4p\+1} == 1} + {{hex_double\(0x1.8p\+0\) *= 0x1.4p\+1} == 1} +} + +# Test that -x fun can find "fun" prototype even if "fun" is in a +# library. + +ltraceParamTest { + void fun(); +} { + void libfun(void); +} { + void fun(void) {} + void libfun(void) { fun(); } +} { + libfun(); +} { + {{fun@.*\(\)} == 1} +} { + -L -x fun +} + +ltraceDone diff --git a/testsuite/ltrace.main/signals.exp b/testsuite/ltrace.main/signals.exp index f0708e9..d812af6 100644 --- a/testsuite/ltrace.main/signals.exp +++ b/testsuite/ltrace.main/signals.exp @@ -7,7 +7,7 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail\n." } @@ -15,7 +15,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-L" # Run PUT for ltarce. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -36,4 +36,4 @@ close $fd # Verify the output of ltrace by checking the number of SIGUSR1 in signal.ltrace set pattern "SIGUSR1" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern $count +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern $count diff --git a/testsuite/ltrace.main/system_calls.exp b/testsuite/ltrace.main/system_calls.exp index b274db5..259ae25 100644 --- a/testsuite/ltrace.main/system_calls.exp +++ b/testsuite/ltrace.main/system_calls.exp @@ -7,7 +7,7 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } @@ -15,7 +15,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-S" #Run PUT for ltarce. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] #check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -30,38 +30,38 @@ if [regexp {ELF from incompatible architecture} $exec_output] { set pattern "SYS_munmap" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 2 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 2 set pattern "SYS_write" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_unlink" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_brk" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_open" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "SYS_fstat" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "SYS_mmap" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "SYS_(new)?fstat" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep +set pattern "SYS_(old_)?mmap" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep set pattern "SYS_close" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_getcwd" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_chdir" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_symlink" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_unlink" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "SYS_stat" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern "SYS_(new)?stat" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep set pattern "SYS_access" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_rename" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_mkdir" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "SYS_rmdir" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 diff --git a/testsuite/ltrace.minor/Makefile.am b/testsuite/ltrace.minor/Makefile.am new file mode 100644 index 0000000..af6cfde --- /dev/null +++ b/testsuite/ltrace.minor/Makefile.am @@ -0,0 +1,46 @@ +# Copyright (C) 1992 - 2001, 2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +EXTRA_DIST = \ + attach-process.exp \ + count-record.c \ + count-record.exp \ + demangle.cpp \ + demangle.exp \ + demangle.h \ + demangle-lib.cpp \ + libdl-simple.c \ + libdl-simple.exp \ + libdl-simple-lib.c \ + print-instruction-pointer.c \ + print-instruction-pointer.exp \ + time-record.c \ + time-record-T.exp \ + time-record-tt.exp \ + time-record-ttt.exp \ + trace-clone.c \ + trace-clone.exp \ + trace-exec.exp \ + trace-fork.c \ + trace-fork.exp + +CLEANFILES = *.o *.so *.log *.sum *.ltrace setval.tmp \ + attach-process count-record demangle print-instruction-pointer \ + time-record-T time-record-tt time-record-ttt trace-clone \ + trace-exec trace-exec1 trace-fork libdl-simple + +MAINTAINERCLEANFILES = Makefile.in diff --git a/testsuite/ltrace.minor/Makefile.in b/testsuite/ltrace.minor/Makefile.in new file mode 100644 index 0000000..e6d7c03 --- /dev/null +++ b/testsuite/ltrace.minor/Makefile.in @@ -0,0 +1,415 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 1992 - 2001, 2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = testsuite/ltrace.minor +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + attach-process.exp \ + count-record.c \ + count-record.exp \ + demangle.cpp \ + demangle.exp \ + demangle.h \ + demangle-lib.cpp \ + libdl-simple.c \ + libdl-simple.exp \ + libdl-simple-lib.c \ + print-instruction-pointer.c \ + print-instruction-pointer.exp \ + time-record.c \ + time-record-T.exp \ + time-record-tt.exp \ + time-record-ttt.exp \ + trace-clone.c \ + trace-clone.exp \ + trace-exec.exp \ + trace-fork.c \ + trace-fork.exp + +CLEANFILES = *.o *.so *.log *.sum *.ltrace setval.tmp \ + attach-process count-record demangle print-instruction-pointer \ + time-record-T time-record-tt time-record-ttt trace-clone \ + trace-exec trace-exec1 trace-fork libdl-simple + +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/ltrace.minor/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/ltrace.minor/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/testsuite/ltrace.minor/attach-process.c b/testsuite/ltrace.minor/attach-process.c deleted file mode 100644 index 4c00bce..0000000 --- a/testsuite/ltrace.minor/attach-process.c +++ /dev/null @@ -1,16 +0,0 @@ -/* Ltrace Test : attach-process.c. - Objectives : Verify that ltrace can attach to a running process - by its PID. - - This file was written by Yao Qi <qiyao@cn.ibm.com>. */ - -#include<unistd.h> -#include <sys/types.h> - -int -main () -{ - sleep (5); - sleep (1); - return 0; -} diff --git a/testsuite/ltrace.minor/attach-process.exp b/testsuite/ltrace.minor/attach-process.exp index ab5460e..2c7d20c 100644 --- a/testsuite/ltrace.minor/attach-process.exp +++ b/testsuite/ltrace.minor/attach-process.exp @@ -1,38 +1,29 @@ -# This file was written by Yao Qi <qiyao@cn.ibm.com>. - -set testfile "attach-process" -set srcfile ${testfile}.c -set binfile ${testfile} - -verbose "compiling source file now....." -# Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { - send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" -} - -# Run the program and get PID of it. -catch "exec $srcdir/$subdir/$binfile &" output - -# get PID from ps output. -regexp {([0-9]+)} $output match PID -verbose "PID = $PID" - -# Run PUT for ltrace. -global LTRACE -catch "exec $LTRACE -S -p $PID -o ${srcdir}/${subdir}/${testfile}.ltrace" exec_output - -# Check the output of this program. -verbose "ltrace runtest output: $exec_output\n" -if [regexp {ELF from incompatible architecture} $exec_output] { - fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" - return -} elseif [ regexp {Couldn't get .hash data} $exec_output ] { - fail "Couldn't get .hash data!" - return -} - -# Verify the output in attach-process.ltrace by checking the number -# of sleep. -set pattern "sleep" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 - +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +set bin [ltraceCompile {} [ltraceSource c { + #include <unistd.h> + int main(void) { + sleep(5); + sleep(1); + } +}]] + +spawn $bin +ltraceMatch1 [ltraceRun -S -p [exp_pid]] { sleep\(} == 1 +ltraceDone diff --git a/testsuite/ltrace.minor/count-record.exp b/testsuite/ltrace.minor/count-record.exp index f8c4923..fe96b4c 100644 --- a/testsuite/ltrace.minor/count-record.exp +++ b/testsuite/ltrace.minor/count-record.exp @@ -6,7 +6,7 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } @@ -14,7 +14,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-c" # Run PUT for ltrace. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -26,9 +26,6 @@ if [regexp {ELF from incompatible architecture} $exec_output] { return } - -ltrace_saveoutput $exec_output $srcdir/$subdir/$binfile.ltrace - # # This is a sample output and Verify the forth and fifth column. # @@ -49,29 +46,29 @@ ltrace_saveoutput $exec_output $srcdir/$subdir/$binfile.ltrace # set pattern " 1 rmdir" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 fopen" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 2 remove" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 mkdir" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 fseek" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 fwrite" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 fclose" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 rename" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 symlink" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 chdir" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 access" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 getcwd" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern set pattern " 1 fread" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern diff --git a/testsuite/ltrace.minor/demangle-lib.cpp b/testsuite/ltrace.minor/demangle-lib.cpp index 01ab18d..3091f31 100644 --- a/testsuite/ltrace.minor/demangle-lib.cpp +++ b/testsuite/ltrace.minor/demangle-lib.cpp @@ -1,6 +1,6 @@ #include<stddef.h> #include<iostream> - +#include<cstdlib> #include"demangle.h" /* Number of arguments */ diff --git a/testsuite/ltrace.minor/demangle.exp b/testsuite/ltrace.minor/demangle.exp index 5077ac0..9dd7694 100644 --- a/testsuite/ltrace.minor/demangle.exp +++ b/testsuite/ltrace.minor/demangle.exp @@ -5,7 +5,7 @@ set srcfile ${testfile}.cpp set binfile ${testfile} set libfile "demangle-lib" set libsrc $srcdir/$subdir/$libfile.cpp -set lib_sl $srcdir/$subdir/lib$testfile.so +set lib_sl $objdir/$subdir/lib$testfile.so verbose "compiling source file now....." if [get_compiler_info $binfile "c++"] { @@ -14,7 +14,7 @@ if [get_compiler_info $binfile "c++"] { verbose "compiling source file now....." if { [ltrace_compile_shlib $libsrc $lib_sl [list debug c++]] != "" - || [ltrace_compile $srcdir/$subdir/$srcfile $srcdir/$subdir/$binfile executable [list debug shlib=$lib_sl c++] ] != ""} { + || [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable [list debug shlib=$lib_sl c++] ] != ""} { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } @@ -22,7 +22,7 @@ if { [ltrace_compile_shlib $libsrc $lib_sl [list debug c++]] != "" ltrace_options "-C" # Run PUT for ltrace. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -32,13 +32,16 @@ if [regexp {ELF from incompatible architecture} $exec_output] { } elseif [ regexp {Couldn't get .hash data} $exec_output ] { fail "Couldn't get .hash data!" return +} elseif [ regexp {invalid option} $exec_output ] { + unsupported "Demangle support not compiled in." + return } # read function declarations from demangle.cpp and verify them in demangle.ltrace. set fd [ open $srcdir/$subdir/$srcfile r] while { [gets $fd line] >= 0 } { if [regexp {extern (double|float|void|char|int|short|long|void \*|void \*\*) ([^ ])\(} $line match type fun] { - ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $fun + ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $fun } } close $fd @@ -53,10 +56,10 @@ while { [gets $fd line] >= 0 } { # $fun = "myclass::operator delete" will confuse ltrace_verify_output if it # was an argument to it. if [regexp {(new|delete)} $fun match sub_fun] { - ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $sub_fun + ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $sub_fun } else { # Verify class member functions without SPACE. - ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $fun + ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $fun } } } diff --git a/testsuite/ltrace.minor/libdl-simple-lib.c b/testsuite/ltrace.minor/libdl-simple-lib.c new file mode 100644 index 0000000..6340d9d --- /dev/null +++ b/testsuite/ltrace.minor/libdl-simple-lib.c @@ -0,0 +1,4 @@ +int test_libdl(int x) +{ + return x * 1337; +} diff --git a/testsuite/ltrace.minor/libdl-simple.c b/testsuite/ltrace.minor/libdl-simple.c new file mode 100644 index 0000000..0bef5cf --- /dev/null +++ b/testsuite/ltrace.minor/libdl-simple.c @@ -0,0 +1,24 @@ +#include <stdlib.h> +#include <stdio.h> +#include <dlfcn.h> + +int main(int argc, char **argv) { + void *handle; + int (*test)(int); + char *error; + + handle = dlopen ("liblibdl-simple.so", RTLD_LAZY); + if (!handle) { + fputs (dlerror(), stderr); + exit(1); + } + + test = dlsym(handle, "test_libdl"); + if ((error = dlerror()) != NULL) { + fputs(error, stderr); + exit(1); + } + + printf("%d\n", test(5)); + dlclose(handle); +} diff --git a/testsuite/ltrace.minor/libdl-simple.exp b/testsuite/ltrace.minor/libdl-simple.exp new file mode 100644 index 0000000..bb1b826 --- /dev/null +++ b/testsuite/ltrace.minor/libdl-simple.exp @@ -0,0 +1,36 @@ +set testfile "libdl-simple" +set srcfile ${testfile}.c +set binfile ${testfile} +set libfile "libdl-simple-lib" +set libsrc $srcdir/$subdir/$libfile.c +set lib_sl $objdir/$subdir/lib$testfile.so + +verbose "compiling source file now....." +if [get_compiler_info $binfile ""] { + return -1 +} + +# Build the shared libraries this test case needs. +if { [ltrace_compile_shlib $libsrc $lib_sl [debug]] != "" + || [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug shlib=-ldl} ] != "" } { + send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" +} + +# set options for ltrace. +ltrace_options "-x" "test_libdl" + +# Run PUT for ltrace. +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] +verbose "ltrace runtest output: $exec_output\n" + +# Check the output of this program. +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +set pattern "test_libdl@liblibdl-simple.so" +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 diff --git a/testsuite/ltrace.minor/print-instruction-pointer.exp b/testsuite/ltrace.minor/print-instruction-pointer.exp index 87cc8f7..039e906 100644 --- a/testsuite/ltrace.minor/print-instruction-pointer.exp +++ b/testsuite/ltrace.minor/print-instruction-pointer.exp @@ -7,14 +7,14 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ltrace_compile "${srcdir}/${subdir}/${srcfile}" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ltrace_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } # set options for ltrace. ltrace_options "-i" # Run PUT for ltrace. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -27,7 +27,7 @@ if [regexp {ELF from incompatible architecture} $exec_output] { } # Get the addrss by objdump and sed. -catch "exec sh -c {objdump -d $srcdir/$subdir/$binfile | sed -n '/^\[0-9a-fA-F\]\[0-9a-fA-F\]* <main>/,/^\[0-9a-fA-F\]\[0-9a-fA-F\]* </p'| grep -A 1 'call\\|bl' }" output +catch "exec sh -c {objdump -d $objdir/$subdir/$binfile | sed -n '/^\[0-9a-fA-F\]\[0-9a-fA-F\]* <main>/,/^\[0-9a-fA-F\]\[0-9a-fA-F\]* </p'| grep -A 1 'call\\|bl' }" output #verbose "output=$output" catch "exec sh -c {echo \"$output\" | sed -n '2p'| awk -F' ' '{print \$1}'|awk -F: '{print \$1}'}" addr1 catch "exec sh -c {echo \"$output\" | sed -n '5p'| awk -F' ' '{print \$1}'|awk -F: '{print \$1}'}" addr2 @@ -36,7 +36,7 @@ verbose "addr1 = $addr1" verbose "addr2 = $addr2" # Verify the output by checking numbers of print in main.ltrace. set pattern "$addr1.*printf" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "$addr2.*printf" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 diff --git a/testsuite/ltrace.minor/time-record-T.exp b/testsuite/ltrace.minor/time-record-T.exp index b411add..fc9a555 100644 --- a/testsuite/ltrace.minor/time-record-T.exp +++ b/testsuite/ltrace.minor/time-record-T.exp @@ -6,7 +6,7 @@ set binfile ${testfile}-T verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } @@ -14,7 +14,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-T" # Run PUT for ltrace. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] verbose "ltrace runtest output: $exec_output\n" # Check the output of this program. @@ -37,7 +37,7 @@ close $fd # Verify the time for calling sleep. -set fd [ open $srcdir/$subdir/$binfile.ltrace r] +set fd [ open $objdir/$subdir/$binfile.ltrace r] set FOUND 0 while { [gets $fd line] >= 0 } { # match the line with sleep and extract the spent time in sleep and sleep argument. @@ -61,7 +61,7 @@ if {$FOUND != 1} then { # Verify the time for calling nanosleep. set FOUND 0 -set fd [ open $srcdir/$subdir/$binfile.ltrace r] +set fd [ open $objdir/$subdir/$binfile.ltrace r] while { [gets $fd line] >= 0 } { # match the line with nanosleep and extract spent time and nanosleep argument. if [ regexp {nanosleep.*<([0-9]+\.[0-9]+)>} $line match usec] then { diff --git a/testsuite/ltrace.minor/time-record-tt.exp b/testsuite/ltrace.minor/time-record-tt.exp index 332704a..6094164 100644 --- a/testsuite/ltrace.minor/time-record-tt.exp +++ b/testsuite/ltrace.minor/time-record-tt.exp @@ -6,7 +6,7 @@ set binfile ${testfile}-tt verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } @@ -14,7 +14,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-tt" # Run PUT for ltrace. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -27,7 +27,7 @@ if [regexp {ELF from incompatible architecture} $exec_output] { } # Verify the time for calling sleep. -set fd [ open $srcdir/$subdir/$binfile.ltrace r] +set fd [ open $objdir/$subdir/$binfile.ltrace r] set FOUND 0 while { [gets $fd line] >= 0 } { # match the line with sleep and extract the strat time and sleep argument. @@ -72,7 +72,7 @@ close $fd # Verify the time for calling nanosleep. set FOUND 0 -set fd [ open $srcdir/$subdir/$binfile.ltrace r] +set fd [ open $objdir/$subdir/$binfile.ltrace r] while { [gets $fd line] >= 0 } { # match the line with sleep and extract the strat time and sleep argument. if [ regexp {[0-9]+:[0-9]+:([0-9]+)\.([0-9][0-9][0-9]).* nanosleep} $line match start_sec start_usec ] then { diff --git a/testsuite/ltrace.minor/time-record-ttt.exp b/testsuite/ltrace.minor/time-record-ttt.exp index 2aee9d3..4271d0b 100644 --- a/testsuite/ltrace.minor/time-record-ttt.exp +++ b/testsuite/ltrace.minor/time-record-ttt.exp @@ -6,7 +6,7 @@ set binfile ${testfile}-ttt verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } @@ -14,7 +14,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-ttt" # Run PUT for ltrace. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. @@ -28,7 +28,7 @@ if [regexp {ELF from incompatible architecture} $exec_output] { } # Verify the time for calling sleep. -set fd [ open $srcdir/$subdir/$binfile.ltrace r] +set fd [ open $objdir/$subdir/$binfile.ltrace r] set FOUND 0 while { [gets $fd line] >= 0 } { # match the line with sleep and extract the strat time and sleep argument. @@ -76,7 +76,7 @@ close $fd # Verify the time for calling nanosleep. set FOUND 0 -set fd [ open $srcdir/$subdir/$binfile.ltrace r] +set fd [ open $objdir/$subdir/$binfile.ltrace r] while { [gets $fd line] >= 0 } { # match the line with sleep and extract the strat time and sleep argument. if [ regexp {([0-9]+)\.([0-9][0-9][0-9]).* nanosleep} $line match start_sec start_usec ] then { diff --git a/testsuite/ltrace.minor/trace-clone.c b/testsuite/ltrace.minor/trace-clone.c index a1ccb22..db1936d 100644 --- a/testsuite/ltrace.minor/trace-clone.c +++ b/testsuite/ltrace.minor/trace-clone.c @@ -3,7 +3,7 @@ clone called. This file was written by Yao Qi <qiyao@cn.ibm.com>. */ - +#define _GNU_SOURCE #include <stdio.h> #include <sys/types.h> #include <stdlib.h> diff --git a/testsuite/ltrace.minor/trace-clone.exp b/testsuite/ltrace.minor/trace-clone.exp index bda036f..3d0c8fe 100644 --- a/testsuite/ltrace.minor/trace-clone.exp +++ b/testsuite/ltrace.minor/trace-clone.exp @@ -7,22 +7,12 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } -global LTRACE -#Run PUT for ltrace. -spawn $LTRACE -f $srcdir/$subdir/$binfile -set timeout 4 -expect timeout { - fail "Time out! Maybe caused by ltrace segment fault or improper timeout value here!" - return -} - -catch "exec $LTRACE -f $srcdir/$subdir/$binfile" exec_output -# Save the output -ltrace_saveoutput "${exec_output}" ${srcdir}/${subdir}/${testfile}.ltrace +ltrace_options "-f" +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] #check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -40,5 +30,5 @@ if [regexp {ELF from incompatible architecture} $exec_output] { set pattern "clone" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 diff --git a/testsuite/ltrace.minor/trace-exec.c b/testsuite/ltrace.minor/trace-exec.c deleted file mode 100644 index e798cde..0000000 --- a/testsuite/ltrace.minor/trace-exec.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <unistd.h> -#include <stdlib.h> - -int main (int argc, char ** argv) -{ - execl (argv[1], argv[1], NULL); - abort (); -} diff --git a/testsuite/ltrace.minor/trace-exec.exp b/testsuite/ltrace.minor/trace-exec.exp index c9de6f3..7a953de 100644 --- a/testsuite/ltrace.minor/trace-exec.exp +++ b/testsuite/ltrace.minor/trace-exec.exp @@ -1,45 +1,37 @@ -set testfile "trace-exec" -set srcfile ${testfile}.c -set binfile ${testfile} - -verbose "compiling first source file now....." -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { - send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" -} - -verbose "compiling second source file now....." -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}1.c" "${srcdir}/${subdir}/${binfile}1" executable {debug} ] != "" } { - send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" -} - -global LTRACE -set exec_output "" - -#Run PUT for ltrace. -spawn $LTRACE $srcdir/$subdir/$testfile $srcdir/$subdir/${testfile}1 -set timeout 4 -expect timeout { - fail "Time out! Maybe caused by ltrace segment fault or improper timeout value here!" - return +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +ltraceMatch [ltraceRun -xmain -- [ltraceCompile {} [ltraceSource c { + #include <unistd.h> + #include <stdlib.h> + int main(int argc, char ** argv) { + execl(argv[1], argv[1], NULL); + abort(); + } +}]] [ltraceCompile {} [ltraceSource c { + #include <stdio.h> + int main(void) { + return puts("Hello, World."); + } +}]]] { + {{^execl\(} == 1} + {{^puts\(.*\) .*= 14} == 1} + {{^main\(} == 2} } -catch "exec $LTRACE $srcdir/$subdir/$testfile $srcdir/$subdir/${testfile}1" exec_output - -#check the output of this program. -verbose "ltrace runtest output: $exec_output\n" -if [regexp {ELF from incompatible architecture} $exec_output] { - fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" - return -} elseif [ regexp {Couldn't get .hash data} $exec_output ] { - fail "Couldn't get .hash data!" - return -} - -ltrace_saveoutput "${exec_output}" ${srcdir}/${subdir}/${testfile}.ltrace - -# execl from first binary -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {"^execl"} 1 -# puts from second binary -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {"^puts"} 1 -# assume glibc and see we really trace both binaries -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace {"^__libc_start_main"} 2 +ltraceDone diff --git a/testsuite/ltrace.minor/trace-exec1.c b/testsuite/ltrace.minor/trace-exec1.c deleted file mode 100644 index e234fa0..0000000 --- a/testsuite/ltrace.minor/trace-exec1.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <stdio.h> -int main (void) -{ - puts("Hello, World."); - return 0; -} diff --git a/testsuite/ltrace.minor/trace-fork.c b/testsuite/ltrace.minor/trace-fork.c index a2d8a56..c5f0c71 100644 --- a/testsuite/ltrace.minor/trace-fork.c +++ b/testsuite/ltrace.minor/trace-fork.c @@ -21,7 +21,7 @@ main () pid = fork (); if (pid == -1) - printf("fork failed!\n"); + puts("fork failed!"); else if (pid == 0) child(); else diff --git a/testsuite/ltrace.minor/trace-fork.exp b/testsuite/ltrace.minor/trace-fork.exp index 5f30061..70815f5 100644 --- a/testsuite/ltrace.minor/trace-fork.exp +++ b/testsuite/ltrace.minor/trace-fork.exp @@ -7,21 +7,12 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail.\n" } -global LTRACE -set exec_output "" - -#Run PUT for ltrace. -spawn $LTRACE -f $srcdir/$subdir/$binfile -set timeout 4 -expect timeout { - fail "Time out! Maybe caused by ltrace segment fault or improper timeout value here!" - return -} -catch "exec $LTRACE -f $srcdir/$subdir/$binfile" exec_output +ltrace_options "-f" +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] #check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -33,8 +24,22 @@ if [regexp {ELF from incompatible architecture} $exec_output] { return } -ltrace_saveoutput "${exec_output}" ${srcdir}/${subdir}/${testfile}.ltrace +if [ regexp {Cannot attach} $exec_output ] { + fail "Couldn't attach to forked process!" + return +} + +set pattern {^[0-9]* fork} +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern {^[0-9]* printf} +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + +set pattern {^[0-9]* puts} +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "fork" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern {^[0-9]* wait} +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +set pattern {^[0-9]* sleep} +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 diff --git a/testsuite/ltrace.torture/Makefile b/testsuite/ltrace.torture/Makefile.am index bb4baa0..daa772f 100644 --- a/testsuite/ltrace.torture/Makefile +++ b/testsuite/ltrace.torture/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 1992 - 2001 Free Software Foundation, Inc. +# Copyright (C) 1992 - 2001, 2012 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,19 +15,17 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -CLEANFILES = *.log *.sum site.bak setval.tmp site.exp +EXTRA_DIST = \ + ia64-sigill.exp \ + ia64-sigill.s \ + ppc-lwarx.c \ + ppc-lwarx.exp \ + signals.c \ + signals.exp \ + vfork-thread.c \ + vfork-thread.exp -.SUFFIXES: -clean: - -rm -f signals - -rm -f *.o *.so - -rm -f *.ltrace - -rm -f $(CLEANFILES) -distclean: clean +CLEANFILES = *.o *.so *.log *.sum *.ltrace setval.tmp \ + signals - -.PHONY: $(RECURSIVE_TARGETS) check clean distclean realclean - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: +MAINTAINERCLEANFILES = Makefile.in diff --git a/testsuite/ltrace.torture/Makefile.in b/testsuite/ltrace.torture/Makefile.in new file mode 100644 index 0000000..b0ff505 --- /dev/null +++ b/testsuite/ltrace.torture/Makefile.in @@ -0,0 +1,400 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 1992 - 2001, 2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = testsuite/ltrace.torture +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/m4/libtool.m4 \ + $(top_srcdir)/config/m4/ltoptions.m4 \ + $(top_srcdir)/config/m4/ltsugar.m4 \ + $(top_srcdir)/config/m4/ltversion.m4 \ + $(top_srcdir)/config/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HOST_CPU = @HOST_CPU@ +HOST_OS = @HOST_OS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libelf_LD_LIBRARY_PATH = @libelf_LD_LIBRARY_PATH@ +liberty_LIBS = @liberty_LIBS@ +libexecdir = @libexecdir@ +libstdcxx_LIBS = @libstdcxx_LIBS@ +libsupcxx_LIBS = @libsupcxx_LIBS@ +libunwind_LD_LIBRARY_PATH = @libunwind_LD_LIBRARY_PATH@ +libunwind_LIBS = @libunwind_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = \ + ia64-sigill.exp \ + ia64-sigill.s \ + ppc-lwarx.c \ + ppc-lwarx.exp \ + signals.c \ + signals.exp \ + vfork-thread.c \ + vfork-thread.exp + +CLEANFILES = *.o *.so *.log *.sum *.ltrace setval.tmp \ + signals + +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/ltrace.torture/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/ltrace.torture/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/testsuite/ltrace.torture/ppc-lwarx.c b/testsuite/ltrace.torture/ppc-lwarx.c new file mode 100644 index 0000000..0716407 --- /dev/null +++ b/testsuite/ltrace.torture/ppc-lwarx.c @@ -0,0 +1,44 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdint.h> + +__attribute__((noinline, optimize(3))) void +atomic_add(uint32_t *a, uint32_t b) +{ + __asm__ volatile("lwarx 9,0,%0\n" + "add 9,9,%2\n" + "stwcx. 9,0,%0\n" + "bne- atomic_add\n" + : "=r"(a) + : "0"(a), "r"(b) + : "%r9"); +} + +uint32_t a = 0; + +__attribute__((optimize(0))) int +main(int argc, char **argv) +{ + atomic_add(&a, 5); + atomic_add(&a, 10); + atomic_add(&a, 15); + return a; +} diff --git a/testsuite/ltrace.torture/ppc-lwarx.exp b/testsuite/ltrace.torture/ppc-lwarx.exp new file mode 100644 index 0000000..bc2eba4 --- /dev/null +++ b/testsuite/ltrace.torture/ppc-lwarx.exp @@ -0,0 +1,55 @@ +# This file is part of ltrace. +# Copyright (C) 2012 Petr Machata, Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA + +set testfile "ppc-lwarx" +set srcfile ${testfile}.c +set binfile ${testfile} + +if [get_compiler_info $binfile] { + return -1 +} + +if { [istarget powerpc*-*] } then { + verbose "compiling source file now....." + if { [ltrace_compile $srcdir/$subdir/$srcfile $objdir/$subdir/$binfile executable {debug} ] != "" } { + send_user "Testcase compile failed, so all tests in this file will automatically fail\n." + } + + # set options for ltrace. + ltrace_options "-x" "atomic_add" "-e" "!atoi" + + # Run PUT for ltarce. + set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] + + # Check the output of this program. + verbose "ltrace runtest output: $exec_output\n" + if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return + } elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return + } + + set pattern "atomic_add(.*, 5,.*)" + ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + set pattern "atomic_add(.*, 10,.*)" + ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 + set pattern "atomic_add(.*, 15,.*)" + ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 +} diff --git a/testsuite/ltrace.torture/signals.c b/testsuite/ltrace.torture/signals.c index 439aba1..b786c81 100644 --- a/testsuite/ltrace.torture/signals.c +++ b/testsuite/ltrace.torture/signals.c @@ -23,7 +23,7 @@ main () pid_t pid; mysigval.sival_int=0; - sig = 10; + sig = SIGUSR1; pid=getpid(); sigemptyset(&act.sa_mask); diff --git a/testsuite/ltrace.torture/signals.exp b/testsuite/ltrace.torture/signals.exp index 56a2ec9..bf10bc9 100644 --- a/testsuite/ltrace.torture/signals.exp +++ b/testsuite/ltrace.torture/signals.exp @@ -7,7 +7,7 @@ set binfile ${testfile} verbose "compiling source file now....." # Build the shared libraries this test case needs. -if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/${binfile}" executable {debug} ] != "" } { +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable {debug} ] != "" } { send_user "Testcase compile failed, so all tests in this file will automatically fail\n." } @@ -15,7 +15,7 @@ if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${srcdir}/${subdir}/ ltrace_options "-L" # Run PUT for ltarce. -set exec_output [ltrace_runtest $srcdir/$subdir $srcdir/$subdir/$binfile] +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] # Check the output of this program. verbose "ltrace runtest output: $exec_output\n" @@ -33,5 +33,5 @@ while { [gets $fd line] >= 0 } { regexp {define LOOP.*([0-9]+)} $line match count } set pattern "SIGUSR1" -ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern $count +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern $count diff --git a/testsuite/ltrace.torture/vfork-thread.c b/testsuite/ltrace.torture/vfork-thread.c new file mode 100644 index 0000000..f909bd3 --- /dev/null +++ b/testsuite/ltrace.torture/vfork-thread.c @@ -0,0 +1,50 @@ +#include <pthread.h> +#include <unistd.h> +#include <sys/types.h> +#include <stdio.h> + + +void * +routine (void *data) +{ + int i; + for (i = 0; i < 6; ++i) + { + puts ("bleble"); + sleep (1); + } +} + + +void * +routine2 (void *data) +{ + pid_t child = vfork (); + if (child == 0) + { + int i, j; + puts ("vforked"); + for (i = 0; i < 100000; ++i) + for (j = 0; j < 10000; ++j) + ; + puts ("vforked child exiting"); + _exit (0); + } + puts ("parent continuing"); + return NULL; +} + +int +main(int argc, char *argv[]) +{ + pthread_t thread; + pthread_create (&thread, NULL, &routine, NULL); + + sleep (1); + + pthread_t thread2; + pthread_create (&thread2, NULL, &routine2, NULL); + pthread_join (thread2, NULL); + pthread_join (thread, NULL); + return 0; +} diff --git a/testsuite/ltrace.torture/vfork-thread.exp b/testsuite/ltrace.torture/vfork-thread.exp new file mode 100644 index 0000000..bd01319 --- /dev/null +++ b/testsuite/ltrace.torture/vfork-thread.exp @@ -0,0 +1,32 @@ +# This file was written by Yao Qi <qiyao@cn.ibm.com>. + +set testfile "vfork-thread" +set srcfile ${testfile}.c +set binfile ${testfile} + + +verbose "compiling source file now....." +# Build the shared libraries this test case needs. +if { [ ltrace_compile "${srcdir}/${subdir}/${testfile}.c" "${objdir}/${subdir}/${binfile}" executable [list debug ldflags=-pthread] ] != "" } { + send_user "Testcase compile failed, so all tests in this file will automatically fail\n." +} + +ltrace_options "-f" + +# Run PUT for ltarce. +set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] + +# Check the output of this program. +verbose "ltrace runtest output: $exec_output\n" +if [regexp {ELF from incompatible architecture} $exec_output] { + fail "32-bit ltrace can not perform on 64-bit PUTs and rebuild ltrace in 64 bit mode!" + return +} elseif [ regexp {Couldn't get .hash data} $exec_output ] { + fail "Couldn't get .hash data!" + return +} + +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "puts" 9 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "sleep" 7 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "vfork resumed" 2 +ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace "_exit" 1 @@ -0,0 +1,570 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 2007,2008 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <assert.h> +#include <stdlib.h> +#include <limits.h> + +#include "type.h" +#include "sysdep.h" +#include "expr.h" +#include "lens.h" + +struct arg_type_info * +type_get_simple(enum arg_type type) +{ +#define HANDLE(T) { \ + static struct arg_type_info t = { T }; \ + case T: \ + return &t; \ + } + + switch (type) { + HANDLE(ARGTYPE_VOID) + HANDLE(ARGTYPE_INT) + HANDLE(ARGTYPE_UINT) + HANDLE(ARGTYPE_LONG) + HANDLE(ARGTYPE_ULONG) + HANDLE(ARGTYPE_CHAR) + HANDLE(ARGTYPE_SHORT) + HANDLE(ARGTYPE_USHORT) + HANDLE(ARGTYPE_FLOAT) + HANDLE(ARGTYPE_DOUBLE) + +#undef HANDLE + + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + case ARGTYPE_POINTER: + assert(!"Not a simple type!"); + }; + abort(); +} + +static void +type_init_common(struct arg_type_info *info, enum arg_type type) +{ + info->type = type; + info->lens = NULL; + info->own_lens = 0; +} + +struct struct_field { + struct arg_type_info *info; + int own_info; +}; + +void +type_init_struct(struct arg_type_info *info) +{ + type_init_common(info, ARGTYPE_STRUCT); + VECT_INIT(&info->u.entries, struct struct_field); +} + +int +type_struct_add(struct arg_type_info *info, + struct arg_type_info *field_info, int own) +{ + assert(info->type == ARGTYPE_STRUCT); + struct struct_field field = { field_info, own }; + return VECT_PUSHBACK(&info->u.entries, &field); +} + +struct arg_type_info * +type_struct_get(struct arg_type_info *info, size_t idx) +{ + assert(info->type == ARGTYPE_STRUCT); + struct struct_field *field = VECT_ELEMENT(&info->u.entries, + struct struct_field, idx); + if (field == NULL) + return NULL; + return field->info; +} + +size_t +type_struct_size(struct arg_type_info *info) +{ + assert(info->type == ARGTYPE_STRUCT); + return vect_size(&info->u.entries); +} + +static void +struct_field_dtor(struct struct_field *field, void *data) +{ + if (field->own_info) { + type_destroy(field->info); + free(field->info); + } +} + +static void +type_struct_destroy(struct arg_type_info *info) +{ + VECT_DESTROY(&info->u.entries, struct struct_field, + struct_field_dtor, NULL); +} + +static int +layout_struct(struct Process *proc, struct arg_type_info *info, + size_t *sizep, size_t *alignmentp, size_t *offsetofp) +{ + size_t sz = 0; + size_t max_alignment = 0; + size_t i; + size_t offsetof_field = (size_t)-1; + if (offsetofp != NULL) + offsetof_field = *offsetofp; + + assert(info->type == ARGTYPE_STRUCT); + for (i = 0; i < vect_size(&info->u.entries); ++i) { + struct struct_field *field + = VECT_ELEMENT(&info->u.entries, + struct struct_field, i); + + size_t alignment = type_alignof(proc, field->info); + if (alignment == (size_t)-1) + return -1; + + /* Add padding to SZ to align the next element. */ + sz = align(sz, alignment); + if (i == offsetof_field) { + *offsetofp = sz; + if (sizep == NULL && alignmentp == NULL) + return 0; + } + + size_t size = type_sizeof(proc, field->info); + if (size == (size_t)-1) + return -1; + sz += size; + + if (alignment > max_alignment) + max_alignment = alignment; + } + + if (max_alignment > 0) + sz = align(sz, max_alignment); + + if (sizep != NULL) + *sizep = sz; + + if (alignmentp != NULL) + *alignmentp = max_alignment; + + return 0; +} + +void +type_init_array(struct arg_type_info *info, + struct arg_type_info *element_info, int own_info, + struct expr_node *length_expr, int own_length) +{ + type_init_common(info, ARGTYPE_ARRAY); + info->u.array_info.elt_type = element_info; + info->u.array_info.own_info = own_info; + info->u.array_info.length = length_expr; + info->u.array_info.own_length = own_length; +} + +static void +type_array_destroy(struct arg_type_info *info) +{ + if (info->u.array_info.own_info) { + type_destroy(info->u.array_info.elt_type); + free(info->u.array_info.elt_type); + } + if (info->u.array_info.own_length) { + expr_destroy(info->u.array_info.length); + free(info->u.array_info.length); + } +} + +void +type_init_pointer(struct arg_type_info *info, + struct arg_type_info *pointee_info, int own_info) +{ + type_init_common(info, ARGTYPE_POINTER); + info->u.ptr_info.info = pointee_info; + info->u.ptr_info.own_info = own_info; +} + +static void +type_pointer_destroy(struct arg_type_info *info) +{ + if (info->u.ptr_info.own_info) { + type_destroy(info->u.ptr_info.info); + free(info->u.ptr_info.info); + } +} + +void +type_destroy(struct arg_type_info *info) +{ + if (info == NULL) + return; + + switch (info->type) { + case ARGTYPE_STRUCT: + type_struct_destroy(info); + break; + + case ARGTYPE_ARRAY: + type_array_destroy(info); + break; + + case ARGTYPE_POINTER: + type_pointer_destroy(info); + break; + + case ARGTYPE_VOID: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + break; + } + + if (info->own_lens) { + lens_destroy(info->lens); + free(info->lens); + } +} + +#ifdef ARCH_HAVE_SIZEOF +size_t arch_type_sizeof(struct Process *proc, struct arg_type_info * arg); +#else +size_t +arch_type_sizeof(struct Process *proc, struct arg_type_info * arg) +{ + /* Use default value. */ + return (size_t)-2; +} +#endif + +#ifdef ARCH_HAVE_ALIGNOF +size_t arch_type_alignof(struct Process *proc, struct arg_type_info * arg); +#else +size_t +arch_type_alignof(struct Process *proc, struct arg_type_info * arg) +{ + /* Use default value. */ + return (size_t)-2; +} +#endif + +/* We need to support alignments that are not power of two. E.g. long + * double on x86 has alignment of 12. */ +size_t +align(size_t sz, size_t alignment) +{ + assert(alignment != 0); + + if ((sz % alignment) != 0) + sz = ((sz / alignment) + 1) * alignment; + + return sz; +} + +size_t +type_sizeof(struct Process *proc, struct arg_type_info *type) +{ + size_t arch_size = arch_type_sizeof(proc, type); + if (arch_size != (size_t)-2) + return arch_size; + + switch (type->type) { + size_t size; + case ARGTYPE_CHAR: + return sizeof(char); + + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return sizeof(short); + + case ARGTYPE_INT: + case ARGTYPE_UINT: + return sizeof(int); + + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + return sizeof(long); + + case ARGTYPE_FLOAT: + return sizeof(float); + + case ARGTYPE_DOUBLE: + return sizeof(double); + + case ARGTYPE_STRUCT: + if (layout_struct(proc, type, &size, NULL, NULL) < 0) + return (size_t)-1; + return size; + + case ARGTYPE_POINTER: + return sizeof(void *); + + case ARGTYPE_ARRAY: + if (expr_is_compile_constant(type->u.array_info.length)) { + long l; + if (expr_eval_constant(type->u.array_info.length, + &l) < 0) + return -1; + + struct arg_type_info *elt_ti + = type->u.array_info.elt_type; + + size_t elt_size = type_sizeof(proc, elt_ti); + if (elt_size == (size_t)-1) + return (size_t)-1; + + return ((size_t)l) * elt_size; + + } else { + /* Flexible arrays don't count into the + * sizeof. */ + return 0; + } + + case ARGTYPE_VOID: + return 0; + } + + abort(); +} + +#undef alignof +#define alignof(field,st) ((size_t) ((char*) &st.field - (char*) &st)) + +size_t +type_alignof(struct Process *proc, struct arg_type_info *type) +{ + size_t arch_alignment = arch_type_alignof(proc, type); + if (arch_alignment != (size_t)-2) + return arch_alignment; + + struct { char c; char C; } cC; + struct { char c; short s; } cs; + struct { char c; int i; } ci; + struct { char c; long l; } cl; + struct { char c; void* p; } cp; + struct { char c; float f; } cf; + struct { char c; double d; } cd; + + static size_t char_alignment = alignof(C, cC); + static size_t short_alignment = alignof(s, cs); + static size_t int_alignment = alignof(i, ci); + static size_t long_alignment = alignof(l, cl); + static size_t ptr_alignment = alignof(p, cp); + static size_t float_alignment = alignof(f, cf); + static size_t double_alignment = alignof(d, cd); + + switch (type->type) { + size_t alignment; + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + return long_alignment; + case ARGTYPE_CHAR: + return char_alignment; + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return short_alignment; + case ARGTYPE_FLOAT: + return float_alignment; + case ARGTYPE_DOUBLE: + return double_alignment; + case ARGTYPE_POINTER: + return ptr_alignment; + + case ARGTYPE_ARRAY: + return type_alignof(proc, type->u.array_info.elt_type); + + case ARGTYPE_STRUCT: + if (layout_struct(proc, type, NULL, &alignment, NULL) < 0) + return (size_t)-1; + return alignment; + + default: + return int_alignment; + } +} + +size_t +type_offsetof(struct Process *proc, struct arg_type_info *type, size_t emt) +{ + assert(type->type == ARGTYPE_STRUCT + || type->type == ARGTYPE_ARRAY); + + switch (type->type) { + size_t alignment; + size_t size; + case ARGTYPE_ARRAY: + alignment = type_alignof(proc, type->u.array_info.elt_type); + if (alignment == (size_t)-1) + return (size_t)-1; + + size = type_sizeof(proc, type->u.array_info.elt_type); + if (size == (size_t)-1) + return (size_t)-1; + + return emt * align(size, alignment); + + case ARGTYPE_STRUCT: + if (layout_struct(proc, type, NULL, NULL, &emt) < 0) + return (size_t)-1; + return emt; + + default: + abort(); + } +} + +struct arg_type_info * +type_element(struct arg_type_info *info, size_t emt) +{ + assert(info->type == ARGTYPE_STRUCT + || info->type == ARGTYPE_ARRAY); + + switch (info->type) { + case ARGTYPE_ARRAY: + return info->u.array_info.elt_type; + + case ARGTYPE_STRUCT: + assert(emt < type_struct_size(info)); + return type_struct_get(info, emt); + + default: + abort(); + } +} + +size_t +type_aggregate_size(struct arg_type_info *info) +{ + assert(info->type == ARGTYPE_STRUCT + || info->type == ARGTYPE_ARRAY); + + switch (info->type) { + long ret; + case ARGTYPE_ARRAY: + if (expr_eval_constant(info->u.array_info.length, &ret) < 0) + return (size_t)-1; + return (size_t)ret; + + case ARGTYPE_STRUCT: + return type_struct_size(info); + + default: + abort(); + } +} + +int +type_is_integral(enum arg_type type) +{ + switch (type) { + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_LONG: + case ARGTYPE_ULONG: + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_USHORT: + return 1; + + case ARGTYPE_VOID: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + case ARGTYPE_POINTER: + return 0; + } + abort(); +} + +int +type_is_signed(enum arg_type type) +{ + assert(type_is_integral(type)); + + switch (type) { + case ARGTYPE_CHAR: + return CHAR_MIN != 0; + + case ARGTYPE_SHORT: + case ARGTYPE_INT: + case ARGTYPE_LONG: + return 1; + + case ARGTYPE_UINT: + case ARGTYPE_ULONG: + case ARGTYPE_USHORT: + return 0; + + case ARGTYPE_VOID: + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + case ARGTYPE_ARRAY: + case ARGTYPE_STRUCT: + case ARGTYPE_POINTER: + abort(); + } + abort(); +} + +struct arg_type_info * +type_get_fp_equivalent(struct arg_type_info *info) +{ + /* Extract innermost structure. Give up early if any + * component has more than one element. */ + while (info->type == ARGTYPE_STRUCT) { + if (type_struct_size(info) != 1) + return NULL; + info = type_element(info, 0); + } + + switch (info->type) { + case ARGTYPE_CHAR: + case ARGTYPE_SHORT: + case ARGTYPE_INT: + case ARGTYPE_LONG: + case ARGTYPE_UINT: + case ARGTYPE_ULONG: + case ARGTYPE_USHORT: + case ARGTYPE_VOID: + case ARGTYPE_ARRAY: + case ARGTYPE_POINTER: + return NULL; + + case ARGTYPE_FLOAT: + case ARGTYPE_DOUBLE: + return info; + + case ARGTYPE_STRUCT: + abort(); + } + abort(); +} @@ -0,0 +1,145 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * Copyright (C) 1997-2009 Juan Cespedes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef TYPE_H +#define TYPE_H + +#include <stddef.h> +#include "forward.h" +#include "vect.h" + +enum arg_type { + ARGTYPE_VOID, + ARGTYPE_INT, + ARGTYPE_UINT, + ARGTYPE_LONG, + ARGTYPE_ULONG, + ARGTYPE_CHAR, + ARGTYPE_SHORT, + ARGTYPE_USHORT, + ARGTYPE_FLOAT, + ARGTYPE_DOUBLE, + ARGTYPE_ARRAY, /* Series of values in memory */ + ARGTYPE_STRUCT, /* Structure of values */ + ARGTYPE_POINTER, /* Pointer to some other type */ +}; + +struct arg_type_info { + enum arg_type type; + union { + struct vect entries; + + /* ARGTYPE_ARRAY */ + struct { + struct arg_type_info *elt_type; + struct expr_node *length; + int own_info:1; + int own_length:1; + } array_info; + + /* ARGTYPE_POINTER */ + struct { + struct arg_type_info *info; + int own_info:1; + } ptr_info; + } u; + + struct lens *lens; + int own_lens; +}; + +/* Return a type info for simple type TYPE (which shall not be array, + * struct, or pointer. Each call with the same TYPE yields the same + * arg_type_info pointer. */ +struct arg_type_info *type_get_simple(enum arg_type type); + +/* Initialize INFO so it becomes ARGTYPE_STRUCT. The created + * structure contains no fields. Use type_struct_add to populate the + * structure. */ +void type_init_struct(struct arg_type_info *info); + +/* Add a new field of type FIELD_INFO to a structure INFO. If OWN, + * the field type is owned and destroyed together with INFO. */ +int type_struct_add(struct arg_type_info *info, + struct arg_type_info *field_info, int own); + +/* Get IDX-th field of structure type INFO. */ +struct arg_type_info *type_struct_get(struct arg_type_info *info, size_t idx); + +/* Return number of fields of structure type INFO. */ +size_t type_struct_size(struct arg_type_info *info); + +/* Return number of elements of an aggregate type INFO. This can be + * either ARGTYPE_STRUCT or ARGTYPE_ARRAY of constant length. If + * ARGTYPE_ARRAY does not have a constant length, this returns -1. */ +size_t type_aggregate_size(struct arg_type_info *info); + +/* Initialize INFO so it becomes ARGTYPE_ARRAY. The element type is + * passed in ELEMENT_INFO, and array length in LENGTH_EXPR. If, + * respectively, OWN_INFO and OWN_LENGTH are true, the pointee and + * length are owned and destroyed together with INFO. */ +void type_init_array(struct arg_type_info *info, + struct arg_type_info *element_info, int own_info, + struct expr_node *length_expr, int own_length); + +/* Initialize INFO so it becomes ARGTYPE_POINTER. The pointee type is + * passed in POINTEE_INFO. If OWN_INFO, the pointee type is owned and + * destroyed together with INFO. */ +void type_init_pointer(struct arg_type_info *info, + struct arg_type_info *pointee_info, int own_info); + +/* Release any memory associated with INFO. Doesn't free INFO + * itself. */ +void type_destroy(struct arg_type_info *info); + +/* Compute a size of given type. Return (size_t)-1 for error. */ +size_t type_sizeof(struct Process *proc, struct arg_type_info *type); + +/* Compute an alignment necessary for elements of this type. Return + * (size_t)-1 for error. */ +size_t type_alignof(struct Process *proc, struct arg_type_info *type); + +/* Align value SZ to ALIGNMENT and return the result. */ +size_t align(size_t sz, size_t alignment); + +/* Return ELT-th element of compound type TYPE. This is useful for + * arrays and structures. */ +struct arg_type_info *type_element(struct arg_type_info *type, size_t elt); + +/* Compute an offset of EMT-th element of type TYPE. This works for + * arrays and structures. Return (size_t)-1 for error. */ +size_t type_offsetof(struct Process *proc, + struct arg_type_info *type, size_t elt); + +/* Whether TYPE is an integral type as defined by the C standard. */ +int type_is_integral(enum arg_type type); + +/* Whether TYPE, which shall be integral, is a signed type. */ +int type_is_signed(enum arg_type type); + +/* If INFO is floating point equivalent type, return the corresponding + * floating point type. Otherwise return NULL. Floating point + * equivalent types are either ARGTYPE_FLOAT, or ARGTYPE_DOUBLE, or + * ARGTYPE_STRUCT whose sole member is a floating point equivalent + * type. */ +struct arg_type_info *type_get_fp_equivalent(struct arg_type_info *info); + +#endif /* TYPE_H */ @@ -0,0 +1,485 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <string.h> +#include <assert.h> +#include <stdlib.h> + +#include "value.h" +#include "type.h" +#include "common.h" +#include "expr.h" +#include "backend.h" + +static void +value_common_init(struct value *valp, struct Process *inferior, + struct value *parent, struct arg_type_info *type, + int own_type) +{ + valp->type = type; + valp->own_type = own_type; + valp->inferior = inferior; + memset(&valp->u, 0, sizeof(valp->u)); + valp->where = VAL_LOC_NODATA; + valp->parent = parent; + valp->size = (size_t)-1; +} + +void +value_init(struct value *valp, struct Process *inferior, struct value *parent, + struct arg_type_info *type, int own_type) +{ + assert(inferior != NULL); + value_common_init(valp, inferior, parent, type, own_type); +} + +void +value_init_detached(struct value *valp, struct value *parent, + struct arg_type_info *type, int own_type) +{ + value_common_init(valp, NULL, parent, type, own_type); +} + +void +value_set_type(struct value *value, struct arg_type_info *type, int own_type) +{ + if (value->own_type) { + type_destroy(value->type); + free(value->type); + } + value->type = type; + value->own_type = own_type; +} + +void +value_take_type(struct value *value, struct arg_type_info **type, + int *own_type) +{ + *type = value->type; + *own_type = value->own_type; + value->own_type = 0; +} + +void +value_release(struct value *val) +{ + if (val == NULL) + return; + if (val->where == VAL_LOC_COPY) { + free(val->u.address); + val->where = VAL_LOC_NODATA; + } +} + +void +value_destroy(struct value *val) +{ + if (val == NULL) + return; + value_release(val); + value_set_type(val, NULL, 0); +} + +unsigned char * +value_reserve(struct value *valp, size_t size) +{ + value_release(valp); + + if (size <= sizeof(valp->u.value)) { + valp->where = VAL_LOC_WORD; + valp->u.value = 0; + } else { + valp->where = VAL_LOC_COPY; + valp->u.address = calloc(size, 1); + if (valp->u.address == 0) + return NULL; + } + return value_get_raw_data(valp); +} + +void +value_in_inferior(struct value *valp, arch_addr_t address) +{ + value_release(valp); + valp->where = VAL_LOC_INFERIOR; + valp->u.address = address; +} + +int +value_reify(struct value *val, struct value_dict *arguments) +{ + if (val->where != VAL_LOC_INFERIOR) + return 0; + assert(val->inferior != NULL); + + size_t size = value_size(val, arguments); + if (size == (size_t)-1) + return -1; + + void *data; + enum value_location_t nloc; + if (size <= sizeof(val->u.value)) { + data = &val->u.value; + nloc = VAL_LOC_WORD; + } else { + data = malloc(size); + if (data == NULL) + return -1; + nloc = VAL_LOC_COPY; + } + + if (umovebytes(val->inferior, val->u.inf_address, data, size) < size) { + if (nloc == VAL_LOC_COPY) + free(data); + return -1; + } + + val->where = nloc; + if (nloc == VAL_LOC_COPY) + val->u.address = data; + + return 0; +} + +unsigned char * +value_get_data(struct value *val, struct value_dict *arguments) +{ + if (value_reify(val, arguments) < 0) + return NULL; + return value_get_raw_data(val); +} + +unsigned char * +value_get_raw_data(struct value *val) +{ + switch (val->where) { + case VAL_LOC_INFERIOR: + abort(); + case VAL_LOC_NODATA: + return NULL; + case VAL_LOC_COPY: + case VAL_LOC_SHARED: + return val->u.address; + case VAL_LOC_WORD: + return val->u.buf; + } + + assert(!"Unexpected value of val->where"); + abort(); +} + +int +value_clone(struct value *retp, const struct value *val) +{ + *retp = *val; + if (val->where == VAL_LOC_COPY) { + assert(val->inferior != NULL); + size_t size = type_sizeof(val->inferior, val->type); + if (size == (size_t)-1) + return -1; + + retp->u.address = malloc(size); + if (retp->u.address == NULL) + return -1; + + memcpy(retp->u.address, val->u.address, size); + } + + return 0; +} + +size_t +value_size(struct value *val, struct value_dict *arguments) +{ + if (val->size != (size_t)-1) + return val->size; + + if (val->type->type != ARGTYPE_ARRAY) + return val->size = type_sizeof(val->inferior, val->type); + + struct value length; + if (expr_eval(val->type->u.array_info.length, val, + arguments, &length) < 0) + return (size_t)-1; + + size_t l; + int o = value_extract_word(&length, (long *)&l, arguments); + value_destroy(&length); + + if (o < 0) + return (size_t)-1; + + size_t elt_size = type_sizeof(val->inferior, + val->type->u.array_info.elt_type); + if (elt_size == (size_t)-1) + return (size_t)-1; + + return val->size = elt_size * l; +} + +int +value_init_element(struct value *ret_val, struct value *val, size_t element) +{ + size_t off = type_offsetof(val->inferior, val->type, element); + if (off == (size_t)-1) + return -1; + + struct arg_type_info *e_info = type_element(val->type, element); + if (e_info == NULL) + return -1; + + value_common_init(ret_val, val->inferior, val, e_info, 0); + + switch (val->where) { + case VAL_LOC_COPY: + case VAL_LOC_SHARED: + ret_val->u.address = val->u.address + off; + ret_val->where = VAL_LOC_SHARED; + return 0; + + case VAL_LOC_WORD: + ret_val->u.address = value_get_raw_data(val) + off; + ret_val->where = VAL_LOC_SHARED; + return 0; + + case VAL_LOC_INFERIOR: + ret_val->u.inf_address = val->u.inf_address + off; + ret_val->where = VAL_LOC_INFERIOR; + return 0; + + case VAL_LOC_NODATA: + assert(!"Can't offset NODATA."); + abort(); + } + abort(); +} + +int +value_init_deref(struct value *ret_val, struct value *valp) +{ + assert(valp->type->type == ARGTYPE_POINTER); + + /* Note: extracting a pointer value should not need value_dict + * with function arguments. */ + long l; + if (value_extract_word(valp, &l, NULL) < 0) + return -1; + + /* We need "long" to be long enough to hold platform + * pointers. */ + typedef char assert__long_enough_long[-(sizeof(l) < sizeof(void *))]; + + value_common_init(ret_val, valp->inferior, valp, + valp->type->u.ptr_info.info, 0); + ret_val->u.value = l; /* Set the address. */ + ret_val->where = VAL_LOC_INFERIOR; + return 0; +} + +/* The functions value_extract_buf and value_extract_word assume that + * data in VALUE is stored at the start of the internal buffer. For + * value_extract_buf in particular there's no other reasonable + * default. If we need to copy out four bytes, they need to be the + * bytes pointed to by the buffer pointer. + * + * But actually the situation is similar for value_extract_word as + * well. This function is used e.g. to extract characters from + * strings. Those weren't stored by value_set_word, they might still + * be in client for all we know. So value_extract_word has to assume + * that the whole of data is data is stored at the buffer pointer. + * + * This is a problem on big endian machines, where 2-byte quantity + * carried in 4- or 8-byte long is stored at the end of that long. + * (Though that quantity itself is still big endian.) So we need to + * make a little dance to shift the value to the right part of the + * buffer. */ + +union word_data { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + long l; + unsigned char buf[0]; +} u; + +void +value_set_word(struct value *value, long word) +{ + size_t sz = type_sizeof(value->inferior, value->type); + assert(sz != (size_t)-1); + assert(sz <= sizeof(value->u.value)); + + value->where = VAL_LOC_WORD; + + union word_data u = {}; + + switch (sz) { + case 0: + u.l = 0; + break; + case 1: + u.u8 = word; + break; + case 2: + u.u16 = word; + break; + case 4: + u.u32 = word; + break; + case 8: + u.u64 = word; + break; + default: + assert(sz != sz); + abort(); + } + + value->u.value = u.l; +} + +static int +value_extract_buf_sz(struct value *value, unsigned char *tgt, size_t sz, + struct value_dict *arguments) +{ + unsigned char *data = value_get_data(value, arguments); + if (data == NULL) + return -1; + + memcpy(tgt, data, sz); + return 0; +} + +int +value_extract_word(struct value *value, long *retp, + struct value_dict *arguments) +{ + size_t sz = type_sizeof(value->inferior, value->type); + if (sz == (size_t)-1) + return -1; + assert(sz <= sizeof(value->u.value)); + + if (sz == 0) { + *retp = 0; + return 0; + } + + union word_data u = {}; + if (value_extract_buf_sz(value, u.buf, sz, arguments) < 0) + return -1; + + switch (sz) { + case 1: + *retp = (long)u.u8; + return 0; + case 2: + *retp = (long)u.u16; + return 0; + case 4: + *retp = (long)u.u32; + return 0; + case 8: + *retp = (long)u.u64; + return 0; + default: + assert(sz != sz); + abort(); + } +} + +int +value_extract_buf(struct value *value, unsigned char *tgt, + struct value_dict *arguments) +{ + size_t sz = type_sizeof(value->inferior, value->type); + if (sz == (size_t)-1) + return -1; + + return value_extract_buf_sz(value, tgt, sz, arguments); +} + +struct value * +value_get_parental_struct(struct value *val) +{ + struct value *parent; + for (parent = val->parent; parent != NULL; parent = parent->parent) + if (parent->type->type == ARGTYPE_STRUCT) + return parent; + return NULL; +} + +int +value_is_zero(struct value *val, struct value_dict *arguments) +{ + unsigned char *data = value_get_data(val, arguments); + if (data == NULL) + return -1; + size_t sz = type_sizeof(val->inferior, val->type); + if (sz == (size_t)-1) + return -1; + + int zero = 1; + size_t j; + for (j = 0; j < sz; ++j) { + if (data[j] != 0) { + zero = 0; + break; + } + } + return zero; +} + +int +value_equal(struct value *val1, struct value *val2, + struct value_dict *arguments) +{ + size_t sz1 = type_sizeof(val1->inferior, val1->type); + size_t sz2 = type_sizeof(val2->inferior, val2->type); + if (sz1 == (size_t)-1 || sz2 == (size_t)-1) + return -1; + if (sz1 != sz2) + return 0; + + unsigned char *data1 = value_get_data(val1, arguments); + unsigned char *data2 = value_get_data(val2, arguments); + if (data1 == NULL || data2 == NULL) + return -1; + return memcmp(data1, data2, sz1) == 0 ? 1 : 0; +} + +int +value_pass_by_reference(struct value *value) +{ + assert(value != NULL); + assert(value->type->type == ARGTYPE_STRUCT); + + struct arg_type_info *new_info = calloc(sizeof(*new_info), 1); + if (new_info == NULL) + return -1; + + int own; + struct arg_type_info *orig; + value_take_type(value, &orig, &own); + type_init_pointer(new_info, orig, own); + new_info->lens = orig->lens; + value_set_type(value, new_info, 1); + + return 0; +} @@ -0,0 +1,164 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef VALUE_H +#define VALUE_H + +#include "forward.h" +#include "sysdep.h" + +/* Values are objects that capture data fetched from an inferior. + * Typically a value is attached to a single inferior where it was + * extracted from, but it is possible to create a detached value. + * Each value is typed. Values support a number of routines, such as + * dereferencing if the value is of pointer type, array or structure + * access, etc. + * + * A value can be uninitialized, abstract or reified. Abstract values + * are just references into inferior, no transfer has taken place yet. + * Reified values have been copied out of the corresponding inferior, + * or otherwise set to some value. */ + +enum value_location_t { + VAL_LOC_NODATA = 0, /* Uninitialized. */ + VAL_LOC_INFERIOR, /* Value is in the inferior process. */ + VAL_LOC_COPY, /* Value was copied out of the inferior. */ + VAL_LOC_SHARED, /* Like VAL_LOC_COPY, but don't free. */ + VAL_LOC_WORD, /* Like VAL_LOC_COPY, but small enough. */ +}; + +struct value { + struct arg_type_info *type; + struct Process *inferior; + struct value *parent; + size_t size; + union { + void *address; /* VAL_LOC_COPY, VAL_LOC_SHARED */ + arch_addr_t inf_address; /* VAL_LOC_INFERIOR */ + long value; /* VAL_LOC_WORD */ + unsigned char buf[0]; + } u; + enum value_location_t where; + int own_type; +}; + +/* Initialize VALUE. INFERIOR must not be NULL. PARENT is parental + * value, in case of compound types. It may be NULL. TYPE is a type + * of the value. It may be NULL if the type is not yet known. If + * OWN_TYPE, the passed-in type is owned and released by value. */ +void value_init(struct value *value, struct Process *inferior, + struct value *parent, struct arg_type_info *type, + int own_type); + +/* Initialize VALUE. This is like value_init, except that inferior is + * NULL. VALP is initialized as a detached value, without assigned + * process. You have to be careful not to use VAL_LOC_INFERIOR + * values if the value is detached. */ +void value_init_detached(struct value *value, struct value *parent, + struct arg_type_info *type, int own_type); + +/* Set TYPE. This releases old type if it was owned. TYPE is owned + * and released if OWN_TYPE. */ +void value_set_type(struct value *value, + struct arg_type_info *type, int own_type); + +/* Transfers the ownership of VALUE's type, if any, to the caller. + * This doesn't reset the VALUE's type, but gives up ownership if + * there was one. Previous ownership is passed in OWN_TYPE. */ +void value_take_type(struct value *value, + struct arg_type_info **type, int *own_type); + +/* Release the data held by VALP, if any, but not the type. */ +void value_release(struct value *valp); + +/* Value resides in inferior, on given ADDRESS. */ +void value_in_inferior(struct value *valp, arch_addr_t address); + +/* Destroy the value. This is like value_release, but it additionally + * frees the value type, if it's own_type. It doesn't free the VAL + * pointer itself. */ +void value_destroy(struct value *val); + +/* Set the data held by VALP to VALUE. This also sets the value's + * where to VAL_LOC_WORD. */ +void value_set_word(struct value *valp, long value); + +/* Set the data held by VALP to a buffer of size SIZE. This buffer + * may be allocated by malloc. Returns NULL on failure. */ +unsigned char *value_reserve(struct value *valp, size_t size); + +/* Access ELEMENT-th field of the compound value VALP, and store the + * result into the value RET_VAL. Returns 0 on success, or negative + * value on failure. */ +int value_init_element(struct value *ret_val, struct value *valp, size_t element); + +/* De-reference pointer value, and store the result into the value + * RET_VAL. Returns 0 on success, or negative value on failure. */ +int value_init_deref(struct value *ret_val, struct value *valp); + +/* If value is in inferior, copy it over to ltrace. Return 0 for + * success or negative value for failure. */ +int value_reify(struct value *val, struct value_dict *arguments); + +/* Return a pointer to the data of the value. This copies the data + * from the inferior to the tracer. Returns NULL on failure. */ +unsigned char *value_get_data(struct value *val, struct value_dict *arguments); + +/* Return a pointer to the raw data of the value. This shall not be + * called on a VAL_LOC_INFERIOR value. */ +unsigned char *value_get_raw_data(struct value *val); + +/* Copy value VAL into the area pointed-to by RETP. Return 0 on + * success or a negative value on failure. */ +int value_clone(struct value *retp, const struct value *val); + +/* Give a size of given value. Return (size_t)-1 for error. This is + * a full size of the value. In particular for arrays, it returns + * actual length of the array, as computed by the length + * expression. */ +size_t value_size(struct value *val, struct value_dict *arguments); + +/* Extract at most word-sized datum from the value. Return 0 on + * success or negative value on failure. */ +int value_extract_word(struct value *val, long *retp, + struct value_dict *arguments); + +/* Copy contents of VAL to DATA. The buffer must be large enough to + * hold all the data inside. */ +int value_extract_buf(struct value *val, unsigned char *data, + struct value_dict *arguments); + +/* Find the most enclosing parental value that is a struct. Return + * NULL when there is no such parental value. */ +struct value *value_get_parental_struct(struct value *val); + +/* Determine whether this is all-zero value. Returns >0 if it is, ==0 + * if it isn't, <0 on error. */ +int value_is_zero(struct value *val, struct value_dict *arguments); + +/* Compare two values for byte-by-byte equality. Returns >0 if they + * are equal, ==0 if they are not, and <0 on error. */ +int value_equal(struct value *val1, struct value *val2, + struct value_dict *arguments); + +/* Convert a structure type to pointer to that structure type. */ +int value_pass_by_reference(struct value *value); + +#endif /* VALUE_H */ diff --git a/value_dict.c b/value_dict.c new file mode 100644 index 0000000..d9c46d4 --- /dev/null +++ b/value_dict.c @@ -0,0 +1,148 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <assert.h> +#include <string.h> +#include <stdlib.h> + +#include "value_dict.h" +#include "value.h" + +struct named_value +{ + const char *name; + struct value value; + int own_name; +}; + +void +val_dict_init(struct value_dict *dict) +{ + VECT_INIT(&dict->numbered, struct value); + VECT_INIT(&dict->named, struct named_value); +} + +static int +value_clone_cb(struct value *tgt, const struct value *src, void *data) +{ + return value_clone(tgt, src); +} + +static void +value_dtor(struct value *val, void *data) +{ + value_destroy(val); +} + +static int +named_value_clone(struct named_value *tgt, + const struct named_value *src, void *data) +{ + tgt->name = strdup(src->name); + if (tgt->name == NULL) + return -1; + tgt->own_name = 1; + if (value_clone(&tgt->value, &src->value) < 0) { + free((char *)tgt->name); + return -1; + } + return 0; +} + +static void +named_value_dtor(struct named_value *named, void *data) +{ + if (named->own_name) + free((char *)named->name); + value_destroy(&named->value); +} + +int +val_dict_clone(struct value_dict *target, struct value_dict *source) +{ + if (VECT_CLONE(&target->numbered, &source->numbered, struct value, + value_clone_cb, value_dtor, NULL) < 0) + return -1; + + if (VECT_CLONE(&target->named, &source->named, struct named_value, + named_value_clone, named_value_dtor, NULL) < 0) { + VECT_DESTROY(&target->numbered, struct value, value_dtor, NULL); + return -1; + } + + return 0; +} + +int +val_dict_push_next(struct value_dict *dict, struct value *val) +{ + return VECT_PUSHBACK(&dict->numbered, val); +} + +int +val_dict_push_named(struct value_dict *dict, struct value *val, + const char *name, int own_name) +{ + if (own_name && (name = strdup(name)) == NULL) + return -1; + struct named_value element = { name, *val, own_name }; + if (VECT_PUSHBACK(&dict->named, &element) < 0) { + if (own_name) + free((char *)name); + return -1; + } + return 0; +} + +size_t +val_dict_count(struct value_dict *dict) +{ + return vect_size(&dict->numbered); +} + +struct value * +val_dict_get_num(struct value_dict *dict, size_t num) +{ + assert(num < vect_size(&dict->numbered)); + return VECT_ELEMENT(&dict->numbered, struct value, num); +} + +struct value * +val_dict_get_name(struct value_dict *dict, const char *name) +{ + size_t i; + for (i = 0; i < vect_size(&dict->named); ++i) { + struct named_value *element + = VECT_ELEMENT(&dict->named, struct named_value, i); + if (strcmp(element->name, name) == 0) + return &element->value; + } + return NULL; +} + +void +val_dict_destroy(struct value_dict *dict) +{ + if (dict == NULL) + return; + + VECT_DESTROY(&dict->numbered, struct value, value_dtor, NULL); + VECT_DESTROY(&dict->named, struct named_value, named_value_dtor, NULL); +} diff --git a/value_dict.h b/value_dict.h new file mode 100644 index 0000000..f75ee37 --- /dev/null +++ b/value_dict.h @@ -0,0 +1,67 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef ARGS_H +#define ARGS_H + +#include "forward.h" +#include "vect.h" + +/* Value dictionary is used to store actual function arguments. It + * supports both numbered and named arguments. */ +struct value_dict +{ + struct vect numbered; + struct vect named; +}; + +/* Initialize DICT. */ +void val_dict_init(struct value_dict *dict); + +/* Clone SOURCE into TARGET. Return 0 on success or a negative value + * on failure. */ +int val_dict_clone(struct value_dict *target, struct value_dict *source); + +/* Push next numbered value, VAL. The value is copied over and the + * dictionary becomes its owner, and is responsible for destroying it + * later. Returns 0 on success and a negative value on failure. */ +int val_dict_push_next(struct value_dict *dict, struct value *val); + +/* Return count of numbered arguments. */ +size_t val_dict_count(struct value_dict *dict); + +/* Push value VAL named NAME. See notes at val_dict_push_next about + * value ownership. The name is owned and freed if OWN_NAME is + * non-zero. */ +int val_dict_push_named(struct value_dict *dict, struct value *val, + const char *name, int own_name); + +/* Get NUM-th numbered argument, or NULL if there's not that much + * arguments. */ +struct value *val_dict_get_num(struct value_dict *dict, size_t num); + +/* Get argument named NAME, or NULL if there's no such argument. */ +struct value *val_dict_get_name(struct value_dict *dict, const char *name); + +/* Destroy the dictionary and all the values in it. Note that DICT + * itself (the pointer) is not freed. */ +void val_dict_destroy(struct value_dict *dict); + +#endif /* ARGS_H */ @@ -0,0 +1,172 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include "vect.h" + +static void * +slot(struct vect *vec, size_t i) +{ + return ((unsigned char *)vec->data) + vec->elt_size * i; +} + +static const void * +cslot(const struct vect *vec, size_t i) +{ + return ((const unsigned char *)vec->data) + vec->elt_size * i; +} + +void +vect_init(struct vect *vec, size_t elt_size) +{ + *vec = (struct vect){ NULL, 0, 0, elt_size }; +} + +static int +copy_elt(void *tgt, const void *src, void *data) +{ + struct vect *target = data; + memcpy(tgt, src, target->elt_size); + return 0; +} + +int +vect_clone(struct vect *target, const struct vect *source, + int (*clone)(void *tgt, const void *src, void *data), + void (*dtor)(void *elt, void *data), + void *data) +{ + vect_init(target, source->elt_size); + if (vect_reserve(target, source->size) < 0) + return -1; + + if (clone == NULL) { + assert(dtor == NULL); + clone = copy_elt; + data = target; + } else { + assert(dtor != NULL); + } + + size_t i; + for (i = 0; i < source->size; ++i) + if (clone(slot(target, i), cslot(source, i), data) < 0) + goto fail; + + target->size = source->size; + return 0; + +fail: + /* N.B. destroy the elements in opposite order. */ + if (dtor != NULL) + while (i-- != 0) + dtor(slot(target, i), data); + vect_destroy(target, NULL, NULL); + return -1; +} + +int +vect_reserve(struct vect *vec, size_t count) +{ + if (count > vec->allocated) { + size_t na = vec->allocated != 0 ? 2 * vec->allocated : 4; + while (na < count) + na *= 2; + void *n = realloc(vec->data, na * vec->elt_size); + if (n == NULL) + return -1; + vec->data = n; + vec->allocated = na; + } + assert(count <= vec->allocated); + return 0; +} + +size_t +vect_size(const struct vect *vec) +{ + return vec->size; +} + +int +vect_empty(const struct vect *vec) +{ + return vec->size == 0; +} + +int +vect_reserve_additional(struct vect *vec, size_t count) +{ + return vect_reserve(vec, vect_size(vec) + count); +} + +int +vect_pushback(struct vect *vec, void *eltp) +{ + if (vect_reserve_additional(vec, 1) < 0) + return -1; + memcpy(slot(vec, vec->size++), eltp, vec->elt_size); + return 0; +} + +void +vect_popback(struct vect *vec) +{ + vec->size--; +} + +void +vect_destroy(struct vect *vec, void (*dtor)(void *emt, void *data), void *data) +{ + if (vec == NULL) + return; + + if (dtor != NULL) { + size_t i; + size_t sz = vect_size(vec); + for (i = 0; i < sz; ++i) + dtor(slot(vec, i), data); + } + free(vec->data); +} + +void * +vect_each(struct vect *vec, void *start_after, + enum callback_status (*cb)(void *, void *), void *data) +{ + size_t i = start_after == NULL ? 0 + : ((start_after - vec->data) / vec->elt_size) + 1; + + for (; i < vec->size; ++i) { + void *slt = slot(vec, i); + switch ((*cb)(slt, data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + return slt; + case CBS_CONT: + break; + } + } + + return NULL; +} @@ -0,0 +1,150 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef VECT_H +#define VECT_H + +#include <stddef.h> +#include <assert.h> + +#include "callback.h" + +/* Vector is an array that can grow as needed to accommodate the data + * that it needs to hold. ELT_SIZE is also used as an elementary + * sanity check, because the array itself is not typed. */ + +struct vect +{ + void *data; + size_t size; /* In elements. */ + size_t allocated; /* In elements. */ + size_t elt_size; /* In bytes. */ +}; + +/* Initialize VEC, which will hold elements of size ELT_SIZE. */ +void vect_init(struct vect *vec, size_t elt_size); + +/* Initialize VECP, which will hold elements of type ELT_TYPE. */ +#define VECT_INIT(VECP, ELT_TYPE) \ + (vect_init(VECP, sizeof(ELT_TYPE))) + +/* Initialize TARGET by copying over contents of vector SOURCE. If + * CLONE is non-NULL, it's evoked on each element, and should clone + * SRC into TGT. It should return 0 on success or negative value on + * failure. DATA is passed to CLONE verbatim. This function returns + * 0 on success or negative value on failure. In case of failure, if + * DTOR is non-NULL, it is invoked on all hitherto created elements + * with the same DATA. If one of CLONE, DTOR is non-NULL, then both + * have to be. */ +int vect_clone(struct vect *target, const struct vect *source, + int (*clone)(void *tgt, const void *src, void *data), + void (*dtor)(void *elt, void *data), + void *data); + +/* Destroy VEC, which holds elements of type ELT_TYPE, using DTOR. */ +#define VECT_CLONE(TGT_VEC, SRC_VEC, ELT_TYPE, CLONE, DTOR, DATA) \ + /* xxx GCC-ism necessary to get in the safety latches. */ \ + ({ \ + const struct vect *_source_vec = (SRC_VEC); \ + assert(_source_vec->elt_size == sizeof(ELT_TYPE)); \ + /* Check that callbacks are typed properly. */ \ + void (*_dtor_callback)(ELT_TYPE *, void *) = DTOR; \ + int (*_clone_callback)(ELT_TYPE *, const ELT_TYPE *, \ + void *) = CLONE; \ + vect_clone((TGT_VEC), _source_vec, \ + (int (*)(void *, const void *, \ + void *))_clone_callback, \ + (void (*)(void *, void *))_dtor_callback, \ + DATA); \ + }) + +/* Return number of elements in VEC. */ +size_t vect_size(const struct vect *vec); + +/* Emptiness predicate. */ +int vect_empty(const struct vect *vec); + +/* Accessor. Fetch ELT_NUM-th argument of type ELT_TYPE from the + * vector referenced by VECP. */ +#define VECT_ELEMENT(VECP, ELT_TYPE, ELT_NUM) \ + (assert((VECP)->elt_size == sizeof(ELT_TYPE)), \ + assert((ELT_NUM) < (VECP)->size), \ + ((ELT_TYPE *)(VECP)->data) + (ELT_NUM)) + +#define VECT_BACK(VECP, ELT_TYPE) \ + VECT_ELEMENT(VECP, ELT_TYPE, (VECP)->size - 1) + +/* Copy element referenced by ELTP to the end of VEC. The object + * referenced by ELTP is now owned by VECT. Returns 0 if the + * operation was successful, or negative value on error. */ +int vect_pushback(struct vect *vec, void *eltp); + +/* Drop last element of VECP. */ +void vect_popback(struct vect *vec); + +/* Copy element referenced by ELTP to the end of VEC. See + * vect_pushback for details. In addition, make a check whether VECP + * holds elements of the right size. */ +#define VECT_PUSHBACK(VECP, ELTP) \ + (assert((VECP)->elt_size == sizeof(*(ELTP))), \ + vect_pushback((VECP), (ELTP))) + +/* Make sure that VEC can hold at least COUNT elements. Return 0 on + * success, negative value on failure. */ +int vect_reserve(struct vect *vec, size_t count); + +/* Make sure that VEC can accommodate COUNT additional elements. */ +int vect_reserve_additional(struct vect *vec, size_t count); + +/* Destroy VEC. If DTOR is non-NULL, then it's called on each element + * of the vector. DATA is passed to DTOR verbatim. The memory + * pointed-to by VEC is not freed. */ +void vect_destroy(struct vect *vec, + void (*dtor)(void *emt, void *data), void *data); + +/* Destroy VEC, which holds elements of type ELT_TYPE, using DTOR. */ +#define VECT_DESTROY(VECP, ELT_TYPE, DTOR, DATA) \ + do { \ + assert((VECP)->elt_size == sizeof(ELT_TYPE)); \ + /* Check that DTOR is typed properly. */ \ + void (*_dtor_callback)(ELT_TYPE *, void *) = DTOR; \ + vect_destroy((VECP), (void (*)(void *, void *))_dtor_callback, \ + DATA); \ + } while (0) + +/* Iterate through vector VEC. See callback.h for notes on iteration + * interfaces. */ +void *vect_each(struct vect *vec, void *start_after, + enum callback_status (*cb)(void *, void *), void *data); + +#define VECT_EACH(VECP, ELT_TYPE, START_AFTER, CB, DATA) \ + /* xxx GCC-ism necessary to get in the safety latches. */ \ + ({ \ + assert((VECP)->elt_size == sizeof(ELT_TYPE)); \ + /* Check that CB is typed properly. */ \ + enum callback_status (*_cb)(ELT_TYPE *, void *) = CB; \ + ELT_TYPE *start_after = (START_AFTER); \ + (ELT_TYPE *)vect_each((VECP), start_after, \ + (enum callback_status \ + (*)(void *, void *))_cb, \ + DATA); \ + }) + +#endif /* VECT_H */ @@ -0,0 +1,105 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <error.h> +#include <errno.h> + +#include "zero.h" +#include "common.h" +#include "type.h" +#include "value.h" +#include "expr.h" + +static int +zero_callback_max(struct value *ret_value, struct value *lhs, + struct value_dict *arguments, + size_t max, void *data) +{ + size_t i; + for (i = 0; i < max; ++i) { + struct value element; + if (value_init_element(&element, lhs, i) < 0) + return -1; + + int zero = value_is_zero(&element, arguments); + + value_destroy(&element); + + if (zero) + break; + } + + struct arg_type_info *long_type = type_get_simple(ARGTYPE_LONG); + value_init_detached(ret_value, NULL, long_type, 0); + value_set_word(ret_value, i); + return 0; +} + +/* LHS->zero(RHS). Looks for a length of zero-terminated array, but + * looks no further than first RHS bytes. */ +static int +zero_callback(struct value *ret_value, struct value *lhs, + struct value *rhs, struct value_dict *arguments, void *data) +{ + long l; + if (value_extract_word(rhs, &l, arguments) < 0) + return -1; + if (l < 0) + /* It might just be a positive value >2GB, but that's + * not likely. */ + report_global_error("maximum array length seems negative"); + size_t max = (size_t)l; + return zero_callback_max(ret_value, lhs, arguments, max, data); +} + +/* LHS->zero. Looks for a length of zero-terminated array, without + * limit. */ +static int +zero1_callback(struct value *ret_value, struct value *lhs, + struct value_dict *arguments, void *data) +{ + return zero_callback_max(ret_value, lhs, arguments, (size_t)-1, data); +} + +struct expr_node * +build_zero_w_arg(struct expr_node *expr, int own) +{ + struct expr_node *e_z = malloc(sizeof(*e_z)); + if (e_z == NULL) + return NULL; + + expr_init_cb2(e_z, &zero_callback, + expr_self(), 0, expr, own, NULL); + return e_z; +} + +struct expr_node * +expr_node_zero(void) +{ + static struct expr_node *node = NULL; + if (node == NULL) { + node = malloc(sizeof(*node)); + if (node == NULL) + error(1, errno, "malloc expr_node_zero"); + expr_init_cb1(node, &zero1_callback, + expr_self(), 0, (void *)-1); + } + return node; +} @@ -0,0 +1,34 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef ZERO_H +#define ZERO_H + +#include "forward.h" + +/* This returns a pre-built "zero" node without argument. Share, but + don't free. */ +struct expr_node *expr_node_zero(void); + +/* This builds a new "zero" node with EXPR as argument. EXPR is owned + * by the built node if OWN. Returns NULL if something failed. */ +struct expr_node *build_zero_w_arg(struct expr_node *expr, int own); + +#endif /* ZERO_H */ |