| rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * hack-coff.c - hack the header of an xcoff file to fill in | 
|  | 3 | * a few fields needed by the Open Firmware xcoff loader on | 
|  | 4 | * Power Macs but not initialized by objcopy. | 
|  | 5 | * | 
|  | 6 | * Copyright (C) Paul Mackerras 1997. | 
|  | 7 | * | 
|  | 8 | * This program is free software; you can redistribute it and/or | 
|  | 9 | * modify it under the terms of the GNU General Public License | 
|  | 10 | * as published by the Free Software Foundation; either version | 
|  | 11 | * 2 of the License, or (at your option) any later version. | 
|  | 12 | */ | 
|  | 13 | #include <stdio.h> | 
|  | 14 | #include <stdlib.h> | 
|  | 15 | #include <unistd.h> | 
|  | 16 | #include <fcntl.h> | 
|  | 17 | #include <string.h> | 
|  | 18 | #include "rs6000.h" | 
|  | 19 |  | 
|  | 20 | #define AOUT_MAGIC	0x010b | 
|  | 21 |  | 
|  | 22 | #define get_16be(x)	((((unsigned char *)(x))[0] << 8) \ | 
|  | 23 | + ((unsigned char *)(x))[1]) | 
|  | 24 | #define put_16be(x, v)	(((unsigned char *)(x))[0] = (v) >> 8, \ | 
|  | 25 | ((unsigned char *)(x))[1] = (v) & 0xff) | 
|  | 26 | #define get_32be(x)	((((unsigned char *)(x))[0] << 24) \ | 
|  | 27 | + (((unsigned char *)(x))[1] << 16) \ | 
|  | 28 | + (((unsigned char *)(x))[2] << 8) \ | 
|  | 29 | + ((unsigned char *)(x))[3]) | 
|  | 30 |  | 
|  | 31 | int | 
|  | 32 | main(int ac, char **av) | 
|  | 33 | { | 
|  | 34 | int fd; | 
|  | 35 | int i, nsect; | 
|  | 36 | int aoutsz; | 
|  | 37 | struct external_filehdr fhdr; | 
|  | 38 | AOUTHDR aout; | 
|  | 39 | struct external_scnhdr shdr; | 
|  | 40 |  | 
|  | 41 | if (ac != 2) { | 
|  | 42 | fprintf(stderr, "Usage: hack-coff coff-file\n"); | 
|  | 43 | exit(1); | 
|  | 44 | } | 
|  | 45 | if ((fd = open(av[1], 2)) == -1) { | 
|  | 46 | perror(av[2]); | 
|  | 47 | exit(1); | 
|  | 48 | } | 
|  | 49 | if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) | 
|  | 50 | goto readerr; | 
|  | 51 | i = get_16be(fhdr.f_magic); | 
|  | 52 | if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { | 
|  | 53 | fprintf(stderr, "%s: not an xcoff file\n", av[1]); | 
|  | 54 | exit(1); | 
|  | 55 | } | 
|  | 56 | aoutsz = get_16be(fhdr.f_opthdr); | 
|  | 57 | if (read(fd, &aout, aoutsz) != aoutsz) | 
|  | 58 | goto readerr; | 
|  | 59 | nsect = get_16be(fhdr.f_nscns); | 
|  | 60 | for (i = 0; i < nsect; ++i) { | 
|  | 61 | if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) | 
|  | 62 | goto readerr; | 
|  | 63 | if (strcmp(shdr.s_name, ".text") == 0) { | 
|  | 64 | put_16be(aout.o_snentry, i+1); | 
|  | 65 | put_16be(aout.o_sntext, i+1); | 
|  | 66 | } else if (strcmp(shdr.s_name, ".data") == 0) { | 
|  | 67 | put_16be(aout.o_sndata, i+1); | 
|  | 68 | } else if (strcmp(shdr.s_name, ".bss") == 0) { | 
|  | 69 | put_16be(aout.o_snbss, i+1); | 
|  | 70 | } | 
|  | 71 | } | 
|  | 72 | put_16be(aout.magic, AOUT_MAGIC); | 
|  | 73 | if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 | 
|  | 74 | || write(fd, &aout, aoutsz) != aoutsz) { | 
|  | 75 | fprintf(stderr, "%s: write error\n", av[1]); | 
|  | 76 | exit(1); | 
|  | 77 | } | 
|  | 78 | close(fd); | 
|  | 79 | exit(0); | 
|  | 80 |  | 
|  | 81 | readerr: | 
|  | 82 | fprintf(stderr, "%s: read error or file too short\n", av[1]); | 
|  | 83 | exit(1); | 
|  | 84 | } |