Sync with upstream (ia64 ABI, -l, bug fixes)

This commit is contained in:
Petr Machata 2012-10-01 16:12:01 +02:00
parent ba67ad5a36
commit f09484d326
6 changed files with 3625 additions and 1 deletions

1539
ltrace-0.6.0-abi-ia64.patch Normal file

File diff suppressed because it is too large Load Diff

652
ltrace-0.6.0-cleanups.patch Normal file
View File

@ -0,0 +1,652 @@
diff --git a/lens_default.c b/lens_default.c
index f59d328..81025b1 100644
--- a/lens_default.c
+++ b/lens_default.c
@@ -63,7 +63,7 @@ READER(read_double, double)
int##BITS##_t i = l; \
switch (format) { \
case INT_FMT_unknown: \
- if (i < -10000 || i > 10000) \
+ if (l < -10000 || l > 10000) \
case INT_FMT_x: \
return fprintf(stream, "%#"PRIx##BITS, i); \
case INT_FMT_i: \
diff --git a/sysdeps/linux-gnu/ia64/breakpoint.c b/sysdeps/linux-gnu/ia64/breakpoint.c
index a0bfaf9..a5071b8 100644
--- a/sysdeps/linux-gnu/ia64/breakpoint.c
+++ b/sysdeps/linux-gnu/ia64/breakpoint.c
@@ -2,11 +2,12 @@
* -Ian Wienand <ianw@gelato.unsw.edu.au> 10/3/2005
*/
-#include "config.h"
-
#include <sys/ptrace.h>
#include <string.h>
-#include "common.h"
+#include <assert.h>
+
+#include "breakpoint.h"
+#include "debug.h"
static long long
extract_bit_field(char *bundle, int from, int len) {
@@ -161,9 +162,7 @@ arch_enable_breakpoint(pid_t pid, struct 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);
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
index 323df65..76a4aac 100644
--- a/sysdeps/linux-gnu/ia64/plt.c
+++ b/sysdeps/linux-gnu/ia64/plt.c
@@ -1,6 +1,8 @@
#include <gelf.h>
+
#include "proc.h"
#include "common.h"
+#include "library.h"
/* A bundle is 128 bits */
#define BUNDLE_SIZE 16
@@ -36,7 +38,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\n", ndx, addr);
return addr;
}
diff --git a/breakpoints.c b/breakpoints.c
index e7120ee..3eee38b 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -302,35 +302,6 @@ enable_all_breakpoints(Process *proc)
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) + strlen(sym->name) + 1);
- memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
- new_sym->next=proc->list_of_symbols;
- proc->list_of_symbols=new_sym;
- insert_breakpoint(proc, addr, new_sym);
- sym=sym->next;
- }
- }
-#endif
}
static void
diff --git a/handle_event.c b/handle_event.c
index 5b6cc40..1720cb3 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -232,6 +232,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);
@@ -592,25 +593,6 @@ handle_breakpoint(Event *event)
for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
if (brk_addr == event->proc->callstack[i].return_addr) {
-#if defined(__mips__)
- void *addr = NULL;
- struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
- struct library_symbol *new_sym;
- assert(sym);
- addr = sym2addr(event->proc, sym);
- sbp = dict_find_entry(leader->breakpoints, addr);
- if (sbp) {
- if (addr != sbp->addr) {
- insert_breakpoint(event->proc, addr, sym);
- }
- } else {
- new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
- memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
- new_sym->next = leader->list_of_symbols;
- leader->list_of_symbols = new_sym;
- insert_breakpoint(event->proc, addr, new_sym);
- }
-#endif
for (j = event->proc->callstack_depth - 1; j > i; j--) {
callstack_pop(event->proc);
}
diff --git a/ltrace-elf.c b/ltrace-elf.c
index c8667a7..bc99c6a 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -50,10 +50,6 @@
#include "debug.h"
#include "options.h"
-#ifdef PLT_REINITALISATION_BP
-extern char *PLTs_initialized_by_here;
-#endif
-
#ifndef ARCH_HAVE_LTELF_DATA
int
arch_elf_init(struct ltelf *lte, struct library *lib)
diff --git a/ltrace.1 b/ltrace.1
index 604f4da..fb64289 100644
--- a/ltrace.1
+++ b/ltrace.1
@@ -7,7 +7,7 @@ ltrace \- A library call tracer
.SH SYNOPSIS
.B ltrace
-.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-X extern] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]"
+.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]"
.SH DESCRIPTION
.B ltrace
@@ -158,14 +158,6 @@ correct execution of setuid and/or setgid binaries.
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
-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.
-.TP
.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
diff --git a/options.c b/options.c
index 8dce7f8..b9472a8 100644
--- a/options.c
+++ b/options.c
@@ -50,12 +50,6 @@ struct opt_p_t *opt_p = NULL; /* attach to process with a given pid */
/* 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);
@@ -78,7 +72,6 @@ usage(void) {
" -e expr modify which events to trace.\n"
" -f trace children (fork() and clone()).\n"
" -F, --config=FILE load alternate configuration file (may be repeated).\n"
- " -g, --no-plt disable breakpoints on PLT entries.\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"
@@ -97,9 +90,6 @@ usage(void) {
" -w=NR, --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);
}
@@ -560,14 +550,6 @@ process_options(int argc, char **argv)
options.bt_depth = atoi(optarg);
break;
#endif /* defined(HAVE_LIBUNWIND) */
- 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 */
case 'x':
parse_filter_chain(optarg, &options.static_filter);
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
index 846961e..2d0ad65 100644
--- a/sysdeps/linux-gnu/ppc/arch.h
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -37,8 +37,6 @@
#define ARCH_SUPPORTS_OPD
#endif
-#define PLT_REINITALISATION_BP "_start"
-
#define ARCH_ENDIAN_BIG
#define ARCH_HAVE_ATOMIC_SINGLESTEP
#define ARCH_HAVE_ADD_PLT_ENTRY
diff --git a/Makefile.am b/Makefile.am
index 177a498..47161f8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -85,6 +85,7 @@ noinst_HEADERS = \
type.h \
value.h \
value_dict.h \
+ callback.h \
expr.h \
fetch.h \
vect.h \
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_ */
diff --git a/filter.c b/filter.c
index 003010d..bf77b76 100644
--- a/filter.c
+++ b/filter.c
@@ -25,6 +25,7 @@
#include "filter.h"
#include "library.h"
+#include "callback.h"
void
filter_init(struct filter *filt)
diff --git a/forward.h b/forward.h
index e4233e5..8c03319 100644
--- a/forward.h
+++ b/forward.h
@@ -12,3 +12,4 @@ struct param;
struct param_enum;
struct value;
struct value_dict;
+struct filter;
diff --git a/library.c b/library.c
index 2ce3427..cbd4a35 100644
--- a/library.c
+++ b/library.c
@@ -25,8 +25,9 @@
#include <assert.h>
#include "library.h"
-#include "proc.h" // for enum callback_status
+#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
diff --git a/library.h b/library.h
index 876a533..f207502 100644
--- a/library.h
+++ b/library.h
@@ -23,6 +23,7 @@
#define _LIBRARY_H_
#include <stdint.h>
+#include "callback.h"
#include "sysdep.h"
struct Process;
@@ -144,9 +145,8 @@ void library_set_soname(struct library *lib,
void library_set_pathname(struct library *lib,
const char *new_name, int own_name);
-/* Iterate through list of symbols of library LIB. Restarts are
- * supported via START_AFTER (see each_process for details of
- * iteration interface). */
+/* 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 *),
diff --git a/options.c b/options.c
index b9472a8..87dddb0 100644
--- a/options.c
+++ b/options.c
@@ -52,7 +52,7 @@ struct opt_F_t *opt_F = NULL; /* alternate configuration file(s) */
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);
}
@@ -127,7 +127,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);
@@ -173,7 +173,7 @@ add_filter_rule(struct filter *filt, const char *expr,
struct filter_lib_matcher *matcher = malloc(sizeof(*matcher));
if (rule == NULL || matcher == NULL) {
- fprintf(stderr, "rule near '%s' will be ignored: %s\n",
+ fprintf(stderr, "Rule near '%s' will be ignored: %s.\n",
expr, strerror(errno));
fail:
free(rule);
@@ -193,7 +193,7 @@ add_filter_rule(struct filter *filt, const char *expr,
if (status != 0) {
char buf[100];
regerror(status, &symbol_re, buf, sizeof buf);
- fprintf(stderr, "rule near '%s' will be ignored: %s\n",
+ fprintf(stderr, "Rule near '%s' will be ignored: %s.\n",
expr, buf);
goto fail;
}
@@ -301,8 +301,8 @@ parse_filter(struct filter *filt, char *expr)
/* /XXX@YYY/ is the same as
* /XXX/@/YYY/. */
if (libend[0] != '/')
- fprintf(stderr, "unmatched '/'"
- " in symbol name\n");
+ fprintf(stderr, "Unmatched '/'"
+ " in symbol name.\n");
else
*libend-- = 0;
}
@@ -339,7 +339,7 @@ recursive_parse_chain(char *expr)
{
struct filter *filt = malloc(sizeof(*filt));
if (filt == NULL) {
- fprintf(stderr, "(part of) filter will be ignored: '%s': %s\n",
+ fprintf(stderr, "(Part of) filter will be ignored: '%s': %s.\n",
expr, strerror(errno));
return NULL;
}
@@ -359,7 +359,7 @@ 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",
+ fprintf(stderr, "Filter '%s' will be ignored: %s.\n",
expr, strerror(errno));
return;
}
@@ -598,7 +598,8 @@ process_options(int argc, char **argv)
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();
}
diff --git a/options.h b/options.h
index 3ffee71..0806928 100644
--- a/options.h
+++ b/options.h
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <sys/types.h>
-struct filter;
+#include "forward.h"
struct options_t {
int align; /* -a: default alignment column for results */
diff --git a/proc.h b/proc.h
index 64c37a9..b61e420 100644
--- a/proc.h
+++ b/proc.h
@@ -34,20 +34,11 @@
#include "ltrace.h"
#include "dict.h"
#include "sysdep.h"
+#include "callback.h"
struct library;
struct breakpoint;
-/* XXX Move this somewhere where it makes sense. When the mess in
- * common.h is disentangled, that would actually be a good place for
- * this. */
-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. */
-};
-
struct event_handler {
/* Event handler that overrides the default one. Should
* return NULL if the event was handled, otherwise the
@@ -184,28 +175,16 @@ Process * pid2proc(pid_t pid);
* 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. CB is
- * called for each process. Tasks are considered to be processes for
- * the purpose of this iterator.
- *
- * Notes on this iteration interface: The iteration starts after the
- * process designated by START_AFTER, or at the first process if
- * START_AFTER is NULL. DATA is passed verbatim to CB. If CB returns
- * CBS_STOP, the iteration stops and the current iterator is returned.
- * That iterator can then be used to restart the iteration. NULL is
- * returned when iteration ends.
- *
- * 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. */
+/* 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. Restarts are
- * supported via START_AFTER (see each_process for details of
- * iteration interface). */
+/* 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),
@@ -227,8 +206,8 @@ void proc_add_library(struct Process *proc, struct library *lib);
* was found and unlinked, otherwise returns a negative value. */
int proc_remove_library(struct Process *proc, struct library *lib);
-/* Iterate through the libraries of PROC. See each_process for
- * detailed description of the iteration interface. */
+/* 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,
@@ -242,8 +221,8 @@ int proc_add_breakpoint(struct Process *proc, struct breakpoint *bp);
* 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 libraries of PROC. See each_process for
- * detailed description of the iteration interface. */
+/* 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,
diff --git a/sysdeps/linux-gnu/x86/arch.h b/sysdeps/linux-gnu/x86/arch.h
index 77a09d7..329cfba 100644
--- a/sysdeps/linux-gnu/x86/arch.h
+++ b/sysdeps/linux-gnu/x86/arch.h
@@ -1,6 +1,6 @@
/*
* This file is part of ltrace.
- * Copyright (C) 2011 Petr Machata
+ * Copyright (C) 2011, 2012 Petr Machata
* Copyright (C) 2006 Ian Wienand
* Copyright (C) 2004 Juan Cespedes
*
@@ -34,7 +34,3 @@
#endif
#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/testsuite/ltrace.main/parameters.c b/testsuite/ltrace.main/parameters.c
index 158fdd7..44d54b2 100644
--- a/testsuite/ltrace.main/parameters.c
+++ b/testsuite/ltrace.main/parameters.c
@@ -190,7 +190,7 @@ main ()
"%c %d %g %d %g %c %d "
"%hd %d %c %g %g %g "
"%ld %g %g %g %g",
- 1, 2, 3, 4.0, '5', 6, 7.0,
+ 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);
diff --git a/vect.c b/vect.c
index f2e58b2..7dae847 100644
--- a/vect.c
+++ b/vect.c
@@ -134,3 +134,25 @@ vect_destroy(struct vect *vec, void (*dtor)(void *emt, void *data), void *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;
+}
diff --git a/vect.h b/vect.h
index 50401bb..c07235f 100644
--- a/vect.h
+++ b/vect.h
@@ -22,6 +22,9 @@
#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
@@ -122,4 +125,22 @@ void vect_destroy(struct vect *vec,
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 */

1293
ltrace-0.6.0-dash-l.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
From 6aa01523f249f9763ccd71db9f46969a6e5d8cfd Mon Sep 17 00:00:00 2001
From: Paul Buerger <pbuerger@avetec.org>
Date: Wed, 12 Sep 2012 10:58:52 -0400
Subject: [PATCH] reported time in system call was too large
when -S and -T are specified and if the system call spans
a second boundary, the reported time in the system call
was too large by precisely 2 seconds
Signed-off-by: Paul Buerger <pbuerger@avetec.org>
---
handle_event.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/handle_event.c b/handle_event.c
index 1720cb3..384e868 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -522,7 +522,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;
--
1.7.6.5

View File

@ -0,0 +1,88 @@
From 78ed40f161c102a10c6033c28ad9a80e5ffe9550 Mon Sep 17 00:00:00 2001
From: Petr Machata <pmachata@redhat.com>
Date: Sat, 22 Sep 2012 18:19:24 +0200
Subject: [PATCH] Fix passing struct(float,struct(float,float)) on x86_64
The problem was that we assumed that structure elements never overlap
eightbyte boundary. This assumption is violated by the above layout,
where the first two floats should be passed in %xmm0 together.
This case is covered by the Itanium HFA tests func_hfa_f3 and func_hfa_f4.
---
ChangeLog | 4 +++
sysdeps/linux-gnu/x86/fetch.c | 46 ++++++++++++++++++++++++++++++++++++----
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c
index 8df900e..cca1638 100644
--- a/sysdeps/linux-gnu/x86/fetch.c
+++ b/sysdeps/linux-gnu/x86/fetch.c
@@ -411,12 +411,34 @@ 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;
@@ -458,11 +480,25 @@ classify(struct Process *proc, struct fetch_context *context,
get_array_field);
case ARGTYPE_STRUCT:
- /* N.B. "big" structs are dealt with in the
- * caller. */
- return classify_eightbytes(proc, context, info, valuep, classes,
- type_struct_size(info),
- eightbytes, type_struct_get);
+ /* 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;
}
abort();
}
--
1.7.6.5

View File

@ -1,7 +1,7 @@
Summary: Tracks runtime library calls from dynamically linked executables
Name: ltrace
Version: 0.6.0
Release: 18%{?dist}
Release: 19%{?dist}
URL: http://ltrace.alioth.debian.org/
License: GPLv2+
Group: Development/Debuggers
@ -37,6 +37,11 @@ Patch21: ltrace-0.6.0-demangle.patch
Patch22: ltrace-0.6.0-abi.patch
Patch23: ltrace-0.6.0-abi-s390.patch
Patch24: ltrace-0.6.0-ppc-flteqv.patch
Patch25: ltrace-0.6.0-cleanups.patch
Patch26: ltrace-0.6.0-syscall-time.patch
Patch27: ltrace-0.6.0-abi-ia64.patch
Patch28: ltrace-0.6.0-x86_64-flatten.patch
Patch29: ltrace-0.6.0-dash-l.patch
%description
Ltrace is a debugging program which runs a specified command until the
@ -72,6 +77,11 @@ execution of processes.
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%build
# This ugly hack is necessary to build and link files for correct
@ -99,6 +109,18 @@ echo ====================TESTING END=====================
%config(noreplace) %{_sysconfdir}/ltrace.conf
%changelog
* Mon Oct 1 2012 Petr Machata <pmachata@redhat.com> - 0.6.0-19
- Upstream patch for ia64 parameter passing
(ltrace-0.6.0-abi-ia64.patch)
- Upstream fix for a bug in computation of time spent in a syscall
(ltrace-0.6.0-syscall-time.patch)
- Upstream fix for a bug in passing struct(float,struct(float,float))
on x86_64 (ltrace-0.6.0-x86_64-flatten.patch)
- Upstream patch for support of -l option (ltrace-0.6.0-dash-l.patch)
- Several more upstream patches with random cleanups. Those were
brought to Fedora to make porting of other patches easier.
(ltrace-0.6.0-cleanups.patch)
* Thu Aug 30 2012 Petr Machata <pmachata@redhat.com> - 0.6.0-18
- PPC64 passes floating point equivalent structures in registers