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 /* No adjustment needed for section zero, it is never loaded.
42 Handle it first, just in case the ELF file has strange section
45 return DWFL_E_NOERROR;
47 Elf_Scn *refscn = elf_getscn (elf, shndx);
48 GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
52 if (refshdr->sh_addr == 0 && (refshdr->sh_flags & SHF_ALLOC))
54 /* This is a loaded section. Find its actual
55 address and update the section header. */
57 if (*shstrndx == SHN_UNDEF
58 && unlikely (elf_getshdrstrndx (elf, shstrndx) < 0))
61 const char *name = elf_strptr (elf, *shstrndx, refshdr->sh_name);
62 if (unlikely (name == NULL))
65 if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod),
70 if (refshdr->sh_addr == (Dwarf_Addr) -1l)
71 /* The callback indicated this section wasn't really loaded but we
73 refshdr->sh_addr = 0; /* Make no adjustment below. */
75 /* Update the in-core file's section header to show the final
76 load address (or unloadedness). This serves as a cache,
77 so we won't get here again for the same section. */
78 if (likely (refshdr->sh_addr != 0)
79 && unlikely (! gelf_update_shdr (refscn, refshdr)))
83 if (refshdr->sh_flags & SHF_ALLOC)
84 /* Apply the adjustment. */
85 *value += dwfl_adjusted_address (mod, refshdr->sh_addr);
87 return DWFL_E_NOERROR;
91 /* Cache used by relocate_getsym. */
92 struct reloc_symtab_cache
96 Elf_Data *symxndxdata;
101 #define RELOC_SYMTAB_CACHE(cache) \
102 struct reloc_symtab_cache cache = \
103 { NULL, NULL, NULL, NULL, SHN_UNDEF, SHN_UNDEF }
105 /* This is just doing dwfl_module_getsym, except that we must always use
106 the symbol table in RELOCATED itself when it has one, not MOD->symfile. */
108 relocate_getsym (Dwfl_Module *mod,
109 Elf *relocated, struct reloc_symtab_cache *cache,
110 int symndx, GElf_Sym *sym, GElf_Word *shndx)
112 if (cache->symdata == NULL)
114 if (mod->symfile == NULL || mod->symfile->elf != relocated)
116 /* We have to look up the symbol table in the file we are
117 relocating, if it has its own. These reloc sections refer to
118 the symbol table in this file, and a symbol table in the main
119 file might not match. However, some tools did produce ET_REL
120 .debug files with relocs but no symtab of their own. */
122 while ((scn = elf_nextscn (relocated, scn)) != NULL)
124 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
127 /* We need uncompressed data. */
128 if ((shdr->sh_type == SHT_SYMTAB
129 || shdr->sh_type == SHT_SYMTAB_SHNDX)
130 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
131 if (elf_compress (scn, 0, 0) < 0)
132 return DWFL_E_LIBELF;
134 switch (shdr->sh_type)
139 cache->symelf = relocated;
140 cache->symdata = elf_getdata (scn, NULL);
141 cache->strtabndx = shdr->sh_link;
142 if (unlikely (cache->symdata == NULL))
143 return DWFL_E_LIBELF;
145 case SHT_SYMTAB_SHNDX:
146 cache->symxndxdata = elf_getdata (scn, NULL);
147 if (unlikely (cache->symxndxdata == NULL))
148 return DWFL_E_LIBELF;
152 if (cache->symdata != NULL && cache->symxndxdata != NULL)
156 if (cache->symdata == NULL)
158 /* We might not have looked for a symbol table file yet,
159 when coming from __libdwfl_relocate_section. */
160 if (unlikely (mod->symfile == NULL)
161 && unlikely (INTUSE(dwfl_module_getsymtab) (mod) < 0))
162 return dwfl_errno ();
164 /* The symbol table we have already cached is the one from
165 the file being relocated, so it's what we need. Or else
166 this is an ET_REL .debug file with no .symtab of its own;
167 the symbols refer to the section indices in the main file. */
168 cache->symelf = mod->symfile->elf;
169 cache->symdata = mod->symdata;
170 cache->symxndxdata = mod->symxndxdata;
171 cache->symstrdata = mod->symstrdata;
175 if (unlikely (gelf_getsymshndx (cache->symdata, cache->symxndxdata,
176 symndx, sym, shndx) == NULL))
177 return DWFL_E_LIBELF;
179 if (sym->st_shndx != SHN_XINDEX)
180 *shndx = sym->st_shndx;
182 switch (sym->st_shndx)
186 return DWFL_E_NOERROR;
189 sym->st_value = 0; /* Value is size, not helpful. */
190 return DWFL_E_NOERROR;
193 return __libdwfl_relocate_value (mod, cache->symelf, &cache->symshstrndx,
194 *shndx, &sym->st_value);
197 /* Handle an undefined symbol. We really only support ET_REL for Linux
198 kernel modules, and offline archives. The behavior of the Linux module
199 loader is very simple and easy to mimic. It only matches magically
200 exported symbols, and we match any defined symbols. But we get the same
201 answer except when the module's symbols are undefined and would prevent
202 it from being loaded. */
204 resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab,
205 GElf_Sym *sym, GElf_Word shndx)
207 /* First we need its name. */
208 if (sym->st_name != 0)
210 if (symtab->symstrdata == NULL)
212 /* Cache the strtab for this symtab. */
213 assert (referer->symfile == NULL
214 || referer->symfile->elf != symtab->symelf);
216 Elf_Scn *scn = elf_getscn (symtab->symelf, symtab->strtabndx);
218 return DWFL_E_LIBELF;
221 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
223 return DWFL_E_LIBELF;
225 if (symtab->symshstrndx == SHN_UNDEF
226 && elf_getshdrstrndx (symtab->symelf, &symtab->symshstrndx) < 0)
227 return DWFL_E_LIBELF;
229 const char *sname = elf_strptr (symtab->symelf, symtab->symshstrndx,
232 return DWFL_E_LIBELF;
234 /* If the section is already decompressed, that isn't an error. */
235 if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
236 elf_compress_gnu (scn, 0, 0);
238 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
239 if (elf_compress (scn, 0, 0) < 0)
240 return DWFL_E_LIBELF;
242 symtab->symstrdata = elf_getdata (scn, NULL);
243 if (unlikely (symtab->symstrdata == NULL
244 || symtab->symstrdata->d_buf == NULL))
245 return DWFL_E_LIBELF;
247 if (unlikely (sym->st_name >= symtab->symstrdata->d_size))
248 return DWFL_E_BADSTROFF;
250 const char *name = symtab->symstrdata->d_buf;
251 name += sym->st_name;
253 for (Dwfl_Module *m = referer->dwfl->modulelist; m != NULL; m = m->next)
256 /* Get this module's symtab.
257 If we got a fresh error reading the table, report it.
258 If we just have no symbols in this module, no harm done. */
259 if (m->symdata == NULL
260 && m->symerr == DWFL_E_NOERROR
261 && INTUSE(dwfl_module_getsymtab) (m) < 0
262 && m->symerr != DWFL_E_NO_SYMTAB)
265 for (size_t ndx = 1; ndx < m->syments; ++ndx)
267 sym = gelf_getsymshndx (m->symdata, m->symxndxdata,
269 if (unlikely (sym == NULL))
270 return DWFL_E_LIBELF;
271 if (sym->st_shndx != SHN_XINDEX)
272 shndx = sym->st_shndx;
274 /* We are looking for a defined global symbol with a name. */
275 if (shndx == SHN_UNDEF || shndx == SHN_COMMON
276 || GELF_ST_BIND (sym->st_info) == STB_LOCAL
277 || sym->st_name == 0)
280 /* Get this candidate symbol's name. */
281 if (unlikely (sym->st_name >= m->symstrdata->d_size))
282 return DWFL_E_BADSTROFF;
283 const char *n = m->symstrdata->d_buf;
286 /* Does the name match? */
287 if (strcmp (name, n))
291 if (shndx == SHN_ABS) /* XXX maybe should apply bias? */
292 return DWFL_E_NOERROR;
294 if (m->e_type != ET_REL)
296 sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf,
298 return DWFL_E_NOERROR;
301 /* In an ET_REL file, the symbol table values are relative
302 to the section, not to the module's load base. */
303 size_t symshstrndx = SHN_UNDEF;
304 return __libdwfl_relocate_value (m, m->symfile->elf,
306 shndx, &sym->st_value);
311 return DWFL_E_RELUNDEF;
314 /* Apply one relocation. Returns true for any invalid data. */
316 relocate (Dwfl_Module * const mod,
317 Elf * const relocated,
318 struct reloc_symtab_cache * const reloc_symtab,
319 Elf_Data * const tdata,
320 const GElf_Ehdr * const ehdr,
322 const GElf_Sxword *addend,
326 /* First see if this is a reloc we can handle.
327 If we are skipping it, don't bother resolving the symbol. */
329 if (unlikely (rtype == 0))
330 /* In some odd situations, the linker can leave R_*_NONE relocs
331 behind. This is probably bogus ld -r behavior, but the only
332 cases it's known to appear in are harmless: DWARF data
333 referring to addresses in a section that has been discarded.
334 So we just pretend it's OK without further relocation. */
335 return DWFL_E_NOERROR;
337 Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
338 if (unlikely (type == ELF_T_NUM))
339 return DWFL_E_BADRELTYPE;
341 /* First, resolve the symbol to an absolute value. */
344 if (symndx == STN_UNDEF)
345 /* When strip removes a section symbol referring to a
346 section moved into the debuginfo file, it replaces
347 that symbol index in relocs with STN_UNDEF. We
348 don't actually need the symbol, because those relocs
349 are always references relative to the nonallocated
350 debugging sections, which start at zero. */
356 Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab,
357 symndx, &sym, &shndx);
358 if (unlikely (error != DWFL_E_NOERROR))
361 if (shndx == SHN_UNDEF || shndx == SHN_COMMON)
363 /* Maybe we can figure it out anyway. */
364 error = resolve_symbol (mod, reloc_symtab, &sym, shndx);
365 if (error != DWFL_E_NOERROR
366 && !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON))
370 value = sym.st_value;
373 /* These are the types we can relocate. */
374 #define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \
375 DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \
376 DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
380 #define DO_TYPE(NAME, Name) \
382 size = sizeof (GElf_##Name); \
387 return DWFL_E_BADRELTYPE;
390 if (offset > tdata->d_size || tdata->d_size - offset < size)
391 return DWFL_E_BADRELOFF;
393 #define DO_TYPE(NAME, Name) GElf_##Name Name;
394 union { TYPES; } tmpbuf;
401 .d_version = EV_CURRENT,
406 .d_buf = tdata->d_buf + offset,
408 .d_version = EV_CURRENT,
411 /* XXX check for overflow? */
414 /* For the addend form, we have the value already. */
418 #define DO_TYPE(NAME, Name) \
420 tmpbuf.Name = value; \
430 /* Extract the original value and apply the reloc. */
431 Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
432 ehdr->e_ident[EI_DATA]);
434 return DWFL_E_LIBELF;
435 assert (d == &tmpdata);
438 #define DO_TYPE(NAME, Name) \
440 tmpbuf.Name += (GElf_##Name) value; \
449 /* Now convert the relocated datum back to the target
450 format. This will write into rdata.d_buf, which
451 points into the raw section data being relocated. */
452 Elf_Data *s = gelf_xlatetof (relocated, &rdata, &tmpdata,
453 ehdr->e_ident[EI_DATA]);
455 return DWFL_E_LIBELF;
456 assert (s == &rdata);
458 /* We have applied this relocation! */
459 return DWFL_E_NOERROR;
463 check_badreltype (bool *first_badreltype,
467 if (*first_badreltype)
469 *first_badreltype = false;
470 if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
471 /* This might be because ebl_openbackend failed to find
472 any libebl_CPU.so library. Diagnose that clearly. */
473 *result = DWFL_E_UNKNOWN_MACHINE;
478 relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
479 size_t shstrndx, struct reloc_symtab_cache *reloc_symtab,
480 Elf_Scn *scn, GElf_Shdr *shdr,
481 Elf_Scn *tscn, bool debugscn, bool partial)
483 /* First, fetch the name of the section these relocations apply to.
484 Then try to decompress both relocation and target section. */
486 GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
488 return DWFL_E_LIBELF;
490 const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name);
492 return DWFL_E_LIBELF;
494 if (debugscn && ! ebl_debugscn_p (mod->ebl, tname))
495 /* This relocation section is not for a debugging section.
496 Nothing to do here. */
497 return DWFL_E_NOERROR;
499 if (strncmp (tname, ".zdebug", strlen ("zdebug")) == 0)
500 elf_compress_gnu (tscn, 0, 0);
502 if ((tshdr->sh_flags & SHF_COMPRESSED) != 0)
503 if (elf_compress (tscn, 0, 0) < 0)
504 return DWFL_E_LIBELF;
506 /* Reload Shdr in case section was just decompressed. */
507 tshdr = gelf_getshdr (tscn, &tshdr_mem);
509 return DWFL_E_LIBELF;
511 if (unlikely (tshdr->sh_type == SHT_NOBITS)
512 || unlikely (tshdr->sh_size == 0))
513 /* No contents to relocate. */
514 return DWFL_E_NOERROR;
516 const char *sname = elf_strptr (relocated, shstrndx, shdr->sh_name);
518 return DWFL_E_LIBELF;
520 if (strncmp (sname, ".zdebug", strlen ("zdebug")) == 0)
521 elf_compress_gnu (scn, 0, 0);
523 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
524 if (elf_compress (scn, 0, 0) < 0)
525 return DWFL_E_LIBELF;
527 /* Reload Shdr in case section was just decompressed. */
529 shdr = gelf_getshdr (scn, &shdr_mem);
531 return DWFL_E_LIBELF;
533 /* Fetch the section data that needs the relocations applied. */
534 Elf_Data *tdata = elf_rawdata (tscn, NULL);
536 return DWFL_E_LIBELF;
538 /* If either the section that needs the relocation applied, or the
539 section that the relocations come from overlap one of the ehdrs,
540 shdrs or phdrs data then we refuse to do the relocations. It
541 isn't illegal for ELF section data to overlap the header data,
542 but updating the (relocation) data might corrupt the in-memory
543 libelf headers causing strange corruptions or errors. */
544 size_t ehsize = gelf_fsize (relocated, ELF_T_EHDR, 1, EV_CURRENT);
545 if (unlikely (shdr->sh_offset < ehsize
546 || tshdr->sh_offset < ehsize))
547 return DWFL_E_BADELF;
549 GElf_Off shdrs_start = ehdr->e_shoff;
551 if (elf_getshdrnum (relocated, &shnums) < 0)
552 return DWFL_E_LIBELF;
553 /* Overflows will have been checked by elf_getshdrnum/get|rawdata. */
554 size_t shentsize = gelf_fsize (relocated, ELF_T_SHDR, 1, EV_CURRENT);
555 GElf_Off shdrs_end = shdrs_start + shnums * shentsize;
556 if (unlikely ((shdrs_start < shdr->sh_offset + shdr->sh_size
557 && shdr->sh_offset < shdrs_end)
558 || (shdrs_start < tshdr->sh_offset + tshdr->sh_size
559 && tshdr->sh_offset < shdrs_end)))
560 return DWFL_E_BADELF;
562 GElf_Off phdrs_start = ehdr->e_phoff;
564 if (elf_getphdrnum (relocated, &phnums) < 0)
565 return DWFL_E_LIBELF;
566 if (phdrs_start != 0 && phnums != 0)
568 /* Overflows will have been checked by elf_getphdrnum/get|rawdata. */
569 size_t phentsize = gelf_fsize (relocated, ELF_T_PHDR, 1, EV_CURRENT);
570 GElf_Off phdrs_end = phdrs_start + phnums * phentsize;
571 if (unlikely ((phdrs_start < shdr->sh_offset + shdr->sh_size
572 && shdr->sh_offset < phdrs_end)
573 || (phdrs_start < tshdr->sh_offset + tshdr->sh_size
574 && tshdr->sh_offset < phdrs_end)))
575 return DWFL_E_BADELF;
578 /* Fetch the relocation section and apply each reloc in it. */
579 Elf_Data *reldata = elf_getdata (scn, NULL);
581 return DWFL_E_LIBELF;
583 Dwfl_Error result = DWFL_E_NOERROR;
584 bool first_badreltype = true;
587 = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
589 size_t nrels = shdr->sh_size / sh_entsize;
591 if (shdr->sh_type == SHT_REL)
592 for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
594 GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem);
596 return DWFL_E_LIBELF;
597 result = relocate (mod, relocated, reloc_symtab, tdata, ehdr,
599 GELF_R_TYPE (r->r_info),
600 GELF_R_SYM (r->r_info));
601 check_badreltype (&first_badreltype, mod, &result);
606 /* We applied the relocation. Elide it. */
607 memset (&rel_mem, 0, sizeof rel_mem);
608 gelf_update_rel (reldata, relidx, &rel_mem);
611 case DWFL_E_BADRELTYPE:
612 case DWFL_E_RELUNDEF:
613 /* We couldn't handle this relocation. Skip it. */
614 result = DWFL_E_NOERROR;
621 for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
623 GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx,
626 return DWFL_E_LIBELF;
627 result = relocate (mod, relocated, reloc_symtab, tdata, ehdr,
628 r->r_offset, &r->r_addend,
629 GELF_R_TYPE (r->r_info),
630 GELF_R_SYM (r->r_info));
631 check_badreltype (&first_badreltype, mod, &result);
636 /* We applied the relocation. Elide it. */
637 memset (&rela_mem, 0, sizeof rela_mem);
638 gelf_update_rela (reldata, relidx, &rela_mem);
641 case DWFL_E_BADRELTYPE:
642 case DWFL_E_RELUNDEF:
643 /* We couldn't handle this relocation. Skip it. */
644 result = DWFL_E_NOERROR;
651 if (likely (result == DWFL_E_NOERROR))
653 if (!partial || complete == nrels)
654 /* Mark this relocation section as being empty now that we have
655 done its work. This affects unstrip -R, so e.g. it emits an
656 empty .rela.debug_info along with a .debug_info that has
657 already been fully relocated. */
659 else if (complete != 0)
661 /* We handled some of the relocations but not all.
662 We've zeroed out the ones we processed.
663 Now remove them from the section. */
666 if (shdr->sh_type == SHT_REL)
667 for (size_t relidx = 0; relidx < nrels; ++relidx)
670 GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
671 if (r->r_info != 0 || r->r_offset != 0)
674 gelf_update_rel (reldata, next, r);
679 for (size_t relidx = 0; relidx < nrels; ++relidx)
682 GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
683 if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0)
686 gelf_update_rela (reldata, next, r);
693 shdr->sh_size = reldata->d_size = nrels * sh_entsize;
694 gelf_update_shdr (scn, shdr);
702 __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
704 assert (mod->e_type == ET_REL);
707 const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
709 return DWFL_E_LIBELF;
712 if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0)
713 return DWFL_E_LIBELF;
715 RELOC_SYMTAB_CACHE (reloc_symtab);
717 /* Look at each section in the debuginfo file, and process the
718 relocation sections for debugging sections. */
719 Dwfl_Error result = DWFL_E_NOERROR;
721 while (result == DWFL_E_NOERROR
722 && (scn = elf_nextscn (debugfile, scn)) != NULL)
725 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
727 if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
728 && shdr->sh_size != 0)
730 /* It's a relocation section. */
732 Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
733 if (unlikely (tscn == NULL))
734 result = DWFL_E_LIBELF;
736 result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
737 &reloc_symtab, scn, shdr, tscn,
747 __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
748 Elf_Scn *relocscn, Elf_Scn *tscn, bool partial)
753 RELOC_SYMTAB_CACHE (reloc_symtab);
756 if (elf_getshdrstrndx (relocated, &shstrndx) < 0)
757 return DWFL_E_LIBELF;
759 return (__libdwfl_module_getebl (mod)
760 ?: relocate_section (mod, relocated,
761 gelf_getehdr (relocated, &ehdr_mem), shstrndx,
763 relocscn, gelf_getshdr (relocscn, &shdr_mem),
764 tscn, false, partial));