[Ltrace-devel] r73 - in ltrace/branches/eav_mipsel_port: .
sysdeps/linux-gnu sysdeps/linux-gnu/mipsel
eric vaitl
evaitl-guest at alioth.debian.org
Thu Dec 28 15:59:03 CET 2006
Author: evaitl-guest
Date: 2006-12-28 15:59:03 +0100 (Thu, 28 Dec 2006)
New Revision: 73
Added:
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Doxyfile
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Makefile
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/arch.h
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/mipsel.h
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/plt.c
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/ptrace.h
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/regs.c
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/signalent.h
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/syscallent.h
ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/trace.c
Modified:
ltrace/branches/eav_mipsel_port/ChangeLog
ltrace/branches/eav_mipsel_port/breakpoints.c
ltrace/branches/eav_mipsel_port/debug.h
ltrace/branches/eav_mipsel_port/elf.c
ltrace/branches/eav_mipsel_port/elf.h
ltrace/branches/eav_mipsel_port/process_event.c
Log:
Added mipsel support to current tips.
Modified: ltrace/branches/eav_mipsel_port/ChangeLog
===================================================================
--- ltrace/branches/eav_mipsel_port/ChangeLog 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/ChangeLog 2006-12-28 14:59:03 UTC (rev 73)
@@ -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/branches/eav_mipsel_port/breakpoints.c
===================================================================
--- ltrace/branches/eav_mipsel_port/breakpoints.c 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/breakpoints.c 2006-12-28 14:59:03 UTC (rev 73)
@@ -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/branches/eav_mipsel_port/debug.h
===================================================================
--- ltrace/branches/eav_mipsel_port/debug.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/debug.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -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/branches/eav_mipsel_port/elf.c
===================================================================
--- ltrace/branches/eav_mipsel_port/elf.c 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/elf.c 2006-12-28 14:59:03 UTC (rev 73)
@@ -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(<e[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/branches/eav_mipsel_port/elf.h
===================================================================
--- ltrace/branches/eav_mipsel_port/elf.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/elf.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -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/branches/eav_mipsel_port/process_event.c
===================================================================
--- ltrace/branches/eav_mipsel_port/process_event.c 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/process_event.c 2006-12-28 14:59:03 UTC (rev 73)
@@ -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);
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Doxyfile
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Doxyfile 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Doxyfile 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,275 @@
+# Doxyfile 1.5.1
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = ltrace-mipsel
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = YES
+SORT_BY_SCOPE_NAME = YES
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = .
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.C \
+ *.CC \
+ *.C++ \
+ *.II \
+ *.I++ \
+ *.H \
+ *.HH \
+ *.H++ \
+ *.CS \
+ *.PHP \
+ *.PHP3 \
+ *.M \
+ *.MM \
+ *.PY
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = YES
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = YES
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 1000
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = NO
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Makefile
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Makefile 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/Makefile 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,22 @@
+.PHONY: all deps clean docs
+
+OBJ = trace.o regs.o plt.o
+SRC=$(OBJ:.o=.c)
+
+all: arch.o
+
+deps:
+ $(CC) $(CFLAGS) $(CPPFLAGS) -M $(SRC) > .depends
+
+arch.o: $(OBJ) arch.h
+ $(CC) -nostdlib -r -o arch.o $(OBJ)
+
+clean:
+ -rm -f $(OBJ) arch.o
+ -rm -rf html
+
+docs:
+ doxygen
+
+
+-include .depends
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/arch.h
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/arch.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/arch.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,9 @@
+#define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 }
+#define BREAKPOINT_LENGTH 4
+#define DECR_PC_AFTER_BREAK 0
+
+#define LT_ELFCLASS ELFCLASS32
+#define LT_ELF_MACHINE EM_MIPS
+
+#define PLTs_INIT_BY_HERE "_start"
+#define E_ENTRY_NAME "_start"
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/mipsel.h
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/mipsel.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/mipsel.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,11 @@
+#ifndef MIPSEL_h
+#define MIPSEL_h
+// linux-2.4.30/arch/mips/kernel/ptrace.c for these offsets.
+#define off_v0 2
+#define off_pc 64
+#define off_a0 4
+#define off_a3 7
+#define off_lr 31
+#define off_sp 29
+
+#endif // MIPSEL_h
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/plt.c
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/plt.c 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/plt.c 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,75 @@
+#include <debug.h>
+#include <gelf.h>
+#include <sys/ptrace.h>
+#include "ltrace.h"
+#include "ltrace_elf.h"
+
+/**
+ \addtogroup mipsel
+ @{
+ */
+
+/**
+ \param lte Structure containing link table entry information
+ \param ndx Index into .dynsym
+ \param rela Not used.
+ \return Address of GOT table entry
+
+ 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.
+
+ Called by read_elf when building the symbol table.
+
+ */
+GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+{
+ debug(1,"plt_addr %x ndx %#x",lte->pltgot_addr, ndx);
+ return
+ lte->pltgot_addr +
+ sizeof(void *) * (lte->mips_local_gotno + (ndx - lte->mips_gotsym));
+}
+/**
+ \param proc The process to work on.
+ \param sym The library symbol.
+ \return What is at the got table address
+
+ The return value should be the address to put the breakpoint at.
+
+ On the mips the library_symbol.enter_addr is the .got addr for the
+ symbol and the breakpoint.addr is the actual breakpoint address.
+
+ Other processors use a plt, the mips is "special" in that is uses
+ the .got for both function and data relocations. Prior to program
+ startup, return 0.
+
+ \warning MIPS relocations are lazy. This means that the breakpoint
+ may move after the first call. Ltrace dictionary routines don't
+ have a delete and symbol is one to one with breakpoint, so if the
+ breakpoint changes I just add a new breakpoint for the new address.
+
+ */
+void *sym2addr(struct process *proc, struct library_symbol *sym)
+{
+ long ret;
+ if(!proc->pid){
+ return 0;
+ }
+ ret=ptrace(PTRACE_PEEKTEXT, proc->pid, sym->enter_addr, 0);
+ if(ret==-1){
+ ret =0;
+ }
+ return (void *)ret;;
+}
+
+/**@}*/
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/ptrace.h
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/ptrace.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/ptrace.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1 @@
+#include <sys/ptrace.h>
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/regs.c
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/regs.c 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/regs.c 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,73 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include <linux/user.h>
+
+#include "ltrace.h"
+#include "mipsel.h"
+
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
+/**
+ \addtogroup mipsel
+ @{
+ */
+
+
+/**
+ \param proc The process to work on.
+ \return The current instruction pointer.
+ */
+void *get_instruction_pointer(struct process *proc)
+{
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
+}
+
+/**
+ \param proc The process to work on.
+ \param addr The address to set to.
+
+ Called by \c continue_after_breakpoint().
+
+ \todo Our mips kernel ptrace doesn't support PTRACE_SINGLESTEP, so
+ we \c continue_process() after a breakpoint. Check if this is OK.
+ */
+void set_instruction_pointer(struct process *proc, void *addr)
+{
+ ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
+}
+
+/**
+ \param proc The process to work on.
+ \return The current stack pointer.
+ */
+void *get_stack_pointer(struct process *proc)
+{
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
+}
+
+/**
+ \param proc The process to work on.
+ \param stack_pointer The current stack pointer for proc
+ \return The current return address.
+
+ Called by \c process_breakpoint().
+
+ Mips uses r31 for the return address, so the stack_pointer is
+ unused.
+ */
+void *get_return_addr(struct process *proc, void *stack_pointer)
+{
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
+}
+/**@}*/
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/signalent.h
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/signalent.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/signalent.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,32 @@
+"SIG_0", /* 0 */
+ "SIGHUP", // 1 /* Hangup (POSIX). */
+ "SIGINT", // 2 /* Interrupt (ANSI). */
+ "SIGQUIT", // 3 /* Quit (POSIX). */
+ "SIGILL", // 4 /* Illegal instruction (ANSI). */
+ "SIGTRAP", // 5 /* Trace trap (POSIX). */
+ "SIGIOT", // 6 /* IOT trap (4.2 BSD). */
+ "SIGEMT", // 7
+ "SIGFPE", // 8 /* Floating-point exception (ANSI). */
+ "SIGKILL", // 9 /* Kill, unblockable (POSIX). */
+ "SIGBUS", // 10 /* BUS error (4.2 BSD). */
+ "SIGSEGV", // 11 /* Segmentation violation (ANSI). */
+ "SIGSYS", // 12
+ "SIGPIPE", // 13 /* Broken pipe (POSIX). */
+ "SIGALRM", // 14 /* Alarm clock (POSIX). */
+ "SIGTERM", // 15 /* Termination (ANSI). */
+ "SIGUSR1", // 16 /* User-defined signal 1 (POSIX). */
+ "SIGUSR2", // 17 /* User-defined signal 2 (POSIX). */
+ "SIGCHLD", // 18 /* Child status has changed (POSIX). */
+ "SIGPWR", // 19 /* Power failure restart (System V). */
+ "SIGWINCH", // 20 /* Window size change (4.3 BSD, Sun). */
+ "SIGURG", // 21 /* Urgent condition on socket (4.2 BSD). */
+ "SIGIO", // 22 /* I/O now possible (4.2 BSD). */
+ "SIGSTOP", // 23 /* Stop, unblockable (POSIX). */
+ "SIGTSTP", // 24 /* Keyboard stop (POSIX). */
+ "SIGCONT", // 25 /* Continue (POSIX). */
+ "SIGTTIN", // 26 /* Background read from tty (POSIX). */
+ "SIGTTOU", // 27 /* Background write to tty (POSIX). */
+ "SIGVTALRM", // 28 /* Virtual alarm clock (4.2 BSD). */
+ "SIGPROF", // 29 /* Profiling alarm clock (4.2 BSD). */
+ "SIGXCPU", // 30 /* CPU limit exceeded (4.2 BSD). */
+ "SIGXFSZ", // 31 /* File size limit exceeded (4.2 BSD). */
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/syscallent.h
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/syscallent.h 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/syscallent.h 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,241 @@
+ "0", /*Linux + 0*/
+ "exit", /*Linux + 1*/
+ "fork", /*Linux + 2*/
+ "read", /*Linux + 3*/
+ "write", /*Linux + 4*/
+ "open", /*Linux + 5*/
+ "close", /*Linux + 6*/
+ "waitpid", /*Linux + 7*/
+ "creat", /*Linux + 8*/
+ "link", /*Linux + 9*/
+ "unlink", /*Linux + 10*/
+ "execve", /*Linux + 11*/
+ "chdir", /*Linux + 12*/
+ "time", /*Linux + 13*/
+ "mknod", /*Linux + 14*/
+ "chmod", /*Linux + 15*/
+ "lchown", /*Linux + 16*/
+ "break", /*Linux + 17*/
+ "unused18", /*Linux + 18*/
+ "lseek", /*Linux + 19*/
+ "getpid", /*Linux + 20*/
+ "mount", /*Linux + 21*/
+ "umount", /*Linux + 22*/
+ "setuid", /*Linux + 23*/
+ "getuid", /*Linux + 24*/
+ "stime", /*Linux + 25*/
+ "ptrace", /*Linux + 26*/
+ "alarm", /*Linux + 27*/
+ "unused28", /*Linux + 28*/
+ "pause", /*Linux + 29*/
+ "utime", /*Linux + 30*/
+ "stty", /*Linux + 31*/
+ "gtty", /*Linux + 32*/
+ "access", /*Linux + 33*/
+ "nice", /*Linux + 34*/
+ "ftime", /*Linux + 35*/
+ "sync", /*Linux + 36*/
+ "kill", /*Linux + 37*/
+ "rename", /*Linux + 38*/
+ "mkdir", /*Linux + 39*/
+ "rmdir", /*Linux + 40*/
+ "dup", /*Linux + 41*/
+ "pipe", /*Linux + 42*/
+ "times", /*Linux + 43*/
+ "prof", /*Linux + 44*/
+ "brk", /*Linux + 45*/
+ "setgid", /*Linux + 46*/
+ "getgid", /*Linux + 47*/
+ "signal", /*Linux + 48*/
+ "geteuid", /*Linux + 49*/
+ "getegid", /*Linux + 50*/
+ "acct", /*Linux + 51*/
+ "umount2", /*Linux + 52*/
+ "lock", /*Linux + 53*/
+ "ioctl", /*Linux + 54*/
+ "fcntl", /*Linux + 55*/
+ "mpx", /*Linux + 56*/
+ "setpgid", /*Linux + 57*/
+ "ulimit", /*Linux + 58*/
+ "unused59", /*Linux + 59*/
+ "umask", /*Linux + 60*/
+ "chroot", /*Linux + 61*/
+ "ustat", /*Linux + 62*/
+ "dup2", /*Linux + 63*/
+ "getppid", /*Linux + 64*/
+ "getpgrp", /*Linux + 65*/
+ "setsid", /*Linux + 66*/
+ "sigaction", /*Linux + 67*/
+ "sgetmask", /*Linux + 68*/
+ "ssetmask", /*Linux + 69*/
+ "setreuid", /*Linux + 70*/
+ "setregid", /*Linux + 71*/
+ "sigsuspend", /*Linux + 72*/
+ "sigpending", /*Linux + 73*/
+ "sethostname", /*Linux + 74*/
+ "setrlimit", /*Linux + 75*/
+ "getrlimit", /*Linux + 76*/
+ "getrusage", /*Linux + 77*/
+ "gettimeofday", /*Linux + 78*/
+ "settimeofday", /*Linux + 79*/
+ "getgroups", /*Linux + 80*/
+ "setgroups", /*Linux + 81*/
+ "reserved82", /*Linux + 82*/
+ "symlink", /*Linux + 83*/
+ "unused84", /*Linux + 84*/
+ "readlink", /*Linux + 85*/
+ "uselib", /*Linux + 86*/
+ "swapon", /*Linux + 87*/
+ "reboot", /*Linux + 88*/
+ "readdir", /*Linux + 89*/
+ "mmap", /*Linux + 90*/
+ "munmap", /*Linux + 91*/
+ "truncate", /*Linux + 92*/
+ "ftruncate", /*Linux + 93*/
+ "fchmod", /*Linux + 94*/
+ "fchown", /*Linux + 95*/
+ "getpriority", /*Linux + 96*/
+ "setpriority", /*Linux + 97*/
+ "profil", /*Linux + 98*/
+ "statfs", /*Linux + 99*/
+ "fstatfs", /*Linux + 100*/
+ "ioperm", /*Linux + 101*/
+ "socketcall", /*Linux + 102*/
+ "syslog", /*Linux + 103*/
+ "setitimer", /*Linux + 104*/
+ "getitimer", /*Linux + 105*/
+ "stat", /*Linux + 106*/
+ "lstat", /*Linux + 107*/
+ "fstat", /*Linux + 108*/
+ "unused109", /*Linux + 109*/
+ "iopl", /*Linux + 110*/
+ "vhangup", /*Linux + 111*/
+ "idle", /*Linux + 112*/
+ "vm86", /*Linux + 113*/
+ "wait4", /*Linux + 114*/
+ "swapoff", /*Linux + 115*/
+ "sysinfo", /*Linux + 116*/
+ "ipc", /*Linux + 117*/
+ "fsync", /*Linux + 118*/
+ "sigreturn", /*Linux + 119*/
+ "clone", /*Linux + 120*/
+ "setdomainname", /*Linux + 121*/
+ "uname", /*Linux + 122*/
+ "modify_ldt", /*Linux + 123*/
+ "adjtimex", /*Linux + 124*/
+ "mprotect", /*Linux + 125*/
+ "sigprocmask", /*Linux + 126*/
+ "create_module", /*Linux + 127*/
+ "init_module", /*Linux + 128*/
+ "delete_module", /*Linux + 129*/
+ "get_kernel_syms", /*Linux + 130*/
+ "quotactl", /*Linux + 131*/
+ "getpgid", /*Linux + 132*/
+ "fchdir", /*Linux + 133*/
+ "bdflush", /*Linux + 134*/
+ "sysfs", /*Linux + 135*/
+ "personality", /*Linux + 136*/
+ "afs_syscall", /*Linux + 137*/ /* Syscall for Andrew File System */
+ "setfsuid", /*Linux + 138*/
+ "setfsgid", /*Linux + 139*/
+ "_llseek", /*Linux + 140*/
+ "getdents", /*Linux + 141*/
+ "_newselect", /*Linux + 142*/
+ "flock", /*Linux + 143*/
+ "msync", /*Linux + 144*/
+ "readv", /*Linux + 145*/
+ "writev", /*Linux + 146*/
+ "cacheflush", /*Linux + 147*/
+ "cachectl", /*Linux + 148*/
+ "sysmips", /*Linux + 149*/
+ "unused150", /*Linux + 150*/
+ "getsid", /*Linux + 151*/
+ "fdatasync", /*Linux + 152*/
+ "_sysctl", /*Linux + 153*/
+ "mlock", /*Linux + 154*/
+ "munlock", /*Linux + 155*/
+ "mlockall", /*Linux + 156*/
+ "munlockall", /*Linux + 157*/
+ "sched_setparam", /*Linux + 158*/
+ "sched_getparam", /*Linux + 159*/
+ "sched_setscheduler", /*Linux + 160*/
+ "sched_getscheduler", /*Linux + 161*/
+ "sched_yield", /*Linux + 162*/
+ "sched_get_priority_max", /*Linux + 163*/
+ "sched_get_priority_min", /*Linux + 164*/
+ "sched_rr_get_interval", /*Linux + 165*/
+ "nanosleep", /*Linux + 166*/
+ "mremap", /*Linux + 167*/
+ "accept", /*Linux + 168*/
+ "bind", /*Linux + 169*/
+ "connect", /*Linux + 170*/
+ "getpeername", /*Linux + 171*/
+ "getsockname", /*Linux + 172*/
+ "getsockopt", /*Linux + 173*/
+ "listen", /*Linux + 174*/
+ "recv", /*Linux + 175*/
+ "recvfrom", /*Linux + 176*/
+ "recvmsg", /*Linux + 177*/
+ "send", /*Linux + 178*/
+ "sendmsg", /*Linux + 179*/
+ "sendto", /*Linux + 180*/
+ "setsockopt", /*Linux + 181*/
+ "shutdown", /*Linux + 182*/
+ "socket", /*Linux + 183*/
+ "socketpair", /*Linux + 184*/
+ "setresuid", /*Linux + 185*/
+ "getresuid", /*Linux + 186*/
+ "query_module", /*Linux + 187*/
+ "poll", /*Linux + 188*/
+ "nfsservctl", /*Linux + 189*/
+ "setresgid", /*Linux + 190*/
+ "getresgid", /*Linux + 191*/
+ "prctl", /*Linux + 192*/
+ "rt_sigreturn", /*Linux + 193*/
+ "rt_sigaction", /*Linux + 194*/
+ "rt_sigprocmask", /*Linux + 195*/
+ "rt_sigpending", /*Linux + 196*/
+ "rt_sigtimedwait", /*Linux + 197*/
+ "rt_sigqueueinfo", /*Linux + 198*/
+ "rt_sigsuspend", /*Linux + 199*/
+ "pread", /*Linux + 200*/
+ "pwrite", /*Linux + 201*/
+ "chown", /*Linux + 202*/
+ "getcwd", /*Linux + 203*/
+ "capget", /*Linux + 204*/
+ "capset", /*Linux + 205*/
+ "sigaltstack", /*Linux + 206*/
+ "sendfile", /*Linux + 207*/
+ "getpmsg", /*Linux + 208*/
+ "putpmsg", /*Linux + 209*/
+ "mmap2", /*Linux + 210*/
+ "truncate64", /*Linux + 211*/
+ "ftruncate64", /*Linux + 212*/
+ "stat64", /*Linux + 213*/
+ "lstat64", /*Linux + 214*/
+ "fstat64", /*Linux + 215*/
+ "pivot_root", /*Linux + 216*/
+ "mincore", /*Linux + 217*/
+ "madvise", /*Linux + 218*/
+ "getdents64", /*Linux + 219*/
+ "fcntl64", /*Linux + 220*/
+ "security", /*Linux + 221*/
+ "gettid", /*Linux + 222*/
+ "readahead", /*Linux + 223*/
+ "setxattr", /*Linux + 224*/
+ "lsetxattr", /*Linux + 225*/
+ "fsetxattr", /*Linux + 226*/
+ "getxattr", /*Linux + 227*/
+ "lgetxattr", /*Linux + 228*/
+ "fgetxattr", /*Linux + 229*/
+ "listxattr", /*Linux + 230*/
+ "llistxattr", /*Linux + 231*/
+ "flistxattr", /*Linux + 232*/
+ "removexattr", /*Linux + 233*/
+ "lremovexattr", /*Linux + 234*/
+ "fremovexattr", /*Linux + 235*/
+ "tkill", /*Linux + 236*/
+ "sendfile64", /*Linux + 237*/
+ "futex", /*Linux + 238*/
+ "sched_setaffinity", /*Linux + 239*/
+ "sched_getaffinity", /*Linux + 240*/
Added: ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/trace.c
===================================================================
--- ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/trace.c 2006-12-28 13:35:03 UTC (rev 72)
+++ ltrace/branches/eav_mipsel_port/sysdeps/linux-gnu/mipsel/trace.c 2006-12-28 14:59:03 UTC (rev 73)
@@ -0,0 +1,169 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include "debug.h"
+#include "ltrace.h"
+#include "mipsel.h"
+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
+#endif
+
+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
+# define PTRACE_POKEUSER PTRACE_POKEUSR
+#endif
+
+
+/**
+ \addtogroup mipsel Mipsel specific functions.
+
+ These are the functions that it looks like I need to implement in
+ order to get ltrace to work on our target.
+
+ @{
+ */
+
+/**
+ \param proc The process that had an event.
+
+ Called by \c wait_for_something() right after the return from wait.
+
+ Most targets just return here. A couple use proc->arch_ptr for a
+ private data area.
+ */
+void get_arch_dep(struct process *proc)
+{
+
+}
+
+/**
+ \param proc Process that had event.
+ \param status From \c wait()
+ \param sysnum 0-based syscall number.
+ \return 1 if syscall, 2 if sysret, 0 otherwise.
+
+ Called by \c wait_for_something() after the call to get_arch_dep()
+
+ It seems that the ptrace call trips twice on a system call, once
+ just before the system call and once when it returns. Both times,
+ the pc points at the instruction just after the mipsel "syscall"
+ instruction.
+
+ There are several possiblities for system call sets, each is offset
+ by a base from the others. On our system, it looks like the base
+ for the system calls is 4000.
+ */
+int syscall_p(struct process *proc, int status, int *sysnum)
+{
+ if (WIFSTOPPED(status)
+ && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
+ /* get the user's pc (plus 8) */
+ long pc = (long)get_instruction_pointer(proc);
+ /* fetch the SWI instruction */
+ int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
+ int num = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 8, 0);
+
+/*
+ On a mipsel, syscall looks like:
+ 24040fa1 li v0, 0x0fa1 # 4001 --> _exit syscall
+ 0000000c syscall
+ */
+ if(insn!=0x0000000c){
+ return 0;
+ }
+
+ *sysnum = (num & 0xFFFF) - 4000;
+ /* if it is a syscall, return 1 or 2 */
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth - 1].is_syscall) {
+ return 2;
+ }
+
+ if (*sysnum >= 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+/**
+ \param type Function/syscall call or return.
+ \param proc The process that had an event.
+ \param arg_num -1 for return value,
+ \return The argument to fetch.
+
+ A couple of assumptions.
+
+- Type is LT_TOF_FUNCTIONR or LT_TOF_SYSCALLR if arg_num==-1. These
+ types are only used in calls for output_right(), which only uses -1
+ for arg_num.
+- Type is LT_TOF_FUNCTION or LT_TOF_SYSCALL for args 0...4.
+- I'm only displaying the first 4 args (Registers a0..a3). Good
+ enough for now.
+
+ Mipsel conventions seem to be:
+- syscall parameters: r4...r9
+- syscall return: if(!a3){ return v0;} else{ errno=v0;return -1;}
+- function call: r4..r7. Not sure how to get arg number 5.
+- function return: v0
+
+The argument registers are wiped by a call, so it is a mistake to ask
+for arguments on a return. If ltrace does this, we will need to cache
+arguments somewhere on the call.
+
+I'm not doing any floating point support here.
+
+*/
+long gimme_arg(enum tof type, struct process *proc, int arg_num)
+{
+ long ret;
+ debug(2,"type %d arg %d",type,arg_num);
+ if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL){
+ if(arg_num <4){
+ ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_a0+arg_num,0);
+ debug(2,"ret = %#lx",ret);
+ return ret;
+ } else {
+ // If we need this, I think we can look at [sp+16] for arg_num==4.
+ CP;
+ return 0;
+ }
+ }
+ if(arg_num>=0){
+ fprintf(stderr,"args on return?");
+ }
+ if(type == LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0);
+ }
+ if (type == LT_TOF_SYSCALLR) {
+ unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0);
+ unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0);
+ if(!a3){
+ return v0;
+ }
+ return -1;
+ }
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ return 0;
+}
+
+/**
+ \param type Type of call/return
+ \param proc Process to work with.
+
+ Called by \c output_left(), which is called on a syscall or
+ function.
+
+ The other architectures stub this out, but seems to be the place to
+ stash off the arguments on a call so we have them on the return.
+
+*/
+void save_register_args(enum tof type, struct process *proc)
+{
+}
+
+/**@}*/
More information about the Ltrace-devel
mailing list