- When the value of undefined symbol in PPC 32-bit binary is 0, use

PPC-specific magic to compute the PLT slots.
- Fix a problem with tracing stripped binary after execl on architectures
    that need PLT reinitalisation breakpoint.
- Support tracing of 31-bit binaries with 64-bit ltrace
- Fix handling of the case where forked child is reported before parent's
    fork event
- Patch from Supriya Kannery implements fetching 5th and further function
    arguments on s390
This commit is contained in:
Petr Machata 2010-05-19 15:42:22 +00:00
parent 803da64aaf
commit 6fe6558eee
9 changed files with 532 additions and 22 deletions

View File

@ -0,0 +1,53 @@
--- ltrace-0.5/elf.c~ 2010-03-25 14:07:20.000000000 +0100
+++ ltrace-0.5/elf.c 2010-03-31 13:11:35.000000000 +0200
@@ -435,6 +435,7 @@ struct library_symbol *read_elf(struct p
struct library_symbol *library_symbols = NULL;
struct ltelf lte[MAX_LIBRARY + 1];
size_t i;
+ struct opt_x_t *opt_x_loc = opt_x;
struct opt_x_t *xptr;
struct library_symbol **lib_tail = NULL;
struct opt_x_t *main_cheat;
@@ -502,11 +503,11 @@ struct library_symbol *read_elf(struct p
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->next = opt_x_loc;
main_cheat->found = 0;
main_cheat->name = PLTs_initialized_by_here;
- for (xptr = opt_x; xptr; xptr = xptr->next)
+ for (xptr = opt_x_loc; xptr; xptr = xptr->next)
if (strcmp(xptr->name, PLTs_initialized_by_here) == 0
&& main_cheat) {
free(main_cheat);
@@ -514,7 +515,7 @@ struct library_symbol *read_elf(struct p
break;
}
if (main_cheat)
- opt_x = main_cheat;
+ opt_x_loc = main_cheat;
}
#endif
@@ -533,7 +534,7 @@ struct library_symbol *read_elf(struct p
if (!addr)
continue;
- for (xptr = opt_x; xptr; xptr = xptr->next)
+ for (xptr = opt_x_loc; 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. */
@@ -543,7 +544,7 @@ struct library_symbol *read_elf(struct p
break;
}
}
- for (xptr = opt_x; xptr; xptr = xptr->next)
+ for (xptr = opt_x_loc; xptr; xptr = xptr->next)
if ( ! xptr->found) {
char *badthing = "WARNING";
#ifdef PLT_REINITALISATION_BP
Diff finished. Wed Mar 31 13:12:38 2010

View File

@ -0,0 +1,88 @@
diff -urp ltrace-0.5/ltrace.h ltrace-0.5-pm/ltrace.h
--- ltrace-0.5/ltrace.h 2009-03-03 02:07:44.000000000 +0100
+++ ltrace-0.5-pm/ltrace.h 2009-03-03 02:07:19.000000000 +0100
@@ -107,6 +107,9 @@ struct process {
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 early; /* for consistency checks, this is true for
+ * children whose TRAP was delivered before
+ * the fork message of the parent. */
int callstack_depth;
struct callstack_element callstack[MAX_CALLDEPTH];
@@ -173,7 +176,7 @@ extern void reinitialize_breakpoints(str
extern struct process *open_program(char *filename, pid_t pid);
extern void open_pid(pid_t pid, int verbose);
-extern void open_forked_pid(pid_t pid);
+extern void open_forked_pid(pid_t pid, int early);
extern void show_summary(void);
/* Arch-dependent stuff: */
diff -urp ltrace-0.5/proc.c ltrace-0.5-pm/proc.c
--- ltrace-0.5/proc.c 2009-03-03 02:07:44.000000000 +0100
+++ ltrace-0.5-pm/proc.c 2009-03-03 02:07:19.000000000 +0100
@@ -59,10 +59,11 @@ void open_pid(pid_t pid, int verbose)
proc->pid = pid;
}
-void open_forked_pid(pid_t pid)
+void open_forked_pid(pid_t pid, int early)
{
char *filename = pid2name(pid);
struct process *proc = open_program(filename, 0);
proc->pid = pid;
proc->breakpoints_enabled = -1;
+ proc->early = early;
}
diff -urp ltrace-0.5/wait_for_something.c ltrace-0.5-pm/wait_for_something.c
--- ltrace-0.5/wait_for_something.c 2009-03-03 02:07:44.000000000 +0100
+++ ltrace-0.5-pm/wait_for_something.c 2009-03-03 02:07:19.000000000 +0100
@@ -45,10 +45,24 @@ struct event *wait_for_something(void)
perror("wait");
exit(1);
}
+
event.proc = pid2proc(pid);
if (!event.proc) {
- fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
- exit(1);
+ if(!opt_f) {
+ fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
+ exit(1);
+ } else {
+ /* Parent forked, but we got child's STOP
+ * signal first. */
+ debug (1, "signal from forked child delivered ahead of time?");
+
+ event.thing = LT_EV_NONE;
+ event.e_un.signum = WSTOPSIG(status);
+ open_forked_pid(pid, 1);
+ event.proc = pid2proc(pid);
+ continue_after_signal(event.proc->pid, event.e_un.signum);
+ return &event;
+ }
}
get_arch_dep(event.proc);
event.proc->instruction_pointer = NULL;
@@ -104,7 +118,18 @@ struct event *wait_for_something(void)
child_pid = (pid_t) get_child_pid(event.proc->pid);
if (child_pid){
debug (3, "fork: get_child_pid gave us %d", child_pid);
- open_forked_pid(child_pid);
+
+ struct process *it = list_of_processes;
+ for (; it != NULL; it = it->next)
+ if (it->pid == child_pid) {
+ if (!it->early)
+ fprintf (stderr,
+ "Child %d re-delivered.\n",
+ child_pid);
+ break;
+ }
+ if (!it)
+ open_forked_pid(child_pid, 0);
}
enable_all_breakpoints(event.proc);
continue_after_signal(event.proc->pid, event.e_un.signum);

View File

@ -0,0 +1,90 @@
diff -urp ltrace-0.5/breakpoints.c ltrace-0.5-pm/breakpoints.c
--- ltrace-0.5/breakpoints.c 2009-03-02 19:43:27.000000000 -0500
+++ ltrace-0.5-pm/breakpoints.c 2009-03-02 18:46:25.000000000 -0500
@@ -98,8 +101,11 @@ void enable_all_breakpoints(struct proce
a = ptrace(PTRACE_PEEKTEXT, proc->pid,
sym2addr(proc, proc->list_of_symbols),
0);
- if (a == 0x0)
+ if (a == 0x0) {
+ debug(2, "Not enabling breakpoints for pid %u "
+ "yet, PLT is not populated.", proc->pid);
return;
+ }
}
#endif
@@ -178,6 +178,7 @@ void breakpoints_init(struct process *pr
}
proc->callstack_depth = 0;
proc->breakpoints_enabled = -1;
+ proc->old = 0;
}
void reinitialize_breakpoints(struct process *proc)
diff -urp ltrace-0.5/ltrace.h ltrace-0.5-pm/ltrace.h
--- ltrace-0.5/ltrace.h 2009-03-02 19:43:27.000000000 -0500
+++ ltrace-0.5-pm/ltrace.h 2009-03-02 19:06:43.000000000 -0500
@@ -110,6 +110,7 @@ struct process {
int early; /* for consistency checks, this is true for
* children whose TRAP was delivered before
* the fork message of the parent. */
+ int old;
int callstack_depth;
struct callstack_element callstack[MAX_CALLDEPTH];
diff -urp ltrace-0.5/proc.c ltrace-0.5-pm/proc.c
--- ltrace-0.5/proc.c 2009-03-02 19:43:27.000000000 -0500
+++ ltrace-0.5-pm/proc.c 2009-03-02 19:07:50.000000000 -0500
@@ -22,11 +22,8 @@ struct process *open_program(char *filen
}
proc->filename = filename;
proc->breakpoints_enabled = -1;
- proc->pid = 0;
breakpoints_init(proc);
- if (pid) {
- proc->pid = pid;
- }
+ proc->pid = pid;
proc->next = list_of_processes;
list_of_processes = proc;
@@ -63,6 +60,9 @@ void open_forked_pid(pid_t pid, int earl
char *filename = pid2name(pid);
struct process *proc = open_program(filename, 0);
proc->pid = pid;
- proc->breakpoints_enabled = -1;
+#ifdef __powerpc__
+ breakpoints_init(proc);
+ proc->breakpoints_enabled = 1;
+#endif
proc->early = early;
}
diff -urp ltrace-0.5/wait_for_something.c ltrace-0.5-pm/wait_for_something.c
--- ltrace-0.5/wait_for_something.c 2009-03-02 19:43:27.000000000 -0500
+++ ltrace-0.5-pm/wait_for_something.c 2009-03-02 19:07:21.000000000 -0500
@@ -46,6 +46,7 @@ struct event *wait_for_something(void)
exit(1);
}
+ debug(3, "signal from pid %u, status %#x", pid, status);
event.proc = pid2proc(pid);
if (!event.proc) {
if(!opt_f) {
@@ -66,9 +67,13 @@ struct event *wait_for_something(void)
}
get_arch_dep(event.proc);
event.proc->instruction_pointer = NULL;
- debug(3, "signal from pid %u", pid);
- if (event.proc->breakpoints_enabled == -1) {
- enable_all_breakpoints(event.proc);
+ if (!event.proc->old) {
+ event.proc->old = 1;
+ if (event.proc->breakpoints_enabled == -1) {
+ debug (2, "BRANCH: enable breakpoints for the first time");
+ enable_all_breakpoints(event.proc);
+ debug (2, "BRANCH: done enabling breakpoints for the first time");
+ }
event.thing = LT_EV_NONE;
if(opt_f){
trace_set_options(event.proc, event.proc->pid, TRACE_FORK);

View File

@ -1,7 +1,3 @@
Only in ltrace-0.5-dasho/: config.h
Only in ltrace-0.5-dasho/: config.log
Only in ltrace-0.5-dasho/: config.status
Only in ltrace-0.5-dasho/: Makefile
diff -ur ltrace-0.5/summary.c ltrace-0.5-dasho/summary.c
--- ltrace-0.5/summary.c 2006-04-24 12:14:01.000000000 -0400
+++ ltrace-0.5-dasho/summary.c 2008-05-19 15:22:13.000000000 -0400
@ -40,20 +36,15 @@ diff -ur ltrace-0.5/summary.c ltrace-0.5-dasho/summary.c
+ fprintf(output, "100.00 %4lu.%06lu %9d total\n",
+ tot_usecs / 1000000, tot_usecs % 1000000, tot_count);
}
Only in ltrace-0.5-dasho/: summary.c~
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: arch_syscallent.h
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: breakpoint.o
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: os.o
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: proc.o
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: signalent1.h
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: signalent.h
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: syscallent1.h
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: syscallent.h
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: sysdep.h
Only in ltrace-0.5-dasho/sysdeps/linux-gnu: trace.o
Only in ltrace-0.5-dasho/sysdeps/linux-gnu/x86_64: regs.o
Only in ltrace-0.5-dasho/sysdeps/linux-gnu/x86_64: trace.o
Only in ltrace-0.5-dasho/testsuite/ltrace.main: Makefile
Only in ltrace-0.5-dasho/testsuite/ltrace.minor: Makefile
Only in ltrace-0.5-dasho/testsuite/ltrace.torture: Makefile
Only in ltrace-0.5-dasho/testsuite: Makefile
diff -urp ltrace-0.5/testsuite/ltrace.minor/count-record.exp ltrace-0.5-pm/testsuite/ltrace.minor/count-record.exp
--- ltrace-0.5/testsuite/ltrace.minor/count-record.exp 2006-03-14 00:12:01.000000000 +0100
+++ ltrace-0.5-pm/testsuite/ltrace.minor/count-record.exp 2009-02-20 16:48:28.000000000 +0100
@@ -27,8 +27,6 @@ if [regexp {ELF from incompatible archit
}
-ltrace_saveoutput $exec_output $srcdir/$subdir/$binfile.ltrace
-
#
# This is a sample output and Verify the forth and fifth column.
#

View File

@ -0,0 +1,220 @@
diff -urp ltrace-0.5/elf.c ltrace-0.5-pm/elf.c
--- ltrace-0.5/elf.c 2010-05-17 14:49:20.004577987 -0400
+++ ltrace-0.5-pm/elf.c 2010-05-17 14:54:31.841118855 -0400
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <assert.h>
#include "ltrace.h"
#include "elf.h"
@@ -29,6 +30,114 @@ static GElf_Addr opd2addr(struct ltelf *
extern char *PLTs_initialized_by_here;
#endif
+// xxx make it only appear on PPC
+#ifndef DT_PPC_GOT
+# define DT_PPC_GOT (DT_LOPROC + 0)
+#endif
+
+#define PPC_PLT_STUB_SIZE 16
+
+static Elf_Data *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 inside(GElf_Addr addr, GElf_Shdr *shdr)
+{
+ return addr >= shdr->sh_addr
+ && addr < shdr->sh_addr + shdr->sh_size;
+}
+
+static int maybe_pick_section(GElf_Addr addr,
+ Elf_Scn *in_sec, GElf_Shdr *in_shdr,
+ Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
+{
+ if (inside (addr, in_shdr)) {
+ *tgt_sec = in_sec;
+ *tgt_shdr = *in_shdr;
+ return 1;
+ }
+ return 0;
+}
+
+static int get_section_covering(struct ltelf *lte, GElf_Addr addr,
+ Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
+{
+ 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 0;
+ }
+
+ if (maybe_pick_section(addr, scn, &shdr, tgt_sec, tgt_shdr))
+ return 1;
+ }
+
+ return 0;
+}
+
+static GElf_Addr read32be(Elf_Data *data, size_t offset)
+{
+ if (data->d_size < offset + 4) {
+ debug(1, "Not enough data to read 32bit value at offset %z.",
+ offset);
+ return 0;
+ }
+
+ unsigned char const *buf = data->d_buf + offset;
+ return ((Elf32_Word)buf[0] << 24)
+ | ((Elf32_Word)buf[1] << 16)
+ | ((Elf32_Word)buf[2] << 8)
+ | ((Elf32_Word)buf[3]);
+}
+
+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
+ && !get_section_covering(lte, ppcgot, &ppcgot_sec, &ppcgot_shdr))
+ // xxx should be the log out
+ fprintf(stderr,
+ "DT_PPC_GOT=%#llx, but no such section found.\n",
+ ppcgot);
+
+ if (ppcgot_sec != NULL) {
+ Elf_Data *data = loaddata(ppcgot_sec, &ppcgot_shdr);
+ if (data == NULL
+ || data->d_size < 8 )
+ debug(1, "Couldn't read GOT data.");
+ else {
+ // where PPCGOT begins in .got
+ size_t offset = ppcgot - ppcgot_shdr.sh_addr;
+ GElf_Addr glink_vma = read32be(data, offset + 4);
+ if (glink_vma != 0) {
+ debug(1, "PPC GOT glink_vma address: %#llx",
+ glink_vma);
+ return glink_vma;
+ }
+ }
+ }
+
+ if (plt_data != NULL) {
+ GElf_Addr glink_vma = read32be(plt_data, 0);
+ debug(1, ".plt glink_vma address: %#llx", glink_vma);
+ return glink_vma;
+ }
+
+ return 0;
+}
+
static void do_init_elf(struct ltelf *lte, const char *filename)
{
int i;
@@ -74,6 +183,9 @@ static void do_init_elf(struct ltelf *lt
error(EXIT_FAILURE, 0,
"\"%s\" is ELF from incompatible architecture", filename);
+ Elf_Data *plt_data = NULL;
+ GElf_Addr ppcgot = 0;
+
for (i = 1; i < lte->ehdr.e_shnum; ++i) {
Elf_Scn *scn;
GElf_Shdr shdr;
@@ -164,6 +276,10 @@ static void do_init_elf(struct ltelf *lt
relplt_addr = dyn.d_un.d_ptr;
else if (dyn.d_tag == DT_PLTRELSZ)
relplt_size = dyn.d_un.d_val;
+ else if (dyn.d_tag == DT_PPC_GOT) {
+ ppcgot = dyn.d_un.d_val;
+ debug(1, "ppcgot %#llx", ppcgot);
+ }
}
} else if (shdr.sh_type == SHT_HASH) {
Elf_Data *data;
@@ -226,9 +342,8 @@ static void do_init_elf(struct ltelf *lt
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)
+ data = loaddata(scn, &shdr);
+ if (data == NULL)
error(EXIT_FAILURE, 0,
"Couldn't get .gnu.hash data from \"%s\"",
filename);
@@ -243,6 +358,12 @@ static void do_init_elf(struct ltelf *lt
if (shdr.sh_flags & SHF_EXECINSTR) {
lte->lte_flags |= LTE_PLT_EXECUTABLE;
}
+ if (lte->ehdr.e_machine == EM_PPC) {
+ plt_data = loaddata(scn, &shdr);
+ if (plt_data == NULL)
+ fprintf(stderr,
+ "Can't load .plt data\n");
+ }
} else if (strcmp(name, ".opd") == 0) {
lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
lte->opd_size = shdr.sh_size;
@@ -259,7 +380,22 @@ static void do_init_elf(struct ltelf *lt
debug(1, "%s has no PLT relocations", filename);
lte->relplt = NULL;
lte->relplt_count = 0;
+ } else if (relplt_size == 0) {
+ debug(1, "%s has unknown PLT size", filename);
+ lte->relplt = NULL;
+ lte->relplt_count = 0;
} else {
+ if (lte->ehdr.e_machine == EM_PPC) {
+ GElf_Addr glink_vma
+ = get_glink_vma(lte, ppcgot, plt_data);
+
+ assert (relplt_size % 12 == 0);
+ size_t count = relplt_size / 12; // size of RELA entry
+ lte->plt_stub_vma = glink_vma
+ - (GElf_Addr)count * PPC_PLT_STUB_SIZE;
+ debug(1, "stub_vma is %#llx", lte->plt_stub_vma);
+ }
+
for (i = 1; i < lte->ehdr.e_shnum; ++i) {
Elf_Scn *scn;
GElf_Shdr shdr;
@@ -482,6 +619,13 @@ struct library_symbol *read_elf(struct p
enum toplt pltt;
if (lte->ehdr.e_machine == EM_PPC) {
addr = sym.st_value;
+ /* If we have neither the symbol
+ * address, nor the PLT stub address,
+ * the tracing will probably fail. */
+ if (addr == 0 && lte->plt_stub_vma != 0) {
+ addr = lte->plt_stub_vma
+ + PPC_PLT_STUB_SIZE * i;
+ }
pltt = LS_TOPLT_EXEC;
}
else {
diff -urp ltrace-0.5/elf.h ltrace-0.5-pm/elf.h
--- ltrace-0.5/elf.h 2010-05-17 14:49:19.844578787 -0400
+++ ltrace-0.5-pm/elf.h 2010-05-17 14:00:52.844954178 -0400
@@ -26,6 +26,7 @@ struct ltelf {
Elf32_Word *hash;
int hash_type;
int lte_flags;
+ GElf_Addr plt_stub_vma;
};
#define LTE_HASH_MALLOCED 1

View File

@ -0,0 +1,15 @@
diff -urp ltrace-0.5/sysdeps/linux-gnu/s390/arch.h ltrace-0.5-64-31/sysdeps/linux-gnu/s390/arch.h
--- ltrace-0.5/sysdeps/linux-gnu/s390/arch.h 2006-04-24 16:06:23.000000000 -0400
+++ ltrace-0.5-64-31/sysdeps/linux-gnu/s390/arch.h 2009-02-25 13:56:16.000000000 -0500
@@ -12,6 +12,11 @@
#define LT_ELF_MACHINE EM_S390
#define LT_ELFCLASS2 ELFCLASS32
#define LT_ELF_MACHINE2 EM_S390
+
+/* __NR_fork, __NR_clone, __NR_clone2, __NR_vfork and __NR_execve
+ from asm-s390/unistd.h. */
+#define FORK_EXEC_SYSCALLS , { 2, 120, -1, 190, 11 }
+
#else
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_S390

View File

@ -0,0 +1,20 @@
--- ltrace/sysdeps/linux-gnu/s390/trace.c.orig 2007-12-17 04:57:08.000000000 +0530
+++ ltrace/sysdeps/linux-gnu/s390/trace.c 2007-12-17 05:04:30.000000000 +0530
@@ -185,8 +185,15 @@
ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
break;
default:
+ /*Rest of the params saved in stack */
+ if (arg_num >= 5) {
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid,
+ proc->stack_pointer + 96 +
+ 4 * (arg_num - 5), 0);
+ } else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
+ }
- fprintf(stderr, "gimme_arg called with wrong arguments\n");
- exit(2);
}
#ifdef __s390x__
if (proc->mask_32bit)

View File

@ -34,3 +34,13 @@ diff -urpd ltrace-0.5-orig/testsuite/ltrace.minor/trace-clone.exp ltrace-0.5/tes
return
} elseif [ regexp {killed by SIGKILL} $exec_output ] {
fail "killed by SIGKILL!"
diff -urp ltrace-0.5/testsuite/ltrace.minor/demangle-lib.cpp ltrace-0.5-m/testsuite/ltrace.minor/demangle-lib.cpp
--- ltrace-0.5/testsuite/ltrace.minor/demangle-lib.cpp 2006-03-14 00:12:01.000000000 +0100
+++ ltrace-0.5-m/testsuite/ltrace.minor/demangle-lib.cpp 2008-09-01 13:11:10.000000000 +0200
@@ -1,5 +1,6 @@
#include<stddef.h>
#include<iostream>
+#include<stdlib.h>
#include"demangle.h"

View File

@ -1,7 +1,7 @@
Summary: Tracks runtime library calls from dynamically linked executables
Name: ltrace
Version: 0.5
Release: 14.45svn%{?dist}
Release: 16.45svn%{?dist}
URL: http://ltrace.alioth.debian.org/
License: GPLv2+
Group: Development/Debuggers
@ -30,6 +30,12 @@ Patch12: ltrace-0.5-man.patch
Patch13: ltrace-0.5-ia64-sigill.patch
Patch14: ltrace-0.5-build.patch
Patch15: ltrace-0.5-o.patch
Patch16: ltrace-0.5-s390-args.patch
Patch17: ltrace-0.5-fork-earlychild.patch
Patch18: ltrace-0.5-s390-31-on-64.patch
Patch19: ltrace-0.5-fork-ppc64.patch
Patch20: ltrace-0.5-exec-stripped.patch
Patch21: ltrace-0.5-ppc-plt-glink.patch
%description
Ltrace is a debugging program which runs a specified command until the
@ -59,6 +65,12 @@ execution of processes.
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
sed -i -e 's/-o root -g root//' Makefile.in
%build
@ -90,6 +102,17 @@ rm -rf $RPM_BUILD_ROOT
%config(noreplace) %{_sysconfdir}/ltrace.conf
%changelog
* Wed May 19 2010 Petr Machata <pmachata@redhat.com> - 0.5-16.45svn.1
- When the value of undefined symbol in PPC 32-bit binary is 0, use
PPC-specific magic to compute the PLT slots.
- Fix a problem with tracing stripped binary after execl on
architectures that need PLT reinitalisation breakpoint.
- Support tracing of 31-bit binaries with 64-bit ltrace
- Fix handling of the case where forked child is reported before
parent's fork event
- Patch from Supriya Kannery implements fetching 5th and further
function arguments on s390
* Sat Jul 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.5-14.45svn
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild