]>
The Tcpdump Group git mirrors - tcpdump/blob - instrument-functions.c
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that: (1) source code
4 * distributions retain the above copyright notice and this paragraph
5 * in its entirety, and (2) distributions including binary code include
6 * the above copyright notice and this paragraph in its entirety in
7 * the documentation or other materials provided with the distribution.
8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE.
21 extern int profile_func_level
;
22 int profile_func_level
= -1;
25 * Generate instrumentation calls for entry and exit to functions.
26 * Just after function entry and just before function exit, the
27 * following profiling functions are called with the address of the
28 * current function and its call site (currently not use).
30 * The attribute 'no_instrument_function' causes this instrumentation is
33 * These profiling functions print the function names with indentation
36 * To instument a static function, remove temporarily the static specifier.
39 #ifndef ND_NO_INSTRUMENT
40 #define ND_NO_INSTRUMENT __attribute__((no_instrument_function))
43 void __cyg_profile_func_enter(void *this_fn
, void *call_site
) ND_NO_INSTRUMENT
;
45 void __cyg_profile_func_exit(void *this_fn
, void *call_site
) ND_NO_INSTRUMENT
;
48 * Structure table to store the functions data from FILE_NAME.
49 * FILE_NAME is generated via:
50 * $ nm $(PROG) | grep ' [tT] '
52 * $ nm $(PROG) | grep ' [T] '
55 #define MAX_FUNCTIONS 20000
60 } functions
[MAX_FUNCTIONS
] ;
61 static int functions_count
;
62 static int initialization_done
;
65 * Read the result of nm in functions[]
68 #define FILE_NAME "tcpdump_instrument_functions.nm"
70 void read_functions_table(void) ND_NO_INSTRUMENT
;
73 read_functions_table(void)
77 if ((fp
= fopen(FILE_NAME
, "r")) == NULL
) {
78 printf("Warning: Cannot open \"%s\" file\n", FILE_NAME
);
81 while (i
< MAX_FUNCTIONS
&& fscanf(fp
, "%p %c %s", &functions
[i
].addr
,
82 &functions
[i
].type
, functions
[i
].name
) != EOF
)
89 * Get the function name by searching in functions[]
92 static const char * get_function_name(void *func
) ND_NO_INSTRUMENT
;
95 get_function_name(void *func
)
99 if (!initialization_done
) {
100 read_functions_table();
101 initialization_done
= 1;
103 while (i
< functions_count
) {
104 if (functions
[i
].addr
== func
) {
111 return (functions
[i
].name
);
117 __cyg_profile_func_enter(void *this_fn
,
118 void *call_site
__attribute__((unused
)))
121 const char *function_name
;
123 if ((function_name
= get_function_name(this_fn
)) != NULL
) {
124 profile_func_level
+= 1;
125 for (i
= 0 ; i
< profile_func_level
; i
++)
127 printf("[>> %s (%d)]\n", function_name
, profile_func_level
);
133 __cyg_profile_func_exit(void *this_fn
,
134 void *call_site
__attribute__((unused
)))
137 const char *function_name
;
139 if ((function_name
= get_function_name(this_fn
)) != NULL
) {
140 for (i
= 0 ; i
< profile_func_level
; i
++)
142 printf ("[<< %s (%d)]\n", function_name
, profile_func_level
);
143 profile_func_level
-= 1;