Implement @MAIN, @/path/name -e selectors, make former default for now
- the default might become "*" in future, but keep things more or less
the same as they always were for now
diff --git a/breakpoints.c b/breakpoints.c
index 87e65d7..20044fa 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -362,8 +362,6 @@
}
proc_add_library(proc, lib);
- fprintf(stderr, "note: symbols in %s were not filtered.\n",
- lib->name);
entry_bp = malloc(sizeof(*entry_bp));
if (entry_bp == NULL
diff --git a/filter.c b/filter.c
index 74a158f..8aa5881 100644
--- a/filter.c
+++ b/filter.c
@@ -18,15 +18,13 @@
* 02110-1301 USA
*/
-#include <stddef.h>
+#include <stdlib.h>
#include <error.h>
#include <assert.h>
#include "filter.h"
#include "library.h"
-void abort(void); //xxx
-
void
filter_init(struct filter *filt)
{
@@ -71,10 +69,19 @@
void
filter_lib_matcher_name_init(struct filter_lib_matcher *matcher,
+ enum filter_lib_matcher_type type,
regex_t libname_re)
{
- matcher->type = FLM_NAME;
- matcher->libname_re = libname_re;
+ switch (type) {
+ case FLM_MAIN:
+ assert(type != type);
+ abort();
+
+ case FLM_SONAME:
+ case FLM_PATHNAME:
+ matcher->type = type;
+ matcher->libname_re = libname_re;
+ }
}
void
@@ -87,7 +94,8 @@
filter_lib_matcher_destroy(struct filter_lib_matcher *matcher)
{
switch (matcher->type) {
- case FLM_NAME:
+ case FLM_SONAME:
+ case FLM_PATHNAME:
regfree(&matcher->libname_re);
break;
case FLM_MAIN:
@@ -115,12 +123,14 @@
matcher_matches_library(struct filter_lib_matcher *matcher, struct library *lib)
{
switch (matcher->type) {
- case FLM_NAME:
- return re_match_or_error(&matcher->libname_re, lib->name,
- "library name");
+ case FLM_SONAME:
+ return re_match_or_error(&matcher->libname_re, lib->soname,
+ "library soname");
+ case FLM_PATHNAME:
+ return re_match_or_error(&matcher->libname_re, lib->pathname,
+ "library pathname");
case FLM_MAIN:
- assert(!"FLM_MAIN not implemented yet!");
- abort();
+ return lib->next == NULL;
}
assert(matcher->type != matcher->type);
abort();
diff --git a/filter.h b/filter.h
index 23ca382..0320036 100644
--- a/filter.h
+++ b/filter.h
@@ -31,8 +31,10 @@
struct library_symbol;
enum filter_lib_matcher_type {
- /* Match by name. */
- FLM_NAME,
+ /* Match by soname. */
+ FLM_SONAME,
+ /* Match by path name. */
+ FLM_PATHNAME,
/* Match main binary. */
FLM_MAIN,
};
@@ -72,10 +74,12 @@
/* RULE is added to FILT and owned and destroyed by it. */
void filter_add_rule(struct filter *filt, struct filter_rule *rule);
-/* Create a matcher that matches based on LIBNAME_RE is owned and
- * destroyed by MATCHER. */
+/* Create a matcher that matches library name. RE is owned and
+ * destroyed by MATCHER. TYPE shall be FLM_SONAME or
+ * FLM_PATHNAME. */
void filter_lib_matcher_name_init(struct filter_lib_matcher *matcher,
- regex_t libname_re);
+ enum filter_lib_matcher_type type,
+ regex_t re);
/* Create a matcher that matches main binary. */
void filter_lib_matcher_main_init(struct filter_lib_matcher *matcher);
diff --git a/handle_event.c b/handle_event.c
index cfb2ad0..28992d4 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -426,7 +426,8 @@
free(syscall);
return NULL;
}
- library_init(syscalls, "SYS", 0);
+ library_init(syscalls);
+ library_set_soname(syscalls, "SYS", 0);
library_symbol_init(syscall, 0, name, 0, LS_TOPLT_NONE);
library_add_symbol(syscalls, syscall);
return syscall;
diff --git a/library.c b/library.c
index 07bbb7f..27c0f2b 100644
--- a/library.c
+++ b/library.c
@@ -100,22 +100,32 @@
}
void
-library_init(struct library *lib, const char *name, int own_name)
+library_init(struct library *lib)
{
lib->next = NULL;
- lib->name = name;
- lib->own_name = own_name;
+ lib->soname = NULL;
+ lib->own_soname = 0;
+ lib->pathname = NULL;
+ lib->own_pathname = 0;
lib->symbols = NULL;
}
int
library_clone(struct library *retp, struct library *lib)
{
- const char *name;
- if (strdup_if_owned(&name, lib->name, lib->own_name) < 0)
+ const char *soname = NULL;
+ const char *pathname;
+ if (strdup_if_owned(&soname, lib->soname, lib->own_soname) < 0
+ || strdup_if_owned(&pathname,
+ lib->pathname, lib->own_pathname) < 0) {
+ if (lib->own_soname)
+ free((char *)soname);
return -1;
+ }
- library_init(retp, lib->name, lib->own_name);
+ library_init(retp);
+ library_set_soname(lib, soname, lib->own_soname);
+ library_set_soname(lib, pathname, lib->own_pathname);
struct library_symbol *it;
struct library_symbol **nsymp = &retp->symbols;
@@ -139,7 +149,8 @@
{
if (lib == NULL)
return;
- library_set_name(lib, NULL, 0);
+ library_set_soname(lib, NULL, 0);
+ library_set_pathname(lib, NULL, 0);
struct library_symbol *sym;
for (sym = lib->symbols; sym != NULL; ) {
@@ -151,12 +162,21 @@
}
void
-library_set_name(struct library *lib, const char *new_name, int own_name)
+library_set_soname(struct library *lib, const char *new_name, int own_name)
{
- if (lib->own_name)
- free((char *)lib->name);
- lib->name = new_name;
- lib->own_name = own_name;
+ if (lib->own_soname)
+ free((char *)lib->soname);
+ lib->soname = new_name;
+ lib->own_soname = own_name;
+}
+
+void
+library_set_pathname(struct library *lib, const char *new_name, int own_name)
+{
+ if (lib->own_pathname)
+ free((char *)lib->pathname);
+ lib->pathname = new_name;
+ lib->own_pathname = own_name;
}
struct library_symbol *
@@ -205,8 +225,8 @@
enum callback_status
library_named_cb(struct Process *proc, struct library *lib, void *name)
{
- if (name == lib->name
- || strcmp(lib->name, (char *)name) == 0)
+ if (name == lib->soname
+ || strcmp(lib->soname, (char *)name) == 0)
return CBS_STOP;
else
return CBS_CONT;
diff --git a/library.h b/library.h
index dbccb08..a517666 100644
--- a/library.h
+++ b/library.h
@@ -102,13 +102,16 @@
/* Symbols associated with the library. */
struct library_symbol *symbols;
- const char *name;
- char own_name;
+
+ const char *soname;
+ const char *pathname;
+
+ char own_soname : 1;
+ char own_pathname : 1;
};
-/* Init LIB. NAME will be freed when LIB is destroyed if
- * OWN_NAME. */
-void library_init(struct library *lib, const char *name, int own_name);
+/* Init LIB. */
+void library_init(struct library *lib);
/* Initialize RETP to a library identical to LIB. Symbols are not
* shared, but copied over. Returns 0 on success and a negative value
@@ -118,8 +121,13 @@
/* Destroy library. Doesn't free LIB itself. */
void library_destroy(struct library *lib);
-/* Set library name. Frees the old name if necessary. */
-void library_set_name(struct library *lib, const char *new_name, int own_name);
+/* Set library soname. Frees the old name if necessary. */
+void library_set_soname(struct library *lib,
+ const char *new_name, int own_name);
+
+/* Set library pathname. Frees the old name if necessary. */
+void library_set_pathname(struct library *lib,
+ const char *new_name, int own_name);
/* Iterate through list of symbols of library LIB. Restarts are
* supported via START_AFTER (see each_process for details of
diff --git a/ltrace-elf.c b/ltrace-elf.c
index b20ea7c..6aa468e 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -465,28 +465,34 @@
proc->e_machine = lte.ehdr.e_machine;
struct library *lib = malloc(sizeof(*lib));
- char *libname = NULL;
+ char *soname = NULL;
if (lib == NULL) {
fail:
- free(libname);
+ free(soname);
library_destroy(lib);
free(lib);
lib = NULL;
goto done;
}
- if (lte.soname != NULL)
- libname = strdup(lte.soname);
- else
- libname = strdup(filename);
- if (libname == NULL)
+ int own_soname;
+ if (lte.soname != NULL) {
+ soname = strdup(lte.soname);
+ own_soname = 1;
+ } else {
+ soname = rindex(filename, '/') + 1;
+ own_soname = 0;
+ }
+ if (soname == NULL)
goto fail;
target_address_t entry = (target_address_t)lte.entry_addr;
if (arch_translate_address(proc, entry + lte.bias, &entry) < 0)
goto fail;
- library_init(lib, libname, 1);
+ library_init(lib);
+ library_set_soname(lib, soname, own_soname);
+ library_set_pathname(lib, filename, 1);
lib->base = (target_address_t)lte.base_addr;
lib->entry = entry;
lib->dyn_addr = (target_address_t)lte.dyn_addr;
@@ -541,7 +547,9 @@
fprintf(stderr, "ltelf_read_main_binary %d %s\n", proc->pid, path);
char *fname = pid2name(proc->pid);
struct library *lib = ltelf_read_library(proc, fname, 0);
- if (lib != NULL)
- library_set_name(lib, path, 0);
+ if (lib != NULL) {
+ library_set_pathname(lib, path, 0);
+ library_set_soname(lib, rindex(path, '/') + 1, 0);
+ }
return lib;
}
diff --git a/options.c b/options.c
index 4f026ea..193b650 100644
--- a/options.c
+++ b/options.c
@@ -207,18 +207,26 @@
goto fail;
}
- regex_t lib_re;
- status = (lib_re_p ? regcomp : globcomp)(&lib_re, lib, 0);
- if (status != 0) {
- char buf[100];
- regerror(status, &lib_re, buf, sizeof buf);
- error(0, 0, "rule near '%s' will be ignored: %s", expr, buf);
+ if (strcmp(lib, "MAIN") == 0) {
+ filter_lib_matcher_main_init(matcher);
+ } else {
+ enum filter_lib_matcher_type type
+ = lib[0] == '/' ? FLM_PATHNAME : FLM_SONAME;
- regfree(&symbol_re);
- goto fail;
+ regex_t lib_re;
+ status = (lib_re_p ? regcomp : globcomp)(&lib_re, lib, 0);
+ if (status != 0) {
+ char buf[100];
+ regerror(status, &lib_re, buf, sizeof buf);
+ error(0, 0, "rule near '%s' will be ignored: %s",
+ expr, buf);
+
+ regfree(&symbol_re);
+ goto fail;
+ }
+ filter_lib_matcher_name_init(matcher, type, lib_re);
}
- filter_lib_matcher_name_init(matcher, lib_re);
filter_rule_init(rule, type, matcher, symbol_re);
filter_add_rule(filt, rule);
}
@@ -628,8 +636,11 @@
opt_F = egg;
}
+ /* Set default filter. Use @MAIN for now, as that's what
+ * ltrace used to have in the past. XXX Maybe we should make
+ * this "*" instead. */
if (options.filter == NULL)
- parse_filter_chain(&options, "*");
+ parse_filter_chain(&options, "@MAIN");
if (!opt_p && argc < 1) {
fprintf(stderr, "%s: too few arguments\n", progname);
diff --git a/output.c b/output.c
index 10bfaf8..0f59e2e 100644
--- a/output.c
+++ b/output.c
@@ -176,7 +176,7 @@
begin_of_line(type, proc);
#ifdef USE_DEMANGLE
current_column +=
- fprintf(options.output, "%s->%s(", libsym->lib->name,
+ fprintf(options.output, "%s->%s(", libsym->lib->soname,
(options.demangle
? my_demangle(function_name) : function_name));
#else
diff --git a/proc.c b/proc.c
index 8fc4cae..8c42c4a 100644
--- a/proc.c
+++ b/proc.c
@@ -500,8 +500,8 @@
assert(lib->next == NULL);
lib->next = proc->libraries;
proc->libraries = lib;
- fprintf(stderr, "=== Added library %s@%p to %d:\n",
- lib->name, lib->base, proc->pid);
+ fprintf(stderr, "=== Added library %s@%p (%s) to %d:\n",
+ lib->soname, lib->base, lib->pathname, proc->pid);
if (!filter_matches_library(options.filter, lib))
return;