[Ltrace-devel] r74 - in ltrace/trunk: . sysdeps/linux-gnu

eric vaitl evaitl-guest at alioth.debian.org
Thu Dec 28 16:16:57 CET 2006


Author: evaitl-guest
Date: 2006-12-28 16:16:56 +0100 (Thu, 28 Dec 2006)
New Revision: 74

Added:
   ltrace/trunk/sysdeps/linux-gnu/mipsel/
Modified:
   ltrace/trunk/ChangeLog
   ltrace/trunk/breakpoints.c
   ltrace/trunk/debug.h
   ltrace/trunk/elf.c
   ltrace/trunk/elf.h
   ltrace/trunk/process_event.c
Log:
svn merge -r 72:73 svn+ssh://evaitl-guest@svn.debian.org/svn/ltrace/ltrace/branches/eav_mipsel_port svn+ssh://evaitl-guest@svn.debian.org/svn/ltrace/ltrace/trunk

Merged mipsel port from branch back to the trunk.



Modified: ltrace/trunk/ChangeLog
===================================================================
--- ltrace/trunk/ChangeLog	2006-12-28 14:59:03 UTC (rev 73)
+++ ltrace/trunk/ChangeLog	2006-12-28 15:16:56 UTC (rev 74)
@@ -1,3 +1,18 @@
+2006-12-28  Eric Vaitl  <evaitl at cisco.com>
+
+	* sysdeps/linux-gnu/mipsel/* Added mipsel support
+	* debug.h Added printf format attribute to debug_
+	* elf.h Added mips relocation data to struct ltelf
+	* elf.c (do_init_elf) Read mips relocation data
+	* elf.c (read_elf) On the mips loop through mips_gotsym 
+	instead of relplt_count.
+	* process_event.c (process_breakpoint) For the mips, 
+	conditionally add a new breakpoint if the address of the 
+	function changes because of lazy relocation. 
+	* breakpoints.c (enable_all_breakpoints) For the mips, 
+	reinsert breakpoints after the child has been started. 
+	
+
 2006-11-30  Petr Machata  <pmachata at redhat.com>
 
 	* elf.c (elf_gnu_hash): renamed to private_elf_gnu_hash to avoid

Modified: ltrace/trunk/breakpoints.c
===================================================================
--- ltrace/trunk/breakpoints.c	2006-12-28 14:59:03 UTC (rev 73)
+++ ltrace/trunk/breakpoints.c	2006-12-28 15:16:56 UTC (rev 74)
@@ -105,6 +105,34 @@
 			dict_apply_to_all(proc->breakpoints, enable_bp_cb,
 					  proc);
 		}
+#ifdef __mips__
+                {
+                    // I'm sure there is a nicer way to do this. We need to
+                    // insert breakpoints _after_ the child has been started.
+                    struct library_symbol *sym;
+                    struct library_symbol *new_sym;
+                    sym=proc->list_of_symbols;
+                    while(sym){
+                        void *addr= sym2addr(proc,sym);
+                        if(!addr){
+                            sym=sym->next;
+                            continue;
+                        }
+                        if(dict_find_entry(proc->breakpoints,addr)){
+                            sym=sym->next;
+                            continue;
+                        }
+                        debug(2,"inserting bp %p %s",addr,sym->name);
+                        new_sym=malloc(sizeof(*new_sym));
+                        memcpy(new_sym,sym,sizeof(*new_sym));
+                        new_sym->next=proc->list_of_symbols;
+                        proc->list_of_symbols=new_sym;
+                        new_sym->brkpnt=0;
+                        insert_breakpoint(proc, addr, new_sym);
+                        sym=sym->next;
+                    }
+                }
+#endif
 	}
 	proc->breakpoints_enabled = 1;
 }

Modified: ltrace/trunk/debug.h
===================================================================
--- ltrace/trunk/debug.h	2006-12-28 14:59:03 UTC (rev 73)
+++ ltrace/trunk/debug.h	2006-12-28 15:16:56 UTC (rev 74)
@@ -1,7 +1,7 @@
 #include <features.h>
 
 void debug_(int level, const char *file, int line, const char *func,
-	    const char *fmt, ...);
+            const char *fmt, ...) __attribute__((format(printf,5,6)));
 
 int xwrite(const char *, size_t);
 int xwrites(const char *);

Modified: ltrace/trunk/elf.c
===================================================================
--- ltrace/trunk/elf.c	2006-12-28 14:59:03 UTC (rev 73)
+++ ltrace/trunk/elf.c	2006-12-28 15:16:56 UTC (rev 74)
@@ -159,7 +159,33 @@
 					error(EXIT_FAILURE, 0,
 					      "Couldn't get .dynamic data from \"%s\"",
 					      filename);
+#ifdef __mips__
+/**
+  MIPS ABI Supplement:
 
+  DT_PLTGOT This member holds the address of the .got section. 
+
+  DT_MIPS_SYMTABNO This member holds the number of entries in the
+  .dynsym section.
+
+  DT_MIPS_LOCAL_GOTNO This member holds the number of local global
+  offset table entries.
+
+  DT_MIPS_GOTSYM This member holds the index of the first dyamic
+  symbol table entry that corresponds to an entry in the gobal offset
+  table.
+
+ */
+                                if(dyn.d_tag==DT_PLTGOT){
+                                    lte->pltgot_addr=dyn.d_un.d_ptr; 
+                                }
+                                if(dyn.d_tag==DT_MIPS_LOCAL_GOTNO){
+                                    lte->mips_local_gotno=dyn.d_un.d_val;
+                                }
+                                if(dyn.d_tag==DT_MIPS_GOTSYM){
+                                    lte->mips_gotsym=dyn.d_un.d_val;
+                                }
+#endif // __mips__
 				if (dyn.d_tag == DT_JMPREL)
 					relplt_addr = dyn.d_un.d_ptr;
 				else if (dyn.d_tag == DT_PLTRELSZ)
