1 /* $NetBSD: bin_bfd.c,v 1.3 2018/04/14 17:53:22 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1996, 2002 Christopher G. Demetriou 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>> 30 */ 31 32 #if HAVE_NBTOOL_CONFIG_H 33 #include "nbtool_config.h" 34 #endif 35 36 #include <sys/cdefs.h> 37 __RCSID("$NetBSD: bin_bfd.c,v 1.3 2018/04/14 17:53:22 christos Exp $"); 38 39 #include <stdio.h> 40 #include <string.h> 41 #include <stdlib.h> 42 #include <err.h> 43 #include <bfd.h> 44 #include "bin.h" 45 46 void * 47 bin_open(int kfd, const char *kfile, const char *bfdname) 48 { 49 bfd *abfd; 50 bfd_init(); 51 if ((abfd = bfd_fdopenr(kfile, bfdname, kfd)) == NULL) { 52 bfd_perror("open"); 53 exit(1); 54 } 55 if (!bfd_check_format(abfd, bfd_object)) { 56 bfd_perror("check format"); 57 exit(1); 58 } 59 return abfd; 60 } 61 62 int 63 bin_find_md_root(void *bin, const char *mappedkfile, off_t size, 64 unsigned long text_start, 65 const char *root_name, const char *size_name, size_t *md_root_offset, 66 size_t *md_root_size_offset, uint32_t *md_root_size, int verbose) 67 { 68 bfd *abfd = bin; 69 long i; 70 long storage_needed; 71 long number_of_symbols; 72 asymbol **symbol_table = NULL; 73 struct symbols { 74 const char *name; 75 size_t offset; 76 } *s, symbols[3]; 77 78 symbols[0].offset = 0; 79 symbols[1].offset = 0; 80 symbols[0].name = root_name; 81 symbols[1].name = size_name; 82 symbols[2].name = NULL; 83 84 storage_needed = bfd_get_symtab_upper_bound(abfd); 85 if (storage_needed <= 0) { 86 warnx("bfd storage needed error"); 87 return 1; 88 } 89 90 symbol_table = malloc(storage_needed); 91 if (symbol_table == NULL) { 92 warn("symbol table"); 93 return 1; 94 } 95 96 number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table); 97 if (number_of_symbols <= 0) { 98 warnx("can't canonicalize symbol table"); 99 free(symbol_table); 100 return 1; 101 } 102 103 for (i = 0; i < number_of_symbols; i++) { 104 for (s = symbols; s->name != NULL; s++) { 105 const char *sym = symbol_table[i]->name; 106 107 /* 108 * match symbol prefix '_' or ''. 109 */ 110 if (!strcmp(s->name, sym) || 111 !strcmp(s->name + 1, sym)) { 112 s->offset = 113 (size_t)(symbol_table[i]->section->filepos 114 + symbol_table[i]->value); 115 } 116 } 117 } 118 119 free(symbol_table); 120 121 for (s = symbols; s->name != NULL; s++) { 122 if (s->offset == 0) { 123 warnx("missing offset for `%s'", s->name); 124 return 1; 125 } 126 } 127 128 *md_root_offset = symbols[0].offset; 129 *md_root_size_offset = symbols[1].offset; 130 *md_root_size = bfd_get_32(abfd, &mappedkfile[*md_root_size_offset]); 131 132 return 0; 133 } 134 135 void 136 bin_put_32(void *bin, off_t size, char *buf) 137 { 138 bfd_put_32((struct bfd *)bin, size, buf); 139 } 140 141 void 142 bin_close(void *bin) 143 { 144 bfd_close_all_done((struct bfd *)bin); 145 } 146 147 const char ** 148 bin_supported_targets(void) 149 { 150 return bfd_target_list(); 151 } 152