]> The Tcpdump Group git mirrors - tcpdump/commitdiff
autoconf: Enhance the --enable-instrument-functions result output
authorFrancois-Xavier Le Bail <[email protected]>
Thu, 20 Jan 2022 18:26:22 +0000 (19:26 +0100)
committerFrancois-Xavier Le Bail <[email protected]>
Sat, 22 Jan 2022 12:19:33 +0000 (13:19 +0100)
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]

Makefile.in
configure
configure.ac
instrument-functions.c
print.c

index 2a3f695e581f6b43fdfc249376ccb6ed758de155..e93ee2d09429a7ef77e102d0d9356a4d6d265644 100644 (file)
@@ -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 $@
index 86a2b97d71febbc7a27c09c66b2a935cff9f87b0..4eaefa3c1886a1c0767290e42cd9422dfdca4547 100755 (executable)
--- 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; }
index 6d29d945bd30c29f1c7cd7a6f0dbd2202cb96cf1..5ed2db91c51cbf12e2d4f59d315e50f1af1c999f 100644 (file)
@@ -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)
        ;;
index 39ec762788a4f900624d6814af208f9d48dc774e..bab3206557c7a326c7d7f7fa868db44ecd0b9656 100644 (file)
@@ -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 be487f661cde496eca6cc69955995cfa0f9eb9d9..b1c81dd652decd0e229a386f15e1ddf6ff366aa8 100644 (file)
--- 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;
        }