Use is_pic field instead of reading ELF header
[babeltrace.git] / tests / lib / test_so_info.c
CommitLineData
394fd13b
AB
1/*
2 * test_so_info.c
3 *
4 * Babeltrace SO info tests
5 *
6 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
7 * Copyright (c) 2015 Antoine Busque <abusque@efficios.com>
8 *
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.
12 *
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.
17 *
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.
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <babeltrace/so-info.h>
27#include "tap/tap.h"
28
29#define NR_TESTS 36
30#define SO_NAME "libhello.so"
31#define SO_NAME_ELF "libhello_elf.so"
32#define SO_NAME_BUILD_ID "libhello_build_id.so"
33#define SO_NAME_DEBUG_LINK "libhello_debug_link.so"
34#define SO_LOW_ADDR 0x400000
35#define SO_MEMSZ 0x400000
36#define FUNC_FOO_ADDR 0x4014ee
37#define FUNC_FOO_LINE_NO 8
38#define FUNC_FOO_FILENAME "/efficios/libhello.c"
39#define FUNC_FOO_TP_ADDR 0x4014d3
40#define FUNC_FOO_TP_LINE_NO 7
41#define FUNC_FOO_TP_FILENAME "/efficios/libhello.c"
42#define FUNC_FOO_ADDR_ELF 0x4013ef
43#define FUNC_FOO_ADDR_DBG_LINK 0x40148e
44#define FUNC_FOO_NAME "foo"
45#define FUNC_FOO_NAME_ELF "foo+0x24"
46#define BUILD_ID_LEN 20
47
3be1e3c9 48char *opt_debug_info_dir;
394fd13b
AB
49
50static
51void test_so_info_build_id(const char *data_dir)
52{
53 int ret;
54 char path[PATH_MAX];
55 char *func_name = NULL;
56 struct so_info *so = NULL;
57 struct source_location *src_loc = NULL;
58 uint8_t build_id[BUILD_ID_LEN] = {
59 0xcd, 0xd9, 0x8c, 0xdd, 0x87, 0xf7, 0xfe, 0x64, 0xc1, 0x3b,
60 0x6d, 0xaa, 0xd5, 0x53, 0x98, 0x7e, 0xaf, 0xd4, 0x0c, 0xbb
61 };
62
63 diag("so-info tests - separate DWARF via build ID");
64
65 snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_BUILD_ID);
66
1a4a1345 67 so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true);
394fd13b
AB
68 ok(so != NULL, "so_info_create succesful");
69
70 /* Test setting build_id */
71 ret = so_info_set_build_id(so, build_id, BUILD_ID_LEN);
72 ok(ret == 0, "so_info_set_build_id succesful");
73
74 /* Test function name lookup (with DWARF) */
75 ret = so_info_lookup_function_name(so, FUNC_FOO_ADDR, &func_name);
76 ok(ret == 0, "so_info_lookup_function_name succesful");
77 ok(strcmp(func_name, FUNC_FOO_NAME) == 0,
78 "so_info_lookup_function_name - correct func_name value");
79 free(func_name);
80
81 /* Test source location lookup */
82 ret = so_info_lookup_source_location(so, FUNC_FOO_ADDR, &src_loc);
83 ok(ret == 0, "so_info_lookup_source_location succesful");
84 ok(src_loc->line_no == FUNC_FOO_LINE_NO,
85 "so_info_lookup_source_location - correct line_no");
86 ok(strcmp(src_loc->filename, FUNC_FOO_FILENAME) == 0,
87 "so_info_lookup_source_location - correct filename");
88 source_location_destroy(src_loc);
89
90 so_info_destroy(so);
91}
92
93static
94void test_so_info_debug_link(const char *data_dir)
95{
96 int ret;
97 char path[PATH_MAX];
98 char *func_name = NULL;
99 struct so_info *so = NULL;
100 struct source_location *src_loc = NULL;
101 char *dbg_filename = "libhello_debug_link.so.debug";
102 uint32_t crc = 0xe55c2b98;
103
104 diag("so-info tests - separate DWARF via debug link");
105
106 snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_DEBUG_LINK);
107
1a4a1345 108 so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true);
394fd13b
AB
109 ok(so != NULL, "so_info_create succesful");
110
111 /* Test setting debug link */
112 ret = so_info_set_debug_link(so, dbg_filename, crc);
113 ok(ret == 0, "so_info_set_debug_link succesful");
114
115 /* Test function name lookup (with DWARF) */
116 ret = so_info_lookup_function_name(so, FUNC_FOO_ADDR_DBG_LINK,
117 &func_name);
118 ok(ret == 0, "so_info_lookup_function_name succesful");
119 ok(strcmp(func_name, FUNC_FOO_NAME) == 0,
120 "so_info_lookup_function_name - correct func_name value");
121 free(func_name);
122
123 /* Test source location lookup */
124 ret = so_info_lookup_source_location(so, FUNC_FOO_ADDR_DBG_LINK,
125 &src_loc);
126 ok(ret == 0, "so_info_lookup_source_location succesful");
127 ok(src_loc->line_no == FUNC_FOO_LINE_NO,
128 "so_info_lookup_source_location - correct line_no");
129 ok(strcmp(src_loc->filename, FUNC_FOO_FILENAME) == 0,
130 "so_info_lookup_source_location - correct filename");
131 source_location_destroy(src_loc);
132
133 so_info_destroy(so);
134}
135
136static
137void test_so_info_elf(const char *data_dir)
138{
139 int ret;
140 char path[PATH_MAX];
141 char *func_name = NULL;
142 struct so_info *so = NULL;
143 struct source_location *src_loc = NULL;
144
145 diag("so-info tests - ELF only");
146
147 snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME_ELF);
148
1a4a1345 149 so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true);
394fd13b
AB
150 ok(so != NULL, "so_info_create succesful");
151
152 /* Test function name lookup (with ELF) */
153 ret = so_info_lookup_function_name(so, FUNC_FOO_ADDR_ELF, &func_name);
154 ok(ret == 0, "so_info_lookup_function_name succesful");
155 ok(strcmp(func_name, FUNC_FOO_NAME_ELF) == 0,
156 "so_info_lookup_function_name - correct func_name value");
157 free(func_name);
158 func_name = NULL;
159
160 /* Test function name lookup - erroneous address */
161 ret = so_info_lookup_function_name(so, 0, &func_name);
162 ok(ret == -1 && func_name == NULL,
163 "so_info_lookup_function_name - fail on addr not found");
164
165 /* Test source location location - should fail on ELF only file */
166 ret = so_info_lookup_source_location(so, FUNC_FOO_ADDR_ELF, &src_loc);
167 ok(ret == -1, "so_info_lookup_source_location - fail on ELF only file");
168
169 source_location_destroy(src_loc);
170 so_info_destroy(so);
171}
172
173static
174void test_so_info(const char *data_dir)
175{
176 int ret;
177 char path[PATH_MAX];
178 char *func_name = NULL;
179 struct so_info *so = NULL;
180 struct source_location *src_loc = NULL;
181
182 diag("so-info tests - DWARF bundled with SO file");
183
184 snprintf(path, PATH_MAX, "%s/%s", data_dir, SO_NAME);
185
1a4a1345 186 so = so_info_create(path, SO_LOW_ADDR, SO_MEMSZ, true);
394fd13b
AB
187 ok(so != NULL, "so_info_create succesful");
188
189 /* Test so_info_has_address */
190 ret = so_info_has_address(so, 0);
191 ok(ret == 0, "so_info_has_address - address under so's range");
192 ret = so_info_has_address(so, SO_LOW_ADDR);
193 ok(ret == 1, "so_info_has_address - lower bound of so's range");
194 ret = so_info_has_address(so, FUNC_FOO_ADDR);
195 ok(ret == 1, "so_info_has_address - address in so's range");
196 ret = so_info_has_address(so, SO_LOW_ADDR + SO_MEMSZ - 1);
197 ok(ret == 1, "so_info_has_address - upper bound of so's range");
198 ret = so_info_has_address(so, SO_LOW_ADDR + SO_MEMSZ);
199 ok(ret == 0, "so_info_has_address - address above so's range");
200
201 /* Test function name lookup (with DWARF) */
202 ret = so_info_lookup_function_name(so, FUNC_FOO_ADDR, &func_name);
203 ok(ret == 0, "so_info_lookup_function_name succesful");
204 ok(strcmp(func_name, FUNC_FOO_NAME) == 0,
205 "so_info_lookup_function_name - correct func_name value");
206 free(func_name);
207 func_name = NULL;
208
209 /* Test function name lookup - erroneous address */
210 ret = so_info_lookup_function_name(so, 0, &func_name);
211 ok(ret == -1 && func_name == NULL,
212 "so_info_lookup_function_name - fail on addr not found");
213
214 /* Test source location lookup */
215 ret = so_info_lookup_source_location(so, FUNC_FOO_ADDR, &src_loc);
216 ok(ret == 0, "so_info_lookup_source_location succesful");
217 ok(src_loc->line_no == FUNC_FOO_LINE_NO,
218 "so_info_lookup_source_location - correct line_no");
219 ok(strcmp(src_loc->filename, FUNC_FOO_FILENAME) == 0,
220 "so_info_lookup_source_location - correct filename");
221 source_location_destroy(src_loc);
222 src_loc = NULL;
223
224 /* Test source location lookup - inlined function */
225 ret = so_info_lookup_source_location(so, FUNC_FOO_TP_ADDR, &src_loc);
226 ok(ret == 0,
227 "so_info_lookup_source_location (inlined func) succesful");
228 ok(src_loc->line_no == FUNC_FOO_TP_LINE_NO,
229 "so_info_lookup_source_location (inlined func) - correct line_no");
230 ok(strcmp(src_loc->filename, FUNC_FOO_TP_FILENAME) == 0,
231 "so_info_lookup_source_location (inlined func) - correct filename");
232 source_location_destroy(src_loc);
233 src_loc = NULL;
234
235 /* Test source location lookup - erroneous address */
236 ret = so_info_lookup_source_location(so, 0, &src_loc);
237 ok(ret == -1 && src_loc == NULL,
238 "so_info_lookup_source_location - fail on addr not found");
239
240 so_info_destroy(so);
241}
242
243int main(int argc, char **argv)
244{
245 int ret;
246
247 plan_tests(NR_TESTS);
248
249 if (argc != 2) {
250 return EXIT_FAILURE;
251 } else {
3be1e3c9 252 opt_debug_info_dir = argv[1];
394fd13b
AB
253 }
254
255 ret = so_info_init();
256 ok(ret == 0, "so_info_init succesful");
257
3be1e3c9
JG
258 test_so_info(opt_debug_info_dir);
259 test_so_info_elf(opt_debug_info_dir);
260 test_so_info_build_id(opt_debug_info_dir);
261 test_so_info_debug_link(opt_debug_info_dir);
394fd13b
AB
262
263 return EXIT_SUCCESS;
264}
This page took 0.031758 seconds and 4 git commands to generate.