diff options
author | Petr Machata <pmachata@redhat.com> | 2013-10-23 00:39:23 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2013-10-23 00:39:23 +0200 |
commit | 82f748d1bc2b95d594327ad15f3a6908070dd5c3 (patch) | |
tree | bca73acc5b6bfd5390e800d678a3868993f489ed /handle_event.c | |
parent | 71025328700158770edf84cbce64d977298b6e88 (diff) | |
download | ltrace-82f748d1bc2b95d594327ad15f3a6908070dd5c3.tar.gz |
System calls are now part of dedicated symbol library
- This symbol library is still special in that symbols are created on
demand and never actually added. It just serves as a link to
protolibrary with system call prototypes, and has a name (SYS).
- Prototypes for system calls were moved to a dedicated prototype
library called syscalls.conf.
- Because it's undesirable to look up syscall prototypes in anything
but the dedicated syscall protolib, prototype.c/.h now understand
that some lookups shouldn't be done recursively (and so we never
pick the definition from -F file that just happens to have the same
name as a system call). The good thing is that now libraries can
actually use symbols named SYS_something without clashing with
system call prototypes.
- One test case needed to be updated, because we now display system
calls as something@SYS instead of SYS_something.
Diffstat (limited to 'handle_event.c')
-rw-r--r-- | handle_event.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/handle_event.c b/handle_event.c index b7a755c..ae61ade 100644 --- a/handle_event.c +++ b/handle_event.c @@ -33,6 +33,7 @@ #include <stdlib.h> #include <string.h> #include <sys/time.h> +#include <stdbool.h> #include "backend.h" #include "breakpoint.h" @@ -41,6 +42,7 @@ #include "library.h" #include "proc.h" #include "value_dict.h" +#include "prototype.h" static void handle_signal(Event *event); static void handle_exit(Event *event); @@ -379,9 +381,7 @@ sysname(struct process *proc, int sysnum) sprintf(result, "SYS_%d", sysnum); return result; } else { - sprintf(result, "SYS_%s", - syscallents[proc->personality][sysnum]); - return result; + return syscallents[proc->personality][sysnum]; } } @@ -445,8 +445,40 @@ output_syscall(struct process *proc, const char *name, enum tof tof, void (*output)(enum tof, struct process *, struct library_symbol *)) { + static struct library syscall_lib; + if (syscall_lib.protolib == NULL) { + struct protolib *protolib + = protolib_cache_search(&g_protocache, "syscalls", 0, 1); + if (protolib == NULL) { + fprintf(stderr, "Couldn't load system call prototypes:" + " %s.\n", strerror(errno)); + + /* Instead, get a fake one just so we can + * carry on, limping. */ + protolib = malloc(sizeof *protolib); + if (protolib == NULL) { + fprintf(stderr, "Couldn't even allocate a fake " + "prototype library: %s.\n", + strerror(errno)); + abort(); + } + protolib_init(protolib); + } + + assert(protolib != NULL); + if (library_init(&syscall_lib, LT_LIBTYPE_SYSCALL) < 0) { + fprintf(stderr, "Couldn't initialize system call " + "library: %s.\n", strerror(errno)); + abort(); + } + + library_set_soname(&syscall_lib, "SYS", 0); + syscall_lib.protolib = protolib; + } + struct library_symbol syscall; if (library_symbol_init(&syscall, 0, name, 0, LS_TOPLT_NONE) >= 0) { + syscall.lib = &syscall_lib; (*output)(tof, proc, &syscall); library_symbol_destroy(&syscall); } |