From ca4dc263500f579375794e3f00560f5dbdef5a4f Mon Sep 17 00:00:00 2001 From: mdodd Date: Thu, 19 Jun 2003 03:55:38 +0000 Subject: 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. --- libexec/rtld-elf/debug.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ libexec/rtld-elf/rtld.1 | 10 ++++++ libexec/rtld-elf/rtld.c | 10 ++++++ libexec/rtld-elf/rtld.h | 5 +++ 4 files changed, 116 insertions(+) (limited to 'libexec') diff --git a/libexec/rtld-elf/debug.c b/libexec/rtld-elf/debug.c index 0c8ca35..19a4407 100644 --- a/libexec/rtld-elf/debug.c +++ b/libexec/rtld-elf/debug.c @@ -33,6 +33,12 @@ #include #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; +} diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1 index 6c74a62..d466b11 100644 --- a/libexec/rtld-elf/rtld.1 +++ b/libexec/rtld-elf/rtld.1 @@ -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 . diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 6bc1f77..484cd8d 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -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); diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index 98808a0..dd793bb 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -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. */ -- cgit v1.1