Version 0.1.7

* Debian: New Standards-Version (2.3.0.1)
* Clean up structures a bit
* Trying to log return values...
diff --git a/THOUGHTS b/THOUGHTS
new file mode 100644
index 0000000..42ffb0f
--- /dev/null
+++ b/THOUGHTS
@@ -0,0 +1,25 @@
+process_options();
+open_program();
+enable_all_breakpoints();
+execute_program();
+forever {
+	wait_for_something();
+	switch(what happened) {
+		signal:
+			log_it();
+		exit:
+			log_it();
+			if (no_more_processes()) { exit(0); }
+		syscall:
+			log_it();
+		sysret:
+			log_it();
+		breakpoint:
+			libcall:
+				enable_brk_on_libret();
+				log_it();
+			libret:
+				log_it();
+			singlestep:
+	}
+}
diff --git a/all.h b/all.h
new file mode 100644
index 0000000..94d9617
--- /dev/null
+++ b/all.h
@@ -0,0 +1,135 @@
+/* elf.c: */
+extern int read_elf(const char *);
+
+
+/*
+ *	Lista de types:
+ */
+
+#define	_T_INT		1
+#define	_T_ADDR		6
+
+#define	_T_UNKNOWN	-1
+#define	_T_VOID		0
+#define	_T_INT		1
+#define	_T_UINT		2
+#define	_T_OCTAL	3
+#define	_T_CHAR		4
+#define	_T_STRING	5
+#define	_T_ADDR		6
+#define	_T_FILE		7
+#define	_T_HEX		8
+#define	_T_FORMAT	9		/* printf-like format */
+
+#define	_T_OUTPUT	0x80		/* OR'ed if arg is an OUTPUT value */
+
+struct function {
+	const char * function_name;
+	int return_type;
+	int num_params;
+	int params_type[10];
+	struct function * next;
+};
+
+extern struct function * list_of_functions;
+
+extern void print_function(const char *, int pid, int esp);
+#ifndef _LTRACE_I386_H
+#define _LTRACE_I386_H
+
+#define BREAKPOINT {0xcc}
+#define BREAKPOINT_LENGTH 1
+
+struct breakpoint {
+	unsigned long addr;
+	unsigned char value[BREAKPOINT_LENGTH];
+};
+
+void insert_breakpoint(int pid, struct breakpoint * sbp);
+void delete_breakpoint(int pid, struct breakpoint * sbp);
+unsigned long get_eip(int pid);
+unsigned long get_esp(int pid);
+unsigned long get_orig_eax(int pid);
+unsigned long get_return(int pid, unsigned long esp);
+unsigned long get_arg(int pid, unsigned long esp, int arg_num);
+int is_there_a_breakpoint(int pid, unsigned long eip);
+void continue_after_breakpoint(int pid, struct breakpoint * sbp, int delete_it);
+void continue_process(int pid, int signal);
+void trace_me(void);
+void untrace_pid(int pid);
+
+#include "process.h"
+#define PROC_BREAKPOINT 1
+#define PROC_SYSCALL 2
+#define PROC_SYSRET 3
+int type_of_stop(struct process * proc, int *what);
+
+#endif
+#include <stdio.h>
+
+extern FILE * output;
+extern int opt_d;
+extern int opt_i;
+extern int opt_S;
+void send_left(const char * fmt, ...);
+void send_right(const char * fmt, ...);
+void send_line(const char * fmt, ...);
+#ifndef _LTRACE_PROCESS_H
+#define _LTRACE_PROCESS_H
+
+#include "i386.h"
+
+/* not ready yet */
+#if 0
+struct symbols_from_filename {
+	char * filename;
+	struct library_symbol * list_of_symbols;
+}
+
+struct library_symbol {
+	char * name;
+	unsigned long addr;
+	unsigned long return_addr;
+	unsigned char old_value[BREAKPOINT_LENGTH];
+	struct library_symbol * next;
+};
+#endif
+
+struct process {
+	char * filename;		/* from execve() (TODO) */
+	int pid;
+	int breakpoints_enabled;
+	struct breakpoint return_value;	/* if within a function */
+	int syscall_number;		/* outside syscall => -1 */
+	struct process * next;
+};
+
+extern struct process * list_of_processes;
+
+unsigned int instruction_pointer;
+
+int execute_process(const char * file, char * const argv[]);
+void wait_for_child(void);
+
+#endif
+extern char * signal_name[];
+#ifndef _LTRACE_SYMBOLS_H
+#define _LTRACE_SYMBOLS_H
+
+#include "i386.h"
+
+struct library_symbol {
+	char * name;
+	struct breakpoint sbp;
+	unsigned long return_addr;
+	struct library_symbol * next;
+};
+
+extern struct library_symbol * library_symbols;
+
+void enable_all_breakpoints(int pid);
+void disable_all_breakpoints(int pid);
+
+#endif
+
+extern char * syscall_list[];
diff --git a/debian/changelog b/debian/changelog
index 0c79334..c06caad 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+ltrace (0.1.7) experimental; urgency=low
+
+  * New Standards-Version (2.3.0.1)
+  * Clean up structures a bit
+  * Trying to log return values...
+
+ -- Juan Cespedes <cespedes@debian.org>  Sun, 26 Oct 1997 19:53:20 +0100
+
 ltrace (0.1.6) experimental; urgency=low
 
   * New maintainer address
