1 /* Relocate debug information.
2 Copyright (C) 2005-2011, 2014 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * 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
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
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 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.
25 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/>. */
31 typedef uint8_t GElf_Byte;
33 /* Adjust *VALUE to add the load address of the SHNDX section.
34 We update the section header in place to cache the result. */
38 __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
39 Elf32_Word shndx, GElf_Addr *value)
41 Elf_Scn *refscn = elf_getscn (elf, shndx);
42 GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
46 if (refshdr->sh_addr == 0 && (refshdr->sh_flags & SHF_ALLOC))
48 /* This is a loaded section. Find its actual
49 address and update the section header. */
51 if (*shstrndx == SHN_UNDEF
52 && unlikely (elf_getshdrstrndx (elf, shstrndx) < 0))
55 const char *name = elf_strptr (elf, *shstrndx, refshdr->sh_name);
56 if (unlikely (name == NULL))
59 if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod),
64 if (refshdr->sh_addr == (Dwarf_Addr) -1l)
65 /* The callback indicated this section wasn't really loaded but we
67 refshdr->sh_addr = 0; /* Make no adjustment below. */
69 /* Update the in-core file's section header to show the final
70 load address (or unloadedness). This serves as a cache,
71 so we won't get here again for the same section. */
72 if (likely (refshdr->sh_addr != 0)
73 && unlikely (! gelf_update_shdr (refscn, refshdr)))
77 if (refshdr->sh_flags & SHF_ALLOC)
78 /* Apply the adjustment. */
79 *value += dwfl_adjusted_address (mod, refshdr->sh_addr);
81 return DWFL_E_NOERROR;
85 /* Cache used by relocate_getsym. */
86 struct reloc_symtab_cache
90 Elf_Data *symxndxdata;
95 #define RELOC_SYMTAB_CACHE(cache) \
96 struct reloc_symtab_cache cache = \
97 { NULL, NULL, NULL, NULL, SHN_UNDEF, SHN_UNDEF }
99 /* This is just doing dwfl_module_getsym, except that we must always use
100 the symbol table in RELOCATED itself when it has one, not MOD->symfile. */
102 relocate_getsym (Dwfl_Module *mod,
103 Elf *relocated, struct reloc_symtab_cache *cache,
104 int symndx, GElf_Sym *sym, GElf_Word *shndx)
106 if (cache->symdata == NULL)
108 if (mod->symfile == NULL || mod->symfile->elf != relocated)
110 /* We have to look up the symbol table in the file we are
111 relocating, if it has its own. These reloc sections refer to
112 the symbol table in this file, and a symbol table in the main
113 file might not match. However, some tools did produce ET_REL
114 .debug files with relocs but no symtab of their own. */
116 while ((scn = elf_nextscn (relocated, scn)) != NULL)
118 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
120 switch (shdr->sh_type)
125 cache->symelf = relocated;
126 cache->symdata = elf_getdata (scn, NULL);
127 cache->strtabndx = shdr->sh_link;
128 if (unlikely (cache->symdata == NULL))
129 return DWFL_E_LIBELF;
131 case SHT_SYMTAB_SHNDX:
132 cache->symxndxdata = elf_getdata (scn, NULL);
133 if (unlikely (cache->symxndxdata == NULL))
134 return DWFL_E_LIBELF;
137 if (cache->symdata != NULL && cache->symxndxdata != NULL)
141 if (cache->symdata == NULL)
143 /* We might not have looked for a symbol table file yet,
144 when coming from __libdwfl_relocate_section. */
145 if (unlikely (mod->symfile == NULL)
146 && unlikely (INTUSE(dwfl_module_getsymtab) (mod) < 0))
147 return dwfl_errno ();
149 /* The symbol table we have already cached is the one from
150 the file being relocated, so it's what we need. Or else
151 this is an ET_REL .debug file with no .symtab of its own;
152 the symbols refer to the section indices in the main file. */
153 cache->symelf = mod->symfile->elf;
154 cache->symdata = mod->symdata;
155 cache->symxndxdata = mod->symxndxdata;
156 cache->symstrdata = mod->symstrdata;
160 if (unlikely (gelf_getsymshndx (cache->symdata, cache->symxndxdata,
161 symndx, sym, shndx) == NULL))
162 return DWFL_E_LIBELF;
164 if (sym->st_shndx != SHN_XINDEX)
165 *shndx = sym->st_shndx;
167 switch (sym->st_shndx)
171 return DWFL_E_NOERROR;
174 sym->st_value = 0; /* Value is size, not helpful. */
175 return DWFL_E_NOERROR;
178 return __libdwfl_relocate_value (mod, cache->symelf, &cache->symshstrndx,
179 *shndx, &sym->st_value);
182 /* Handle an undefined symbol. We really only support ET_REL for Linux
183 kernel modules, and offline archives. The behavior of the Linux module
184 loader is very simple and easy to mimic. It only matches magically
185 exported symbols, and we match any defined symbols. But we get the same
186 answer except when the module's symbols are undefined and would prevent
187 it from being loaded. */
189 resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab,
190 GElf_Sym *sym, GElf_Word shndx)
192 /* First we need its name. */
193 if (sym->st_name != 0)
195 if (symtab->symstrdata == NULL)
197 /* Cache the strtab for this symtab. */
198 assert (referer->symfile == NULL
199 || referer->symfile->elf != symtab->symelf);
200 symtab->symstrdata = elf_getdata (elf_getscn (symtab->symelf,
203 if (unlikely (symtab->symstrdata == NULL))
204 return DWFL_E_LIBELF;
206 if (unlikely (sym->st_name >= symtab->symstrdata->d_size))
207 return DWFL_E_BADSTROFF;
209 const char *name = symtab->symstrdata->d_buf;
210 name += sym->st_name;
212 for (Dwfl_Module *m = referer->dwfl->modulelist; m != NULL; m = m->next)
215 /* Get this module's symtab.
216 If we got a fresh error reading the table, report it.
217 If we just have no symbols in this module, no harm done. */
218 if (m->symdata == NULL
219 && m->symerr == DWFL_E_NOERROR
220 && INTUSE(dwfl_module_getsymtab) (m) < 0
221 && m->symerr != DWFL_E_NO_SYMTAB)
224 for (size_t ndx = 1; ndx < m->syments; ++ndx)
226 sym = gelf_getsymshndx (m->symdata, m->symxndxdata,
228 if (unlikely (sym == NULL))
229 return DWFL_E_LIBELF;
230 if (sym->st_shndx != SHN_XINDEX)
231 shndx = sym->st_shndx;
233 /* We are looking for a defined global symbol with a name. */
234 if (shndx == SHN_UNDEF || shndx == SHN_COMMON
235 || GELF_ST_BIND (sym->st_info) == STB_LOCAL
236 || sym->st_name == 0)
239 /* Get this candidate symbol's name. */
240 if (unlikely (sym->st_name >= m->symstrdata->d_size))
241 return DWFL_E_BADSTROFF;
242 const char *n = m->symstrdata->d_buf;
245 /* Does the name match? */
246 if (strcmp (name, n))
250 if (shndx == SHN_ABS) /* XXX maybe should apply bias? */
251 return DWFL_E_NOERROR;
253 if (m->e_type != ET_REL)
255 sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf,
257 return DWFL_E_NOERROR;
260 /* In an ET_REL file, the symbol table values are relative
261 to the section, not to the module's load base. */
262 size_t symshstrndx = SHN_UNDEF;
263 return __libdwfl_relocate_value (m, m->symfile->elf,
265 shndx, &sym->st_value);
270 return DWFL_E_RELUNDEF;
274 relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
275 size_t shstrndx, struct reloc_symtab_cache *reloc_symtab,
276 Elf_Scn *scn, GElf_Shdr *shdr,
277 Elf_Scn *tscn, bool debugscn, bool partial)
279 /* First, fetch the name of the section these relocations apply to. */
281 GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
282 const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name);
284 return DWFL_E_LIBELF;
286 if (unlikely (tshdr->sh_type == SHT_NOBITS) || unlikely (tshdr->sh_size == 0))
287 /* No contents to relocate. */
288 return DWFL_E_NOERROR;
290 if (debugscn && ! ebl_debugscn_p (mod->ebl, tname))
291 /* This relocation section is not for a debugging section.
292 Nothing to do here. */
293 return DWFL_E_NOERROR;
295 /* Fetch the section data that needs the relocations applied. */
296 Elf_Data *tdata = elf_rawdata (tscn, NULL);
298 return DWFL_E_LIBELF;
300 /* Apply one relocation. Returns true for any invalid data. */
301 Dwfl_Error relocate (GElf_Addr offset, const GElf_Sxword *addend,
302 int rtype, int symndx)
304 /* First see if this is a reloc we can handle.
305 If we are skipping it, don't bother resolving the symbol. */
307 if (unlikely (rtype == 0))
308 /* In some odd situations, the linker can leave R_*_NONE relocs
309 behind. This is probably bogus ld -r behavior, but the only
310 cases it's known to appear in are harmless: DWARF data
311 referring to addresses in a section that has been discarded.
312 So we just pretend it's OK without further relocation. */
313 return DWFL_E_NOERROR;
315 Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
316 if (unlikely (type == ELF_T_NUM))
317 return DWFL_E_BADRELTYPE;
319 /* First, resolve the symbol to an absolute value. */
322 if (symndx == STN_UNDEF)
323 /* When strip removes a section symbol referring to a
324 section moved into the debuginfo file, it replaces
325 that symbol index in relocs with STN_UNDEF. We
326 don't actually need the symbol, because those relocs
327 are always references relative to the nonallocated
328 debugging sections, which start at zero. */
334 Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab,
335 symndx, &sym, &shndx);
336 if (unlikely (error != DWFL_E_NOERROR))
339 if (shndx == SHN_UNDEF || shndx == SHN_COMMON)
341 /* Maybe we can figure it out anyway. */
342 error = resolve_symbol (mod, reloc_symtab, &sym, shndx);
343 if (error != DWFL_E_NOERROR
344 && !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON))
348 value = sym.st_value;
351 /* These are the types we can relocate. */
352 #define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \
353 DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \
354 DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
358 #define DO_TYPE(NAME, Name) \
360 size = sizeof (GElf_##Name); \
365 return DWFL_E_BADRELTYPE;
368 if (offset + size > tdata->d_size)
369 return DWFL_E_BADRELOFF;
371 #define DO_TYPE(NAME, Name) GElf_##Name Name;
372 union { TYPES; } tmpbuf;
379 .d_version = EV_CURRENT,
384 .d_buf = tdata->d_buf + offset,
386 .d_version = EV_CURRENT,
389 /* XXX check for overflow? */
392 /* For the addend form, we have the value already. */
396 #define DO_TYPE(NAME, Name) \
398 tmpbuf.Name = value; \
408 /* Extract the original value and apply the reloc. */
409 Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
410 ehdr->e_ident[EI_DATA]);
412 return DWFL_E_LIBELF;
413 assert (d == &tmpdata);
416 #define DO_TYPE(NAME, Name) \
418 tmpbuf.Name += (GElf_##Name) value; \
427 /* Now convert the relocated datum back to the target
428 format. This will write into rdata.d_buf, which
429 points into the raw section data being relocated. */
430 Elf_Data *s = gelf_xlatetof (relocated, &rdata, &tmpdata,
431 ehdr->e_ident[EI_DATA]);
433 return DWFL_E_LIBELF;
434 assert (s == &rdata);
436 /* We have applied this relocation! */
437 return DWFL_E_NOERROR;
440 /* Fetch the relocation section and apply each reloc in it. */
441 Elf_Data *reldata = elf_getdata (scn, NULL);
443 return DWFL_E_LIBELF;
445 Dwfl_Error result = DWFL_E_NOERROR;
446 bool first_badreltype = true;
447 inline void check_badreltype (void)
449 if (first_badreltype)
451 first_badreltype = false;
452 if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
453 /* This might be because ebl_openbackend failed to find
454 any libebl_CPU.so library. Diagnose that clearly. */
455 result = DWFL_E_UNKNOWN_MACHINE;
460 = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
462 size_t nrels = shdr->sh_size / sh_entsize;
464 if (shdr->sh_type == SHT_REL)
465 for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
467 GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem);
469 return DWFL_E_LIBELF;
470 result = relocate (r->r_offset, NULL,
471 GELF_R_TYPE (r->r_info),
472 GELF_R_SYM (r->r_info));
478 /* We applied the relocation. Elide it. */
479 memset (&rel_mem, 0, sizeof rel_mem);
480 gelf_update_rel (reldata, relidx, &rel_mem);
483 case DWFL_E_BADRELTYPE:
484 case DWFL_E_RELUNDEF:
485 /* We couldn't handle this relocation. Skip it. */
486 result = DWFL_E_NOERROR;
493 for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
495 GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx,
498 return DWFL_E_LIBELF;
499 result = relocate (r->r_offset, &r->r_addend,
500 GELF_R_TYPE (r->r_info),
501 GELF_R_SYM (r->r_info));
507 /* We applied the relocation. Elide it. */
508 memset (&rela_mem, 0, sizeof rela_mem);
509 gelf_update_rela (reldata, relidx, &rela_mem);
512 case DWFL_E_BADRELTYPE:
513 case DWFL_E_RELUNDEF:
514 /* We couldn't handle this relocation. Skip it. */
515 result = DWFL_E_NOERROR;
522 if (likely (result == DWFL_E_NOERROR))
524 if (!partial || complete == nrels)
525 /* Mark this relocation section as being empty now that we have
526 done its work. This affects unstrip -R, so e.g. it emits an
527 empty .rela.debug_info along with a .debug_info that has
528 already been fully relocated. */
530 else if (complete != 0)
532 /* We handled some of the relocations but not all.
533 We've zeroed out the ones we processed.
534 Now remove them from the section. */
537 if (shdr->sh_type == SHT_REL)
538 for (size_t relidx = 0; relidx < nrels; ++relidx)
541 GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
542 if (r->r_info != 0 || r->r_offset != 0)
545 gelf_update_rel (reldata, next, r);
550 for (size_t relidx = 0; relidx < nrels; ++relidx)
553 GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
554 if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0)
557 gelf_update_rela (reldata, next, r);
564 shdr->sh_size = reldata->d_size = nrels * sh_entsize;
565 gelf_update_shdr (scn, shdr);
573 __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
575 assert (mod->e_type == ET_REL);
578 const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
580 return DWFL_E_LIBELF;
583 if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0)
584 return DWFL_E_LIBELF;
586 RELOC_SYMTAB_CACHE (reloc_symtab);
588 /* Look at each section in the debuginfo file, and process the
589 relocation sections for debugging sections. */
590 Dwfl_Error result = DWFL_E_NOERROR;
592 while (result == DWFL_E_NOERROR
593 && (scn = elf_nextscn (debugfile, scn)) != NULL)
596 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
598 if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
599 && shdr->sh_size != 0)
601 /* It's a relocation section. */
603 Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
604 if (unlikely (tscn == NULL))
605 result = DWFL_E_LIBELF;
607 result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
608 &reloc_symtab, scn, shdr, tscn,
618 __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
619 Elf_Scn *relocscn, Elf_Scn *tscn, bool partial)
624 RELOC_SYMTAB_CACHE (reloc_symtab);
627 if (elf_getshdrstrndx (relocated, &shstrndx) < 0)
628 return DWFL_E_LIBELF;
630 return (__libdwfl_module_getebl (mod)
631 ?: relocate_section (mod, relocated,
632 gelf_getehdr (relocated, &ehdr_mem), shstrndx,
634 relocscn, gelf_getshdr (relocscn, &shdr_mem),
635 tscn, false, partial));