summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2022-01-20 19:26:22 +0100
committerFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2022-01-22 13:19:33 +0100
commit6d854639ea6702adc7fcb077361ae00d2229f875 (patch)
treefe7ae49ab53bcecf8262cbeb18f53f6ba4f38553
parent26c266dca507a6e2f6db31196dfbc19ce83a3279 (diff)
downloadtcpdump-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.in7
-rwxr-xr-xconfigure8
-rw-r--r--configure.ac8
-rw-r--r--instrument-functions.c80
-rw-r--r--print.c10
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 $@
diff --git a/configure b/configure
index 86a2b97d..4eaefa3c 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/print.c b/print.c
index be487f66..b1c81dd6 100644
--- a/print.c
+++ b/print.c
@@ -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;
}