[Ltrace-devel] current make check failures

Petr Machata pmachata at redhat.com
Thu Oct 12 13:34:46 UTC 2006


Steve Fink wrote:
> On 9/18/06, Steve Fink <sphink at gmail.com> wrote:
>> On 9/14/06, Olaf Hering <olh at suse.de> wrote:
>> > The current trunk gives these make check failures in openSuSE 10.2 beta.
>> > ltrace -x does not work, on ppc64 at least.
>>
>>
>> ia64 is broken too.
>>
> 
> I looked into this further. I don't understand what it's doing, but Petr
> Machata's patch at
> http://www.redhat.com/archives/fedora-cvs-commits/2006-April/msg01088.html
> would fix this. Was it applied and then reverted, or never applied, or what?
> 
> Basically, on ia64 it seems like opd2addr() shouldn't do anything to the
> passed-in address. The test passes, at least, if you just have it return
> the address unmodified.

It was never commited upstream.  More systematic fix to this would be
 1) move opd2addr into sysdeps/arch/ and make it part of backend api
 2) or #define ARCH_SUPPORTS_OPD in backend's arch.h, and only handle
opd with this #define

I attached the patch prepared according to the second scenario.  Testing
on x86 and ppc went well, only alreade-present failures occur.  I'll do
more thorough testing once I get to my work machine. Comments welcome.

PM

-------------- next part --------------
Index: trunk/elf.c
===================================================================
--- trunk/elf.c	(revision 68)
+++ trunk/elf.c	(working copy)
@@ -240,11 +240,14 @@
 				if (shdr.sh_flags & SHF_EXECINSTR) {
 					lte->lte_flags |= LTE_PLT_EXECUTABLE;
 				}
-			} else if (strcmp(name, ".opd") == 0) {
+			}
+#ifdef ARCH_SUPPORTS_OPD
+			else if (strcmp(name, ".opd") == 0) {
 				lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
 				lte->opd_size = shdr.sh_size;
 				lte->opd = elf_rawdata(scn, NULL);
 			}
+#endif
 		}
 	}
 
@@ -351,13 +354,12 @@
 			Elf32_Word nbuckets = *hashbase++;
 			Elf32_Word symbias = *hashbase++;
 			Elf32_Word bitmask_nwords = *hashbase++;
-			Elf32_Word bitmask_idxbits = bitmask_nwords - 1;
-			Elf32_Word shift = *hashbase++;
 			Elf32_Word * buckets;
 			Elf32_Word * chain_zero;
 			Elf32_Word bucket;
 
-			hashbase += lte[i].ehdr.e_ident[EI_CLASS] * bitmask_nwords;
+			// +1 for skipped `shift'
+			hashbase += lte[i].ehdr.e_ident[EI_CLASS] * bitmask_nwords + 1;
 			buckets = hashbase;
 			hashbase += nbuckets;
 			chain_zero = hashbase - symbias;
@@ -408,6 +410,7 @@
 
 static GElf_Addr opd2addr(struct ltelf *lte, GElf_Addr addr)
 {
+#ifdef ARCH_SUPPORTS_OPD
 	unsigned long base, offset;
 
 	if (!lte->opd)
@@ -419,6 +422,9 @@
 		error(EXIT_FAILURE, 0, "static plt not in .opd");
 
 	return *(GElf_Addr*)(base + offset);
+#else //!ARCH_SUPPORTS_OPD
+	return addr;
+#endif
 }
 
 struct library_symbol *read_elf(struct process *proc)
Index: trunk/sysdeps/linux-gnu/ppc/arch.h
===================================================================
--- trunk/sysdeps/linux-gnu/ppc/arch.h	(revision 68)
+++ trunk/sysdeps/linux-gnu/ppc/arch.h	(working copy)
@@ -4,9 +4,11 @@
 
 #define LT_ELFCLASS	ELFCLASS32
 #define LT_ELF_MACHINE	EM_PPC
+
 #ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
 #define LT_ELFCLASS2	ELFCLASS64
 #define LT_ELF_MACHINE2	EM_PPC64
+#define ARCH_SUPPORTS_OPD
 #endif
 
 #define PLT_REINITALISATION_BP    "_start"
Index: trunk/sysdeps/linux-gnu/ia64/arch.h
===================================================================
--- trunk/sysdeps/linux-gnu/ia64/arch.h	(revision 68)
+++ trunk/sysdeps/linux-gnu/ia64/arch.h	(working copy)
@@ -7,3 +7,7 @@
 
 #define LT_ELFCLASS   ELFCLASS64
 #define LT_ELF_MACHINE EM_IA_64
+
+// ia64 actually does use .opd, but we don't need to do the
+// translation manually.
+#undef ARCH_SUPPORTS_OPD
Index: trunk/breakpoints.c
===================================================================
--- trunk/breakpoints.c	(revision 68)
+++ trunk/breakpoints.c	(working copy)
@@ -28,6 +28,7 @@
 		  struct library_symbol *libsym)
 {
 	struct breakpoint *sbp;
+	debug(1, "insert_breakpoint(symbol=%s, addr=%p)", libsym?libsym->name:"(nil)", addr);
 
 	if (!proc->breakpoints) {
 		proc->breakpoints =
@@ -165,11 +166,9 @@
 	} else {
 		proc->list_of_symbols = NULL;
 	}
-	sym = proc->list_of_symbols;
-	while (sym) {
+	for (sym = proc->list_of_symbols; sym; sym = sym->next) {
 		/* proc->pid==0 delays enabling. */
 		insert_breakpoint(proc, sym2addr(proc, sym), sym);
-		sym = sym->next;
 	}
 	proc->callstack_depth = 0;
 	proc->breakpoints_enabled = -1;


More information about the Ltrace-devel mailing list