Home | History | Annotate | Line # | Download | only in dbsym
dbsym.c revision 1.6
      1  1.6  joerg /* $NetBSD: dbsym.c,v 1.6 2017/07/11 21:19:42 joerg Exp $ */
      2  1.1  skrll 
      3  1.1  skrll /*
      4  1.1  skrll  * Copyright (c) 2001 Simon Burge (for Wasabi Systems)
      5  1.1  skrll  * Copyright (c) 1996 Christopher G. Demetriou
      6  1.1  skrll  * All rights reserved.
      7  1.1  skrll  *
      8  1.1  skrll  * Redistribution and use in source and binary forms, with or without
      9  1.1  skrll  * modification, are permitted provided that the following conditions
     10  1.1  skrll  * are met:
     11  1.1  skrll  * 1. Redistributions of source code must retain the above copyright
     12  1.1  skrll  *    notice, this list of conditions and the following disclaimer.
     13  1.1  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  skrll  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  skrll  *    documentation and/or other materials provided with the distribution.
     16  1.1  skrll  * 3. The name of the author may not be used to endorse or promote products
     17  1.1  skrll  *    derived from this software without specific prior written permission.
     18  1.1  skrll  *
     19  1.1  skrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  1.1  skrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  1.1  skrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  1.1  skrll  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  1.1  skrll  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  1.1  skrll  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  1.1  skrll  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  1.1  skrll  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  1.1  skrll  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  1.1  skrll  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  1.1  skrll  *
     30  1.1  skrll  * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
     31  1.1  skrll  */
     32  1.1  skrll 
     33  1.1  skrll #if HAVE_NBTOOL_CONFIG_H
     34  1.1  skrll #include "nbtool_config.h"
     35  1.1  skrll #endif
     36  1.1  skrll 
     37  1.1  skrll #include <sys/cdefs.h>
     38  1.1  skrll #if !defined(lint)
     39  1.1  skrll __COPYRIGHT("@(#) Copyright (c) 1996 Christopher G. Demetriou.\
     40  1.1  skrll   Copyright 2001 Simon Burge.\
     41  1.1  skrll   All rights reserved.");
     42  1.6  joerg __RCSID("$NetBSD: dbsym.c,v 1.6 2017/07/11 21:19:42 joerg Exp $");
     43  1.1  skrll #endif /* not lint */
     44  1.1  skrll 
     45  1.1  skrll #include <sys/param.h>
     46  1.1  skrll #include <sys/mman.h>
     47  1.1  skrll #include <sys/stat.h>
     48  1.1  skrll 
     49  1.1  skrll #include <bfd.h>
     50  1.1  skrll #include <err.h>
     51  1.1  skrll #include <fcntl.h>
     52  1.1  skrll #include <stdio.h>
     53  1.1  skrll #include <stdlib.h>
     54  1.1  skrll #include <string.h>
     55  1.1  skrll #include <unistd.h>
     56  1.1  skrll 
     57  1.1  skrll /* BFD ELF headers */
     58  1.1  skrll #include <elf/common.h>
     59  1.1  skrll #include <elf/external.h>
     60  1.1  skrll 
     61  1.1  skrll struct symbols {
     62  1.1  skrll 	char *name;
     63  1.1  skrll 	size_t offset;
     64  1.1  skrll } db_symtab_symbols[] = {
     65  1.1  skrll #define	X_DB_SYMTAB	0
     66  1.1  skrll 	{ "_db_symtab", 0 },
     67  1.1  skrll #define	X_DB_SYMTABSIZE	1
     68  1.1  skrll 	{ "_db_symtabsize", 0 },
     69  1.1  skrll 	{ NULL, 0 }
     70  1.1  skrll };
     71  1.1  skrll 
     72  1.1  skrll int	main(int, char **);
     73  1.1  skrll void	usage(void) __attribute__((noreturn));
     74  1.1  skrll int	find_symtab(bfd *, struct symbols *);
     75  1.1  skrll int	load_symtab(bfd *, int fd, char **, u_int32_t *);
     76  1.1  skrll 
     77  1.1  skrll int	verbose;
     78  1.2    bsh int	printsize;
     79  1.4  joerg int	printsize2;
     80  1.1  skrll 
     81  1.1  skrll int
     82  1.1  skrll main(int argc, char **argv)
     83  1.1  skrll {
     84  1.1  skrll 	int ch, kfd;
     85  1.1  skrll 	struct stat ksb;
     86  1.1  skrll 	size_t symtab_offset;
     87  1.1  skrll 	u_int32_t symtab_space, symtabsize;
     88  1.1  skrll 	const char *kfile;
     89  1.1  skrll 	char *bfdname, *mappedkfile, *symtab;
     90  1.1  skrll 	bfd *abfd;
     91  1.1  skrll 
     92  1.1  skrll 	setprogname(argv[0]);
     93  1.1  skrll 
     94  1.1  skrll 	bfdname = NULL;
     95  1.4  joerg 	while ((ch = getopt(argc, argv, "b:Ppv")) != -1)
     96  1.1  skrll 		switch (ch) {
     97  1.1  skrll 		case 'b':
     98  1.1  skrll 			bfdname = optarg;
     99  1.1  skrll 			break;
    100  1.1  skrll 		case 'v':
    101  1.1  skrll 			verbose = 1;
    102  1.1  skrll 			break;
    103  1.2    bsh 		case 'p':
    104  1.2    bsh 			printsize = 1;
    105  1.2    bsh 			break;
    106  1.4  joerg 		case 'P':
    107  1.4  joerg 			printsize2 = 1;
    108  1.4  joerg 			break;
    109  1.1  skrll 		case '?':
    110  1.1  skrll 		default:
    111  1.1  skrll 			usage();
    112  1.1  skrll 	}
    113  1.1  skrll 	argc -= optind;
    114  1.1  skrll 	argv += optind;
    115  1.1  skrll 
    116  1.1  skrll 	if (argc != 1)
    117  1.1  skrll 		usage();
    118  1.1  skrll 	kfile = argv[0];
    119  1.1  skrll 
    120  1.1  skrll 	if ((kfd = open(kfile, O_RDWR, 0))  == -1)
    121  1.1  skrll 		err(1, "open %s", kfile);
    122  1.1  skrll 
    123  1.1  skrll 	bfd_init();
    124  1.1  skrll 	if ((abfd = bfd_fdopenr(kfile, bfdname, kfd)) == NULL) {
    125  1.1  skrll 		bfd_perror("open");
    126  1.1  skrll 		exit(1);
    127  1.1  skrll 	}
    128  1.1  skrll 	if (!bfd_check_format(abfd, bfd_object)) {
    129  1.1  skrll 		bfd_perror("check format");
    130  1.1  skrll 		exit(1);
    131  1.1  skrll 	}
    132  1.1  skrll 
    133  1.1  skrll 	if (!(bfd_get_file_flags(abfd) & HAS_SYMS))
    134  1.1  skrll 		errx(1, "no symbol table in %s", kfile);
    135  1.1  skrll 
    136  1.1  skrll 	if (find_symtab(abfd, db_symtab_symbols) != 0)
    137  1.1  skrll 		errx(1, "could not find SYMTAB_SPACE in %s", kfile);
    138  1.1  skrll 	if (verbose)
    139  1.1  skrll 		fprintf(stderr, "got SYMTAB_SPACE symbols from %s\n", kfile);
    140  1.1  skrll 
    141  1.1  skrll 	if (load_symtab(abfd, kfd, &symtab, &symtabsize) != 0)
    142  1.1  skrll 		errx(1, "could not load symbol table from %s", kfile);
    143  1.1  skrll 	if (verbose)
    144  1.1  skrll 		fprintf(stderr, "loaded symbol table from %s\n", kfile);
    145  1.1  skrll 
    146  1.1  skrll 	if (fstat(kfd, &ksb) == -1)
    147  1.1  skrll 		err(1, "fstat %s", kfile);
    148  1.1  skrll 	if (ksb.st_size != (size_t)ksb.st_size)
    149  1.1  skrll 		errx(1, "%s too big to map", kfile);
    150  1.1  skrll 
    151  1.1  skrll 	if ((mappedkfile = mmap(NULL, ksb.st_size, PROT_READ | PROT_WRITE,
    152  1.1  skrll 	    MAP_FILE | MAP_SHARED, kfd, 0)) == (caddr_t)-1)
    153  1.1  skrll 		err(1, "mmap %s", kfile);
    154  1.1  skrll 	if (verbose)
    155  1.1  skrll 		fprintf(stderr, "mapped %s\n", kfile);
    156  1.1  skrll 
    157  1.1  skrll 	symtab_offset = db_symtab_symbols[X_DB_SYMTAB].offset;
    158  1.1  skrll 	symtab_space = bfd_get_32(abfd,
    159  1.1  skrll 	    &mappedkfile[db_symtab_symbols[X_DB_SYMTABSIZE].offset]);
    160  1.1  skrll 
    161  1.2    bsh 	if (printsize) {
    162  1.2    bsh 		printf("%d %d\n", symtabsize, symtab_space);
    163  1.2    bsh 		goto done;
    164  1.2    bsh 	}
    165  1.4  joerg 	if (printsize2) {
    166  1.4  joerg 		printf("%d\n", symtabsize);
    167  1.4  joerg 		goto done;
    168  1.4  joerg 	}
    169  1.2    bsh 
    170  1.1  skrll 	if (symtabsize > symtab_space)
    171  1.1  skrll 		errx(1, "symbol table (%u bytes) too big for buffer (%u bytes)\n"
    172  1.1  skrll 		    "Increase options SYMTAB_SPACE in your kernel config",
    173  1.1  skrll 		    symtabsize, symtab_space);
    174  1.1  skrll 
    175  1.1  skrll 	if (verbose)
    176  1.1  skrll 		fprintf(stderr, "symtab size %d, space available %d\n",
    177  1.1  skrll 		    symtabsize, symtab_space);
    178  1.1  skrll 
    179  1.1  skrll 	memcpy(mappedkfile + symtab_offset, symtab, symtabsize);
    180  1.1  skrll 
    181  1.1  skrll 	if (verbose)
    182  1.1  skrll 		fprintf(stderr, "done copying image to file offset %#lx\n",
    183  1.1  skrll 		    (long)db_symtab_symbols[X_DB_SYMTAB].offset);
    184  1.1  skrll 
    185  1.1  skrll 	bfd_put_32(abfd, symtabsize,
    186  1.1  skrll 	    &mappedkfile[db_symtab_symbols[X_DB_SYMTABSIZE].offset]);
    187  1.1  skrll 
    188  1.2    bsh done:
    189  1.1  skrll 	munmap(mappedkfile, ksb.st_size);
    190  1.1  skrll 	close(kfd);
    191  1.1  skrll 
    192  1.1  skrll 	if (verbose)
    193  1.1  skrll 		fprintf(stderr, "exiting\n");
    194  1.1  skrll 
    195  1.1  skrll 	bfd_close_all_done(abfd);
    196  1.1  skrll 	exit(0);
    197  1.1  skrll }
    198  1.1  skrll 
    199  1.1  skrll void
    200  1.1  skrll usage(void)
    201  1.1  skrll {
    202  1.1  skrll 	const char **list;
    203  1.1  skrll 
    204  1.1  skrll 	fprintf(stderr,
    205  1.4  joerg 	    "usage: %s [-Ppv] [-b bfdname] kernel\n",
    206  1.1  skrll 	    getprogname());
    207  1.1  skrll 	fprintf(stderr, "supported targets:");
    208  1.1  skrll 	for (list = bfd_target_list(); *list != NULL; list++)
    209  1.1  skrll 		fprintf(stderr, " %s", *list);
    210  1.1  skrll 	fprintf(stderr, "\n");
    211  1.1  skrll 	exit(1);
    212  1.1  skrll }
    213  1.1  skrll 
    214  1.1  skrll int
    215  1.1  skrll find_symtab(bfd *abfd, struct symbols *symbols)
    216  1.1  skrll {
    217  1.1  skrll 	long i;
    218  1.1  skrll 	long storage_needed;
    219  1.1  skrll 	long number_of_symbols;
    220  1.1  skrll 	asymbol **symbol_table = NULL;
    221  1.1  skrll 	struct symbols *s;
    222  1.1  skrll 
    223  1.1  skrll 	storage_needed = bfd_get_symtab_upper_bound(abfd);
    224  1.1  skrll 	if (storage_needed <= 0)
    225  1.1  skrll 		return (1);
    226  1.1  skrll 
    227  1.1  skrll 	if ((symbol_table = (asymbol **)malloc(storage_needed)) == NULL)
    228  1.1  skrll 		return (1);
    229  1.1  skrll 
    230  1.1  skrll 	number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
    231  1.1  skrll 	if (number_of_symbols <= 0) {
    232  1.1  skrll 		free(symbol_table);
    233  1.1  skrll 		return (1);
    234  1.1  skrll 	}
    235  1.1  skrll 
    236  1.1  skrll 	for (i = 0; i < number_of_symbols; i++) {
    237  1.1  skrll 		for (s = symbols; s->name != NULL; s++) {
    238  1.1  skrll 		  const char *sym = symbol_table[i]->name;
    239  1.1  skrll 
    240  1.1  skrll 			/*
    241  1.1  skrll 			 * match symbol prefix '_' or ''.
    242  1.1  skrll 			 * XXX: use bfd_get_symbol_leading_char() here?
    243  1.1  skrll 			 */
    244  1.1  skrll 			if (!strcmp(s->name, sym) ||
    245  1.1  skrll 			    !strcmp(s->name + 1, sym)) {
    246  1.1  skrll 				s->offset = (size_t)
    247  1.1  skrll 				    (symbol_table[i]->section->filepos
    248  1.1  skrll                                     + symbol_table[i]->value);
    249  1.1  skrll 
    250  1.1  skrll 			}
    251  1.1  skrll 		}
    252  1.1  skrll 	}
    253  1.1  skrll 
    254  1.1  skrll 	free(symbol_table);
    255  1.1  skrll 
    256  1.1  skrll 	for (s = symbols; s->name != NULL; s++) {
    257  1.1  skrll 		if (s->offset == 0)
    258  1.1  skrll 			return (1);
    259  1.1  skrll 	}
    260  1.1  skrll 
    261  1.1  skrll 	return (0);
    262  1.1  skrll }
    263  1.1  skrll 
    264  1.1  skrll /* --------------------------- ELF gunk follows --------------------------- */
    265  1.1  skrll 
    266  1.1  skrll /*
    267  1.1  skrll  * The format of the symbols loaded by the boot program is:
    268  1.1  skrll  *
    269  1.1  skrll  *      Elf exec header
    270  1.1  skrll  *      first section header
    271  1.1  skrll  *      . . .
    272  1.1  skrll  *      . . .
    273  1.1  skrll  *      last section header
    274  1.1  skrll  *      first symbol or string table section
    275  1.1  skrll  *      . . .
    276  1.1  skrll  *      . . .
    277  1.1  skrll  *      last symbol or string table section
    278  1.1  skrll  */
    279  1.1  skrll 
    280  1.1  skrll 
    281  1.1  skrll /* Note elftype is local to load_symtab()... */
    282  1.1  skrll #define	ELF_TYPE_64	0x01
    283  1.1  skrll #define	ISELF64		(elftype & ELF_TYPE_64)
    284  1.1  skrll 
    285  1.1  skrll /*
    286  1.1  skrll  * Field sizes for the Elf exec header:
    287  1.1  skrll  *
    288  1.1  skrll  *    ELF32    ELF64
    289  1.1  skrll  *
    290  1.1  skrll  *    unsigned char      e_ident[ELF_NIDENT];    # Id bytes
    291  1.1  skrll  *     16       16       e_type;                 # file type
    292  1.1  skrll  *     16       16       e_machine;              # machine type
    293  1.1  skrll  *     32       32       e_version;              # version number
    294  1.1  skrll  *     32       64       e_entry;                # entry point
    295  1.1  skrll  *     32       64       e_phoff;                # Program hdr offset
    296  1.1  skrll  *     32       64       e_shoff;                # Section hdr offset
    297  1.1  skrll  *     32       32       e_flags;                # Processor flags
    298  1.1  skrll  *     16       16       e_ehsize;               # sizeof ehdr
    299  1.1  skrll  *     16       16       e_phentsize;            # Program header entry size
    300  1.1  skrll  *     16       16       e_phnum;                # Number of program headers
    301  1.1  skrll  *     16       16       e_shentsize;            # Section header entry size
    302  1.1  skrll  *     16       16       e_shnum;                # Number of section headers
    303  1.1  skrll  *     16       16       e_shstrndx;             # String table index
    304  1.1  skrll  */
    305  1.1  skrll 
    306  1.1  skrll typedef union {
    307  1.1  skrll 	Elf32_External_Ehdr e32hdr;
    308  1.1  skrll 	Elf64_External_Ehdr e64hdr;
    309  1.1  skrll 	char e_ident[16];		/* XXX MAGIC NUMBER */
    310  1.1  skrll } elf_ehdr;
    311  1.1  skrll 
    312  1.1  skrll #define	e32_hdr	ehdr.e32hdr
    313  1.1  skrll #define	e64_hdr	ehdr.e64hdr
    314  1.1  skrll 
    315  1.1  skrll /*
    316  1.1  skrll  * Field sizes for Elf section headers
    317  1.1  skrll  *
    318  1.1  skrll  *    ELF32    ELF64
    319  1.1  skrll  *
    320  1.1  skrll  *     32       32       sh_name;        # section name (.shstrtab index)
    321  1.1  skrll  *     32       32       sh_type;        # section type
    322  1.1  skrll  *     32       64       sh_flags;       # section flags
    323  1.1  skrll  *     32       64       sh_addr;        # virtual address
    324  1.1  skrll  *     32       64       sh_offset;      # file offset
    325  1.1  skrll  *     32       64       sh_size;        # section size
    326  1.1  skrll  *     32       32       sh_link;        # link to another
    327  1.1  skrll  *     32       32       sh_info;        # misc info
    328  1.1  skrll  *     32       64       sh_addralign;   # memory alignment
    329  1.1  skrll  *     32       64       sh_entsize;     # table entry size
    330  1.1  skrll  */
    331  1.1  skrll 
    332  1.1  skrll /* Extract a 32 bit field from Elf32_Shdr */
    333  1.1  skrll #define	SH_E32_32(x, n)		bfd_get_32(abfd, s32hdr[(x)].n)
    334  1.1  skrll 
    335  1.1  skrll /* Extract a 32 bit field from Elf64_Shdr */
    336  1.1  skrll #define	SH_E64_32(x, n)		bfd_get_32(abfd, s64hdr[(x)].n)
    337  1.1  skrll 
    338  1.1  skrll /* Extract a 64 bit field from Elf64_Shdr */
    339  1.1  skrll #define	SH_E64_64(x, n)		bfd_get_64(abfd, s64hdr[(x)].n)
    340  1.1  skrll 
    341  1.1  skrll /* Extract a 32 bit field from either size Shdr */
    342  1.1  skrll #define	SH_E32E32(x, n)	(ISELF64 ? SH_E64_32(x, n) : SH_E32_32(x, n))
    343  1.1  skrll 
    344  1.1  skrll /* Extract a 32 bit field from Elf32_Shdr or 64 bit field from Elf64_Shdr */
    345  1.1  skrll #define	SH_E32E64(x, n)	(ISELF64 ? SH_E64_64(x, n) : SH_E32_32(x, n))
    346  1.1  skrll 
    347  1.1  skrll #define	SH_NAME(x)	SH_E32E32(x, sh_name)
    348  1.1  skrll #define	SH_TYPE(x)	SH_E32E32(x, sh_type)
    349  1.1  skrll #define	SH_FLAGS(x)	SH_E32E64(x, sh_flags)
    350  1.1  skrll #define	SH_ADDR(x)	SH_E32E64(x, sh_addr)
    351  1.1  skrll #define	SH_OFFSET(x)	SH_E32E64(x, sh_offset)
    352  1.1  skrll #define	SH_SIZE(x)	SH_E32E64(x, sh_size)
    353  1.1  skrll #define	SH_LINK(x)	SH_E32E32(x, sh_link)
    354  1.1  skrll #define	SH_INFO(x)	SH_E32E32(x, sh_info)
    355  1.1  skrll #define	SH_ADDRALIGN(x)	SH_E32E64(x, sh_addralign)
    356  1.1  skrll #define	SH_ENTSIZE(x)	SH_E32E64(x, sh_entsize)
    357  1.1  skrll 
    358  1.1  skrll int
    359  1.1  skrll load_symtab(bfd *abfd, int fd, char **symtab, u_int32_t *symtabsize)
    360  1.1  skrll {
    361  1.1  skrll 	elf_ehdr ehdr;
    362  1.1  skrll 	Elf32_External_Shdr *s32hdr = NULL;
    363  1.1  skrll 	Elf64_External_Shdr *s64hdr = NULL;
    364  1.1  skrll 	void *shdr;
    365  1.5    chs 	char *shstrtab = NULL;
    366  1.1  skrll 	u_int32_t osymtabsize, sh_offset;
    367  1.5    chs 	int elftype, e_shnum, i, sh_size, rv = 1, shstridx;
    368  1.1  skrll 	off_t e_shoff;
    369  1.1  skrll 
    370  1.1  skrll 	if (lseek(fd, 0, SEEK_SET) < 0)
    371  1.1  skrll 		return (1);
    372  1.1  skrll 	if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
    373  1.1  skrll 		return (1);
    374  1.1  skrll 
    375  1.1  skrll 	/*
    376  1.1  skrll 	 * Check that we are targetting an Elf binary.
    377  1.1  skrll 	 */
    378  1.1  skrll 	if (ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
    379  1.1  skrll 	    ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
    380  1.1  skrll 	    ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
    381  1.1  skrll 	    ehdr.e_ident[EI_MAG3] != ELFMAG3)
    382  1.1  skrll 		return (1);
    383  1.1  skrll 
    384  1.1  skrll 	/*
    385  1.1  skrll 	 * Determine Elf size and endianness.
    386  1.1  skrll 	 */
    387  1.1  skrll 	elftype = 0;
    388  1.1  skrll 	if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
    389  1.1  skrll 		elftype |= ELF_TYPE_64;
    390  1.1  skrll 
    391  1.1  skrll 	/*
    392  1.1  skrll 	 * Elf exec header.  Only need to allocate space for now,
    393  1.1  skrll 	 * the header is copied into place at the end.
    394  1.1  skrll 	 */
    395  1.1  skrll 	*symtabsize = ISELF64 ? sizeof(Elf64_External_Ehdr)
    396  1.1  skrll 			      : sizeof(Elf32_External_Ehdr);
    397  1.1  skrll 	*symtab = NULL;
    398  1.1  skrll 
    399  1.1  skrll 	/*
    400  1.1  skrll 	 * Section headers.  Allocate a temporary copy that will
    401  1.1  skrll 	 * be copied into place at the end.
    402  1.1  skrll 	 */
    403  1.1  skrll 	sh_offset = osymtabsize = *symtabsize;
    404  1.1  skrll 	e_shnum = (ISELF64
    405  1.1  skrll 	    ? bfd_get_16(abfd, e64_hdr.e_shnum)
    406  1.1  skrll 	    : bfd_get_16(abfd, e32_hdr.e_shnum));
    407  1.1  skrll 	sh_size = e_shnum * (ISELF64 ? sizeof(Elf64_External_Shdr)
    408  1.1  skrll 				     : sizeof(Elf32_External_Shdr));
    409  1.1  skrll 	if ((shdr = malloc(sh_size)) == NULL)
    410  1.1  skrll 		return (1);
    411  1.1  skrll 	if (ISELF64)
    412  1.1  skrll 		s64hdr = shdr;
    413  1.1  skrll 	else
    414  1.1  skrll 		s32hdr = shdr;
    415  1.1  skrll 
    416  1.1  skrll 	*symtabsize += roundup(sh_size, ISELF64 ? 8 : 4);
    417  1.1  skrll 
    418  1.1  skrll 	e_shoff = (ISELF64
    419  1.1  skrll 	   ? bfd_get_64(abfd, e64_hdr.e_shoff)
    420  1.1  skrll 	   : bfd_get_32(abfd, e32_hdr.e_shoff));
    421  1.1  skrll 	if (lseek(fd, e_shoff, SEEK_SET) < 0)
    422  1.1  skrll 		goto out;
    423  1.1  skrll 	if (read(fd, shdr, sh_size) != sh_size)
    424  1.1  skrll 		goto out;
    425  1.1  skrll 
    426  1.5    chs 	shstridx = (ISELF64
    427  1.5    chs 	   ? bfd_get_16(abfd, e64_hdr.e_shstrndx)
    428  1.5    chs 	   : bfd_get_16(abfd, e32_hdr.e_shstrndx));
    429  1.6  joerg 	shstrtab = malloc(SH_SIZE(shstridx));
    430  1.5    chs 	if (shstrtab == NULL)
    431  1.5    chs 		goto out;
    432  1.5    chs 	if (pread(fd, shstrtab, SH_SIZE(shstridx), SH_OFFSET(shstridx)) !=
    433  1.5    chs 	    SH_SIZE(shstridx))
    434  1.5    chs 		goto out;
    435  1.5    chs 
    436  1.1  skrll 	for (i = 0; i < e_shnum; i++) {
    437  1.5    chs 		if (SH_TYPE(i) == SHT_SYMTAB || SH_TYPE(i) == SHT_STRTAB ||
    438  1.5    chs 		    !strcmp(shstrtab + SH_NAME(i), ".SUNW_ctf")) {
    439  1.1  skrll 			osymtabsize = *symtabsize;
    440  1.1  skrll 			*symtabsize += roundup(SH_SIZE(i), ISELF64 ? 8 : 4);
    441  1.1  skrll 			if ((*symtab = realloc(*symtab, *symtabsize)) == NULL)
    442  1.1  skrll 				goto out;
    443  1.1  skrll 
    444  1.1  skrll 			if (lseek(fd, SH_OFFSET(i), SEEK_SET) < 0)
    445  1.1  skrll 				goto out;
    446  1.1  skrll 			if (read(fd, *symtab + osymtabsize, SH_SIZE(i)) !=
    447  1.1  skrll 			    SH_SIZE(i))
    448  1.1  skrll 				goto out;
    449  1.1  skrll 			if (ISELF64) {
    450  1.1  skrll 				bfd_put_64(abfd, osymtabsize,
    451  1.1  skrll 				    s64hdr[i].sh_offset);
    452  1.1  skrll 			} else {
    453  1.1  skrll 				bfd_put_32(abfd, osymtabsize,
    454  1.1  skrll 				    s32hdr[i].sh_offset);
    455  1.1  skrll 			}
    456  1.1  skrll 		}
    457  1.1  skrll 	}
    458  1.1  skrll 
    459  1.1  skrll 	if (*symtab == NULL)
    460  1.1  skrll 		goto out;
    461  1.1  skrll 
    462  1.1  skrll 	/*
    463  1.1  skrll 	 * Copy updated section headers.
    464  1.1  skrll 	 */
    465  1.1  skrll 	memcpy(*symtab + sh_offset, shdr, sh_size);
    466  1.1  skrll 
    467  1.1  skrll 	/*
    468  1.1  skrll 	 * Update and copy the exec header.
    469  1.1  skrll 	 */
    470  1.1  skrll 	if (ISELF64) {
    471  1.1  skrll 		bfd_put_64(abfd, 0, e64_hdr.e_phoff);
    472  1.1  skrll 		bfd_put_64(abfd, sizeof(Elf64_External_Ehdr), e64_hdr.e_shoff);
    473  1.1  skrll 		bfd_put_16(abfd, 0, e64_hdr.e_phentsize);
    474  1.1  skrll 		bfd_put_16(abfd, 0, e64_hdr.e_phnum);
    475  1.1  skrll 	} else {
    476  1.1  skrll 		bfd_put_32(abfd, 0, e32_hdr.e_phoff);
    477  1.1  skrll 		bfd_put_32(abfd, sizeof(Elf32_External_Ehdr), e32_hdr.e_shoff);
    478  1.1  skrll 		bfd_put_16(abfd, 0, e32_hdr.e_phentsize);
    479  1.1  skrll 		bfd_put_16(abfd, 0, e32_hdr.e_phnum);
    480  1.1  skrll 	}
    481  1.1  skrll 	memcpy(*symtab, &ehdr, sizeof(ehdr));
    482  1.5    chs 	rv = 0;
    483  1.1  skrll 
    484  1.1  skrll out:
    485  1.5    chs 	if (shstrtab != NULL)
    486  1.5    chs 		free(shstrtab);
    487  1.1  skrll 	free(shdr);
    488  1.5    chs 	return (rv);
    489  1.1  skrll }
    490