diff options
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/ld/ldd/Makefile | 9 | ||||
-rw-r--r-- | gnu/usr.bin/ld/ldd/ldd.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/ld/ldd/sods.c | 127 |
3 files changed, 86 insertions, 54 deletions
diff --git a/gnu/usr.bin/ld/ldd/Makefile b/gnu/usr.bin/ld/ldd/Makefile index 61c95a8..e52f626 100644 --- a/gnu/usr.bin/ld/ldd/Makefile +++ b/gnu/usr.bin/ld/ldd/Makefile @@ -1,7 +1,8 @@ -# $Id$ +# $Id: Makefile,v 1.6 1997/02/22 15:46:40 peter Exp $ -PROG= ldd -SRCS= ldd.c sods.c -BINDIR= /usr/bin +PROG= ldd +SRCS= ldd.c sods.c +CFLAGS+= -Wall +BINDIR= /usr/bin .include <bsd.prog.mk> diff --git a/gnu/usr.bin/ld/ldd/ldd.c b/gnu/usr.bin/ld/ldd/ldd.c index 331d3c7..d940261 100644 --- a/gnu/usr.bin/ld/ldd/ldd.c +++ b/gnu/usr.bin/ld/ldd/ldd.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: ldd.c,v 1.13 1997/02/22 15:46:43 peter Exp $ */ #include <sys/types.h> @@ -44,7 +44,7 @@ #include <string.h> #include <unistd.h> -extern void dump_filename __P((const char *)); +extern void dump_file __P((const char *)); extern int error_count; void diff --git a/gnu/usr.bin/ld/ldd/sods.c b/gnu/usr.bin/ld/ldd/sods.c index b3732c1..d55a2de 100644 --- a/gnu/usr.bin/ld/ldd/sods.c +++ b/gnu/usr.bin/ld/ldd/sods.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996 John D. Polstra. All rights reserved. + * Copyright (C) 1996-1997 John D. Polstra. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: sods.c,v 1.4 1997/02/22 15:46:44 peter Exp $ */ #include <assert.h> @@ -42,6 +42,8 @@ #include <link.h> #include <stab.h> +#define PAGE_SIZE 4096 /* i386 specific */ + #ifndef N_SETA #define N_SETA 0x14 /* Absolute set element symbol */ #endif /* This is input to LD, in a .o file. */ @@ -74,7 +76,6 @@ static void dump_sods(); static void dump_sym(const struct nlist *); static void dump_syms(); -static void dump_rtrels(); static void dump_rtsyms(); static void error(const char *, ...); @@ -129,7 +130,7 @@ main(int argc, char *argv[]) { int i; - for(i = 1; i < argc; ++i) + for (i = 1; i < argc; ++i) dump_file(argv[i]); return error_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE; @@ -145,25 +146,24 @@ dump_file(const char *fname) int fd; struct stat sb; caddr_t objbase; - long load_offset; - if(stat(fname, &sb) == -1) { + if (stat(fname, &sb) == -1) { error("Cannot stat \"%s\"", fname); return; } - if((sb.st_mode & S_IFMT) != S_IFREG) { + if ((sb.st_mode & S_IFMT) != S_IFREG) { error("\"%s\" is not a regular file", fname); return; } - if((fd = open(fname, O_RDONLY, 0)) == -1) { + if ((fd = open(fname, O_RDONLY, 0)) == -1) { error("Cannot open \"%s\"", fname); return; } objbase = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); - if(objbase == (caddr_t) -1) { + if (objbase == (caddr_t) -1) { error("Cannot mmap \"%s\"", fname); close(fd); return; @@ -176,11 +176,11 @@ dump_file(const char *fname) ex = (const struct exec *) file_base; printf("%s: a_midmag = 0x%lx\n", fname, ex->a_midmag); - printf(" magic = 0x%x = 0%o, netmagic = 0x%x = 0%o\n", + printf(" magic = 0x%lx = 0%lo, netmagic = 0x%lx = 0%lo\n", N_GETMAGIC(*ex), N_GETMAGIC(*ex), N_GETMAGIC_NET(*ex), N_GETMAGIC_NET(*ex)); - if(N_BADMAG(*ex)) { + if (N_BADMAG(*ex)) { error("%s: Bad magic number", fname); munmap(objbase, sb.st_size); return; @@ -194,8 +194,6 @@ dump_file(const char *fname) printf(" a_trsize = 0x%lx\n", ex->a_trsize); printf(" a_drsize = 0x%lx\n", ex->a_drsize); - load_offset = N_TXTADDR(*ex) - N_TXTOFF(*ex); - text_base = file_base + N_TXTOFF(*ex); data_base = file_base + N_DATOFF(*ex); rel_base = (const struct relocation_info *) (file_base + N_RELOFF(*ex)); @@ -207,21 +205,18 @@ dump_file(const char *fname) sym_count = ex->a_syms / sizeof sym_base[0]; assert(sym_count * sizeof sym_base[0] == ex->a_syms); - if(sym_count != 0) { + if (sym_count != 0) { sym_used = (unsigned char *) calloc(sym_count, sizeof(unsigned char)); assert(sym_used != NULL); } - printf(" Entry = 0x%x, load offset = 0x%lx\n", - ex->a_entry, load_offset); - printf(" Text offset = %lx, address = %lx\n", N_TXTOFF(*ex), + printf(" Entry = 0x%lx\n", ex->a_entry); + printf(" Text offset = %x, address = %x\n", N_TXTOFF(*ex), N_TXTADDR(*ex)); printf(" Data offset = %lx, address = %lx\n", N_DATOFF(*ex), N_DATADDR(*ex)); /* - * DEBUG - * * In an executable program file, everything is relocated relative to * the assumed run-time load address, i.e., N_TXTADDR(*ex), i.e., 0x1000. * @@ -247,21 +242,25 @@ dump_file(const char *fname) data_addr = data_base; origin = 0; - if(ex->a_entry >= load_offset) { /* Executable, not a shared library */ + if (ex->a_entry >= PAGE_SIZE) { /* Executable, not a shared library */ /* * The fields in the object have already been relocated on the * assumption that the object will be loaded at N_TXTADDR(*ex). * We have to compensate for that. */ - text_addr -= load_offset; - data_addr -= load_offset; - origin = load_offset; + text_addr -= PAGE_SIZE; + data_addr -= PAGE_SIZE; + origin = PAGE_SIZE; printf(" Program, origin = %lx\n", origin); - } else - printf(" Library, origin = %lx\n", origin); + } else if (N_GETFLAG(*ex) & EX_DYNAMIC) + printf(" Shared library, origin = %lx\n", origin); + else + printf(" Object file, origin = %lx\n", origin); - if(N_GETFLAG(*ex) & EX_DYNAMIC) { + if (N_GETFLAG(*ex) & EX_DYNAMIC) { dyn = (const struct _dynamic *) data_base; + printf(" Dynamic version = %d\n", dyn->d_version); + sdt = (const struct section_dispatch_table *) (text_addr + (unsigned long) dyn->d_un.d_sdt); @@ -277,7 +276,7 @@ dump_file(const char *fname) assert(rtsym_count * sizeof rtsym_base[0] == sdt->sdt_strings - sdt->sdt_nzlist); - if(rtsym_count != 0) { + if (rtsym_count != 0) { rtsym_used = (unsigned char *) calloc(rtsym_count, sizeof(unsigned char)); assert(rtsym_used != NULL); @@ -295,11 +294,11 @@ dump_file(const char *fname) rtsym_used); dump_rtsyms(); - if(rtsym_used != NULL) { + if (rtsym_used != NULL) { free(rtsym_used); rtsym_used = NULL; } - if(sym_used != NULL) { + if (sym_used != NULL) { free(sym_used); sym_used = NULL; } @@ -314,11 +313,40 @@ dump_rels(const char *label, const struct relocation_info *base, unsigned long i; printf(" %s:\n", label); - for(i = 0; i < count; ++i) { + for (i = 0; i < count; ++i) { const struct relocation_info *r = &base[i]; - - printf(" %6lu %8x/%u %c%c%c%c%c%c", i, - r->r_address, 1u << r->r_length, + unsigned int size; + char contents[16]; + + size = 1u << r->r_length; + + if (origin <= r->r_address + && r->r_address < origin + ex->a_text + ex->a_data + && 1 <= size && size <= 4) { + /* + * XXX - This can cause unaligned accesses. OK for the + * i386, not so for other architectures. + */ + switch (size) { + case 1: + snprintf(contents, sizeof contents, " [%02x]", + *(unsigned char *)(text_addr + r->r_address)); + break; + case 2: + snprintf(contents, sizeof contents, " [%04x]", + *(unsigned short *)(text_addr + r->r_address)); + break; + case 4: + snprintf(contents, sizeof contents, "[%08lx]", + *(unsigned long *)(text_addr + r->r_address)); + break; + } + } else + snprintf(contents, sizeof contents, " "); + + printf(" %6lu %8x/%u %s %c%c%c%c%c%c", i, + r->r_address, size, + contents, r->r_extern ? 'e' : '-', r->r_jmptable ? 'j' : '-', r->r_relative ? 'r' : '-', @@ -326,7 +354,7 @@ dump_rels(const char *label, const struct relocation_info *base, r->r_pcrel ? 'p' : '-', r->r_copy ? 'c' : '-'); - if(r->r_extern || r->r_baserel || r->r_jmptable || r->r_copy) { + if (r->r_extern || r->r_baserel || r->r_jmptable || r->r_copy) { printf(" %4u %s", r->r_symbolnum, name(r->r_symbolnum)); sym_used_flags[r->r_symbolnum] = 1; } @@ -341,7 +369,7 @@ dump_rtsyms() unsigned long i; printf(" Run-time symbols:\n"); - for(i = 0; i < rtsym_count; ++i) { + for (i = 0; i < rtsym_count; ++i) { printf(" %6lu%c ", i, rtsym_used[i] ? '*' : ' '); dump_sym(&rtsym_base[i].nlist); printf("/%-5ld %s\n", rtsym_base[i].nz_size, rtsym_name(i)); @@ -352,7 +380,7 @@ static void dump_segs() { printf(" Text segment starts at address %lx\n", origin + N_TXTOFF(*ex)); - if(N_GETFLAG(*ex) & EX_DYNAMIC) { + if (N_GETFLAG(*ex) & EX_DYNAMIC) { printf(" rel starts at %lx\n", sdt->sdt_rel); printf(" hash starts at %lx\n", sdt->sdt_hash); printf(" nzlist starts at %lx\n", sdt->sdt_nzlist); @@ -360,7 +388,7 @@ dump_segs() } printf(" Data segment starts at address %lx\n", origin + N_DATOFF(*ex)); - if(N_GETFLAG(*ex) & EX_DYNAMIC) { + if (N_GETFLAG(*ex) & EX_DYNAMIC) { printf(" _dynamic starts at %lx\n", origin + N_DATOFF(*ex)); printf(" so_debug starts at %lx\n", (unsigned long) dyn->d_debug); printf(" sdt starts at %lx\n", (unsigned long) dyn->d_un.d_sdt); @@ -377,12 +405,12 @@ dump_sods() long sod_offset; long paths_offset; - if(dyn == NULL) /* Not a shared object */ + if (dyn == NULL) /* Not a shared object */ return; sod_offset = sdt->sdt_sods; printf(" Shared object dependencies:\n"); - while(sod_offset != 0) { + while (sod_offset != 0) { const struct sod *sodp = (const struct sod *) (text_addr + sod_offset); const char *name = (const char *) (text_addr + sodp->sod_name); @@ -399,7 +427,7 @@ dump_sods() char *path = (char *)(text_addr + paths_offset); printf(" %s\n", path); } else { - printf(" NULL\n"); + printf(" (none)\n"); } } @@ -407,9 +435,10 @@ static void dump_sym(const struct nlist *np) { char type[8]; + char weak; char *p; - switch(np->n_type & ~N_EXT) { + switch (np->n_type & ~N_EXT) { case N_UNDF: strcpy(type, "undf"); break; case N_ABS: strcpy(type, "abs"); break; case N_TEXT: strcpy(type, "text"); break; @@ -450,14 +479,16 @@ dump_sym(const struct nlist *np) case N_ECOMM: strcpy(type, "ecomm"); break; case N_ECOML: strcpy(type, "ecoml"); break; case N_LENG: strcpy(type, "leng"); break; - default: sprintf(type, "0x%02x", np->n_type); + default: snprintf(type, sizeof type, "0x%02x", np->n_type); } - if(np->n_type & N_EXT && type[0] != '0') - for(p = type; *p != '\0'; ++p) + if (np->n_type & N_EXT && type[0] != '0') + for (p = type; *p != '\0'; ++p) *p = toupper(*p); - printf("%-5s %8lx", type, np->n_value); + weak = N_BIND(np) == BIND_WEAK ? 'w' : ' '; + + printf("%c%-5s %8lx", weak, type, np->n_value); } static void @@ -466,7 +497,7 @@ dump_syms() unsigned long i; printf(" Symbols:\n"); - for(i = 0; i < sym_count; ++i) { + for (i = 0; i < sym_count; ++i) { printf(" %6lu%c ", i, sym_used[i] ? '*' : ' '); dump_sym(&sym_base[i]); printf(" %s\n", sym_name(i)); @@ -490,7 +521,7 @@ static const char * rtsym_name(unsigned long n) { assert(n < rtsym_count); - if(rtsym_base[n].nz_strx == 0) + if (rtsym_base[n].nz_strx == 0) return ""; return rtstr_base + rtsym_base[n].nz_strx; } @@ -499,7 +530,7 @@ static const char * sym_name(unsigned long n) { assert(n < sym_count); - if(sym_base[n].n_un.n_strx == 0) + if (sym_base[n].n_un.n_strx == 0) return ""; return str_base + sym_base[n].n_un.n_strx; } |