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"
34 #define SO_NAME_ELF "libhello_elf_so"
35 #define SO_NAME_BUILD_ID "libhello_build_id_so"
36 #define SO_NAME_DEBUG_LINK "libhello_debug_link_so"
37 #define SO_LOW_ADDR 0x400000
38 #define SO_MEMSZ 0x400000
39 #define FUNC_FOO_ADDR 0x4014ee
40 #define FUNC_FOO_LINE_NO 8
41 #define FUNC_FOO_FILENAME "/efficios/libhello.c"
42 #define FUNC_FOO_TP_ADDR 0x4014d3
43 #define FUNC_FOO_TP_LINE_NO 7
44 #define FUNC_FOO_TP_FILENAME "/efficios/libhello.c"
45 #define FUNC_FOO_ADDR_ELF 0x4013ef
46 #define FUNC_FOO_ADDR_DBG_LINK 0x40148e
47 #define FUNC_FOO_NAME "foo+0xc3"
48 #define FUNC_FOO_NAME_ELF "foo+0x24"
49 #define BUILD_ID_LEN 20
51 char *opt_debug_info_dir
;
52 char *opt_debug_info_target_prefix
;
55 void test_bin_info_build_id(const char *data_dir
)
59 char *func_name
= NULL
;
60 struct bin_info
*bin
= NULL
;
61 struct source_location
*src_loc
= NULL
;
62 struct bt_fd_cache fdc
;
63 uint8_t build_id
[BUILD_ID_LEN
] = {
64 0xcd, 0xd9, 0x8c, 0xdd, 0x87, 0xf7, 0xfe, 0x64, 0xc1, 0x3b,
65 0x6d, 0xaa, 0xd5, 0x53, 0x98, 0x7e, 0xaf, 0xd4, 0x0c, 0xbb
68 diag("bin-info tests - separate DWARF via build ID");
70 snprintf(path
, PATH_MAX
, "%s/%s", data_dir
, SO_NAME_BUILD_ID
);
72 ret
= bt_fd_cache_init(&fdc
);
74 bin
= bin_info_create(&fdc
, path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
, NULL
);
75 ok(bin
!= NULL
, "bin_info_create successful");
77 /* Test setting build_id */
78 ret
= bin_info_set_build_id(bin
, build_id
, BUILD_ID_LEN
);
79 ok(ret
== 0, "bin_info_set_build_id successful");
81 /* Test function name lookup (with DWARF) */
82 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR
, &func_name
);
83 ok(ret
== 0, "bin_info_lookup_function_name successful");
85 ok(strcmp(func_name
, FUNC_FOO_NAME
) == 0,
86 "bin_info_lookup_function_name - correct func_name value");
89 skip(1, "bin_info_lookup_function_name - func_name is NULL");
92 /* Test source location lookup */
93 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR
, &src_loc
);
94 ok(ret
== 0, "bin_info_lookup_source_location successful");
96 ok(src_loc
->line_no
== FUNC_FOO_LINE_NO
,
97 "bin_info_lookup_source_location - correct line_no");
98 ok(strcmp(src_loc
->filename
, FUNC_FOO_FILENAME
) == 0,
99 "bin_info_lookup_source_location - correct filename");
100 source_location_destroy(src_loc
);
102 skip(2, "bin_info_lookup_source_location - src_loc is NULL");
105 bin_info_destroy(bin
);
106 bt_fd_cache_fini(&fdc
);
110 void test_bin_info_debug_link(const char *data_dir
)
114 char *func_name
= NULL
;
115 struct bin_info
*bin
= NULL
;
116 struct source_location
*src_loc
= NULL
;
117 char *dbg_filename
= "libhello_debug_link_so.debug";
118 uint32_t crc
= 0xe55c2b98;
119 struct bt_fd_cache fdc
;
121 diag("bin-info tests - separate DWARF via debug link");
123 snprintf(path
, PATH_MAX
, "%s/%s", data_dir
, SO_NAME_DEBUG_LINK
);
125 ret
= bt_fd_cache_init(&fdc
);
127 bin
= bin_info_create(&fdc
, path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
,
129 ok(bin
!= NULL
, "bin_info_create successful");
131 /* Test setting debug link */
132 ret
= bin_info_set_debug_link(bin
, dbg_filename
, crc
);
133 ok(ret
== 0, "bin_info_set_debug_link successful");
135 /* Test function name lookup (with DWARF) */
136 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR_DBG_LINK
,
138 ok(ret
== 0, "bin_info_lookup_function_name successful");
140 ok(strcmp(func_name
, FUNC_FOO_NAME
) == 0,
141 "bin_info_lookup_function_name - correct func_name value");
144 skip(1, "bin_info_lookup_function_name - func_name is NULL");
147 /* Test source location lookup */
148 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR_DBG_LINK
,
150 ok(ret
== 0, "bin_info_lookup_source_location successful");
152 ok(src_loc
->line_no
== FUNC_FOO_LINE_NO
,
153 "bin_info_lookup_source_location - correct line_no");
154 ok(strcmp(src_loc
->filename
, FUNC_FOO_FILENAME
) == 0,
155 "bin_info_lookup_source_location - correct filename");
156 source_location_destroy(src_loc
);
158 skip(2, "bin_info_lookup_source_location - src_loc is NULL");
161 bin_info_destroy(bin
);
162 bt_fd_cache_fini(&fdc
);
166 void test_bin_info_elf(const char *data_dir
)
170 char *func_name
= NULL
;
171 struct bin_info
*bin
= NULL
;
172 struct source_location
*src_loc
= NULL
;
173 struct bt_fd_cache fdc
;
175 diag("bin-info tests - ELF only");
177 snprintf(path
, PATH_MAX
, "%s/%s", data_dir
, SO_NAME_ELF
);
179 ret
= bt_fd_cache_init(&fdc
);
181 bin
= bin_info_create(&fdc
, path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
, NULL
);
182 ok(bin
!= NULL
, "bin_info_create successful");
184 /* Test function name lookup (with ELF) */
185 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR_ELF
, &func_name
);
186 ok(ret
== 0, "bin_info_lookup_function_name successful");
188 ok(strcmp(func_name
, FUNC_FOO_NAME_ELF
) == 0,
189 "bin_info_lookup_function_name - correct func_name value");
193 skip(1, "bin_info_lookup_function_name - func_name is NULL");
196 /* Test function name lookup - erroneous address */
197 ret
= bin_info_lookup_function_name(bin
, 0, &func_name
);
198 ok(ret
== -1 && func_name
== NULL
,
199 "bin_info_lookup_function_name - fail on addr not found");
201 /* Test source location location - should fail on ELF only file */
202 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR_ELF
, &src_loc
);
203 ok(ret
== -1, "bin_info_lookup_source_location - fail on ELF only file");
205 source_location_destroy(src_loc
);
206 bin_info_destroy(bin
);
207 bt_fd_cache_fini(&fdc
);
211 void test_bin_info(const char *data_dir
)
215 char *func_name
= NULL
;
216 struct bin_info
*bin
= NULL
;
217 struct source_location
*src_loc
= NULL
;
218 struct bt_fd_cache fdc
;
220 diag("bin-info tests - DWARF bundled with SO file");
223 snprintf(path
, PATH_MAX
, "%s/%s", data_dir
, SO_NAME
);
225 ret
= bt_fd_cache_init(&fdc
);
227 bin
= bin_info_create(&fdc
, path
, SO_LOW_ADDR
, SO_MEMSZ
, true, data_dir
, NULL
);
228 ok(bin
!= NULL
, "bin_info_create successful");
230 /* Test bin_info_has_address */
231 ret
= bin_info_has_address(bin
, 0);
232 ok(ret
== 0, "bin_info_has_address - address under so's range");
233 ret
= bin_info_has_address(bin
, SO_LOW_ADDR
);
234 ok(ret
== 1, "bin_info_has_address - lower bound of so's range");
235 ret
= bin_info_has_address(bin
, FUNC_FOO_ADDR
);
236 ok(ret
== 1, "bin_info_has_address - address in so's range");
237 ret
= bin_info_has_address(bin
, SO_LOW_ADDR
+ SO_MEMSZ
- 1);
238 ok(ret
== 1, "bin_info_has_address - upper bound of so's range");
239 ret
= bin_info_has_address(bin
, SO_LOW_ADDR
+ SO_MEMSZ
);
240 ok(ret
== 0, "bin_info_has_address - address above so's range");
242 /* Test function name lookup (with DWARF) */
243 ret
= bin_info_lookup_function_name(bin
, FUNC_FOO_ADDR
, &func_name
);
244 ok(ret
== 0, "bin_info_lookup_function_name successful");
246 ok(strcmp(func_name
, FUNC_FOO_NAME
) == 0,
247 "bin_info_lookup_function_name - correct func_name value");
251 skip(1, "bin_info_lookup_function_name - func_name is NULL");
254 /* Test function name lookup - erroneous address */
255 ret
= bin_info_lookup_function_name(bin
, 0, &func_name
);
256 ok(ret
== -1 && func_name
== NULL
,
257 "bin_info_lookup_function_name - fail on addr not found");
259 /* Test source location lookup */
260 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_ADDR
, &src_loc
);
261 ok(ret
== 0, "bin_info_lookup_source_location successful");
263 ok(src_loc
->line_no
== FUNC_FOO_LINE_NO
,
264 "bin_info_lookup_source_location - correct line_no");
265 ok(strcmp(src_loc
->filename
, FUNC_FOO_FILENAME
) == 0,
266 "bin_info_lookup_source_location - correct filename");
267 source_location_destroy(src_loc
);
270 skip(2, "bin_info_lookup_source_location - src_loc is NULL");
273 /* Test source location lookup - inlined function */
274 ret
= bin_info_lookup_source_location(bin
, FUNC_FOO_TP_ADDR
, &src_loc
);
276 "bin_info_lookup_source_location (inlined func) successful");
278 ok(src_loc
->line_no
== FUNC_FOO_TP_LINE_NO
,
279 "bin_info_lookup_source_location (inlined func) - correct line_no");
280 ok(strcmp(src_loc
->filename
, FUNC_FOO_TP_FILENAME
) == 0,
281 "bin_info_lookup_source_location (inlined func) - correct filename");
282 source_location_destroy(src_loc
);
285 skip(2, "bin_info_lookup_source_location (inlined func) - src_loc is NULL");
288 /* Test source location lookup - erroneous address */
289 ret
= bin_info_lookup_source_location(bin
, 0, &src_loc
);
290 ok(ret
== -1 && src_loc
== NULL
,
291 "bin_info_lookup_source_location - fail on addr not found");
293 bin_info_destroy(bin
);
294 bt_fd_cache_fini(&fdc
);
297 int main(int argc
, char **argv
)
301 plan_tests(NR_TESTS
);
306 opt_debug_info_dir
= argv
[1];
309 ret
= bin_info_init();
310 ok(ret
== 0, "bin_info_init successful");
312 test_bin_info(opt_debug_info_dir
);
313 test_bin_info_elf(opt_debug_info_dir
);
314 test_bin_info_build_id(opt_debug_info_dir
);
315 test_bin_info_debug_link(opt_debug_info_dir
);