[Ltrace-devel] r42 - in ltrace/trunk: . sysdeps/linux-gnu sysdeps/linux-gnu/alpha sysdeps/linux-gnu/arm sysdeps/linux-gnu/i386 sysdeps/linux-gnu/ia64 sysdeps/linux-gnu/m68k sysdeps/linux-gnu/ppc sysdeps/linux-gnu/s390 sysdeps/linux-gnu/sparc sysdeps/linux-gnu/x86_64

Ian Wienand ianw-guest at costa.debian.org
Wed Jun 14 04:55:22 UTC 2006


Author: ianw-guest
Date: 2006-06-14 04:55:21 +0000 (Wed, 14 Jun 2006)
New Revision: 42

Modified:
   ltrace/trunk/ChangeLog
   ltrace/trunk/breakpoints.c
   ltrace/trunk/configure.ac
   ltrace/trunk/elf.c
   ltrace/trunk/elf.h
   ltrace/trunk/ltrace.h
   ltrace/trunk/output.c
   ltrace/trunk/process_event.c
   ltrace/trunk/sysdeps/linux-gnu/alpha/plt.c
   ltrace/trunk/sysdeps/linux-gnu/arm/plt.c
   ltrace/trunk/sysdeps/linux-gnu/breakpoint.c
   ltrace/trunk/sysdeps/linux-gnu/i386/plt.c
   ltrace/trunk/sysdeps/linux-gnu/ia64/plt.c
   ltrace/trunk/sysdeps/linux-gnu/m68k/plt.c
   ltrace/trunk/sysdeps/linux-gnu/ppc/arch.h
   ltrace/trunk/sysdeps/linux-gnu/ppc/plt.c
   ltrace/trunk/sysdeps/linux-gnu/s390/plt.c
   ltrace/trunk/sysdeps/linux-gnu/sparc/plt.c
   ltrace/trunk/sysdeps/linux-gnu/x86_64/plt.c
Log:
import Paul Gilliam's secure PLT patch


Modified: ltrace/trunk/ChangeLog
===================================================================
--- ltrace/trunk/ChangeLog	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/ChangeLog	2006-06-14 04:55:21 UTC (rev 42)
@@ -1,3 +1,27 @@
+2006-06-14  Ian Wienand  <ianw at 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 at de.ibm.com>
 
 	* sysdeps/linux-gnu/mksyscallent_s390: add

