- 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:
parent
803da64aaf
commit
6fe6558eee
53
ltrace-0.5-exec-stripped.patch
Normal file
53
ltrace-0.5-exec-stripped.patch
Normal 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
|
||||
88
ltrace-0.5-fork-earlychild.patch
Normal file
88
ltrace-0.5-fork-earlychild.patch
Normal 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);
|
||||
90
ltrace-0.5-fork-ppc64.patch
Normal file
90
ltrace-0.5-fork-ppc64.patch
Normal 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);
|
||||
@ -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.
|
||||
#
|
||||
|
||||
220
ltrace-0.5-ppc-plt-glink.patch
Normal file
220
ltrace-0.5-ppc-plt-glink.patch
Normal 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
|
||||
15
ltrace-0.5-s390-31-on-64.patch
Normal file
15
ltrace-0.5-s390-31-on-64.patch
Normal 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
|
||||
20
ltrace-0.5-s390-args.patch
Normal file
20
ltrace-0.5-s390-args.patch
Normal 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)
|
||||
@ -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"
|
||||
|
||||
|
||||
25
ltrace.spec
25
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 <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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user