134192Sjdp/*-
234192Sjdp * Copyright 1996-1998 John D. Polstra.
334192Sjdp * All rights reserved.
434192Sjdp *
534192Sjdp * Redistribution and use in source and binary forms, with or without
634192Sjdp * modification, are permitted provided that the following conditions
734192Sjdp * are met:
834192Sjdp * 1. Redistributions of source code must retain the above copyright
934192Sjdp *    notice, this list of conditions and the following disclaimer.
1034192Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1134192Sjdp *    notice, this list of conditions and the following disclaimer in the
1234192Sjdp *    documentation and/or other materials provided with the distribution.
1334192Sjdp *
1434192Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1534192Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1634192Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1734192Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1834192Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1934192Sjdp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2034192Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2134192Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2234192Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2334192Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2434192Sjdp *
2550476Speter * $FreeBSD$
2634192Sjdp */
2734192Sjdp
2834192Sjdp/*
2934192Sjdp * Support for printing debugging messages.
3034192Sjdp */
3134192Sjdp
3234192Sjdp#include <stdarg.h>
3334192Sjdp#include <stdio.h>
3434192Sjdp
3534192Sjdp#include "debug.h"
36116563Smdodd#include "rtld.h"
37225152Skib#include "rtld_printf.h"
3834192Sjdp
39116563Smdoddstatic const char rel_header[] =
40116563Smdodd    " symbol name               r_info r_offset st_value st_size    address    value\n"
41116563Smdodd    " ------------------------------------------------------------------------------\n";
42116582Smdoddstatic const char rel_format[] =  " %-25s %6lx %08lx %08lx %7d %10p %08lx\n";
43116563Smdodd
4434192Sjdpint debug = 0;
4534192Sjdp
4634192Sjdpvoid
4734192Sjdpdebug_printf(const char *format, ...)
4834192Sjdp{
4934192Sjdp    if (debug) {
5034192Sjdp	va_list ap;
5134192Sjdp	va_start(ap, format);
5234192Sjdp
53225152Skib	rtld_vfdprintf(STDERR_FILENO, format, ap);
54225152Skib	rtld_fdputchar(STDERR_FILENO, '\n');
5534192Sjdp
5634192Sjdp	va_end(ap);
5734192Sjdp    }
5834192Sjdp}
59116563Smdodd
60116563Smdoddvoid
61116563Smdodddump_relocations (Obj_Entry *obj0)
62116563Smdodd{
63116563Smdodd    Obj_Entry *obj;
64116563Smdodd
65296727Skib    for (obj = globallist_curr(obj0); obj != NULL;
66296727Skib      obj = globallist_next(obj)) {
67116563Smdodd        dump_obj_relocations(obj);
68116563Smdodd    }
69116563Smdodd}
70116563Smdodd
71116563Smdoddvoid
72116563Smdodddump_obj_relocations (Obj_Entry *obj)
73116563Smdodd{
74116563Smdodd
75225152Skib    rtld_printf("Object \"%s\", relocbase %p\n", obj->path, obj->relocbase);
76116563Smdodd
77116563Smdodd    if (obj->relsize) {
78225152Skib        rtld_printf("Non-PLT Relocations: %ld\n",
79116563Smdodd            (obj->relsize / sizeof(Elf_Rel)));
80116563Smdodd        dump_Elf_Rel(obj, obj->rel, obj->relsize);
81116563Smdodd    }
82116563Smdodd
83116563Smdodd    if (obj->relasize) {
84225152Skib        rtld_printf("Non-PLT Relocations with Addend: %ld\n",
85116563Smdodd            (obj->relasize / sizeof(Elf_Rela)));
86116563Smdodd        dump_Elf_Rela(obj, obj->rela, obj->relasize);
87116563Smdodd    }
88116563Smdodd
89116563Smdodd    if (obj->pltrelsize) {
90225152Skib        rtld_printf("PLT Relocations: %ld\n",
91116563Smdodd            (obj->pltrelsize / sizeof(Elf_Rel)));
92116563Smdodd        dump_Elf_Rel(obj, obj->pltrel, obj->pltrelsize);
93116563Smdodd    }
94116563Smdodd
95116563Smdodd    if (obj->pltrelasize) {
96225152Skib        rtld_printf("PLT Relocations with Addend: %ld\n",
97116563Smdodd            (obj->pltrelasize / sizeof(Elf_Rela)));
98116563Smdodd        dump_Elf_Rela(obj, obj->pltrela, obj->pltrelasize);
99116563Smdodd    }
100116563Smdodd}
101116563Smdodd
102116563Smdoddvoid
103116563Smdodddump_Elf_Rel (Obj_Entry *obj, const Elf_Rel *rel0, u_long relsize)
104116563Smdodd{
105116563Smdodd    const Elf_Rel *rel;
106116563Smdodd    const Elf_Rel *rellim;
107116563Smdodd    const Elf_Sym *sym;
108116563Smdodd    Elf_Addr *dstaddr;
109116563Smdodd
110225152Skib    rtld_putstr(rel_header);
111116582Smdodd    rellim = (const Elf_Rel *)((const char *)rel0 + relsize);
112116563Smdodd    for (rel = rel0; rel < rellim; rel++) {
113116563Smdodd	dstaddr = (Elf_Addr *)(obj->relocbase + rel->r_offset);
114116563Smdodd        sym = obj->symtab + ELF_R_SYM(rel->r_info);
115225152Skib        rtld_printf(rel_format,
116116563Smdodd		obj->strtab + sym->st_name,
117116582Smdodd		(u_long)rel->r_info, (u_long)rel->r_offset,
118116582Smdodd		(u_long)sym->st_value, (int)sym->st_size,
119116582Smdodd		dstaddr, (u_long)*dstaddr);
120116563Smdodd    }
121116563Smdodd    return;
122116563Smdodd}
123116563Smdodd
124116563Smdoddvoid
125116563Smdodddump_Elf_Rela (Obj_Entry *obj, const Elf_Rela *rela0, u_long relasize)
126116563Smdodd{
127116563Smdodd    const Elf_Rela *rela;
128116563Smdodd    const Elf_Rela *relalim;
129116563Smdodd    const Elf_Sym *sym;
130116563Smdodd    Elf_Addr *dstaddr;
131116563Smdodd
132225152Skib    rtld_putstr(rel_header);
133116582Smdodd    relalim = (const Elf_Rela *)((const char *)rela0 + relasize);
134116563Smdodd    for (rela = rela0; rela < relalim; rela++) {
135116563Smdodd	dstaddr = (Elf_Addr *)(obj->relocbase + rela->r_offset);
136116563Smdodd        sym = obj->symtab + ELF_R_SYM(rela->r_info);
137225152Skib        rtld_printf(rel_format,
138116563Smdodd		obj->strtab + sym->st_name,
139116582Smdodd		(u_long)rela->r_info, (u_long)rela->r_offset,
140116582Smdodd		(u_long)sym->st_value, (int)sym->st_size,
141116582Smdodd		dstaddr, (u_long)*dstaddr);
142116563Smdodd    }
143116563Smdodd    return;
144116563Smdodd}
145