blob: bbf9ff3d8b42b4c407a403a9995d911900e9595d [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Find debugging and symbol information for a module in libdwfl.
Roland McGrath2c7d0dd2011-01-04 19:29:53 -08002 Copyright (C) 2005-2011 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004
Mark Wielaardde2ed972012-06-05 17:15:16 +02005 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00007
Mark Wielaardde2ed972012-06-05 17:15:16 +02008 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
Ulrich Drepper361df7d2006-04-04 21:38:57 +000021 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
Mark Wielaardde2ed972012-06-05 17:15:16 +020025 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000028
29#include "libdwflP.h"
30#include <fcntl.h>
31#include <string.h>
Roland McGrathd17fac72005-08-23 08:20:21 +000032#include <unistd.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000033#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
34
35
36/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD.
Roland McGrath5ad466d2011-01-11 10:17:01 -080037 When we return success, FILE->elf and FILE->vaddr are set up. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000038static inline Dwfl_Error
39open_elf (Dwfl_Module *mod, struct dwfl_file *file)
40{
41 if (file->elf == NULL)
42 {
Roland McGrathe07da4f2011-03-08 16:26:02 -080043 /* CBFAIL uses errno if it's set, so clear it first in case we don't
44 set it with an open failure below. */
45 errno = 0;
46
Roland McGrath059c83e2008-02-21 06:19:39 +000047 /* If there was a pre-primed file name left that the callback left
48 behind, try to open that file name. */
49 if (file->fd < 0 && file->name != NULL)
50 file->fd = TEMP_FAILURE_RETRY (open64 (file->name, O_RDONLY));
51
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000052 if (file->fd < 0)
53 return CBFAIL;
54
Roland McGrathbca43152009-01-05 23:59:32 -080055 Dwfl_Error error = __libdw_open_file (&file->fd, &file->elf, true, false);
56 if (error != DWFL_E_NOERROR)
57 return error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000058 }
Roland McGrathbca43152009-01-05 23:59:32 -080059 else if (unlikely (elf_kind (file->elf) != ELF_K_ELF))
Roland McGrath122f3882008-08-26 07:20:29 +000060 {
Roland McGrathed431dd2010-05-06 00:52:51 -070061 elf_end (file->elf);
62 file->elf = NULL;
Roland McGrath122f3882008-08-26 07:20:29 +000063 close (file->fd);
64 file->fd = -1;
65 return DWFL_E_BADELF;
66 }
67
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000068 GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
69 if (ehdr == NULL)
Ulrich Drepper6258e742007-03-13 06:22:40 +000070 {
71 elf_error:
Roland McGrathed431dd2010-05-06 00:52:51 -070072 elf_end (file->elf);
73 file->elf = NULL;
Ulrich Drepper6258e742007-03-13 06:22:40 +000074 close (file->fd);
75 file->fd = -1;
Roland McGrath122f3882008-08-26 07:20:29 +000076 return DWFL_E (LIBELF, elf_errno ());
Ulrich Drepper6258e742007-03-13 06:22:40 +000077 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000078
Roland McGrath1743d7f2010-11-12 16:46:47 -080079 if (mod->e_type != ET_REL)
Roland McGrathf95760a2010-01-07 20:24:34 -080080 {
Roland McGrath2c7d0dd2011-01-04 19:29:53 -080081 /* In any non-ET_REL file, we compute the "synchronization address".
82
83 We start with the address at the end of the first PT_LOAD
84 segment. When prelink converts REL to RELA in an ET_DYN
85 file, it expands the space between the beginning of the
86 segment and the actual code/data addresses. Since that
87 change wasn't made in the debug file, the distance from
88 p_vaddr to an address of interest (in an st_value or DWARF
89 data) now differs between the main and debug files. The
90 distance from address_sync to an address of interest remains
91 consistent.
92
93 If there are no section headers at all (full stripping), then
94 the end of the first segment is a valid synchronization address.
95 This cannot happen in a prelinked file, since prelink itself
96 relies on section headers for prelinking and for undoing it.
97 (If you do full stripping on a prelinked file, then you get what
98 you deserve--you can neither undo the prelinking, nor expect to
99 line it up with a debug file separated before prelinking.)
100
101 However, when prelink processes an ET_EXEC file, it can do
102 something different. There it juggles the "special" sections
103 (SHT_DYNSYM et al) to make space for the additional prelink
104 special sections. Sometimes it will do this by moving a special
Roland McGrath5ad466d2011-01-11 10:17:01 -0800105 section like .dynstr after the real program sections in the first
106 PT_LOAD segment--i.e. to the end. That changes the end address of
107 the segment, so it no longer lines up correctly and is not a valid
108 synchronization address to use. Because of this, we need to apply
109 a different prelink-savvy means to discover the synchronization
110 address when there is a separate debug file and a prelinked main
111 file. That is done in find_debuginfo, below. */
Roland McGrath2c7d0dd2011-01-04 19:29:53 -0800112
Roland McGrathf95760a2010-01-07 20:24:34 -0800113 size_t phnum;
114 if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0))
115 goto elf_error;
116
Roland McGrath1743d7f2010-11-12 16:46:47 -0800117 file->vaddr = file->address_sync = 0;
Roland McGrathf95760a2010-01-07 20:24:34 -0800118 for (size_t i = 0; i < phnum; ++i)
119 {
120 GElf_Phdr ph_mem;
121 GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
Roland McGrath1743d7f2010-11-12 16:46:47 -0800122 if (unlikely (ph == NULL))
Roland McGrathf95760a2010-01-07 20:24:34 -0800123 goto elf_error;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800124 if (ph->p_type == PT_LOAD)
Roland McGrathf95760a2010-01-07 20:24:34 -0800125 {
Roland McGrath5ad466d2011-01-11 10:17:01 -0800126 file->vaddr = ph->p_vaddr & -ph->p_align;
127 file->address_sync = ph->p_vaddr + ph->p_memsz;
Roland McGrathf95760a2010-01-07 20:24:34 -0800128 break;
129 }
130 }
131 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000132
Ulrich Drepper6258e742007-03-13 06:22:40 +0000133 mod->e_type = ehdr->e_type;
134
135 /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN. */
Roland McGrath1743d7f2010-11-12 16:46:47 -0800136 if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
Ulrich Drepper6258e742007-03-13 06:22:40 +0000137 mod->e_type = ET_DYN;
138
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000139 return DWFL_E_NOERROR;
140}
141
142/* Find the main ELF file for this module and open libelf on it.
143 When we return success, MOD->main.elf and MOD->main.bias are set up. */
Roland McGratha605a3c2009-04-19 18:27:01 -0700144void
Roland McGrath10361572009-04-20 11:50:50 -0700145internal_function
Roland McGratha605a3c2009-04-19 18:27:01 -0700146__libdwfl_getelf (Dwfl_Module *mod)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000147{
148 if (mod->main.elf != NULL /* Already done. */
149 || mod->elferr != DWFL_E_NOERROR) /* Cached failure. */
150 return;
151
152 mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
153 &mod->main.name,
154 &mod->main.elf);
Roland McGrathed431dd2010-05-06 00:52:51 -0700155 const bool fallback = mod->main.elf == NULL && mod->main.fd < 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000156 mod->elferr = open_elf (mod, &mod->main);
Roland McGrathed431dd2010-05-06 00:52:51 -0700157 if (mod->elferr != DWFL_E_NOERROR)
158 return;
Roland McGrath59ea7f32007-10-04 08:50:09 +0000159
Roland McGrathed431dd2010-05-06 00:52:51 -0700160 if (!mod->main.valid)
Roland McGrath59ea7f32007-10-04 08:50:09 +0000161 {
162 /* Clear any explicitly reported build ID, just in case it was wrong.
163 We'll fetch it from the file when asked. */
Roland McGrathbfc01702008-04-06 01:57:32 +0000164 free (mod->build_id_bits);
165 mod->build_id_bits = NULL;
Roland McGrath59ea7f32007-10-04 08:50:09 +0000166 mod->build_id_len = 0;
167 }
Roland McGrathed431dd2010-05-06 00:52:51 -0700168 else if (fallback)
169 {
170 /* We have an authoritative build ID for this module, so
171 don't use a file by name that doesn't match that ID. */
172
173 assert (mod->build_id_len > 0);
174
175 switch (__builtin_expect (__libdwfl_find_build_id (mod, false,
176 mod->main.elf), 2))
177 {
178 case 2:
179 /* Build ID matches as it should. */
180 return;
181
182 case -1: /* ELF error. */
183 mod->elferr = INTUSE(dwfl_errno) ();
184 break;
185
186 case 0: /* File has no build ID note. */
187 case 1: /* FIle has a build ID that does not match. */
188 mod->elferr = DWFL_E_WRONG_ID_ELF;
189 break;
190
191 default:
192 abort ();
193 }
194
195 /* We get here when it was the right ELF file. Clear it out. */
196 elf_end (mod->main.elf);
197 mod->main.elf = NULL;
198 if (mod->main.fd >= 0)
199 {
200 close (mod->main.fd);
201 mod->main.fd = -1;
202 }
203 }
Roland McGrath1743d7f2010-11-12 16:46:47 -0800204
205 mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000206}
207
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000208/* Search an ELF file for a ".gnu_debuglink" section. */
209static const char *
210find_debuglink (Elf *elf, GElf_Word *crc)
211{
212 size_t shstrndx;
Ulrich Drepperf1894932009-06-13 15:55:42 -0700213 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000214 return NULL;
215
216 Elf_Scn *scn = NULL;
217 while ((scn = elf_nextscn (elf, scn)) != NULL)
218 {
219 GElf_Shdr shdr_mem;
220 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
221 if (shdr == NULL)
222 return NULL;
223
224 const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
225 if (name == NULL)
226 return NULL;
227
228 if (!strcmp (name, ".gnu_debuglink"))
229 break;
230 }
231
232 if (scn == NULL)
233 return NULL;
234
235 /* Found the .gnu_debuglink section. Extract its contents. */
236 Elf_Data *rawdata = elf_rawdata (scn, NULL);
237 if (rawdata == NULL)
238 return NULL;
239
240 Elf_Data crcdata =
241 {
242 .d_type = ELF_T_WORD,
243 .d_buf = crc,
244 .d_size = sizeof *crc,
245 .d_version = EV_CURRENT,
246 };
247 Elf_Data conv =
248 {
249 .d_type = ELF_T_WORD,
250 .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc,
251 .d_size = sizeof *crc,
252 .d_version = EV_CURRENT,
253 };
254
255 GElf_Ehdr ehdr_mem;
256 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
257 if (ehdr == NULL)
258 return NULL;
259
260 Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]);
261 if (d == NULL)
262 return NULL;
263 assert (d == &crcdata);
264
265 return rawdata->d_buf;
266}
267
Roland McGrath5ad466d2011-01-11 10:17:01 -0800268/* If the main file might have been prelinked, then we need to
269 discover the correct synchronization address between the main and
270 debug files. Because of prelink's section juggling, we cannot rely
271 on the address_sync computed from PT_LOAD segments (see open_elf).
272
273 We will attempt to discover a synchronization address based on the
274 section headers instead. But finding a section address that is
275 safe to use requires identifying which sections are SHT_PROGBITS.
276 We can do that in the main file, but in the debug file all the
277 allocated sections have been transformed into SHT_NOBITS so we have
278 lost the means to match them up correctly.
279
280 The only method left to us is to decode the .gnu.prelink_undo
281 section in the prelinked main file. This shows what the sections
282 looked like before prelink juggled them--when they still had a
283 direct correspondence to the debug file. */
284static Dwfl_Error
285find_prelink_address_sync (Dwfl_Module *mod)
286{
287 /* The magic section is only identified by name. */
288 size_t shstrndx;
289 if (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)
290 return DWFL_E_LIBELF;
291
292 Elf_Scn *scn = NULL;
293 while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
294 {
295 GElf_Shdr shdr_mem;
296 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
297 if (unlikely (shdr == NULL))
298 return DWFL_E_LIBELF;
299 if (shdr->sh_type == SHT_PROGBITS
300 && !(shdr->sh_flags & SHF_ALLOC)
301 && shdr->sh_name != 0)
302 {
303 const char *secname = elf_strptr (mod->main.elf, shstrndx,
304 shdr->sh_name);
305 if (unlikely (secname == NULL))
306 return DWFL_E_LIBELF;
307 if (!strcmp (secname, ".gnu.prelink_undo"))
308 break;
309 }
310 }
311
312 if (scn == NULL)
313 /* There was no .gnu.prelink_undo section. */
314 return DWFL_E_NOERROR;
315
316 Elf_Data *undodata = elf_rawdata (scn, NULL);
317 if (unlikely (undodata == NULL))
318 return DWFL_E_LIBELF;
319
320 /* Decode the section. It consists of the original ehdr, phdrs,
321 and shdrs (but omits section 0). */
322
323 union
324 {
325 Elf32_Ehdr e32;
326 Elf64_Ehdr e64;
327 } ehdr;
328 Elf_Data dst =
329 {
330 .d_buf = &ehdr,
331 .d_size = sizeof ehdr,
332 .d_type = ELF_T_EHDR,
333 .d_version = EV_CURRENT
334 };
335 Elf_Data src = *undodata;
336 src.d_size = gelf_fsize (mod->main.elf, ELF_T_EHDR, 1, EV_CURRENT);
337 src.d_type = ELF_T_EHDR;
338 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
339 elf_getident (mod->main.elf, NULL)[EI_DATA])
340 == NULL))
341 return DWFL_E_LIBELF;
342
343 size_t shentsize = gelf_fsize (mod->main.elf, ELF_T_SHDR, 1, EV_CURRENT);
344 size_t phentsize = gelf_fsize (mod->main.elf, ELF_T_PHDR, 1, EV_CURRENT);
345
346 uint_fast16_t phnum;
347 uint_fast16_t shnum;
348 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
349 {
350 if (ehdr.e32.e_shentsize != shentsize
351 || ehdr.e32.e_phentsize != phentsize)
352 return DWFL_E_BAD_PRELINK;
353 phnum = ehdr.e32.e_phnum;
354 shnum = ehdr.e32.e_shnum;
355 }
356 else
357 {
358 if (ehdr.e64.e_shentsize != shentsize
359 || ehdr.e64.e_phentsize != phentsize)
360 return DWFL_E_BAD_PRELINK;
361 phnum = ehdr.e64.e_phnum;
362 shnum = ehdr.e64.e_shnum;
363 }
364
365 /* Since prelink does not store the zeroth section header in the undo
366 section, it cannot support SHN_XINDEX encoding. */
367 if (unlikely (shnum >= SHN_LORESERVE)
368 || unlikely (undodata->d_size != (src.d_size
369 + phnum * phentsize
370 + (shnum - 1) * shentsize)))
371 return DWFL_E_BAD_PRELINK;
372
373 /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections. (Most
374 every file will have some SHT_PROGBITS sections, but it's possible to
375 have one with nothing but .bss, i.e. SHT_NOBITS.) The special sections
376 that can be moved around have different sh_type values--except for
377 .interp, the section that became the PT_INTERP segment. So we exclude
378 the SHT_PROGBITS section whose address matches the PT_INTERP p_vaddr.
379 For this reason, we must examine the phdrs first to find PT_INTERP. */
380
Roland McGrath0ef40202011-02-01 16:58:32 -0800381 GElf_Addr main_interp = 0;
382 {
383 size_t main_phnum;
384 if (unlikely (elf_getphdrnum (mod->main.elf, &main_phnum)))
385 return DWFL_E_LIBELF;
386 for (size_t i = 0; i < main_phnum; ++i)
387 {
388 GElf_Phdr phdr;
389 if (unlikely (gelf_getphdr (mod->main.elf, i, &phdr) == NULL))
390 return DWFL_E_LIBELF;
391 if (phdr.p_type == PT_INTERP)
392 {
393 main_interp = phdr.p_vaddr;
394 break;
395 }
396 }
397 }
398
Roland McGrath5ad466d2011-01-11 10:17:01 -0800399 src.d_buf += src.d_size;
400 src.d_type = ELF_T_PHDR;
401 src.d_size = phnum * phentsize;
402
Roland McGrath0ef40202011-02-01 16:58:32 -0800403 GElf_Addr undo_interp = 0;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800404 {
405 union
406 {
407 Elf32_Phdr p32[phnum];
408 Elf64_Phdr p64[phnum];
409 } phdr;
410 dst.d_buf = &phdr;
411 dst.d_size = sizeof phdr;
412 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
413 ehdr.e32.e_ident[EI_DATA]) == NULL))
414 return DWFL_E_LIBELF;
415 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
416 {
417 for (uint_fast16_t i = 0; i < phnum; ++i)
418 if (phdr.p32[i].p_type == PT_INTERP)
419 {
Roland McGrath0ef40202011-02-01 16:58:32 -0800420 undo_interp = phdr.p32[i].p_vaddr;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800421 break;
422 }
423 }
424 else
425 {
426 for (uint_fast16_t i = 0; i < phnum; ++i)
Roland McGrath9fdd4612011-02-01 16:09:43 -0800427 if (phdr.p64[i].p_type == PT_INTERP)
Roland McGrath5ad466d2011-01-11 10:17:01 -0800428 {
Roland McGrath0ef40202011-02-01 16:58:32 -0800429 undo_interp = phdr.p64[i].p_vaddr;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800430 break;
431 }
432 }
433 }
434
Roland McGrath0ef40202011-02-01 16:58:32 -0800435 if (unlikely ((main_interp == 0) != (undo_interp == 0)))
436 return DWFL_E_BAD_PRELINK;
437
Roland McGrath5ad466d2011-01-11 10:17:01 -0800438 src.d_buf += src.d_size;
439 src.d_type = ELF_T_SHDR;
440 src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT);
441
442 union
443 {
444 Elf32_Shdr s32[shnum - 1];
445 Elf64_Shdr s64[shnum - 1];
446 } shdr;
447 dst.d_buf = &shdr;
448 dst.d_size = sizeof shdr;
449 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
450 ehdr.e32.e_ident[EI_DATA]) == NULL))
451 return DWFL_E_LIBELF;
452
453 /* Now we can look at the original section headers of the main file
454 before it was prelinked. First we'll apply our method to the main
455 file sections as they are after prelinking, to calculate the
456 synchronization address of the main file. Then we'll apply that
457 same method to the saved section headers, to calculate the matching
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800458 synchronization address of the debug file.
459
460 The method is to consider SHF_ALLOC sections that are either
461 SHT_PROGBITS or SHT_NOBITS, excluding the section whose sh_addr
462 matches the PT_INTERP p_vaddr. The special sections that can be
463 moved by prelink have other types, except for .interp (which
464 becomes PT_INTERP). The "real" sections cannot move as such, but
465 .bss can be split into .dynbss and .bss, with the total memory
466 image remaining the same but being spread across the two sections.
467 So we consider the highest section end, which still matches up. */
Roland McGrath5ad466d2011-01-11 10:17:01 -0800468
469 GElf_Addr highest;
470
Roland McGrath0ef40202011-02-01 16:58:32 -0800471 inline void consider_shdr (GElf_Addr interp,
472 GElf_Word sh_type,
Roland McGrath5ad466d2011-01-11 10:17:01 -0800473 GElf_Xword sh_flags,
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800474 GElf_Addr sh_addr,
475 GElf_Xword sh_size)
Roland McGrath5ad466d2011-01-11 10:17:01 -0800476 {
477 if ((sh_flags & SHF_ALLOC)
478 && ((sh_type == SHT_PROGBITS && sh_addr != interp)
479 || sh_type == SHT_NOBITS))
480 {
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800481 const GElf_Addr sh_end = sh_addr + sh_size;
482 if (sh_end > highest)
483 highest = sh_end;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800484 }
485 }
486
487 highest = 0;
488 scn = NULL;
489 while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
490 {
491 GElf_Shdr sh_mem;
492 GElf_Shdr *sh = gelf_getshdr (scn, &sh_mem);
493 if (unlikely (sh == NULL))
494 return DWFL_E_LIBELF;
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800495 consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
496 sh->sh_addr, sh->sh_size);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800497 }
498 if (highest > mod->main.vaddr)
499 {
500 mod->main.address_sync = highest;
501
502 highest = 0;
503 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
504 for (size_t i = 0; i < shnum - 1; ++i)
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800505 consider_shdr (undo_interp, shdr.s32[i].sh_type, shdr.s32[i].sh_flags,
506 shdr.s32[i].sh_addr, shdr.s32[i].sh_size);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800507 else
508 for (size_t i = 0; i < shnum - 1; ++i)
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800509 consider_shdr (undo_interp, shdr.s64[i].sh_type, shdr.s64[i].sh_flags,
510 shdr.s64[i].sh_addr, shdr.s64[i].sh_size);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800511
512 if (highest > mod->debug.vaddr)
513 mod->debug.address_sync = highest;
514 else
515 return DWFL_E_BAD_PRELINK;
516 }
517
518 return DWFL_E_NOERROR;
519}
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000520
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000521/* Find the separate debuginfo file for this module and open libelf on it.
522 When we return success, MOD->debug is set up. */
523static Dwfl_Error
524find_debuginfo (Dwfl_Module *mod)
525{
Roland McGrathd17fac72005-08-23 08:20:21 +0000526 if (mod->debug.elf != NULL)
527 return DWFL_E_NOERROR;
528
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000529 GElf_Word debuglink_crc = 0;
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000530 const char *debuglink_file = find_debuglink (mod->main.elf, &debuglink_crc);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000531
532 mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
533 mod->main.name,
534 debuglink_file,
535 debuglink_crc,
536 &mod->debug.name);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800537 Dwfl_Error result = open_elf (mod, &mod->debug);
538 if (result == DWFL_E_NOERROR && mod->debug.address_sync != 0)
539 result = find_prelink_address_sync (mod);
540 return result;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000541}
542
543
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000544/* Try to find a symbol table in FILE.
545 Returns DWFL_E_NOERROR if a proper one is found.
546 Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000547static Dwfl_Error
548load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
549 Elf_Scn **symscn, Elf_Scn **xndxscn,
Mark Wielaardef431cd2011-10-31 23:17:06 +0100550 size_t *syments, int *first_global, GElf_Word *strshndx)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000551{
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000552 bool symtab = false;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000553 Elf_Scn *scn = NULL;
554 while ((scn = elf_nextscn (file->elf, scn)) != NULL)
555 {
556 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
557 if (shdr != NULL)
558 switch (shdr->sh_type)
559 {
560 case SHT_SYMTAB:
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000561 symtab = true;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000562 *symscn = scn;
563 *symfile = file;
564 *strshndx = shdr->sh_link;
565 *syments = shdr->sh_size / shdr->sh_entsize;
Mark Wielaardef431cd2011-10-31 23:17:06 +0100566 *first_global = shdr->sh_info;
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000567 if (*xndxscn != NULL)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000568 return DWFL_E_NOERROR;
569 break;
570
571 case SHT_DYNSYM:
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000572 if (symtab)
573 break;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000574 /* Use this if need be, but keep looking for SHT_SYMTAB. */
575 *symscn = scn;
576 *symfile = file;
577 *strshndx = shdr->sh_link;
578 *syments = shdr->sh_size / shdr->sh_entsize;
579 break;
580
581 case SHT_SYMTAB_SHNDX:
582 *xndxscn = scn;
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000583 if (symtab)
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000584 return DWFL_E_NOERROR;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000585 break;
586
587 default:
588 break;
589 }
590 }
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000591
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000592 if (symtab)
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000593 /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
594 return DWFL_E_NOERROR;
595
596 /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus.
597 We might have found an SHT_DYNSYM and set *SYMSCN et al though. */
598 *xndxscn = NULL;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000599 return DWFL_E_NO_SYMTAB;
600}
601
Roland McGrath59ea7f32007-10-04 08:50:09 +0000602
603/* Translate addresses into file offsets.
604 OFFS[*] start out zero and remain zero if unresolved. */
605static void
Roland McGrathf95760a2010-01-07 20:24:34 -0800606find_offsets (Elf *elf, size_t phnum, size_t n,
Roland McGrath59ea7f32007-10-04 08:50:09 +0000607 GElf_Addr addrs[n], GElf_Off offs[n])
608{
609 size_t unsolved = n;
Roland McGrathf95760a2010-01-07 20:24:34 -0800610 for (size_t i = 0; i < phnum; ++i)
Roland McGrath59ea7f32007-10-04 08:50:09 +0000611 {
612 GElf_Phdr phdr_mem;
613 GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
614 if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
615 for (size_t j = 0; j < n; ++j)
616 if (offs[j] == 0
617 && addrs[j] >= phdr->p_vaddr
618 && addrs[j] - phdr->p_vaddr < phdr->p_filesz)
619 {
620 offs[j] = addrs[j] - phdr->p_vaddr + phdr->p_offset;
621 if (--unsolved == 0)
622 break;
623 }
624 }
625}
626
627/* Try to find a dynamic symbol table via phdrs. */
628static void
629find_dynsym (Dwfl_Module *mod)
630{
631 GElf_Ehdr ehdr_mem;
632 GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
633
Roland McGrathf95760a2010-01-07 20:24:34 -0800634 size_t phnum;
635 if (unlikely (elf_getphdrnum (mod->main.elf, &phnum) != 0))
636 return;
637
638 for (size_t i = 0; i < phnum; ++i)
Roland McGrath59ea7f32007-10-04 08:50:09 +0000639 {
640 GElf_Phdr phdr_mem;
641 GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
642 if (phdr == NULL)
643 break;
644
645 if (phdr->p_type == PT_DYNAMIC)
646 {
647 /* Examine the dynamic section for the pointers we need. */
648
649 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
650 phdr->p_offset, phdr->p_filesz,
651 ELF_T_DYN);
652 if (data == NULL)
653 continue;
654
655 enum
656 {
657 i_symtab,
658 i_strtab,
659 i_hash,
660 i_gnu_hash,
661 i_max
662 };
663 GElf_Addr addrs[i_max] = { 0, };
664 GElf_Xword strsz = 0;
665 size_t n = data->d_size / gelf_fsize (mod->main.elf,
666 ELF_T_DYN, 1, EV_CURRENT);
667 for (size_t j = 0; j < n; ++j)
668 {
669 GElf_Dyn dyn_mem;
670 GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
671 if (dyn != NULL)
672 switch (dyn->d_tag)
673 {
674 case DT_SYMTAB:
675 addrs[i_symtab] = dyn->d_un.d_ptr;
676 continue;
677
678 case DT_HASH:
679 addrs[i_hash] = dyn->d_un.d_ptr;
680 continue;
681
682 case DT_GNU_HASH:
683 addrs[i_gnu_hash] = dyn->d_un.d_ptr;
684 continue;
685
686 case DT_STRTAB:
687 addrs[i_strtab] = dyn->d_un.d_ptr;
688 continue;
689
690 case DT_STRSZ:
691 strsz = dyn->d_un.d_val;
692 continue;
693
694 default:
695 continue;
696
697 case DT_NULL:
698 break;
699 }
700 break;
701 }
702
703 /* Translate pointers into file offsets. */
704 GElf_Off offs[i_max] = { 0, };
Roland McGrathf95760a2010-01-07 20:24:34 -0800705 find_offsets (mod->main.elf, phnum, i_max, addrs, offs);
Roland McGrath59ea7f32007-10-04 08:50:09 +0000706
707 /* Figure out the size of the symbol table. */
708 if (offs[i_hash] != 0)
709 {
710 /* In the original format, .hash says the size of .dynsym. */
711
712 size_t entsz = SH_ENTSIZE_HASH (ehdr);
713 data = elf_getdata_rawchunk (mod->main.elf,
714 offs[i_hash] + entsz, entsz,
715 entsz == 4 ? ELF_T_WORD
716 : ELF_T_XWORD);
717 if (data != NULL)
718 mod->syments = (entsz == 4
719 ? *(const GElf_Word *) data->d_buf
720 : *(const GElf_Xword *) data->d_buf);
721 }
722 if (offs[i_gnu_hash] != 0 && mod->syments == 0)
723 {
724 /* In the new format, we can derive it with some work. */
725
726 const struct
727 {
728 Elf32_Word nbuckets;
729 Elf32_Word symndx;
730 Elf32_Word maskwords;
731 Elf32_Word shift2;
732 } *header;
733
734 data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
735 sizeof *header, ELF_T_WORD);
736 if (data != NULL)
737 {
738 header = data->d_buf;
739 Elf32_Word nbuckets = header->nbuckets;
740 Elf32_Word symndx = header->symndx;
741 GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
742 + (gelf_getclass (mod->main.elf)
743 * sizeof (Elf32_Word)
744 * header->maskwords));
745
746 data = elf_getdata_rawchunk (mod->main.elf, buckets_at,
747 nbuckets * sizeof (Elf32_Word),
748 ELF_T_WORD);
749 if (data != NULL && symndx < nbuckets)
750 {
751 const Elf32_Word *const buckets = data->d_buf;
752 Elf32_Word maxndx = symndx;
753 for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
754 if (buckets[bucket] > maxndx)
755 maxndx = buckets[bucket];
756
757 GElf_Off hasharr_at = (buckets_at
758 + nbuckets * sizeof (Elf32_Word));
759 hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
760 do
761 {
762 data = elf_getdata_rawchunk (mod->main.elf,
763 hasharr_at,
764 sizeof (Elf32_Word),
765 ELF_T_WORD);
766 if (data != NULL
767 && (*(const Elf32_Word *) data->d_buf & 1u))
768 {
769 mod->syments = maxndx + 1;
770 break;
771 }
772 ++maxndx;
773 hasharr_at += sizeof (Elf32_Word);
774 } while (data != NULL);
775 }
776 }
777 }
778 if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
779 mod->syments = ((offs[i_strtab] - offs[i_symtab])
780 / gelf_fsize (mod->main.elf,
781 ELF_T_SYM, 1, EV_CURRENT));
782
783 if (mod->syments > 0)
784 {
785 mod->symdata = elf_getdata_rawchunk (mod->main.elf,
786 offs[i_symtab],
787 gelf_fsize (mod->main.elf,
788 ELF_T_SYM,
789 mod->syments,
790 EV_CURRENT),
791 ELF_T_SYM);
792 if (mod->symdata != NULL)
793 {
794 mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
795 offs[i_strtab],
796 strsz,
797 ELF_T_BYTE);
798 if (mod->symstrdata == NULL)
799 mod->symdata = NULL;
800 }
801 if (mod->symdata == NULL)
802 mod->symerr = DWFL_E (LIBELF, elf_errno ());
803 else
804 {
805 mod->symfile = &mod->main;
806 mod->symerr = DWFL_E_NOERROR;
807 }
808 return;
809 }
810 }
811 }
812}
813
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000814/* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf. */
815static void
816find_symtab (Dwfl_Module *mod)
817{
818 if (mod->symdata != NULL /* Already done. */
819 || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */
820 return;
821
Roland McGratha605a3c2009-04-19 18:27:01 -0700822 __libdwfl_getelf (mod);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000823 mod->symerr = mod->elferr;
824 if (mod->symerr != DWFL_E_NOERROR)
825 return;
826
Mark Wielaardef431cd2011-10-31 23:17:06 +0100827 mod->first_global = -1; /* Unknown, unless explicitly set by load_symtab. */
828
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000829 /* First see if the main ELF file has the debugging information. */
830 Elf_Scn *symscn = NULL, *xndxscn = NULL;
831 GElf_Word strshndx;
832 mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn,
Mark Wielaardef431cd2011-10-31 23:17:06 +0100833 &xndxscn, &mod->syments, &mod->first_global,
834 &strshndx);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000835 switch (mod->symerr)
836 {
837 default:
838 return;
839
840 case DWFL_E_NOERROR:
841 break;
842
843 case DWFL_E_NO_SYMTAB:
844 /* Now we have to look for a separate debuginfo file. */
845 mod->symerr = find_debuginfo (mod);
846 switch (mod->symerr)
847 {
848 default:
849 return;
850
851 case DWFL_E_NOERROR:
852 mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn,
Mark Wielaardef431cd2011-10-31 23:17:06 +0100853 &xndxscn, &mod->syments,
854 &mod->first_global, &strshndx);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000855 break;
856
857 case DWFL_E_CB: /* The find_debuginfo hook failed. */
858 mod->symerr = DWFL_E_NO_SYMTAB;
859 break;
860 }
861
862 switch (mod->symerr)
863 {
864 default:
865 return;
866
867 case DWFL_E_NOERROR:
868 break;
869
870 case DWFL_E_NO_SYMTAB:
Roland McGrath59ea7f32007-10-04 08:50:09 +0000871 if (symscn != NULL)
872 {
873 /* We still have the dynamic symbol table. */
874 mod->symerr = DWFL_E_NOERROR;
875 break;
876 }
877
878 /* Last ditch, look for dynamic symbols without section headers. */
879 find_dynsym (mod);
880 return;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000881 }
882 break;
883 }
884
885 /* This does some sanity checks on the string table section. */
886 if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL)
887 {
888 elferr:
889 mod->symerr = DWFL_E (LIBELF, elf_errno ());
890 return;
891 }
892
Mark Wielaardef431cd2011-10-31 23:17:06 +0100893 /* Cache the data; MOD->syments and MOD->first_global were set above. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000894
Roland McGrath3712b282005-08-23 05:58:42 +0000895 mod->symstrdata = elf_getdata (elf_getscn (mod->symfile->elf, strshndx),
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000896 NULL);
897 if (mod->symstrdata == NULL)
898 goto elferr;
899
900 if (xndxscn == NULL)
901 mod->symxndxdata = NULL;
902 else
903 {
Roland McGrath3712b282005-08-23 05:58:42 +0000904 mod->symxndxdata = elf_getdata (xndxscn, NULL);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000905 if (mod->symxndxdata == NULL)
906 goto elferr;
907 }
908
Roland McGrath3712b282005-08-23 05:58:42 +0000909 mod->symdata = elf_getdata (symscn, NULL);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000910 if (mod->symdata == NULL)
911 goto elferr;
912}
913
914
Roland McGrath994b4892005-12-05 22:46:21 +0000915/* Try to open a libebl backend for MOD. */
916Dwfl_Error
Ulrich Drepper077c65f2006-07-12 19:54:51 +0000917internal_function
Roland McGrath994b4892005-12-05 22:46:21 +0000918__libdwfl_module_getebl (Dwfl_Module *mod)
919{
920 if (mod->ebl == NULL)
921 {
Roland McGratha605a3c2009-04-19 18:27:01 -0700922 __libdwfl_getelf (mod);
Roland McGrath994b4892005-12-05 22:46:21 +0000923 if (mod->elferr != DWFL_E_NOERROR)
924 return mod->elferr;
925
926 mod->ebl = ebl_openbackend (mod->main.elf);
927 if (mod->ebl == NULL)
928 return DWFL_E_LIBEBL;
929 }
930 return DWFL_E_NOERROR;
931}
932
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000933/* Try to start up libdw on DEBUGFILE. */
934static Dwfl_Error
Roland McGrathd17fac72005-08-23 08:20:21 +0000935load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000936{
Roland McGrath059c83e2008-02-21 06:19:39 +0000937 if (mod->e_type == ET_REL && !debugfile->relocated)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000938 {
939 const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
940
941 /* The debugging sections have to be relocated. */
942 if (cb->section_address == NULL)
943 return DWFL_E_NOREL;
944
Roland McGrath994b4892005-12-05 22:46:21 +0000945 Dwfl_Error error = __libdwfl_module_getebl (mod);
946 if (error != DWFL_E_NOERROR)
947 return error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000948
949 find_symtab (mod);
950 Dwfl_Error result = mod->symerr;
951 if (result == DWFL_E_NOERROR)
Roland McGrathe4c22ea2007-10-23 13:07:39 +0000952 result = __libdwfl_relocate (mod, debugfile->elf, true);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000953 if (result != DWFL_E_NOERROR)
954 return result;
Roland McGrathd17fac72005-08-23 08:20:21 +0000955
956 /* Don't keep the file descriptors around. */
957 if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
958 {
959 close (mod->main.fd);
960 mod->main.fd = -1;
961 }
962 if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0)
963 {
964 close (debugfile->fd);
965 debugfile->fd = -1;
966 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000967 }
968
Roland McGrathd17fac72005-08-23 08:20:21 +0000969 mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000970 if (mod->dw == NULL)
971 {
Roland McGrath4959bf82005-08-09 10:31:08 +0000972 int err = INTUSE(dwarf_errno) ();
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000973 return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
974 }
975
976 /* Until we have iterated through all CU's, we might do lazy lookups. */
977 mod->lazycu = 1;
978
979 return DWFL_E_NOERROR;
980}
981
982/* Try to start up libdw on either the main file or the debuginfo file. */
983static void
984find_dw (Dwfl_Module *mod)
985{
986 if (mod->dw != NULL /* Already done. */
987 || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure. */
988 return;
989
Roland McGratha605a3c2009-04-19 18:27:01 -0700990 __libdwfl_getelf (mod);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000991 mod->dwerr = mod->elferr;
992 if (mod->dwerr != DWFL_E_NOERROR)
993 return;
994
995 /* First see if the main ELF file has the debugging information. */
Roland McGrathd17fac72005-08-23 08:20:21 +0000996 mod->dwerr = load_dw (mod, &mod->main);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000997 switch (mod->dwerr)
998 {
999 case DWFL_E_NOERROR:
1000 mod->debug.elf = mod->main.elf;
Roland McGrath1743d7f2010-11-12 16:46:47 -08001001 mod->debug.address_sync = mod->main.address_sync;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001002 return;
1003
1004 case DWFL_E_NO_DWARF:
1005 break;
1006
1007 default:
1008 goto canonicalize;
1009 }
1010
1011 /* Now we have to look for a separate debuginfo file. */
1012 mod->dwerr = find_debuginfo (mod);
1013 switch (mod->dwerr)
1014 {
1015 case DWFL_E_NOERROR:
Roland McGrathd17fac72005-08-23 08:20:21 +00001016 mod->dwerr = load_dw (mod, &mod->debug);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001017 break;
1018
1019 case DWFL_E_CB: /* The find_debuginfo hook failed. */
1020 mod->dwerr = DWFL_E_NO_DWARF;
1021 return;
1022
1023 default:
1024 break;
1025 }
1026
1027 canonicalize:
1028 mod->dwerr = __libdwfl_canon_error (mod->dwerr);
1029}
1030
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001031Dwarf *
1032dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
1033{
1034 if (mod == NULL)
1035 return NULL;
1036
1037 find_dw (mod);
1038 if (mod->dwerr == DWFL_E_NOERROR)
1039 {
Roland McGrathe4c22ea2007-10-23 13:07:39 +00001040 /* If dwfl_module_getelf was used previously, then partial apply
1041 relocation to miscellaneous sections in the debug file too. */
1042 if (mod->e_type == ET_REL
1043 && mod->main.relocated && ! mod->debug.relocated)
1044 {
1045 mod->debug.relocated = true;
1046 if (mod->debug.elf != mod->main.elf)
1047 (void) __libdwfl_relocate (mod, mod->debug.elf, false);
1048 }
1049
Roland McGrath1743d7f2010-11-12 16:46:47 -08001050 *bias = dwfl_adjusted_dwarf_addr (mod, 0);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001051 return mod->dw;
1052 }
1053
1054 __libdwfl_seterrno (mod->dwerr);
1055 return NULL;
1056}
1057INTDEF (dwfl_module_getdwarf)
1058
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001059int
1060dwfl_module_getsymtab (Dwfl_Module *mod)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001061{
1062 if (mod == NULL)
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001063 return -1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001064
1065 find_symtab (mod);
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001066 if (mod->symerr == DWFL_E_NOERROR)
1067 return mod->syments;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001068
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001069 __libdwfl_seterrno (mod->symerr);
1070 return -1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001071}
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001072INTDEF (dwfl_module_getsymtab)