11.13Skre/* $NetBSD: fixcoff.c,v 1.13 2024/10/29 11:37:57 kre Exp $ */ 21.1Swrstuden 31.1Swrstuden/* 41.1Swrstuden * Copyright (c) 1999 National Aeronautics & Space Administration 51.1Swrstuden * All rights reserved. 61.1Swrstuden * 71.1Swrstuden * This software was written by William Studenmund of the 81.1Swrstuden * Numerical Aerospace Similation Facility, NASA Ames Research Center. 91.1Swrstuden * 101.1Swrstuden * Redistribution and use in source and binary forms, with or without 111.1Swrstuden * modification, are permitted provided that the following conditions 121.1Swrstuden * are met: 131.1Swrstuden * 1. Redistributions of source code must retain the above copyright 141.1Swrstuden * notice, this list of conditions and the following disclaimer. 151.1Swrstuden * 2. Redistributions in binary form must reproduce the above copyright 161.1Swrstuden * notice, this list of conditions and the following disclaimer in the 171.1Swrstuden * documentation and/or other materials provided with the distribution. 181.2Ssoren * 3. Neither the name of the National Aeronautics & Space Administration 191.1Swrstuden * nor the names of its contributors may be used to endorse or promote 201.1Swrstuden * products derived from this software without specific prior written 211.1Swrstuden * permission. 221.1Swrstuden * 231.1Swrstuden * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION 241.1Swrstuden * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 251.1Swrstuden * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 261.1Swrstuden * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB- 271.1Swrstuden * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 281.1Swrstuden * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 291.1Swrstuden * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 301.1Swrstuden * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 311.1Swrstuden * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 321.1Swrstuden * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 331.1Swrstuden * POSSIBILITY OF SUCH DAMAGE. 341.1Swrstuden */ 351.1Swrstuden 361.1Swrstuden/* 371.1Swrstuden * This program fixes up the extended xcoff headers generated when an elf 381.1Swrstuden * file is turned into an xcoff one with the current objcopy. It should 391.1Swrstuden * go away someday, when objcopy will correctly fix up the output xcoff 401.1Swrstuden * 411.1Swrstuden * Partially inspired by hack-coff, written by Paul Mackerras. 421.1Swrstuden */ 431.8Smatt 441.8Smatt#if HAVE_NBTOOL_CONFIG_H 451.8Smatt#include "nbtool_config.h" 461.12Scjep#else /* HAVE_NBTOOL_CONFIG_H */ 471.12Scjep#include <sys/endian.h> 481.12Scjep#endif /* HAVE_NBTOOL_CONFIG_H */ 491.1Swrstuden 501.1Swrstuden#include <stdio.h> 511.1Swrstuden#include <stdlib.h> 521.1Swrstuden#include <unistd.h> 531.1Swrstuden#include <fcntl.h> 541.10Sgdamore 551.5Smrgstruct filehdr { 561.5Smrg#define U802WRMAGIC 0730 571.5Smrg#define U802ROMAGIC 0735 581.5Smrg#define U802TOCMAGIC 0737 591.5Smrg char f_magic[2]; 601.5Smrg char f_nsect[2]; 611.5Smrg char f_time[4]; 621.5Smrg char f_symtab[4]; 631.5Smrg char f_nsyms[4]; 641.5Smrg char f_opthdr[2]; 651.5Smrg char f_flags[2]; 661.5Smrg}; 671.5Smrg 681.5Smrgstruct sectionhdr { 691.5Smrg char s_name[8]; 701.5Smrg char s_paddr[4]; 711.5Smrg char s_vaddr[4]; 721.5Smrg char s_size[4]; 731.5Smrg char s_section[4]; 741.5Smrg char s_reloc[4]; 751.5Smrg char s_lineno[4]; 761.5Smrg char s_nreloc[2]; 771.5Smrg char s_nlineno[2]; 781.5Smrg char s_flags[4]; 791.5Smrg}; 801.5Smrg 811.5Smrgstruct aouthdr { 821.5Smrg char magic[2]; 831.5Smrg char vstamp[2]; 841.5Smrg char tsize[4]; 851.5Smrg char dsize[4]; 861.5Smrg char bsize[4]; 871.5Smrg char entry[4]; 881.5Smrg char text_start[4]; 891.5Smrg char data_start[4]; 901.5Smrg#define SMALL_AOUTSZ 28 911.5Smrg char o_toc[4]; 921.5Smrg char o_snentry[2]; 931.5Smrg char o_sntext[2]; 941.5Smrg char o_sndata[2]; 951.5Smrg char o_sntoc[2]; 961.5Smrg char o_snloader[2]; 971.5Smrg char o_snbss[2]; 981.5Smrg char o_algntext[2]; 991.5Smrg char o_algndata[2]; 1001.5Smrg char o_modtype[2]; 1011.5Smrg char o_cputype[2]; 1021.5Smrg char o_maxstack[4]; 1031.5Smrg char o_maxdata[4]; 1041.5Smrg char o_resv2[12]; 1051.5Smrg}; 1061.5Smrg#define RS6K_AOUTHDR_ZMAGIC 0x010B 1071.1Swrstuden 1081.1Swrstudenvoid 1091.13Skreusage(const char *prog) 1101.1Swrstuden{ 1111.1Swrstuden fprintf(stderr, "Usage: %s [-h] | [<file to fix>]\n", prog); 1121.1Swrstuden} 1131.1Swrstuden 1141.1Swrstudenvoid 1151.13Skrehelp(const char *prog) 1161.1Swrstuden{ 1171.5Smrg fprintf(stderr, "%s\tis designed to fix the xcoff headers in a\n",prog); 1181.1Swrstuden fprintf(stderr, 1191.1Swrstuden"\tbinary generated using objcopy from a non-xcoff source.\n"); 1201.1Swrstuden usage(prog); 1211.1Swrstuden exit(0); 1221.1Swrstuden} 1231.1Swrstuden 1241.13Skreint 1251.11Sdslmain(int argc, char * const *argv) 1261.1Swrstuden{ 1271.1Swrstuden int fd, i, n, ch; 1281.5Smrg struct filehdr fh; 1291.5Smrg struct aouthdr aoh; 1301.5Smrg struct sectionhdr sh; 1311.1Swrstuden 1321.1Swrstuden while ((ch = getopt(argc, argv, "h")) != -1) 1331.1Swrstuden switch (ch) { 1341.1Swrstuden case 'h': 1351.3Scgd help(getprogname()); 1361.1Swrstuden } 1371.1Swrstuden 1381.1Swrstuden argc -= optind; 1391.1Swrstuden argv += optind; 1401.1Swrstuden 1411.1Swrstuden if (argc != 1) { 1421.3Scgd usage(getprogname()); 1431.1Swrstuden exit(1); 1441.1Swrstuden } 1451.1Swrstuden 1461.1Swrstuden if ((fd = open(argv[0], O_RDWR, 0)) == -1) 1471.1Swrstuden err(i, "%s", argv[0]); 1481.1Swrstuden 1491.1Swrstuden /* 1501.1Swrstuden * Make sure it looks like an xcoff file.. 1511.1Swrstuden */ 1521.5Smrg if (read(fd, &fh, sizeof(fh)) != sizeof(fh)) 1531.1Swrstuden err(1, "%s reading header", argv[0]); 1541.1Swrstuden 1551.7Smatt i = be16toh(*(uint16_t *)fh.f_magic); 1561.1Swrstuden if ((i != U802WRMAGIC) && (i != U802ROMAGIC) && (i != U802TOCMAGIC)) 1571.1Swrstuden errx(1, "%s: not a valid xcoff file", argv[0]); 1581.1Swrstuden 1591.5Smrg /* Does the AOUT "Optional header" make sense? */ 1601.7Smatt i = be16toh(*(uint16_t *)fh.f_opthdr); 1611.1Swrstuden 1621.1Swrstuden if (i == SMALL_AOUTSZ) 1631.3Scgd errx(1, "%s: file has small \"optional\" header, inappropriate for use with %s", argv[0], getprogname()); 1641.5Smrg else if (i != sizeof(aoh)) 1651.1Swrstuden errx(1, "%s: invalid \"optional\" header", argv[0]); 1661.1Swrstuden 1671.1Swrstuden if (read(fd, &aoh, i) != i) 1681.1Swrstuden err(1, "%s reading \"optional\" header", argv[0]); 1691.1Swrstuden 1701.1Swrstuden /* Now start filing in the AOUT header */ 1711.7Smatt *(uint16_t *)aoh.magic = htobe16(RS6K_AOUTHDR_ZMAGIC); 1721.7Smatt n = be16toh(*(uint16_t *)fh.f_nsect); 1731.1Swrstuden 1741.1Swrstuden for (i = 0; i < n; i++) { 1751.5Smrg if (read(fd, &sh, sizeof(sh)) != sizeof(sh)) 1761.1Swrstuden err(1, "%s reading section headers", argv[0]); 1771.5Smrg if (strcmp(sh.s_name, ".text") == 0) { 1781.7Smatt *(uint16_t *)(aoh.o_snentry) = htobe16(i+1); 1791.7Smatt *(uint16_t *)(aoh.o_sntext) = htobe16(i+1); 1801.5Smrg } else if (strcmp(sh.s_name, ".data") == 0) { 1811.7Smatt *(uint16_t *)(aoh.o_sndata) = htobe16(i+1); 1821.5Smrg } else if (strcmp(sh.s_name, ".bss") == 0) { 1831.7Smatt *(uint16_t *)(aoh.o_snbss) = htobe16(i+1); 1841.1Swrstuden } 1851.1Swrstuden } 1861.1Swrstuden 1871.1Swrstuden /* now write it out */ 1881.5Smrg if (pwrite(fd, &aoh, sizeof(aoh), sizeof(struct filehdr)) 1891.1Swrstuden != sizeof(aoh)) 1901.1Swrstuden err(1, "%s writing modified header", argv[0]); 1911.1Swrstuden close(fd); 1921.1Swrstuden exit(0); 1931.1Swrstuden} 194