diff --git a/elf.c b/elf.c
index 03918aa..08e4b67 100644
--- a/elf.c
+++ b/elf.c
@@ -91,7 +91,7 @@
 				perror("malloc");
 				exit(1);
 			}
-			library_symbols->addr = ((symtab+i)->st_value);
+			library_symbols->sbp.addr = ((symtab+i)->st_value);
 			library_symbols->name = strtab+(symtab+i)->st_name;
 			library_symbols->next = tmp;
 			if (opt_d>1) {
diff --git a/i386.c b/i386.c
index c2e9a98..4d62b43 100644
--- a/i386.c
+++ b/i386.c
@@ -8,25 +8,25 @@
 #include "i386.h"
 #include "ltrace.h"
 
-void insert_breakpoint(int pid, unsigned long addr, unsigned char * value)
+void insert_breakpoint(int pid, struct breakpoint * sbp)
 {
 	int a;
 
-	a = ptrace(PTRACE_PEEKTEXT, pid, addr, 0);
-	value[0] = a & 0xFF;
+	a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr, 0);
+	sbp->value[0] = a & 0xFF;
 	a &= 0xFFFFFF00;
 	a |= 0xCC;
-	ptrace(PTRACE_POKETEXT, pid, addr, a);
+	ptrace(PTRACE_POKETEXT, pid, sbp->addr, a);
 }
 
-void delete_breakpoint(int pid, unsigned long addr, unsigned char * value)
+void delete_breakpoint(int pid, struct breakpoint * sbp)
 {
 	int a;
 
-	a = ptrace(PTRACE_PEEKTEXT, pid, addr, 0);
+	a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr, 0);
 	a &= 0xFFFFFF00;
-	a |= value[0];
-	ptrace(PTRACE_POKETEXT, pid, addr, a);
+	a |= sbp->value[0];
+	ptrace(PTRACE_POKETEXT, pid, sbp->addr, a);
 }
 
 unsigned long get_eip(int pid)
@@ -78,10 +78,10 @@
 	ptrace(PTRACE_SYSCALL, pid, 1, signal);
 }
 
-void continue_after_breakpoint(int pid, unsigned long eip, unsigned char * value, int delete_it)
+void continue_after_breakpoint(int pid, struct breakpoint * sbp, int delete_it)
 {
-	delete_breakpoint(pid, eip, value);
-	ptrace(PTRACE_POKEUSER, pid, 4*EIP, eip);
+	delete_breakpoint(pid, sbp);
+	ptrace(PTRACE_POKEUSER, pid, 4*EIP, sbp->addr);
 	if (delete_it) {
 		continue_process(pid, 0);
 	} else {
@@ -94,7 +94,7 @@
 			perror("wait4");
 			exit(1);
 		}
-		insert_breakpoint(pid, eip, value);
+		insert_breakpoint(pid, sbp);
 		continue_process(pid, 0);
 	}
 }
