diff options
author | Francois-Xavier Le Bail <devel.fx.lebail@orange.fr> | 2022-01-20 19:26:22 +0100 |
---|---|---|
committer | Francois-Xavier Le Bail <devel.fx.lebail@orange.fr> | 2022-01-22 13:19:33 +0100 |
commit | 6d854639ea6702adc7fcb077361ae00d2229f875 (patch) | |
tree | fe7ae49ab53bcecf8262cbeb18f53f6ba4f38553 | |
parent | 26c266dca507a6e2f6db31196dfbc19ce83a3279 (diff) | |
download | tcpdump-6d854639ea6702adc7fcb077361ae00d2229f875.tar.gz |
autoconf: Enhance the --enable-instrument-functions result output
It prints now, by default, also the static functions names.
To configure the printing of only the global functions names, as before:
$ make instrument_global
To go back to print all the functions names:
$ make instrument_all
In case of truncation, the indentation level is reset to its previous
level in pretty_print_packet().
[skip ci]
-rw-r--r-- | Makefile.in | 7 | ||||
-rwxr-xr-x | configure | 8 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | instrument-functions.c | 80 | ||||
-rw-r--r-- | print.c | 10 |
5 files changed, 91 insertions, 22 deletions
diff --git a/Makefile.in b/Makefile.in index 2a3f695e..e93ee2d0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -389,6 +389,13 @@ all: $(PROG) $(PROG): $(OBJ) @V_PCAPDEP@ $(LIBNETDISSECT) @rm -f $@ $(CC) $(FULL_CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBNETDISSECT) $(LIBS) + nm $(PROG) | grep ' [tT] ' > $(PROG)_instrument_functions.nm + +instrument_all: $(PROG) + nm $(PROG) | grep ' [tT] ' > $(PROG)_instrument_functions.nm + +instrument_global: $(PROG) + nm $(PROG) | grep ' [T] ' > $(PROG)_instrument_functions.nm $(LIBNETDISSECT): $(LIBNETDISSECT_OBJ) @rm -f $@ @@ -4399,9 +4399,11 @@ $as_echo "yes" >&6; } $as_echo "#define ENABLE_INSTRUMENT_FUNCTIONS 1" >>confdefs.h LOCALSRC="$LOCALSRC instrument-functions.c" - CFLAGS="$CFLAGS -finstrument-functions" - LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - LIBS="$LIBS -ldl" + # Add '-finstrument-functions' instrumentation option to generate + # instrumentation calls for entry and exit to functions. + # Try to avoid Address Space Layout Randomization (ALSR). + CFLAGS="$CFLAGS -finstrument-functions -fno-stack-protector -fno-pic" + LDFLAGS="$LDFLAGS -fno-stack-protector -no-pie" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } diff --git a/configure.ac b/configure.ac index 6d29d945..5ed2db91 100644 --- a/configure.ac +++ b/configure.ac @@ -157,9 +157,11 @@ yes) AC_MSG_RESULT(yes) AC_DEFINE(ENABLE_INSTRUMENT_FUNCTIONS, 1, [define if you want to build the instrument functions code]) LOCALSRC="$LOCALSRC instrument-functions.c" - CFLAGS="$CFLAGS -finstrument-functions" - LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - LIBS="$LIBS -ldl" + # Add '-finstrument-functions' instrumentation option to generate + # instrumentation calls for entry and exit to functions. + # Try to avoid Address Space Layout Randomization (ALSR). + CFLAGS="$CFLAGS -finstrument-functions -fno-stack-protector -fno-pic" + LDFLAGS="$LDFLAGS -fno-stack-protector -no-pie" ;; *) AC_MSG_RESULT(no) ;; diff --git a/instrument-functions.c b/instrument-functions.c index 39ec7627..bab32065 100644 --- a/instrument-functions.c +++ b/instrument-functions.c @@ -36,30 +36,82 @@ int profile_func_level = -1; * To instument a static function, remove temporarily the static specifier. */ -void __cyg_profile_func_enter(void *this_fn, void *call_site) - __attribute__((no_instrument_function)); +#ifndef ND_NO_INSTRUMENT +#define ND_NO_INSTRUMENT __attribute__((no_instrument_function)) +#endif + +void __cyg_profile_func_enter(void *this_fn, void *call_site) ND_NO_INSTRUMENT; + +void __cyg_profile_func_exit(void *this_fn, void *call_site) ND_NO_INSTRUMENT; + +/* + * Structure table to store the functions data from FILE_NAME. + * FILE_NAME is generated via: + * $ nm $(PROG) | grep ' [tT] ' + * or + * $ nm $(PROG) | grep ' [T] ' + */ -void __cyg_profile_func_exit(void *this_fn, void *call_site) - __attribute__((no_instrument_function)); +#define MAX_FUNCTIONS 20000 +static struct { + void *addr; + char type; + char name[128]; +} functions[MAX_FUNCTIONS] ; +static int functions_count; +static int initialization_done; /* - * The get_function_name() get the function name by calling dladdr() + * Read the result of nm in functions[] */ -static const char *get_function_name(void *func) - __attribute__((no_instrument_function)); +#define FILE_NAME "tcpdump_instrument_functions.nm" + +void read_functions_table(void) ND_NO_INSTRUMENT; + +void +read_functions_table(void) +{ + FILE *fp; + int i = 0; + if ((fp = fopen(FILE_NAME, "r")) == NULL) { + printf("Warning: Cannot open \"%s\" file\n", FILE_NAME); + return; + } + while (i < MAX_FUNCTIONS && fscanf(fp, "%p %c %s", &functions[i].addr, + &functions[i].type, functions[i].name) != EOF) + + i++; + fclose(fp); + functions_count = i; +} + +/* + * Get the function name by searching in functions[] + */ + +static const char * get_function_name(void *func) ND_NO_INSTRUMENT; static const char * get_function_name(void *func) { - Dl_info info; - const char *function_name; - - if (dladdr(func, &info)) - function_name = info.dli_sname; + int i = 0; + int found = 0; + if (!initialization_done) { + read_functions_table(); + initialization_done = 1; + } + while (i < functions_count) { + if (functions[i].addr == func) { + found = 1; + break; + } + i++; + } + if (found) + return (functions[i].name); else - function_name = NULL; - return function_name; + return NULL; } void @@ -310,6 +310,7 @@ get_if_printer(int type) #ifdef ENABLE_INSTRUMENT_FUNCTIONS extern int profile_func_level; +static int pretty_print_packet_level = -1; #endif void @@ -322,6 +323,11 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, if (ndo->ndo_print_sampling && packets_captured % ndo->ndo_print_sampling != 0) return; +#ifdef ENABLE_INSTRUMENT_FUNCTIONS + if (pretty_print_packet_level == -1) + pretty_print_packet_level = profile_func_level; +#endif + if (ndo->ndo_packet_number) ND_PRINT("%5u ", packets_captured); @@ -411,8 +417,8 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, /* Print the full packet */ ndo->ndo_ll_hdr_len = 0; #ifdef ENABLE_INSTRUMENT_FUNCTIONS - /* truncation => reassignment, currently: 1 (main is 0) */ - profile_func_level = 1; + /* truncation => reassignment */ + profile_func_level = pretty_print_packet_level; #endif break; } |