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);
126 switch (shdr->sh_type)
131 cache->symelf = relocated;
132 cache->symdata = elf_getdata (scn, NULL);
133 cache->strtabndx = shdr->sh_link;
134 if (unlikely (cache->symdata == NULL))
135 return DWFL_E_LIBELF;
137 case SHT_SYMTAB_SHNDX:
138 cache->symxndxdata = elf_getdata (scn, NULL);
139 if (unlikely (cache->symxndxdata == NULL))
140 return DWFL_E_LIBELF;
143 if (cache->symdata != NULL && cache->symxndxdata != NULL)
147 if (cache->symdata == NULL)
149 /* We might not have looked for a symbol table file yet,
150 when coming from __libdwfl_relocate_section. */
151 if (unlikely (mod->symfile == NULL)
152 && unlikely (INTUSE(dwfl_module_getsymtab) (mod) < 0))
153 return dwfl_errno ();
155 /* The symbol table we have already cached is the one from
156 the file being relocated, so it's what we need. Or else
157 this is an ET_REL .debug file with no .symtab of its own;
158 the symbols refer to the section indices in the main file. */
159 cache->symelf = mod->symfile->elf;
160 cache->symdata = mod->symdata;
161 cache->symxndxdata = mod->symxndxdata;
162 cache->symstrdata = mod->symstrdata;
166 if (unlikely (gelf_getsymshndx (cache->symdata, cache->symxndxdata,
167 symndx, sym, shndx) == NULL))
168 return DWFL_E_LIBELF;
170 if (sym->st_shndx != SHN_XINDEX)
171 *shndx = sym->st_shndx;
173 switch (sym->st_shndx)
177 return DWFL_E_NOERROR;
180 sym->st_value = 0; /* Value is size, not helpful. */
181 return DWFL_E_NOERROR;
184 return __libdwfl_relocate_value (mod, cache->symelf, &cache->symshstrndx,
185 *shndx, &sym->st_value);
188 /* Handle an undefined symbol. We really only support ET_REL for Linux
189 kernel modules, and offline archives. The behavior of the Linux module
190 loader is very simple and easy to mimic. It only matches magically
191 exported symbols, and we match any defined symbols. But we get the same
192 answer except when the module's symbols are undefined and would prevent
193 it from being loaded. */
195 resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab,
196 GElf_Sym *sym, GElf_Word shndx)
198 /* First we need its name. */
199 if (sym->st_name != 0)
201 if (symtab->symstrdata == NULL)
203 /* Cache the strtab for this symtab. */
204 assert (referer->symfile == NULL
205 || referer->symfile->elf != symtab->symelf);
206 symtab->symstrdata = elf_getdata (elf_getscn (symtab->symelf,
209 if (unlikely (symtab->symstrdata == NULL
210 || symtab->symstrdata->d_buf == NULL))
211 return DWFL_E_LIBELF;
213 if (unlikely (sym->st_name >= symtab->symstrdata->d_size))
214 return DWFL_E_BADSTROFF;
216 const char *name = symtab->symstrdata->d_buf;
217 name += sym->st_name;
219 for (Dwfl_Module *m = referer->dwfl->modulelist; m != NULL; m = m->next)
222 /* Get this module's symtab.
223 If we got a fresh error reading the table, report it.
224 If we just have no symbols in this module, no harm done. */
225 if (m->symdata == NULL
226 && m->symerr == DWFL_E_NOERROR
227 && INTUSE(dwfl_module_getsymtab) (m) < 0
228 && m->symerr != DWFL_E_NO_SYMTAB)
231 for (size_t ndx = 1; ndx < m->syments; ++ndx)
233 sym = gelf_getsymshndx (m->symdata, m->symxndxdata,
235 if (unlikely (sym == NULL))
236 return DWFL_E_LIBELF;
237 if (sym->st_shndx != SHN_XINDEX)
238 shndx = sym->st_shndx;
240 /* We are looking for a defined global symbol with a name. */
241 if (shndx == SHN_UNDEF || shndx == SHN_COMMON
242 || GELF_ST_BIND (sym->st_info) == STB_LOCAL
243 || sym->st_name == 0)
246 /* Get this candidate symbol's name. */
247 if (unlikely (sym->st_name >= m->symstrdata->d_size))
248 return DWFL_E_BADSTROFF;
249 const char *n = m->symstrdata->d_buf;
252 /* Does the name match? */
253 if (strcmp (name, n))
257 if (shndx == SHN_ABS) /* XXX maybe should apply bias? */
258 return DWFL_E_NOERROR;
260 if (m->e_type != ET_REL)
262 sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf,
264 return DWFL_E_NOERROR;
267 /* In an ET_REL file, the symbol table values are relative
268 to the section, not to the module's load base. */
269 size_t symshstrndx = SHN_UNDEF;
270 return __libdwfl_relocate_value (m, m->symfile->elf,
272 shndx, &sym->st_value);
277 return DWFL_E_RELUNDEF;
281 relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
282 size_t shstrndx, struct reloc_symtab_cache *reloc_symtab,
283 Elf_Scn *scn, GElf_Shdr *shdr,
284 Elf_Scn *tscn, bool debugscn, bool partial)
286 /* First, fetch the name of the section these relocations apply to. */
288 GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
289 const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name);
291 return DWFL_E_LIBELF;
293 if (unlikely (tshdr->sh_type == SHT_NOBITS) || unlikely (tshdr->sh_size == 0))
294 /* No contents to relocate. */
295 return DWFL_E_NOERROR;
297 if (debugscn && ! ebl_debugscn_p (mod->ebl, tname))
298 /* This relocation section is not for a debugging section.
299 Nothing to do here. */
300 return DWFL_E_NOERROR;
302 /* Fetch the section data that needs the relocations applied. */
303 Elf_Data *tdata = elf_rawdata (tscn, NULL);
305 return DWFL_E_LIBELF;
307 /* If either the section that needs the relocation applied, or the
308 section that the relocations come from overlap one of the ehdrs,
309 shdrs or phdrs data then we refuse to do the relocations. It
310 isn't illegal for ELF section data to overlap the header data,
311 but updating the (relocation) data might corrupt the in-memory
312 libelf headers causing strange corruptions or errors. */
313 size_t ehsize = gelf_fsize (relocated, ELF_T_EHDR, 1, EV_CURRENT);
314 if (unlikely (shdr->sh_offset < ehsize
315 || tshdr->sh_offset < ehsize))
316 return DWFL_E_BADELF;
318 GElf_Off shdrs_start = ehdr->e_shoff;
320 if (elf_getshdrnum (relocated, &shnums) < 0)
321 return DWFL_E_LIBELF;
322 /* Overflows will have been checked by elf_getshdrnum/get|rawdata. */
323 size_t shentsize = gelf_fsize (relocated, ELF_T_SHDR, 1, EV_CURRENT);
324 GElf_Off shdrs_end = shdrs_start + shnums * shentsize;
325 if (unlikely ((shdrs_start < shdr->sh_offset + shdr->sh_size
326 && shdr->sh_offset < shdrs_end)
327 || (shdrs_start < tshdr->sh_offset + tshdr->sh_size
328 && tshdr->sh_offset < shdrs_end)))
329 return DWFL_E_BADELF;
331 GElf_Off phdrs_start = ehdr->e_phoff;
333 if (elf_getphdrnum (relocated, &phnums) < 0)
334 return DWFL_E_LIBELF;
335 if (phdrs_start != 0 && phnums != 0)
337 /* Overflows will have been checked by elf_getphdrnum/get|rawdata. */
338 size_t phentsize = gelf_fsize (relocated, ELF_T_PHDR, 1, EV_CURRENT);
339 GElf_Off phdrs_end = phdrs_start + phnums * phentsize;
340 if (unlikely ((phdrs_start < shdr->sh_offset + shdr->sh_size
341 && shdr->sh_offset < phdrs_end)
342 || (phdrs_start < tshdr->sh_offset + tshdr->sh_size
343 && tshdr->sh_offset < phdrs_end)))
344 return DWFL_E_BADELF;
347 /* Apply one relocation. Returns true for any invalid data. */
348 Dwfl_Error relocate (GElf_Addr offset, const GElf_Sxword *addend,
349 int rtype, int symndx)
351 /* First see if this is a reloc we can handle.
352 If we are skipping it, don't bother resolving the symbol. */
354 if (unlikely (rtype == 0))
355 /* In some odd situations, the linker can leave R_*_NONE relocs
356 behind. This is probably bogus ld -r behavior, but the only
357 cases it's known to appear in are harmless: DWARF data
358 referring to addresses in a section that has been discarded.
359 So we just pretend it's OK without further relocation. */
360 return DWFL_E_NOERROR;
362 Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
363 if (unlikely (type == ELF_T_NUM))
364 return DWFL_E_BADRELTYPE;
366 /* First, resolve the symbol to an absolute value. */
369 if (symndx == STN_UNDEF)
370 /* When strip removes a section symbol referring to a
371 section moved into the debuginfo file, it replaces
372 that symbol index in relocs with STN_UNDEF. We
373 don't actually need the symbol, because those relocs
374 are always references relative to the nonallocated
375 debugging sections, which start at zero. */
381 Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab,
382 symndx, &sym, &shndx);
383 if (unlikely (error != DWFL_E_NOERROR))
386 if (shndx == SHN_UNDEF || shndx == SHN_COMMON)
388 /* Maybe we can figure it out anyway. */
389 error = resolve_symbol (mod, reloc_symtab, &sym, shndx);
390 if (error != DWFL_E_NOERROR
391 && !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON))
395 value = sym.st_value;
398 /* These are the types we can relocate. */
399 #define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \
400 DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \
401 DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
405 #define DO_TYPE(NAME, Name) \
407 size = sizeof (GElf_##Name); \
412 return DWFL_E_BADRELTYPE;
415 if (offset > tdata->d_size || tdata->d_size - offset < size)
416 return DWFL_E_BADRELOFF;
418 #define DO_TYPE(NAME, Name) GElf_##Name Name;
419 union { TYPES; } tmpbuf;
426 .d_version = EV_CURRENT,
431 .d_buf = tdata->d_buf + offset,
433 .d_version = EV_CURRENT,
436 /* XXX check for overflow? */
439 /* For the addend form, we have the value already. */
443 #define DO_TYPE(NAME, Name) \
445 tmpbuf.Name = value; \
455 /* Extract the original value and apply the reloc. */
456 Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
457 ehdr->e_ident[EI_DATA]);
459 return DWFL_E_LIBELF;
460 assert (d == &tmpdata);
463 #define DO_TYPE(NAME, Name) \
465 tmpbuf.Name += (GElf_##Name) value; \
474 /* Now convert the relocated datum back to the target
475 format. This will write into rdata.d_buf, which
476 points into the raw section data being relocated. */
477 Elf_Data *s = gelf_xlatetof (relocated, &rdata, &tmpdata,
478 ehdr->e_ident[EI_DATA]);
480 return DWFL_E_LIBELF;
481 assert (s == &rdata);
483 /* We have applied this relocation! */
484 return DWFL_E_NOERROR;
487 /* Fetch the relocation section and apply each reloc in it. */
488 Elf_Data *reldata = elf_getdata (scn, NULL);
490 return DWFL_E_LIBELF;
492 Dwfl_Error result = DWFL_E_NOERROR;
493 bool first_badreltype = true;
494 inline void check_badreltype (void)
496 if (first_badreltype)
498 first_badreltype = false;
499 if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
500 /* This might be because ebl_openbackend failed to find
501 any libebl_CPU.so library. Diagnose that clearly. */
502 result = DWFL_E_UNKNOWN_MACHINE;
507 = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
509 size_t nrels = shdr->sh_size / sh_entsize;
511 if (shdr->sh_type == SHT_REL)
512 for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
514 GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem);
516 return DWFL_E_LIBELF;
517 result = relocate (r->r_offset, NULL,
518 GELF_R_TYPE (r->r_info),
519 GELF_R_SYM (r->r_info));
525 /* We applied the relocation. Elide it. */
526 memset (&rel_mem, 0, sizeof rel_mem);
527 gelf_update_rel (reldata, relidx, &rel_mem);
530 case DWFL_E_BADRELTYPE:
531 case DWFL_E_RELUNDEF:
532 /* We couldn't handle this relocation. Skip it. */
533 result = DWFL_E_NOERROR;
540 for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
542 GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx,
545 return DWFL_E_LIBELF;
546 result = relocate (r->r_offset, &r->r_addend,
547 GELF_R_TYPE (r->r_info),
548 GELF_R_SYM (r->r_info));
554 /* We applied the relocation. Elide it. */
555 memset (&rela_mem, 0, sizeof rela_mem);
556 gelf_update_rela (reldata, relidx, &rela_mem);
559 case DWFL_E_BADRELTYPE:
560 case DWFL_E_RELUNDEF:
561 /* We couldn't handle this relocation. Skip it. */
562 result = DWFL_E_NOERROR;
569 if (likely (result == DWFL_E_NOERROR))
571 if (!partial || complete == nrels)
572 /* Mark this relocation section as being empty now that we have
573 done its work. This affects unstrip -R, so e.g. it emits an
574 empty .rela.debug_info along with a .debug_info that has
575 already been fully relocated. */
577 else if (complete != 0)
579 /* We handled some of the relocations but not all.
580 We've zeroed out the ones we processed.
581 Now remove them from the section. */
584 if (shdr->sh_type == SHT_REL)
585 for (size_t relidx = 0; relidx < nrels; ++relidx)
588 GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
589 if (r->r_info != 0 || r->r_offset != 0)
592 gelf_update_rel (reldata, next, r);
597 for (size_t relidx = 0; relidx < nrels; ++relidx)
600 GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
601 if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0)
604 gelf_update_rela (reldata, next, r);
611 shdr->sh_size = reldata->d_size = nrels * sh_entsize;
612 gelf_update_shdr (scn, shdr);
620 __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
622 assert (mod->e_type == ET_REL);
625 const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
627 return DWFL_E_LIBELF;
630 if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0)
631 return DWFL_E_LIBELF;
633 RELOC_SYMTAB_CACHE (reloc_symtab);
635 /* Look at each section in the debuginfo file, and process the
636 relocation sections for debugging sections. */
637 Dwfl_Error result = DWFL_E_NOERROR;
639 while (result == DWFL_E_NOERROR
640 && (scn = elf_nextscn (debugfile, scn)) != NULL)
643 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
645 if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
646 && shdr->sh_size != 0)
648 /* It's a relocation section. */
650 Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
651 if (unlikely (tscn == NULL))
652 result = DWFL_E_LIBELF;
654 result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
655 &reloc_symtab, scn, shdr, tscn,
665 __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
666 Elf_Scn *relocscn, Elf_Scn *tscn, bool partial)
671 RELOC_SYMTAB_CACHE (reloc_symtab);
674 if (elf_getshdrstrndx (relocated, &shstrndx) < 0)
675 return DWFL_E_LIBELF;
677 return (__libdwfl_module_getebl (mod)
678 ?: relocate_section (mod, relocated,
679 gelf_getehdr (relocated, &ehdr_mem), shstrndx,
681 relocscn, gelf_getshdr (relocscn, &shdr_mem),
682 tscn, false, partial));