1 1.30 rin /* $NetBSD: elf2bb.c,v 1.30 2022/04/29 07:12:42 rin Exp $ */ 2 1.1 mhitch 3 1.1 mhitch /*- 4 1.12 is * Copyright (c) 1996,2006 The NetBSD Foundation, Inc. 5 1.1 mhitch * All rights reserved. 6 1.1 mhitch * 7 1.1 mhitch * This code is derived from software contributed to The NetBSD Foundation 8 1.1 mhitch * by Ignatios Souvatzis. 9 1.1 mhitch * 10 1.1 mhitch * Redistribution and use in source and binary forms, with or without 11 1.1 mhitch * modification, are permitted provided that the following conditions 12 1.1 mhitch * are met: 13 1.1 mhitch * 1. Redistributions of source code must retain the above copyright 14 1.1 mhitch * notice, this list of conditions and the following disclaimer. 15 1.1 mhitch * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 mhitch * notice, this list of conditions and the following disclaimer in the 17 1.1 mhitch * documentation and/or other materials provided with the distribution. 18 1.1 mhitch * 19 1.1 mhitch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 mhitch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 mhitch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 mhitch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 mhitch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 mhitch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 mhitch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 mhitch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 mhitch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 mhitch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 mhitch * POSSIBILITY OF SUCH DAMAGE. 30 1.1 mhitch */ 31 1.1 mhitch 32 1.9 jmc #if HAVE_NBTOOL_CONFIG_H 33 1.9 jmc #include "nbtool_config.h" 34 1.9 jmc #endif 35 1.9 jmc 36 1.18 rin #include <sys/param.h> 37 1.1 mhitch #include <sys/types.h> 38 1.1 mhitch 39 1.1 mhitch #include <err.h> 40 1.1 mhitch #include <fcntl.h> 41 1.1 mhitch #include <stdio.h> 42 1.1 mhitch #include <stdlib.h> 43 1.1 mhitch #include <string.h> 44 1.1 mhitch #include <unistd.h> 45 1.1 mhitch 46 1.1 mhitch #include <sys/mman.h> /* of the machine we're running on */ 47 1.13 gdamore 48 1.13 gdamore #ifndef HAVE_NBTOOL_CONFIG_H 49 1.9 jmc #include <sys/endian.h> /* of the machine we're running on */ 50 1.13 gdamore #endif 51 1.1 mhitch 52 1.9 jmc #include <sys/exec_elf.h> /* TARGET */ 53 1.1 mhitch #ifndef R_68K_32 /* XXX host not m68k XXX */ 54 1.1 mhitch #define R_68K_32 1 55 1.1 mhitch #define R_68K_PC32 4 56 1.1 mhitch #define R_68K_PC16 5 57 1.1 mhitch #endif 58 1.1 mhitch 59 1.1 mhitch #include "elf2bb.h" 60 1.1 mhitch #include "chksum.h" 61 1.1 mhitch 62 1.24 rin static void usage(void); 63 1.24 rin static int intcmp(const void *, const void *); 64 1.24 rin static int eval(Elf32_Sym *, uint32_t *); 65 1.1 mhitch 66 1.1 mhitch #ifdef DEBUG 67 1.1 mhitch #define dprintf(x) if (debug) printf x 68 1.1 mhitch #else 69 1.1 mhitch #define dprintf(x) 70 1.1 mhitch #endif 71 1.1 mhitch int debug; 72 1.1 mhitch 73 1.1 mhitch #define BBSIZE 8192 74 1.1 mhitch 75 1.1 mhitch char *progname; 76 1.1 mhitch int bbsize = BBSIZE; 77 1.22 rin uint8_t *buffer; 78 1.22 rin uint32_t *relbuf; 79 1.26 rin /* can't have more relocs than that */ 80 1.1 mhitch 81 1.24 rin static int 82 1.2 aymeric intcmp(const void *i, const void *j) 83 1.1 mhitch { 84 1.1 mhitch int r; 85 1.1 mhitch 86 1.22 rin r = (*(uint32_t *)i) < (*(uint32_t *)j); 87 1.1 mhitch 88 1.26 rin return 2 * r - 1; 89 1.1 mhitch } 90 1.1 mhitch 91 1.1 mhitch int 92 1.2 aymeric main(int argc, char *argv[]) 93 1.1 mhitch { 94 1.1 mhitch int ifd, ofd; 95 1.14 christos void *image; 96 1.1 mhitch Elf32_Ehdr *eh; 97 1.1 mhitch Elf32_Shdr *sh; 98 1.1 mhitch char *shstrtab; 99 1.1 mhitch Elf32_Sym *symtab; 100 1.1 mhitch char *strtab; 101 1.22 rin uint32_t *lptr; 102 1.1 mhitch int i, l, delta; 103 1.22 rin uint8_t *rpo; 104 1.22 rin uint32_t oldaddr, addrdiff; 105 1.22 rin uint32_t tsz, dsz, bsz, trsz, relver; 106 1.22 rin uint32_t pcrelsz, r32sz; 107 1.1 mhitch int sumsize = 16; 108 1.1 mhitch int c; 109 1.22 rin uint32_t *sect_offset; 110 1.3 mhitch int undefsyms; 111 1.10 chs uint32_t tmp32; 112 1.10 chs uint16_t tmp16; 113 1.18 rin int Sflag = 0; 114 1.1 mhitch 115 1.1 mhitch progname = argv[0]; 116 1.1 mhitch 117 1.1 mhitch /* insert getopt here, if needed */ 118 1.3 mhitch while ((c = getopt(argc, argv, "dFS")) != -1) 119 1.1 mhitch switch(c) { 120 1.1 mhitch case 'F': 121 1.1 mhitch sumsize = 2; 122 1.1 mhitch break; 123 1.1 mhitch case 'S': 124 1.3 mhitch /* Dynamically size second-stage boot */ 125 1.18 rin Sflag = 1; 126 1.1 mhitch break; 127 1.1 mhitch case 'd': 128 1.1 mhitch debug = 1; 129 1.1 mhitch break; 130 1.1 mhitch default: 131 1.1 mhitch usage(); 132 1.1 mhitch } 133 1.1 mhitch argv += optind; 134 1.1 mhitch argc -= optind; 135 1.1 mhitch 136 1.1 mhitch if (argc < 2) 137 1.1 mhitch usage(); 138 1.1 mhitch 139 1.1 mhitch ifd = open(argv[0], O_RDONLY, 0); 140 1.1 mhitch if (ifd < 0) 141 1.1 mhitch err(1, "Can't open %s", argv[0]); 142 1.1 mhitch 143 1.1 mhitch image = mmap(0, 65536, PROT_READ, MAP_FILE|MAP_PRIVATE, ifd, 0); 144 1.17 riastrad if (image == MAP_FAILED) 145 1.1 mhitch err(1, "Can't mmap %s", argv[1]); 146 1.1 mhitch 147 1.1 mhitch eh = (Elf32_Ehdr *)image; /* XXX endianness */ 148 1.1 mhitch 149 1.26 rin dprintf(("%04x sections, offset %08x\n", be16toh(eh->e_shnum), 150 1.26 rin be32toh(eh->e_shoff))); 151 1.23 rin if (be16toh(eh->e_type) != ET_REL) 152 1.5 grant errx(1, "%s isn't a relocatable file, type=%d", 153 1.23 rin argv[0], be16toh(eh->e_type)); 154 1.23 rin if (be16toh(eh->e_machine) != EM_68K) 155 1.5 grant errx(1, "%s isn't M68K, machine=%d", argv[0], 156 1.23 rin be16toh(eh->e_machine)); 157 1.1 mhitch 158 1.8 mhitch /* Calculate sizes from section headers. */ 159 1.18 rin tsz = dsz = bsz = trsz = 0; 160 1.23 rin sh = (Elf32_Shdr *)(image + be32toh(eh->e_shoff)); 161 1.26 rin shstrtab = (char *)(image + 162 1.26 rin be32toh(sh[be16toh(eh->e_shstrndx)].sh_offset)); 163 1.26 rin symtab = NULL; /* XXX */ 164 1.26 rin strtab = NULL; /* XXX */ 165 1.26 rin dprintf((" name type flags" 166 1.26 rin " addr offset size align\n")); 167 1.23 rin for (i = 0; i < be16toh(eh->e_shnum); ++i) { 168 1.22 rin uint32_t sh_size; 169 1.1 mhitch 170 1.26 rin dprintf(("%2d: %08x %-16s %08x %08x %08x %08x %08x %08x\n", i, 171 1.23 rin be32toh(sh[i].sh_name), shstrtab + be32toh(sh[i].sh_name), 172 1.26 rin be32toh(sh[i].sh_type), be32toh(sh[i].sh_flags), 173 1.26 rin be32toh(sh[i].sh_addr), be32toh(sh[i].sh_offset), 174 1.26 rin be32toh(sh[i].sh_size), be32toh(sh[i].sh_addralign))); 175 1.26 rin sh_size = (be32toh(sh[i].sh_size) + 176 1.26 rin be32toh(sh[i].sh_addralign) - 1) & 177 1.26 rin (- be32toh(sh[i].sh_addralign)); 178 1.26 rin /* 179 1.26 rin * If section allocates memory, add to text, data, 180 1.26 rin * or bss size. 181 1.26 rin */ 182 1.23 rin if (be32toh(sh[i].sh_flags) & SHF_ALLOC) { 183 1.23 rin if (be32toh(sh[i].sh_type) == SHT_PROGBITS) { 184 1.23 rin if (be32toh(sh[i].sh_flags) & SHF_WRITE) 185 1.8 mhitch dsz += sh_size; 186 1.8 mhitch else 187 1.8 mhitch tsz += sh_size; 188 1.8 mhitch } else 189 1.8 mhitch bsz += sh_size; 190 1.8 mhitch /* If it's relocations, add to relocation count */ 191 1.23 rin } else if (be32toh(sh[i].sh_type) == SHT_RELA) { 192 1.23 rin trsz += be32toh(sh[i].sh_size); 193 1.1 mhitch } 194 1.1 mhitch /* Check for SHT_REL? */ 195 1.8 mhitch /* Get symbol table location. */ 196 1.23 rin else if (be32toh(sh[i].sh_type) == SHT_SYMTAB) { 197 1.26 rin symtab = (Elf32_Sym *)(image + 198 1.26 rin be32toh(sh[i].sh_offset)); 199 1.26 rin } else if (strcmp(".strtab", shstrtab + 200 1.26 rin be32toh(sh[i].sh_name)) == 0) { 201 1.23 rin strtab = image + be32toh(sh[i].sh_offset); 202 1.1 mhitch } 203 1.1 mhitch } 204 1.1 mhitch dprintf(("tsz = 0x%x, dsz = 0x%x, bsz = 0x%x, total 0x%x\n", 205 1.1 mhitch tsz, dsz, bsz, tsz + dsz + bsz)); 206 1.1 mhitch 207 1.1 mhitch if (trsz == 0) 208 1.5 grant errx(1, "%s has no relocation records.", argv[0]); 209 1.1 mhitch 210 1.26 rin dprintf(("%d relocs\n", trsz / 12)); 211 1.1 mhitch 212 1.18 rin if (Sflag) { 213 1.12 is /* 214 1.18 rin * For second-stage boot, there's no limit for binary size, 215 1.18 rin * and we dynamically scale it. However, it should be small 216 1.18 rin * enough so that 217 1.18 rin * 218 1.18 rin * (1) all R_68K_PC16 symbols get relocated, and 219 1.18 rin * 220 1.18 rin * (2) all values in our relocation table for R_68K_32 221 1.18 rin * symbols fit within 16-bit integer. 222 1.18 rin * 223 1.18 rin * Both will be checked by codes below. 224 1.18 rin * 225 1.18 rin * At the moment, (2) is satisfied with sufficient margin. 226 1.18 rin * But if it is not the case in the future, format for 227 1.18 rin * relocation table should be modified. 228 1.12 is */ 229 1.18 rin bbsize = roundup(tsz + dsz, 512); 230 1.3 mhitch sumsize = bbsize / 512; 231 1.18 rin } else { 232 1.18 rin /* 233 1.18 rin * We have one contiguous area allocated by the ROM to us. 234 1.18 rin */ 235 1.18 rin if (tsz + dsz + bsz > bbsize) 236 1.18 rin errx(1, "%s: resulting image too big %d+%d+%d=%d", 237 1.18 rin argv[0], tsz, dsz, bsz, tsz + dsz + bsz); 238 1.3 mhitch } 239 1.3 mhitch 240 1.18 rin buffer = NULL; 241 1.18 rin relbuf = NULL; 242 1.18 rin 243 1.26 rin retry: 244 1.18 rin pcrelsz = r32sz = 0; 245 1.18 rin 246 1.18 rin buffer = realloc(buffer, bbsize); 247 1.18 rin relbuf = realloc(relbuf, bbsize); 248 1.3 mhitch if (buffer == NULL || relbuf == NULL) 249 1.3 mhitch err(1, "Unable to allocate memory\n"); 250 1.3 mhitch 251 1.4 mjl memset(buffer, 0, bbsize); 252 1.1 mhitch 253 1.1 mhitch /* Allocate and load loadable sections */ 254 1.25 rin sect_offset = malloc(be16toh(eh->e_shnum) * sizeof(uint32_t)); 255 1.23 rin for (i = 0, l = 0; i < be16toh(eh->e_shnum); ++i) { 256 1.23 rin if (be32toh(sh[i].sh_flags) & SHF_ALLOC) { 257 1.1 mhitch dprintf(("vaddr 0x%04x size 0x%04x offset 0x%04x section %s\n", 258 1.23 rin l, be32toh(sh[i].sh_size), be32toh(sh[i].sh_offset), 259 1.23 rin shstrtab + be32toh(sh[i].sh_name))); 260 1.23 rin if (be32toh(sh[i].sh_type) == SHT_PROGBITS) 261 1.26 rin memcpy(buffer + l, 262 1.26 rin image + be32toh(sh[i].sh_offset), 263 1.23 rin be32toh(sh[i].sh_size)); 264 1.1 mhitch sect_offset[i] = l; 265 1.26 rin l += (be32toh(sh[i].sh_size) + 266 1.26 rin be32toh(sh[i].sh_addralign) - 1) & 267 1.26 rin (- be32toh(sh[i].sh_addralign)); 268 1.1 mhitch } 269 1.1 mhitch } 270 1.1 mhitch 271 1.1 mhitch /* 272 1.2 aymeric * Hm. This tool REALLY should understand more than one 273 1.1 mhitch * relocator version. For now, check that the relocator at 274 1.1 mhitch * the image start does understand what we output. 275 1.1 mhitch */ 276 1.23 rin relver = be32toh(*(uint32_t *)(buffer + 4)); 277 1.1 mhitch switch (relver) { 278 1.1 mhitch default: 279 1.5 grant errx(1, "%s: unrecognized relocator version %d", 280 1.1 mhitch argv[0], relver); 281 1.26 rin /* NOTREACHED */ 282 1.1 mhitch 283 1.1 mhitch case RELVER_RELATIVE_BYTES: 284 1.1 mhitch rpo = buffer + bbsize - 1; 285 1.1 mhitch delta = -1; 286 1.1 mhitch break; 287 1.1 mhitch 288 1.1 mhitch case RELVER_RELATIVE_BYTES_FORWARD: 289 1.1 mhitch rpo = buffer + tsz + dsz; 290 1.1 mhitch delta = +1; 291 1.29 rin *(uint16_t *)(buffer + 14) /* reltab */ = htobe16(tsz + dsz); 292 1.1 mhitch break; 293 1.1 mhitch } 294 1.1 mhitch 295 1.1 mhitch if (symtab == NULL) 296 1.5 grant errx(1, "No symbol table found"); 297 1.1 mhitch /* 298 1.1 mhitch * Link sections and generate relocation data 299 1.1 mhitch * Nasty: .text, .rodata, .data, .bss sections are not linked 300 1.1 mhitch * Symbol table values relative to start of sections. 301 1.1 mhitch * For each relocation entry: 302 1.1 mhitch * Symbol value needs to be calculated: value + section offset 303 1.1 mhitch * Image data adjusted to calculated value of symbol + addend 304 1.1 mhitch * Add relocation table entry for 32-bit relocatable values 305 1.1 mhitch * PC-relative entries will be absolute and don't need relocation 306 1.1 mhitch */ 307 1.3 mhitch undefsyms = 0; 308 1.23 rin for (i = 0; i < be16toh(eh->e_shnum); ++i) { 309 1.1 mhitch int n; 310 1.1 mhitch Elf32_Rela *ra; 311 1.22 rin uint8_t *base; 312 1.1 mhitch 313 1.23 rin if (be32toh(sh[i].sh_type) != SHT_RELA) 314 1.1 mhitch continue; 315 1.1 mhitch base = NULL; 316 1.23 rin if (strncmp(shstrtab + be32toh(sh[i].sh_name), ".rela", 5) != 0) 317 1.26 rin err(1, "bad relocation section name %s", 318 1.26 rin shstrtab + be32toh(sh[i].sh_name)); 319 1.23 rin for (n = 0; n < be16toh(eh->e_shnum); ++n) { 320 1.26 rin if (strcmp(shstrtab + be32toh(sh[i].sh_name) + 5, 321 1.26 rin shstrtab + be32toh(sh[n].sh_name)) != 0) 322 1.1 mhitch continue; 323 1.1 mhitch base = buffer + sect_offset[n]; 324 1.1 mhitch break; 325 1.1 mhitch } 326 1.1 mhitch if (base == NULL) 327 1.26 rin errx(1, "Can't find section for reloc %s", 328 1.26 rin shstrtab + be32toh(sh[i].sh_name)); 329 1.23 rin ra = (Elf32_Rela *)(image + be32toh(sh[i].sh_offset)); 330 1.26 rin for (n = 0; n < be32toh(sh[i].sh_size); 331 1.26 rin n += sizeof(Elf32_Rela), ++ra) { 332 1.3 mhitch Elf32_Sym *s; 333 1.1 mhitch int value; 334 1.3 mhitch 335 1.23 rin s = &symtab[ELF32_R_SYM(be32toh(ra->r_info))]; 336 1.3 mhitch if (s->st_shndx == ELF_SYM_UNDEFINED) { 337 1.3 mhitch fprintf(stderr, "Undefined symbol: %s\n", 338 1.23 rin strtab + be32toh(s->st_name)); 339 1.3 mhitch ++undefsyms; 340 1.3 mhitch } 341 1.23 rin value = be32toh(ra->r_addend) + eval(s, sect_offset); 342 1.1 mhitch dprintf(("reloc %04x info %04x (type %d sym %d) add 0x%x val %x\n", 343 1.23 rin be32toh(ra->r_offset), be32toh(ra->r_info), 344 1.23 rin ELF32_R_TYPE(be32toh(ra->r_info)), 345 1.23 rin ELF32_R_SYM(be32toh(ra->r_info)), 346 1.23 rin be32toh(ra->r_addend), value)); 347 1.23 rin switch (ELF32_R_TYPE(be32toh(ra->r_info))) { 348 1.1 mhitch case R_68K_32: 349 1.10 chs tmp32 = htobe32(value); 350 1.23 rin memcpy(base + be32toh(ra->r_offset), &tmp32, 351 1.10 chs sizeof(tmp32)); 352 1.26 rin relbuf[r32sz++] = (base - buffer) + 353 1.26 rin be32toh(ra->r_offset); 354 1.1 mhitch break; 355 1.1 mhitch case R_68K_PC32: 356 1.1 mhitch ++pcrelsz; 357 1.23 rin tmp32 = htobe32(value - be32toh(ra->r_offset)); 358 1.23 rin memcpy(base + be32toh(ra->r_offset), &tmp32, 359 1.10 chs sizeof(tmp32)); 360 1.1 mhitch break; 361 1.1 mhitch case R_68K_PC16: 362 1.1 mhitch ++pcrelsz; 363 1.23 rin value -= be32toh(ra->r_offset); 364 1.7 mhitch if (value < -0x8000 || value > 0x7fff) 365 1.26 rin errx(1, "PC-relative offset out of range: %x\n", 366 1.7 mhitch value); 367 1.10 chs tmp16 = htobe16(value); 368 1.23 rin memcpy(base + be32toh(ra->r_offset), &tmp16, 369 1.10 chs sizeof(tmp16)); 370 1.1 mhitch break; 371 1.1 mhitch default: 372 1.1 mhitch errx(1, "Relocation type %d not supported", 373 1.23 rin ELF32_R_TYPE(be32toh(ra->r_info))); 374 1.1 mhitch } 375 1.1 mhitch } 376 1.1 mhitch } 377 1.1 mhitch dprintf(("%d PC-relative relocations, %d 32-bit relocations\n", 378 1.1 mhitch pcrelsz, r32sz)); 379 1.26 rin printf("%d absolute reloc%s found, ", r32sz, r32sz == 1 ? "" : "s"); 380 1.1 mhitch 381 1.1 mhitch i = r32sz; 382 1.1 mhitch if (i > 1) 383 1.1 mhitch heapsort(relbuf, r32sz, 4, intcmp); 384 1.1 mhitch 385 1.1 mhitch oldaddr = 0; 386 1.1 mhitch 387 1.26 rin for (--i; i >= 0; --i) { 388 1.1 mhitch dprintf(("0x%04x: ", relbuf[i])); 389 1.22 rin lptr = (uint32_t *)&buffer[relbuf[i]]; 390 1.1 mhitch addrdiff = relbuf[i] - oldaddr; 391 1.1 mhitch dprintf(("(0x%04x, 0x%04x): ", *lptr, addrdiff)); 392 1.18 rin if (addrdiff > 0xffff) { 393 1.18 rin errx(1, "addrdiff overflows: relbuf = 0x%08x, " 394 1.18 rin "oldaddr = 0x%08x, abort.\n", relbuf[i], oldaddr); 395 1.18 rin } else if (addrdiff > 0xff) { 396 1.1 mhitch *rpo = 0; 397 1.30 rin tmp16 = htobe16(addrdiff); 398 1.1 mhitch if (delta > 0) { 399 1.1 mhitch ++rpo; 400 1.30 rin memcpy(rpo, &tmp16, sizeof(tmp16)); 401 1.30 rin rpo += sizeof(tmp16); 402 1.1 mhitch dprintf(("%02x%02x%02x\n", 403 1.1 mhitch rpo[-3], rpo[-2], rpo[-1])); 404 1.1 mhitch } else { 405 1.30 rin rpo -= sizeof(tmp16); 406 1.30 rin memcpy(rpo, &tmp16, sizeof(tmp16)); 407 1.1 mhitch --rpo; 408 1.1 mhitch dprintf(("%02x%02x%02x\n", 409 1.1 mhitch rpo[0], rpo[1], rpo[2])); 410 1.1 mhitch } 411 1.1 mhitch } else { 412 1.1 mhitch *rpo = addrdiff; 413 1.1 mhitch dprintf(("%02x\n", *rpo)); 414 1.1 mhitch rpo += delta; 415 1.1 mhitch } 416 1.1 mhitch 417 1.1 mhitch oldaddr = relbuf[i]; 418 1.1 mhitch 419 1.26 rin if (delta < 0 ? 420 1.26 rin rpo <= buffer + tsz + dsz : rpo >= buffer + bbsize) { 421 1.18 rin printf("relocs don't fit, "); 422 1.18 rin if (Sflag) { 423 1.18 rin printf("retry.\n"); 424 1.18 rin bbsize += 512; 425 1.18 rin sumsize++; 426 1.18 rin goto retry; 427 1.18 rin } else 428 1.18 rin errx(1, "abort."); 429 1.18 rin } 430 1.1 mhitch } 431 1.1 mhitch *rpo = 0; rpo += delta; 432 1.1 mhitch *rpo = 0; rpo += delta; 433 1.1 mhitch *rpo = 0; rpo += delta; 434 1.1 mhitch 435 1.28 rin printf("using %td bytes, %td bytes remaining.\n", 436 1.28 rin delta > 0 ? rpo - buffer - tsz - dsz : buffer + bbsize - rpo, 437 1.28 rin delta > 0 ? buffer + bbsize - rpo : rpo - buffer - tsz - dsz); 438 1.1 mhitch /* 439 1.1 mhitch * RELOCs must fit into the bss area. 440 1.1 mhitch */ 441 1.26 rin if (delta < 0 ? 442 1.26 rin rpo <= buffer + tsz + dsz : rpo >= buffer + bbsize) { 443 1.18 rin printf("relocs don't fit, "); 444 1.18 rin if (Sflag) { 445 1.18 rin printf("retry.\n"); 446 1.18 rin bbsize += 512; 447 1.18 rin sumsize++; 448 1.18 rin goto retry; 449 1.18 rin } else 450 1.18 rin errx(1, "abort."); 451 1.18 rin } 452 1.3 mhitch 453 1.3 mhitch if (undefsyms > 0) 454 1.3 mhitch errx(1, "Undefined symbols referenced"); 455 1.1 mhitch 456 1.22 rin ((uint32_t *)buffer)[1] = 0; 457 1.26 rin ((uint32_t *)buffer)[1] = htobe32((0xffffffff - 458 1.26 rin chksum((uint32_t *)buffer, sumsize * 512 / 4))); 459 1.1 mhitch 460 1.1 mhitch ofd = open(argv[1], O_CREAT|O_WRONLY, 0644); 461 1.1 mhitch if (ofd < 0) 462 1.1 mhitch err(1, "Can't open %s", argv[1]); 463 1.1 mhitch 464 1.1 mhitch if (write(ofd, buffer, bbsize) != bbsize) 465 1.1 mhitch err(1, "Writing output file"); 466 1.1 mhitch 467 1.1 mhitch exit(0); 468 1.1 mhitch } 469 1.1 mhitch 470 1.27 rin static void 471 1.2 aymeric usage(void) 472 1.1 mhitch { 473 1.1 mhitch fprintf(stderr, "Usage: %s [-F] bootprog bootprog.bin\n", 474 1.1 mhitch progname); 475 1.1 mhitch exit(1); 476 1.1 mhitch /* NOTREACHED */ 477 1.1 mhitch } 478 1.1 mhitch 479 1.27 rin static int 480 1.22 rin eval(Elf32_Sym *s, uint32_t *o) 481 1.1 mhitch { 482 1.1 mhitch int value; 483 1.1 mhitch 484 1.23 rin value = be32toh(s->st_value); 485 1.23 rin if (be16toh(s->st_shndx) < 0xf000) 486 1.23 rin value += o[be16toh(s->st_shndx)]; 487 1.1 mhitch else 488 1.23 rin printf("eval: %x\n", be16toh(s->st_shndx)); 489 1.1 mhitch return value; 490 1.1 mhitch } 491