Modified: ltrace/trunk/breakpoints.c
===================================================================
--- ltrace/trunk/breakpoints.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/breakpoints.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -92,8 +92,7 @@
 		 */
 		if (opt_L) {
 			a = ptrace(PTRACE_PEEKTEXT, proc->pid,
-				   plt2addr(proc,
-					    proc->list_of_symbols->enter_addr),
+				   sym2addr(proc, proc->list_of_symbols),
 				   0);
 			if (a == 0x0)
 				return;
@@ -169,11 +168,7 @@
 	sym = proc->list_of_symbols;
 	while (sym) {
 		/* proc->pid==0 delays enabling. */
-		if (sym->static_plt2addr) {
-			insert_breakpoint(proc, sym->enter_addr, sym);
-		} else {
-			insert_breakpoint(proc, plt2addr(proc, sym->enter_addr), sym);	/* proc->pid==0 delays enabling. */
-		}
+		insert_breakpoint(proc, sym2addr(proc, sym), sym);
 		sym = sym->next;
 	}
 	proc->callstack_depth = 0;
@@ -186,7 +181,7 @@
 
 	while (sym) {
 		if (sym->needs_init) {
-			insert_breakpoint(proc, plt2addr(proc, sym->enter_addr),
+			insert_breakpoint(proc, sym2addr(proc, sym),
 					  sym);
 			if (sym->needs_init && !sym->is_weak) {
 				fprintf(stderr,

Modified: ltrace/trunk/configure.ac
===================================================================
--- ltrace/trunk/configure.ac	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/configure.ac	2006-06-14 04:55:21 UTC (rev 42)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.57)
-AC_INIT(ltrace,0.4,[ltrace-devel <ltrace-devel at alioth.debian.org>])
+AC_INIT(ltrace,0.5,[ltrace-devel <ltrace-devel at alioth.debian.org>])
 AC_CONFIG_SRCDIR(ltrace.c)
 AC_CONFIG_HEADER(config.h)
 

Modified: ltrace/trunk/elf.c
===================================================================
--- ltrace/trunk/elf.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/elf.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -21,9 +21,9 @@
 static void do_close_elf(struct ltelf *lte);
 static void add_library_symbol(GElf_Addr addr, const char *name,
 			       struct library_symbol **library_symbolspp,
-			       int use_elf_plt2addr, int is_weak);
+			       enum toplt type_of_plt, int is_weak);
 static int in_load_libraries(const char *name, struct ltelf *lte);
-static GElf_Addr elf_plt2addr(struct ltelf *ltc, void *addr);
+static GElf_Addr opd2addr(struct ltelf *ltc, void *addr);
 
 #ifdef PLT_REINITALISATION_BP
 extern char *PLTs_initialized_by_here;
@@ -194,7 +194,7 @@
 					error(EXIT_FAILURE, 0,
 					      "Couldn't convert .hash section from \"%s\"",
 					      filename);
-				lte->hash_malloced = 1;
+				lte->lte_flags |= LTE_HASH_MALLOCED;
 				dst = lte->hash;
 				src = (Elf32_Word *) data->d_buf;
 				if ((data->d_type == ELF_T_WORD
@@ -214,6 +214,9 @@
 			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;
+				}
 			} else if (strcmp(name, ".opd") == 0) {
 				lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
 				lte->opd_size = shdr.sh_size;
@@ -265,7 +268,7 @@
 
 static void do_close_elf(struct ltelf *lte)
 {
-	if (lte->hash_malloced)
+	if (lte->lte_flags & LTE_HASH_MALLOCED)
 		free((char *)lte->hash);
 	elf_end(lte->elf);
 	close(lte->fd);
@@ -274,7 +277,7 @@
 static void
 add_library_symbol(GElf_Addr addr, const char *name,
 		   struct library_symbol **library_symbolspp,
-		   int use_elf_plt2addr, int is_weak)
+		   enum toplt type_of_plt, int is_weak)
 {
 	struct library_symbol *s;
 	s = malloc(sizeof(struct library_symbol) + strlen(name) + 1);
@@ -283,7 +286,7 @@
 
 	s->needs_init = 1;
 	s->is_weak = is_weak;
-	s->static_plt2addr = use_elf_plt2addr;
+	s->plt_type = type_of_plt;
 	s->next = *library_symbolspp;
 	s->enter_addr = (void *)(uintptr_t) addr;
 	s->brkpnt = NULL;
@@ -330,7 +333,7 @@
 	return 0;
 }
 
-static GElf_Addr elf_plt2addr(struct ltelf *lte, void *addr)
+static GElf_Addr opd2addr(struct ltelf *lte, void *addr)
 {
 	long base;
 	long offset;
@@ -397,7 +400,9 @@
 		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, 0,
+			add_library_symbol(addr, name, &library_symbols,
+					   (PLTS_ARE_EXECUTABLE(lte)
+					   ?  LS_TOPLT_EXEC : LS_TOPLT_POINT),
 					   ELF64_ST_BIND(sym.st_info) != 0);
 			if (!lib_tail)
 				lib_tail = &(library_symbols->next);
@@ -446,9 +451,8 @@
 			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(elf_plt2addr
-						   (lte, (void *) (long) addr),
-						   name, lib_tail, 1, 0);
+				add_library_symbol(opd2addr(lte, (void*)addr),
+						   name, lib_tail, LS_TOPLT_NONE, 0);
 				xptr->found = 1;
 				break;
 			}

Modified: ltrace/trunk/elf.h
===================================================================
--- ltrace/trunk/elf.h	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/elf.h	2006-06-14 04:55:21 UTC (rev 42)
@@ -24,9 +24,14 @@
 	GElf_Addr *opd_addr;
 	size_t opd_size;
 	Elf32_Word *hash;
-	int hash_malloced;
+	int lte_flags;
 };
 
+#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_LIBRARY];
 

Modified: ltrace/trunk/ltrace.h
===================================================================
--- ltrace/trunk/ltrace.h	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/ltrace.h	2006-06-14 04:55:21 UTC (rev 42)
@@ -66,6 +66,13 @@
 	struct 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 struct function *list_of_functions;
 extern char *PLTs_initialized_by_here;
 
@@ -74,9 +81,8 @@
 	void *enter_addr;
 	struct breakpoint *brkpnt;
 	char needs_init;
-	char static_plt2addr;
+	enum toplt plt_type;
 	char is_weak;
-
 	struct library_symbol *next;
 };
 
@@ -193,7 +199,7 @@
 extern void save_register_args(enum tof type, struct process *proc);
 extern int umovestr(struct process *proc, void *addr, int len, void *laddr);
 extern int ffcheck(void *maddr);
-extern void *plt2addr(struct process *, void **);
+extern void *sym2addr(struct process *, struct library_symbol *);
 
 #if 0				/* not yet */
 extern int umoven(struct process *proc, void *addr, int len, void *laddr);

Modified: ltrace/trunk/output.c
===================================================================
--- ltrace/trunk/output.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/output.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -24,7 +24,7 @@
 
 struct dict *dict_opt_c = NULL;
 
-static pid_t current_pid = 0;
+static struct process *current_proc = 0;
 static int current_depth = 0;
 static int current_column = 0;
 
@@ -134,10 +134,14 @@
 	if (opt_c) {
 		return;
 	}
-	if (current_pid) {
-		fprintf(output, " <unfinished ...>\n");
+	if (current_proc) {
+		if (current_proc->callstack[current_depth].return_addr) {
+			fprintf(output, " <unfinished ...>\n");
+		} else {
+			fprintf(output, " <no return ...>\n");
+		}
 	}
-	current_pid = 0;
+	current_proc = 0;
 	if (!fmt) {
 		return;
 	}
@@ -164,12 +168,12 @@
 	if (opt_c) {
 		return;
 	}
-	if (current_pid) {
+	if (current_proc) {
 		fprintf(output, " <unfinished ...>\n");
-		current_pid = 0;
+		current_proc = 0;
 		current_column = 0;
 	}
-	current_pid = proc->pid;
+	current_proc = proc;
 	current_depth = proc->callstack_depth;
 	proc->type_being_displayed = type;
 	begin_of_line(type, proc);
@@ -248,12 +252,12 @@
 //                              current_time_spent.tv_sec, (int)current_time_spent.tv_usec);
 		return;
 	}
-	if (current_pid && (current_pid != proc->pid ||
+	if (current_proc && (current_proc != proc ||
 			    current_depth != proc->callstack_depth)) {
 		fprintf(output, " <unfinished ...>\n");
-		current_pid = 0;
+		current_proc = 0;
 	}
-	if (current_pid != proc->pid) {
+	if (current_proc != proc) {
 		begin_of_line(type, proc);
 #ifdef USE_DEMANGLE
 		current_column +=
@@ -297,6 +301,6 @@
 			(int)current_time_spent.tv_usec);
 	}
 	fprintf(output, "\n");
-	current_pid = 0;
+	current_proc = 0;
 	current_column = 0;
 }

Modified: ltrace/trunk/process_event.c
===================================================================
--- ltrace/trunk/process_event.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/process_event.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -260,10 +260,23 @@
 static void process_breakpoint(struct event *event)
 {
 	int i, j;
-	struct breakpoint *sbp;
+	struct breakpoint *sbp, *nxtbp;
 
 	debug(2, "event: breakpoint (%p)", event->e_un.brk_addr);
-	if (event->proc->breakpoint_being_enabled) {
+	if ((sbp = event->proc->breakpoint_being_enabled) != 0) {
+#ifdef __powerpc__
+		char nop_inst[] = PPC_NOP;
+                if (memcmp(sbp->orig_value, nop_inst, PPC_NOP_LENGTH) == 0) {
+                	nxtbp = address2bpstruct(event->proc,
+                                                 event->e_un.brk_addr +
+                                                 	PPC_NOP_LENGTH);
+			if (nxtbp != 0) {
+				enable_breakpoint(event->proc->pid, sbp);
+				continue_after_breakpoint(event->proc, nxtbp);
+				return;
+			}
+		}
+#endif
 		/* Reinsert breakpoint */
 		continue_enabling_breakpoint(event->proc->pid,
 					     event->proc->
@@ -284,9 +297,9 @@
 			unsigned long a;
 			struct library_symbol *libsym =
 			    event->proc->callstack[i].c_un.libfunc;
-			void *addr = plt2addr(event->proc, libsym->enter_addr);
+			void *addr = sym2addr(event->proc, libsym);
 
-			if (event->proc->e_machine == EM_PPC) {
+			if (libsym->plt_type != LS_TOPLT_POINT) {
 				unsigned char break_insn[] = BREAKPOINT_VALUE;
 
 				sbp = address2bpstruct(event->proc, addr);
@@ -294,7 +307,7 @@
 				a = ptrace(PTRACE_PEEKTEXT, event->proc->pid,
 					   addr);
 
-				if (memcmp(&a, break_insn, 4)) {
+				if (memcmp(&a, break_insn, BREAKPOINT_LENGTH)) {
 					sbp->enabled--;
 					insert_breakpoint(event->proc, addr,
 							  libsym);
@@ -302,9 +315,10 @@
 			} else {
 				sbp = libsym->brkpnt;
 				assert(sbp);
-				if (addr != sbp->addr)
+				if (addr != sbp->addr) {
 					insert_breakpoint(event->proc, addr,
 							  libsym);
+				}
 			}
 #endif
 			for (j = event->proc->callstack_depth - 1; j > i; j--) {
@@ -386,7 +400,9 @@
 	elem->c_un.libfunc = sym;
 
 	elem->return_addr = proc->return_addr;
-	insert_breakpoint(proc, elem->return_addr, 0);
+        if (elem->return_addr) {
+		insert_breakpoint(proc, elem->return_addr, 0);
+	}
 
 	proc->callstack_depth++;
 	if (opt_T || opt_c) {
@@ -401,7 +417,7 @@
 	assert(proc->callstack_depth > 0);
 
 	elem = &proc->callstack[proc->callstack_depth - 1];
-	if (!elem->is_syscall) {
+	if (!elem->is_syscall && elem->return_addr) {
 		delete_breakpoint(proc, elem->return_addr);
 	}
 	proc->callstack_depth--;

Modified: ltrace/trunk/sysdeps/linux-gnu/alpha/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/alpha/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/alpha/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -7,7 +7,7 @@
 	return lte->plt_addr + ndx * 12 + 32;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/arm/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/arm/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/arm/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -7,7 +7,7 @@
 	return lte->plt_addr + 20 + ndx * 12;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/breakpoint.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/breakpoint.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/breakpoint.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -33,7 +33,7 @@
 		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
 			unsigned char *bytes = (unsigned char *)&a;
 
-			sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
+			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);
@@ -52,9 +52,7 @@
 {
 	unsigned int i, j;
 
-	if (opt_d > 1) {
-		output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
-	}
+	debug(2, "disable_breakpoint(%d,%p)", pid, sbp->addr);
 
 	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
 		long a =

Modified: ltrace/trunk/sysdeps/linux-gnu/i386/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/i386/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/i386/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -7,7 +7,7 @@
 	return lte->plt_addr + (ndx + 1) * 16;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/ia64/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/ia64/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/ia64/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -42,7 +42,7 @@
 	return addr;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/m68k/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/m68k/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/m68k/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -8,7 +8,7 @@
 	    * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12);
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/ppc/arch.h
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/ppc/arch.h	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/ppc/arch.h	2006-06-14 04:55:21 UTC (rev 42)
@@ -4,10 +4,18 @@
 
 #define LT_ELFCLASS	ELFCLASS32
 #define LT_ELF_MACHINE	EM_PPC
-#ifdef __powerpc64__
+#ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
 #define LT_ELFCLASS2	ELFCLASS64
 #define LT_ELF_MACHINE2	EM_PPC64
 
 #define PLT_REINITALISATION_BP    "_start"
 
+#define PPC_NOP { 0x60, 0x00, 0x00, 0x00 }
+#define PPC_NOP_LENGTH 4
+
+#if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
+#error "Length of the breakpoint value not equal to the length of a nop instruction"
 #endif
+
+
+#endif

Modified: ltrace/trunk/sysdeps/linux-gnu/ppc/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/ppc/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/ppc/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -10,31 +10,49 @@
 	return rela->r_offset;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	long addr;
+	long addr = sym->enter_addr;
+	long pt_ret;
 
 	debug(3, 0);
 
-	if (proc->e_machine == EM_PPC || plt == 0)
-		return (void *)plt;
+	if (sym->plt_type != LS_TOPLT_POINT) {
+		return addr;
+	}
 
-	if (proc->pid == 0)
-		return (void *)0;
+	if (proc->pid == 0) {
+		return 0;
+	}
 
+	if (opt_d >= 3) {
+		xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0),
+			 sizeof(void*)*8);
+	}
+
 	// 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.
+	// 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.
 
-	addr = ptrace(PTRACE_PEEKTEXT, proc->pid, plt);
+	// 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.
 
-	if (opt_d >= 3) {
-		xinfdump(proc->pid, plt, sizeof(void *) * 3);
+	pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
+
+	if (proc->mask_32bit) {
+		// Assume big-endian.
+		addr = (void *)((pt_ret >> 32) & 0xffffffff);
+	} else {
+		addr = (void *)pt_ret;
 	}
 
-	return (void *)addr;
+	return addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/s390/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/s390/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/s390/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -7,7 +7,7 @@
 	return lte->plt_addr + (ndx + 1) * 32;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/sparc/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/sparc/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/sparc/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -7,7 +7,7 @@
 	return rela->r_offset + 4;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }

Modified: ltrace/trunk/sysdeps/linux-gnu/x86_64/plt.c
===================================================================
--- ltrace/trunk/sysdeps/linux-gnu/x86_64/plt.c	2006-05-11 05:03:29 UTC (rev 41)
+++ ltrace/trunk/sysdeps/linux-gnu/x86_64/plt.c	2006-06-14 04:55:21 UTC (rev 42)
@@ -7,7 +7,7 @@
 	return lte->plt_addr + (ndx + 1) * 16;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }




More information about the Ltrace-devel mailing list