@@ -121,19 +121,24 @@
  *  PROC_SYSCALL - Syscall entry
  *  PROC_SYSRET - Syscall return
  */
-int type_of_stop(struct process * proc, int *what)
+int type_of_stop(int pid, struct proc_arch * proc_arch, int *what)
 {
-	*what = get_orig_eax(proc->pid);
+	*what = get_orig_eax(pid);
 
 	if (*what!=-1) {
-		if (proc->syscall_number != *what) {
-			proc->syscall_number = *what;
+		if (proc_arch->syscall_number != *what) {
+			proc_arch->syscall_number = *what;
 			return PROC_SYSCALL;
 		} else {
-			proc->syscall_number = -1;
+			proc_arch->syscall_number = -1;
 			return PROC_SYSRET;
 		}
 	}
 
 	return PROC_BREAKPOINT;
 }
+
+void proc_arch_init(struct proc_arch *proc_arch)
+{
+	proc_arch->syscall_number=-1;
+}
diff --git a/i386.h b/i386.h
index 54075ee..aecb891 100644
--- a/i386.h
+++ b/i386.h
@@ -4,23 +4,32 @@
 #define BREAKPOINT {0xcc}
 #define BREAKPOINT_LENGTH 1
 
-void insert_breakpoint(int pid, unsigned long addr, unsigned char * value);
-void delete_breakpoint(int pid, unsigned long addr, unsigned char * value);
+struct breakpoint {
+	unsigned long addr;
+	unsigned char value[BREAKPOINT_LENGTH];
+};
+
+void insert_breakpoint(int pid, struct breakpoint * sbp);
+void delete_breakpoint(int pid, struct breakpoint * sbp);
 unsigned long get_eip(int pid);
 unsigned long get_esp(int pid);
 unsigned long get_orig_eax(int pid);
 unsigned long get_return(int pid, unsigned long esp);
 unsigned long get_arg(int pid, unsigned long esp, int arg_num);
 int is_there_a_breakpoint(int pid, unsigned long eip);
-void continue_after_breakpoint(int pid, unsigned long eip, unsigned char * value, int delete_it);
+void continue_after_breakpoint(int pid, struct breakpoint * sbp, int delete_it);
 void continue_process(int pid, int signal);
 void trace_me(void);
 void untrace_pid(int pid);
 
-#include "process.h"
+struct proc_arch {
+	int syscall_number;		/* outside syscall => -1 */
+};
+
 #define PROC_BREAKPOINT 1
 #define PROC_SYSCALL 2
 #define PROC_SYSRET 3
-int type_of_stop(struct process * proc, int *what);
+int type_of_stop(int pid, struct proc_arch *proc_arch, int *what);
+void proc_arch_init(struct proc_arch *proc_arch);
 
 #endif
diff --git a/ltrace.h b/ltrace.h
index a1617bd..3dde957 100644
--- a/ltrace.h
+++ b/ltrace.h
@@ -1,6 +1,7 @@
 #include <stdio.h>
 
 extern FILE * output;
+
 extern int opt_d;
 extern int opt_i;
 extern int opt_S;
diff --git a/output.c b/output.c
index f4173a3..142b725 100644
--- a/output.c
+++ b/output.c
@@ -45,3 +45,13 @@
 	va_end(args);
 	new_line=1;
 }
+
+void print_libcall(const char name, int pid, int esp)
+{
+	fprintf(output, "libcall: %s\n", name);
+}
+
+void print_libret(const char name, int pid, int esp)
+{
+	fprintf(output, "libret: %s\n", name);
+}
diff --git a/process.c b/process.c
index 71f9791..2852310 100644
--- a/process.c
+++ b/process.c
@@ -3,6 +3,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <sys/wait.h>
@@ -44,7 +45,8 @@
 	tmp = (struct process *)malloc(sizeof(struct process));
 	tmp->pid = pid;
 	tmp->breakpoints_enabled = 0;
