From 6fe6558eeef284d05ea2c0cea37bb34958cc9033 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: May 19 2010 15:42:22 +0000 Subject: - 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 --- diff --git a/ltrace-0.5-exec-stripped.patch b/ltrace-0.5-exec-stripped.patch new file mode 100644 index 0000000..51d8a33 --- /dev/null +++ b/ltrace-0.5-exec-stripped.patch @@ -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 diff --git a/ltrace-0.5-fork-earlychild.patch b/ltrace-0.5-fork-earlychild.patch new file mode 100644 index 0000000..4bc8e1c --- /dev/null +++ b/ltrace-0.5-fork-earlychild.patch @@ -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); diff --git a/ltrace-0.5-fork-ppc64.patch b/ltrace-0.5-fork-ppc64.patch new file mode 100644 index 0000000..567aac6 --- /dev/null +++ b/ltrace-0.5-fork-ppc64.patch @@ -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); diff --git a/ltrace-0.5-o.patch b/ltrace-0.5-o.patch index dadf75d..74e728b 100644 --- a/ltrace-0.5-o.patch +++ b/ltrace-0.5-o.patch @@ -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. + # diff --git a/ltrace-0.5-ppc-plt-glink.patch b/ltrace-0.5-ppc-plt-glink.patch new file mode 100644 index 0000000..570ecd3 --- /dev/null +++ b/ltrace-0.5-ppc-plt-glink.patch @@ -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 + #include + #include ++#include + + #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 diff --git a/ltrace-0.5-s390-31-on-64.patch b/ltrace-0.5-s390-31-on-64.patch new file mode 100644 index 0000000..213db03 --- /dev/null +++ b/ltrace-0.5-s390-31-on-64.patch @@ -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 diff --git a/ltrace-0.5-s390-args.patch b/ltrace-0.5-s390-args.patch new file mode 100644 index 0000000..61a532d --- /dev/null +++ b/ltrace-0.5-s390-args.patch @@ -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) diff --git a/ltrace-0.5-testsuite.patch b/ltrace-0.5-testsuite.patch index e6d8015..597c374 100644 --- a/ltrace-0.5-testsuite.patch +++ b/ltrace-0.5-testsuite.patch @@ -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 + #include ++#include + + #include"demangle.h" + diff --git a/ltrace.spec b/ltrace.spec index d94b452..97d31c0 100644 --- a/ltrace.spec +++ b/ltrace.spec @@ -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 - 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 - 0.5-14.45svn - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild