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