Provide a mechanism for dumping relocation information.
Setting the LD_DUMP_REL_PRE or LD_DUMP_REL_POST environment variables cause rtld-elf to output a table of all relocations. This is useful for debugging.
This commit is contained in:
parent
8d5f9131fc
commit
c5d061c17a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=116563
@ -33,6 +33,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "rtld.h"
|
||||
|
||||
static const char rel_header[] =
|
||||
" symbol name r_info r_offset st_value st_size address value\n"
|
||||
" ------------------------------------------------------------------------------\n";
|
||||
static const char rel_format[] = " %-25s %6x %08x %08x %7d %10p %08x\n";
|
||||
|
||||
int debug = 0;
|
||||
|
||||
@ -50,3 +56,88 @@ debug_printf(const char *format, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dump_relocations (Obj_Entry *obj0)
|
||||
{
|
||||
Obj_Entry *obj;
|
||||
|
||||
for (obj = obj0; obj != NULL; obj = obj->next) {
|
||||
dump_obj_relocations(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dump_obj_relocations (Obj_Entry *obj)
|
||||
{
|
||||
|
||||
printf("Object \"%s\", relocbase %p\n", obj->path, obj->relocbase);
|
||||
|
||||
if (obj->relsize) {
|
||||
printf("Non-PLT Relocations: %ld\n",
|
||||
(obj->relsize / sizeof(Elf_Rel)));
|
||||
dump_Elf_Rel(obj, obj->rel, obj->relsize);
|
||||
}
|
||||
|
||||
if (obj->relasize) {
|
||||
printf("Non-PLT Relocations with Addend: %ld\n",
|
||||
(obj->relasize / sizeof(Elf_Rela)));
|
||||
dump_Elf_Rela(obj, obj->rela, obj->relasize);
|
||||
}
|
||||
|
||||
if (obj->pltrelsize) {
|
||||
printf("PLT Relocations: %ld\n",
|
||||
(obj->pltrelsize / sizeof(Elf_Rel)));
|
||||
dump_Elf_Rel(obj, obj->pltrel, obj->pltrelsize);
|
||||
}
|
||||
|
||||
if (obj->pltrelasize) {
|
||||
printf("PLT Relocations with Addend: %ld\n",
|
||||
(obj->pltrelasize / sizeof(Elf_Rela)));
|
||||
dump_Elf_Rela(obj, obj->pltrela, obj->pltrelasize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dump_Elf_Rel (Obj_Entry *obj, const Elf_Rel *rel0, u_long relsize)
|
||||
{
|
||||
const Elf_Rel *rel;
|
||||
const Elf_Rel *rellim;
|
||||
const Elf_Sym *sym;
|
||||
Elf_Addr *dstaddr;
|
||||
|
||||
printf("%s", rel_header);
|
||||
rellim = (const Elf_Rel *)((char *)rel0 + relsize);
|
||||
for (rel = rel0; rel < rellim; rel++) {
|
||||
dstaddr = (Elf_Addr *)(obj->relocbase + rel->r_offset);
|
||||
sym = obj->symtab + ELF_R_SYM(rel->r_info);
|
||||
printf(rel_format,
|
||||
obj->strtab + sym->st_name,
|
||||
rel->r_info, rel->r_offset,
|
||||
sym->st_value, sym->st_size,
|
||||
dstaddr, *dstaddr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
dump_Elf_Rela (Obj_Entry *obj, const Elf_Rela *rela0, u_long relasize)
|
||||
{
|
||||
const Elf_Rela *rela;
|
||||
const Elf_Rela *relalim;
|
||||
const Elf_Sym *sym;
|
||||
Elf_Addr *dstaddr;
|
||||
|
||||
printf("%s", rel_header);
|
||||
relalim = (const Elf_Rela *)((char *)rela0 + relasize);
|
||||
for (rela = rela0; rela < relalim; rela++) {
|
||||
dstaddr = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
sym = obj->symtab + ELF_R_SYM(rela->r_info);
|
||||
printf(rel_format,
|
||||
obj->strtab + sym->st_name,
|
||||
rela->r_info, rela->r_offset,
|
||||
sym->st_value, sym->st_size,
|
||||
dstaddr, *dstaddr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -83,6 +83,16 @@ recognizes a number of environment variables that can be used to modify
|
||||
its behaviour as follows:
|
||||
.Pp
|
||||
.Bl -tag -width ".Ev LD_LIBMAP_DISABLE"
|
||||
.It Ev LD_DUMP_REL_POST
|
||||
If set
|
||||
.Nm
|
||||
will print (to stderr) a table containing all relocations after symbol
|
||||
binding and relocation.
|
||||
.It Ev LD_DUMP_REL_PRE
|
||||
If set
|
||||
.Nm
|
||||
will print (to stderr) a table containing all relocations before symbol
|
||||
binding and relocation.
|
||||
.It Ev LD_LIBMAP_DISABLE
|
||||
If set, disables the use of
|
||||
.Xr libmap.conf 5 .
|
||||
|
@ -365,6 +365,11 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (getenv("LD_DUMP_REL_PRE") != NULL) {
|
||||
dump_relocations(obj_main);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (relocate_objects(obj_main,
|
||||
ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld) == -1)
|
||||
die();
|
||||
@ -373,6 +378,11 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
if (do_copy_relocations(obj_main) == -1)
|
||||
die();
|
||||
|
||||
if (getenv("LD_DUMP_REL_POST") != NULL) {
|
||||
dump_relocations(obj_main);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
dbg("initializing key program variables");
|
||||
set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
|
||||
set_program_var("environ", env);
|
||||
|
@ -186,6 +186,11 @@ extern void *xmalloc(size_t);
|
||||
extern char *xstrdup(const char *);
|
||||
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
|
||||
|
||||
extern void dump_relocations (Obj_Entry *);
|
||||
extern void dump_obj_relocations (Obj_Entry *);
|
||||
extern void dump_Elf_Rel (Obj_Entry *, const Elf_Rel *, u_long);
|
||||
extern void dump_Elf_Rela (Obj_Entry *, const Elf_Rela *, u_long);
|
||||
|
||||
/*
|
||||
* Function declarations.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user