@@ -442,7 +468,30 @@
 	proc->e_machine = lte->ehdr.e_machine;
 	for (i = 0; i < library_num; ++i)
 		do_init_elf(&lte[i + 1], library[i]);
-
+#ifdef __mips__
+        // MIPS doesn't use the PLT and the GOT entries get changed
+        // on startup. 
+        proc->need_to_reinitialize_breakpoints = 1;
+        for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){
+            GElf_Sym sym;
+            const char *name;
+            GElf_Addr addr = arch_plt_sym_val(lte, i, 0);
+            if (gelf_getsym(lte->dynsym, i, &sym) == NULL){
+                error(EXIT_FAILURE, 0,
+                      "Couldn't get relocation from \"%s\"",
+                      proc->filename);       
+            }
+            name=lte->dynstr+sym.st_name;
+            if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){
+                debug(2,"sym %s not a function",name);
+                continue;
+            }
+            add_library_symbol(addr, name, &library_symbols, 0,
+                               ELF64_ST_BIND(sym.st_info) != 0);
+            if (!lib_tail)
+                lib_tail = &(library_symbols->next);
+        }
+#else
 	for (i = 0; i < lte->relplt_count; ++i) {
 		GElf_Rel rel;
 		GElf_Rela rela;
@@ -483,7 +532,7 @@
 				lib_tail = &(library_symbols->next);
 		}
 	}
-
+#endif // !__mips__
 #ifdef PLT_REINITALISATION_BP
 	struct opt_x_t *main_cheat;
 

Modified: ltrace/trunk/elf.h
===================================================================
--- ltrace/trunk/elf.h	2006-12-28 14:59:03 UTC (rev 73)
+++ ltrace/trunk/elf.h	2006-12-28 15:16:56 UTC (rev 74)
@@ -26,6 +26,11 @@
 	Elf32_Word *hash;
 	int hash_type;
 	int lte_flags;
+#ifdef __mips__
+        size_t pltgot_addr;
+        size_t mips_local_gotno;
+        size_t mips_gotsym;
+#endif // __mips__
 };
 
 #define LTE_HASH_MALLOCED 1

Modified: ltrace/trunk/process_event.c
===================================================================
--- ltrace/trunk/process_event.c	2006-12-28 14:59:03 UTC (rev 73)
+++ ltrace/trunk/process_event.c	2006-12-28 15:16:56 UTC (rev 74)
@@ -327,6 +327,23 @@
 							  libsym);
 				}
 			}
+#elif defined(__mips__)
+                        void *addr;
+                        void *old_addr;
+                        struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
+                        assert(sym && sym->brkpnt);
+                        old_addr=sym->brkpnt->addr;
+                        addr=sym2addr(event->proc,sym);
+                        assert(old_addr !=0 && addr !=0);
+                        if(addr != old_addr){
+                            struct library_symbol *new_sym;
+                            new_sym=malloc(sizeof(*new_sym));
+                            memcpy(new_sym,sym,sizeof(*new_sym));
+                            new_sym->next=event->proc->list_of_symbols;
+                            event->proc->list_of_symbols=new_sym;
+                            new_sym->brkpnt=0;
+                            insert_breakpoint(event->proc, addr, new_sym);
+                        }
 #endif
 			for (j = event->proc->callstack_depth - 1; j > i; j--) {
 				callstack_pop(event->proc);

Copied: ltrace/trunk/sysdeps/linux-gnu/mipsel (from rev 73, ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel)




More information about the Ltrace-devel mailing list