4 * Babeltrace SO info tests
6 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
7 * Copyright (c) 2015 Antoine Busque <abusque@efficios.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; under version 2 of the License.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <babeltrace/assert-internal.h>
28 #include <lttng-utils/debug-info/bin-info.h>
33 #define SO_NAME "libhello_so"
35 #define DWARF_DIR_NAME "dwarf_full"
36 #define ELF_DIR_NAME "elf_only"
37 #define BUILDID_DIR_NAME "build_id"
38 #define DEBUGLINK_DIR_NAME "debug_link"
40 #define SO_LOW_ADDR 0x400000
41 #define SO_MEMSZ 0x400000
42 #define FUNC_FOO_ADDR 0x402367
43 #define FUNC_FOO_LINE_NO 36
44 #define FUNC_FOO_FILENAME "./libhello.c"
45 #define FUNC_FOO_TP_ADDR 0x402300
46 #define FUNC_FOO_TP_LINE_NO 35
47 #define FUNC_FOO_TP_FILENAME "./libhello.c"
48 #define FUNC_FOO_ADDR_ELF 0x402367
49 #define FUNC_FOO_ADDR_DBG_LINK 0x402367
50 #define FUNC_FOO_NAME "foo+0xf0"
51 #define FUNC_FOO_NAME_ELF "foo+0xf0"
52 #define BUILD_ID_LEN 20
54 char *opt_debug_info_dir
;
55 char *opt_debug_info_target_prefix
;
58 void test_bin_info_build_id(const char *bin_info_dir
)
61 char *data_dir
, *bin_path
;
62 char *func_name
= NULL
;
63 struct bin_info
*bin
= NULL
;
64 struct source_location
*src_loc
= NULL
;
65 struct bt_fd_cache fdc
;
66 uint8_t build_id
[BUILD_ID_LEN
] = {
67 0xcd, 0xd9, 0x8c, 0xdd, 0x87, 0xf7, 0xfe, 0x64, 0xc1, 0x3b,
68 0x6d, 0xaa, 0xd5, 0x53, 0x98, 0x7e, 0xaf, 0xd4, 0x0c, 0xbb
71 diag("bin-info tests - separate DWARF via build ID");
73 data_dir
= g_build_filename(bin_info_dir
, BUILDID_DIR_NAME
, NULL
);
74 bin_path
= g_build_filename(bin_info_dir
, BUILDID_DIR_NAME
, SO_NAME
, NULL
);
76 if (data_dir
== NULL
|| bin_path
== NULL
) {
80 ret
= bt_fd_cache_init(&fdc
);
82 bin
= bin_info_create(&fdc
, bin_path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
, NULL
);
83 ok(bin
!= NULL
, "bin_info_create successful");
85 /* Test setting build_id */
86 ret
= bin_info_set_build_id(bin
, build_id
, BUILD_ID_LEN
);
87 ok(ret
== 0, "bin_info_set_build_id successful");
89 /* Test function name lookup (with DWARF) */
90 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR
, &func_name
);
91 ok(ret
== 0, "bin_info_lookup_function_name successful");
93 ok(strcmp(func_name
, FUNC_FOO_NAME
) == 0,
94 "bin_info_lookup_function_name - correct func_name value");
97 skip(1, "bin_info_lookup_function_name - func_name is NULL");
100 /* Test source location lookup */
101 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR
, &src_loc
);
102 ok(ret
== 0, "bin_info_lookup_source_location successful");
104 ok(src_loc
->line_no
== FUNC_FOO_LINE_NO
,
105 "bin_info_lookup_source_location - correct line_no");
106 ok(strcmp(src_loc
->filename
, FUNC_FOO_FILENAME
) == 0,
107 "bin_info_lookup_source_location - correct filename");
108 source_location_destroy(src_loc
);
110 skip(2, "bin_info_lookup_source_location - src_loc is NULL");
113 bin_info_destroy(bin
);
114 bt_fd_cache_fini(&fdc
);
120 void test_bin_info_debug_link(const char *bin_info_dir
)
123 char *data_dir
, *bin_path
;
124 char *func_name
= NULL
;
125 struct bin_info
*bin
= NULL
;
126 struct source_location
*src_loc
= NULL
;
127 char *dbg_filename
= "libhello_so.debug";
128 uint32_t crc
= 0x289a8fdc;
129 struct bt_fd_cache fdc
;
131 diag("bin-info tests - separate DWARF via debug link");
133 data_dir
= g_build_filename(bin_info_dir
, DEBUGLINK_DIR_NAME
, NULL
);
134 bin_path
= g_build_filename(bin_info_dir
, DEBUGLINK_DIR_NAME
, SO_NAME
, NULL
);
136 if (data_dir
== NULL
|| bin_path
== NULL
) {
140 ret
= bt_fd_cache_init(&fdc
);
142 bin
= bin_info_create(&fdc
, bin_path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
,
144 ok(bin
!= NULL
, "bin_info_create successful");
146 /* Test setting debug link */
147 ret
= bin_info_set_debug_link(bin
, dbg_filename
, crc
);
148 ok(ret
== 0, "bin_info_set_debug_link successful");
150 /* Test function name lookup (with DWARF) */
151 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR_DBG_LINK
,
153 ok(ret
== 0, "bin_info_lookup_function_name successful");
155 ok(strcmp(func_name
, FUNC_FOO_NAME
) == 0,
156 "bin_info_lookup_function_name - correct func_name value");
159 skip(1, "bin_info_lookup_function_name - func_name is NULL");
162 /* Test source location lookup */
163 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR_DBG_LINK
,
165 ok(ret
== 0, "bin_info_lookup_source_location successful");
167 ok(src_loc
->line_no
== FUNC_FOO_LINE_NO
,
168 "bin_info_lookup_source_location - correct line_no");
169 ok(strcmp(src_loc
->filename
, FUNC_FOO_FILENAME
) == 0,
170 "bin_info_lookup_source_location - correct filename");
171 source_location_destroy(src_loc
);
173 skip(2, "bin_info_lookup_source_location - src_loc is NULL");
176 bin_info_destroy(bin
);
177 bt_fd_cache_fini(&fdc
);
183 void test_bin_info_elf(const char *bin_info_dir
)
186 char *data_dir
, *bin_path
;
187 char *func_name
= NULL
;
188 struct bin_info
*bin
= NULL
;
189 struct source_location
*src_loc
= NULL
;
190 struct bt_fd_cache fdc
;
192 diag("bin-info tests - ELF only");
194 data_dir
= g_build_filename(bin_info_dir
, ELF_DIR_NAME
, NULL
);
195 bin_path
= g_build_filename(bin_info_dir
, ELF_DIR_NAME
, SO_NAME
, NULL
);
197 if (data_dir
== NULL
|| bin_path
== NULL
) {
201 ret
= bt_fd_cache_init(&fdc
);
203 bin
= bin_info_create(&fdc
, bin_path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
, NULL
);
204 ok(bin
!= NULL
, "bin_info_create successful");
206 /* Test function name lookup (with ELF) */
207 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR_ELF
, &func_name
);
208 ok(ret
== 0, "bin_info_lookup_function_name successful");
210 ok(strcmp(func_name
, FUNC_FOO_NAME_ELF
) == 0,
211 "bin_info_lookup_function_name - correct func_name value");
215 skip(1, "bin_info_lookup_function_name - func_name is NULL");
218 /* Test function name lookup - erroneous address */
219 ret
= bin_info_lookup_function_name(bin
, 0, &func_name
);
220 ok(ret
== -1 && func_name
== NULL
,
221 "bin_info_lookup_function_name - fail on addr not found");
223 /* Test source location location - should fail on ELF only file */
224 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR_ELF
, &src_loc
);
225 ok(ret
== -1, "bin_info_lookup_source_location - fail on ELF only file");
227 source_location_destroy(src_loc
);
228 bin_info_destroy(bin
);
229 bt_fd_cache_fini(&fdc
);
235 void test_bin_info(const char *bin_info_dir
)
238 char *data_dir
, *bin_path
;
239 char *func_name
= NULL
;
240 struct bin_info
*bin
= NULL
;
241 struct source_location
*src_loc
= NULL
;
242 struct bt_fd_cache fdc
;
244 diag("bin-info tests - DWARF bundled with SO file");
247 data_dir
= g_build_filename(bin_info_dir
, DWARF_DIR_NAME
, NULL
);
248 bin_path
= g_build_filename(bin_info_dir
, DWARF_DIR_NAME
, SO_NAME
, NULL
);
250 if (data_dir
== NULL
|| bin_path
== NULL
) {
254 ret
= bt_fd_cache_init(&fdc
);
256 bin
= bin_info_create(&fdc
, bin_path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
, NULL
);
257 ok(bin
!= NULL
, "bin_info_create successful");
259 /* Test bin_info_has_address */
260 ret
= bin_info_has_address(bin
, 0);
261 ok(ret
== 0, "bin_info_has_address - address under so's range");
262 ret
= bin_info_has_address(bin
, SO_LOW_ADDR
);
263 ok(ret
== 1, "bin_info_has_address - lower bound of so's range");
264 ret
= bin_info_has_address(bin
, FUNC_FOO_ADDR
);
265 ok(ret
== 1, "bin_info_has_address - address in so's range");
266 ret
= bin_info_has_address(bin
, SO_LOW_ADDR
+ SO_MEMSZ
- 1);
267 ok(ret
== 1, "bin_info_has_address - upper bound of so's range");
268 ret
= bin_info_has_address(bin
, SO_LOW_ADDR
+ SO_MEMSZ
);
269 ok(ret
== 0, "bin_info_has_address - address above so's range");
271 /* Test function name lookup (with DWARF) */
272 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR
, &func_name
);
273 ok(ret
== 0, "bin_info_lookup_function_name successful");
275 ok(strcmp(func_name
, FUNC_FOO_NAME
) == 0,
276 "bin_info_lookup_function_name - correct func_name value");
280 skip(1, "bin_info_lookup_function_name - func_name is NULL");
283 /* Test function name lookup - erroneous address */
284 ret
= bin_info_lookup_function_name(bin
, 0, &func_name
);
285 ok(ret
== -1 && func_name
== NULL
,
286 "bin_info_lookup_function_name - fail on addr not found");
288 /* Test source location lookup */
289 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR
, &src_loc
);
290 ok(ret
== 0, "bin_info_lookup_source_location successful");
292 ok(src_loc
->line_no
== FUNC_FOO_LINE_NO
,
293 "bin_info_lookup_source_location - correct line_no");
294 ok(strcmp(src_loc
->filename
, FUNC_FOO_FILENAME
) == 0,
295 "bin_info_lookup_source_location - correct filename");
296 source_location_destroy(src_loc
);
299 skip(2, "bin_info_lookup_source_location - src_loc is NULL");
302 /* Test source location lookup - inlined function */
303 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_TP_ADDR
, &src_loc
);
305 "bin_info_lookup_source_location (inlined func) successful");
307 ok(src_loc
->line_no
== FUNC_FOO_TP_LINE_NO
,
308 "bin_info_lookup_source_location (inlined func) - correct line_no");
309 ok(strcmp(src_loc
->filename
, FUNC_FOO_TP_FILENAME
) == 0,
310 "bin_info_lookup_source_location (inlined func) - correct filename");
311 source_location_destroy(src_loc
);
314 skip(2, "bin_info_lookup_source_location (inlined func) - src_loc is NULL");
317 /* Test source location lookup - erroneous address */
318 ret
= bin_info_lookup_source_location(bin
, 0, &src_loc
);
319 ok(ret
== -1 && src_loc
== NULL
,
320 "bin_info_lookup_source_location - fail on addr not found");
322 bin_info_destroy(bin
);
323 bt_fd_cache_fini(&fdc
);
328 int main(int argc
, char **argv
)
332 plan_tests(NR_TESTS
);
337 opt_debug_info_dir
= argv
[1];
340 ret
= bin_info_init();
341 ok(ret
== 0, "bin_info_init successful");
343 test_bin_info(opt_debug_info_dir
);
344 test_bin_info_elf(opt_debug_info_dir
);
345 test_bin_info_build_id(opt_debug_info_dir
);
346 test_bin_info_debug_link(opt_debug_info_dir
);