-	tmp->syscall_number = -1;
+	proc_arch_init(&tmp->proc_arch);
+	tmp->within_function = 0;
 	tmp->next = list_of_processes;
 	list_of_processes = tmp;
 	
@@ -155,7 +157,7 @@
 	eip = get_eip(pid);
 	instruction_pointer = eip;
 
-	switch (type_of_stop(current_process, &status)) {
+	switch (type_of_stop(current_process->pid, &current_process->proc_arch, &status)) {
 		case PROC_SYSCALL:
 			if (status==__NR_fork) {
 				disable_all_breakpoints(pid);
@@ -178,16 +180,31 @@
 		default:
 	}
 	/* pid is breakpointed... */
-	/* TODO: I may be here after a PTRACE_SINGLESTEP ... */
+	/* TODO: I could be here after a PTRACE_SINGLESTEP ... */
 	esp = get_esp(pid);
 	instruction_pointer = get_return(pid, esp);
 	tmp = library_symbols;
 	function_seen = 0;
-	while(tmp) {
-		if (eip == tmp->addr) {
+	if (eip == current_process->return_value.addr) {
+		function_seen = 1;
+#if 0
+		send_line("return");
+		print_libret(tmp->name, pid, esp);
+#endif
+		continue_after_breakpoint(pid, &current_process->return_value, 1);
+	} else while(tmp) {
+		if (eip == tmp->sbp.addr) {
 			function_seen = 1;
-			print_function(tmp->name, pid, esp);
-			continue_after_breakpoint(pid, eip, tmp->old_value, 0);
+			if (current_process->within_function) {
+				delete_breakpoint(pid, &current_process->return_value);
+			}
+			current_process->return_value.addr = instruction_pointer;
+			insert_breakpoint(pid, &current_process->return_value);
+			current_process->within_function=1;
+#if 0
+			print_libcall(tmp->name, pid, esp);
+#endif
+			continue_after_breakpoint(pid, &tmp->sbp, 0);
 			break;
 		}
 		tmp = tmp->next;
diff --git a/process.h b/process.h
index f14dc95..568f61d 100644
--- a/process.h
+++ b/process.h
@@ -1,6 +1,8 @@
 #ifndef _LTRACE_PROCESS_H
 #define _LTRACE_PROCESS_H
 
+#include "i386.h"
+
 /* not ready yet */
 #if 0
 struct symbols_from_filename {
@@ -21,13 +23,15 @@
 	char * filename;		/* from execve() (TODO) */
 	int pid;
 	int breakpoints_enabled;
-	int syscall_number;		/* outside syscall => -1 */
+	int within_function;
+	struct breakpoint return_value;	/* if within a function */
+	struct proc_arch proc_arch;
 	struct process * next;
 };
 
 extern struct process * list_of_processes;
 
-unsigned int instruction_pointer;
+extern unsigned int instruction_pointer;
 
 int execute_process(const char * file, char * const argv[]);
 void wait_for_child(void);
diff --git a/symbols.c b/symbols.c
index b36c775..be109cb 100644
--- a/symbols.c
+++ b/symbols.c
@@ -15,7 +15,7 @@
 
 	tmp = library_symbols;
 	while(tmp) {
-		insert_breakpoint(pid, tmp->addr, &tmp->old_value[0]);
+		insert_breakpoint(pid, &tmp->sbp);
 		tmp = tmp->next;
 	}
 }
@@ -26,7 +26,7 @@
 
 	tmp = library_symbols;
 	while(tmp) {
-		delete_breakpoint(pid, tmp->addr, &tmp->old_value[0]);
+		delete_breakpoint(pid, &tmp->sbp);
 		tmp = tmp->next;
 	}
 }
diff --git a/symbols.h b/symbols.h
index cc410fe..55747fa 100644
--- a/symbols.h
+++ b/symbols.h
@@ -5,9 +5,8 @@
 
 struct library_symbol {
 	char * name;
-	unsigned long addr;
+	struct breakpoint sbp;
 	unsigned long return_addr;
-	unsigned char old_value[BREAKPOINT_LENGTH];
 	struct library_symbol * next;
 };