diff -urp ltrace-0.5/execute_program.c ltrace-0.5-pm/execute_program.c --- ltrace-0.5/execute_program.c 2006-02-20 22:48:07.000000000 +0100 +++ ltrace-0.5-pm/execute_program.c 2011-07-28 16:57:40.822397935 +0200 @@ -17,7 +17,8 @@ #include "debug.h" #include "sysdep.h" -static void change_uid(struct process *proc) +static void +change_uid(const char * command) { uid_t run_uid, run_euid; gid_t run_gid, run_egid; @@ -50,7 +51,7 @@ static void change_uid(struct process *p run_euid = run_uid; run_egid = run_gid; - if (!stat(proc->filename, &statbuf)) { + if (!stat(command, &statbuf)) { if (statbuf.st_mode & S_ISUID) { run_euid = statbuf.st_uid; } @@ -69,28 +70,27 @@ static void change_uid(struct process *p } } -void execute_program(struct process *sp, char **argv) +pid_t +execute_program(const char * command, char **argv) { pid_t pid; - debug(1, "Executing `%s'...", sp->filename); + debug(1, "Executing `%s'...", command); pid = fork(); if (pid < 0) { perror("ltrace: fork"); exit(1); } else if (!pid) { /* child */ - change_uid(sp); + change_uid(command); trace_me(); - execvp(sp->filename, argv); - fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, + execvp(command, argv); + fprintf(stderr, "Can't execute `%s': %s\n", command, strerror(errno)); exit(1); } debug(1, "PID=%d", pid); - sp->pid = pid; - - return; + return pid; } diff -urp ltrace-0.5/ltrace.c ltrace-0.5-pm/ltrace.c --- ltrace-0.5/ltrace.c 2006-02-20 22:48:07.000000000 +0100 +++ ltrace-0.5-pm/ltrace.c 2011-07-28 16:58:27.743790805 +0200 @@ -17,6 +17,7 @@ #include "read_config_file.h" #include "options.h" #include "debug.h" +#include "elf.h" #ifndef SYSCONFDIR #define SYSCONFDIR "/etc" @@ -126,7 +126,12 @@ int main(int argc, char **argv) } } if (command) { - execute_program(open_program(command, 0), argv); + /* Check that the binary ABI is supported before + * calling execute_program. */ + struct ltelf lte = {}; + open_elf(<e, command); + + open_program(command, execute_program(command, argv)); } opt_p_tmp = opt_p; while (opt_p_tmp) { diff -urp ltrace-0.5/ltrace.h ltrace-0.5-pm/ltrace.h --- ltrace-0.5/ltrace.h 2011-07-28 16:52:37.822885569 +0200 +++ ltrace-0.5-pm/ltrace.h 2011-07-28 16:55:21.458275729 +0200 @@ -172,7 +172,7 @@ extern void *instruction_pointer; extern struct event *wait_for_something(void); extern void process_event(struct event *event); -extern void execute_program(struct process *, char **); +extern pid_t execute_program(const char * command, char ** argv); extern int display_arg(enum tof type, struct process *proc, int arg_num, enum arg_type at); extern struct breakpoint *address2bpstruct(struct process *proc, void *addr); diff -urp ltrace-0.5/proc.c ltrace-0.5-pm/proc.c --- ltrace-0.5/proc.c 2011-07-28 16:52:37.790883905 +0200 +++ ltrace-0.5-pm/proc.c 2011-07-28 16:58:58.776371612 +0200 @@ -7,6 +7,7 @@ #include <stdio.h> #include <errno.h> #include <stdlib.h> +#include <assert.h> #include "ltrace.h" #include "options.h" @@ -15,6 +16,7 @@ struct process *open_program(char *filename, pid_t pid) { struct process *proc; + assert(pid != 0); proc = calloc(sizeof(struct process), 1); if (!proc) { perror("malloc"); diff -urp ltrace-0.5/elf.c ltrace-0.5-pm2/elf.c --- ltrace-0.5/elf.c 2011-09-21 17:55:57.346185917 +0200 +++ ltrace-0.5-pm2/elf.c 2011-09-21 17:55:54.735185860 +0200 @@ -29,19 +29,15 @@ static GElf_Addr opd2addr(struct ltelf * extern char *PLTs_initialized_by_here; #endif -static void do_init_elf(struct ltelf *lte, const char *filename) +void +open_elf(struct ltelf *lte, const char *filename) { - int i; - GElf_Addr relplt_addr = 0; - size_t relplt_size = 0; - - debug(1, "Reading ELF from %s...", filename); - - memset(lte, 0, sizeof(*lte)); lte->fd = open(filename, O_RDONLY); if (lte->fd == -1) error(EXIT_FAILURE, errno, "Can't open \"%s\"", filename); + elf_version(EV_CURRENT); + #ifdef HAVE_ELF_C_READ_MMAP lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); #else @@ -73,6 +69,18 @@ static void do_init_elf(struct ltelf *lt ) error(EXIT_FAILURE, 0, "\"%s\" is ELF from incompatible architecture", filename); +} + +static void do_init_elf(struct ltelf *lte, const char *filename) +{ + int i; + GElf_Addr relplt_addr = 0; + size_t relplt_size = 0; + + debug(1, "Reading ELF from %s...", filename); + + memset(lte, 0, sizeof(*lte)); + open_elf(lte, filename); for (i = 1; i < lte->ehdr.e_shnum; ++i) { Elf_Scn *scn; @@ -442,8 +450,6 @@ struct library_symbol *read_elf(struct p memset(lte, 0, sizeof(lte)); - elf_version(EV_CURRENT); - do_init_elf(lte, proc->filename); proc->e_machine = lte->ehdr.e_machine; for (i = 0; i < library_num; ++i) diff -urp ltrace-0.5/elf.h ltrace-0.5-pm2/elf.h --- ltrace-0.5/elf.h 2011-09-21 17:55:57.282185917 +0200 +++ ltrace-0.5-pm2/elf.h 2011-09-21 17:55:54.811185860 +0200 @@ -36,6 +36,7 @@ struct ltelf { extern int library_num; extern char *library[MAX_LIBRARY]; +extern void open_elf(struct ltelf *lte, const char *filename); extern struct library_symbol *read_elf(struct process *); extern GElf_Addr arch_plt_sym_val(struct ltelf *, size_t, GElf_Rela *);