fixcoff.c revision 1.10
11.10Sgdamore/* $NetBSD: fixcoff.c,v 1.10 2006/04/07 02:34:55 gdamore 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.8Smatt#endif 471.1Swrstuden 481.1Swrstuden#include <stdio.h> 491.1Swrstuden#include <stdlib.h> 501.1Swrstuden#include <unistd.h> 511.1Swrstuden#include <fcntl.h> 521.10Sgdamore 531.10Sgdamore#if HAVE_NBTOOL_CONFIG_H 541.10Sgdamore 551.10Sgdamore#if WORDS_BIGENDIAN 561.10Sgdamore#define htobe16(x) (x) 571.10Sgdamore#else 581.10Sgdamorestatic unsigned short 591.10Sgdamore__htobe16(unsigned short x) 601.10Sgdamore{ 611.10Sgdamore return (((x & 0xff00) >> 8) | ((x & 0x00ff) << 8)); 621.10Sgdamore} 631.10Sgdamore#define htobe16(x) __htobe16(x) 641.10Sgdamore#endif /* WORDS_BIGENDIAN */ 651.10Sgdamore 661.10Sgdamore#else /* HAVE_NBTOOL_CONFIG_H */ 671.7Smatt#include <sys/endian.h> 681.10Sgdamore#endif /* HAVE_NBTOOL_CONFIG_H */ 691.1Swrstuden 701.5Smrgstruct filehdr { 711.5Smrg#define U802WRMAGIC 0730 721.5Smrg#define U802ROMAGIC 0735 731.5Smrg#define U802TOCMAGIC 0737 741.5Smrg char f_magic[2]; 751.5Smrg char f_nsect[2]; 761.5Smrg char f_time[4]; 771.5Smrg char f_symtab[4]; 781.5Smrg char f_nsyms[4]; 791.5Smrg char f_opthdr[2]; 801.5Smrg char f_flags[2]; 811.5Smrg}; 821.5Smrg 831.5Smrgstruct sectionhdr { 841.5Smrg char s_name[8]; 851.5Smrg char s_paddr[4]; 861.5Smrg char s_vaddr[4]; 871.5Smrg char s_size[4]; 881.5Smrg char s_section[4]; 891.5Smrg char s_reloc[4]; 901.5Smrg char s_lineno[4]; 911.5Smrg char s_nreloc[2]; 921.5Smrg char s_nlineno[2]; 931.5Smrg char s_flags[4]; 941.5Smrg}; 951.5Smrg 961.5Smrgstruct aouthdr { 971.5Smrg char magic[2]; 981.5Smrg char vstamp[2]; 991.5Smrg char tsize[4]; 1001.5Smrg char dsize[4]; 1011.5Smrg char bsize[4]; 1021.5Smrg char entry[4]; 1031.5Smrg char text_start[4]; 1041.5Smrg char data_start[4]; 1051.5Smrg#define SMALL_AOUTSZ 28 1061.5Smrg char o_toc[4]; 1071.5Smrg char o_snentry[2]; 1081.5Smrg char o_sntext[2]; 1091.5Smrg char o_sndata[2]; 1101.5Smrg char o_sntoc[2]; 1111.5Smrg char o_snloader[2]; 1121.5Smrg char o_snbss[2]; 1131.5Smrg char o_algntext[2]; 1141.5Smrg char o_algndata[2]; 1151.5Smrg char o_modtype[2]; 1161.5Smrg char o_cputype[2]; 1171.5Smrg char o_maxstack[4]; 1181.5Smrg char o_maxdata[4]; 1191.5Smrg char o_resv2[12]; 1201.5Smrg}; 1211.5Smrg#define RS6K_AOUTHDR_ZMAGIC 0x010B 1221.1Swrstuden 1231.1Swrstudenvoid 1241.1Swrstudenusage(prog) 1251.1Swrstuden char *prog; 1261.1Swrstuden{ 1271.1Swrstuden fprintf(stderr, "Usage: %s [-h] | [<file to fix>]\n", prog); 1281.1Swrstuden} 1291.1Swrstuden 1301.1Swrstudenvoid 1311.1Swrstudenhelp(prog) 1321.1Swrstuden char *prog; 1331.1Swrstuden{ 1341.5Smrg fprintf(stderr, "%s\tis designed to fix the xcoff headers in a\n",prog); 1351.1Swrstuden fprintf(stderr, 1361.1Swrstuden"\tbinary generated using objcopy from a non-xcoff source.\n"); 1371.1Swrstuden usage(prog); 1381.1Swrstuden exit(0); 1391.1Swrstuden} 1401.1Swrstuden 1411.1Swrstudenmain(argc, argv) 1421.1Swrstuden int argc; 1431.1Swrstuden char * const *argv; 1441.1Swrstuden{ 1451.1Swrstuden int fd, i, n, ch; 1461.5Smrg struct filehdr fh; 1471.5Smrg struct aouthdr aoh; 1481.5Smrg struct sectionhdr sh; 1491.1Swrstuden 1501.1Swrstuden while ((ch = getopt(argc, argv, "h")) != -1) 1511.1Swrstuden switch (ch) { 1521.1Swrstuden case 'h': 1531.3Scgd help(getprogname()); 1541.1Swrstuden } 1551.1Swrstuden 1561.1Swrstuden argc -= optind; 1571.1Swrstuden argv += optind; 1581.1Swrstuden 1591.1Swrstuden if (argc != 1) { 1601.3Scgd usage(getprogname()); 1611.1Swrstuden exit(1); 1621.1Swrstuden } 1631.1Swrstuden 1641.1Swrstuden if ((fd = open(argv[0], O_RDWR, 0)) == -1) 1651.1Swrstuden err(i, "%s", argv[0]); 1661.1Swrstuden 1671.1Swrstuden /* 1681.1Swrstuden * Make sure it looks like an xcoff file.. 1691.1Swrstuden */ 1701.5Smrg if (read(fd, &fh, sizeof(fh)) != sizeof(fh)) 1711.1Swrstuden err(1, "%s reading header", argv[0]); 1721.1Swrstuden 1731.7Smatt i = be16toh(*(uint16_t *)fh.f_magic); 1741.1Swrstuden if ((i != U802WRMAGIC) && (i != U802ROMAGIC) && (i != U802TOCMAGIC)) 1751.1Swrstuden errx(1, "%s: not a valid xcoff file", argv[0]); 1761.1Swrstuden 1771.5Smrg /* Does the AOUT "Optional header" make sense? */ 1781.7Smatt i = be16toh(*(uint16_t *)fh.f_opthdr); 1791.1Swrstuden 1801.1Swrstuden if (i == SMALL_AOUTSZ) 1811.3Scgd errx(1, "%s: file has small \"optional\" header, inappropriate for use with %s", argv[0], getprogname()); 1821.5Smrg else if (i != sizeof(aoh)) 1831.1Swrstuden errx(1, "%s: invalid \"optional\" header", argv[0]); 1841.1Swrstuden 1851.1Swrstuden if (read(fd, &aoh, i) != i) 1861.1Swrstuden err(1, "%s reading \"optional\" header", argv[0]); 1871.1Swrstuden 1881.1Swrstuden /* Now start filing in the AOUT header */ 1891.7Smatt *(uint16_t *)aoh.magic = htobe16(RS6K_AOUTHDR_ZMAGIC); 1901.7Smatt n = be16toh(*(uint16_t *)fh.f_nsect); 1911.1Swrstuden 1921.1Swrstuden for (i = 0; i < n; i++) { 1931.5Smrg if (read(fd, &sh, sizeof(sh)) != sizeof(sh)) 1941.1Swrstuden err(1, "%s reading section headers", argv[0]); 1951.5Smrg if (strcmp(sh.s_name, ".text") == 0) { 1961.7Smatt *(uint16_t *)(aoh.o_snentry) = htobe16(i+1); 1971.7Smatt *(uint16_t *)(aoh.o_sntext) = htobe16(i+1); 1981.5Smrg } else if (strcmp(sh.s_name, ".data") == 0) { 1991.7Smatt *(uint16_t *)(aoh.o_sndata) = htobe16(i+1); 2001.5Smrg } else if (strcmp(sh.s_name, ".bss") == 0) { 2011.7Smatt *(uint16_t *)(aoh.o_snbss) = htobe16(i+1); 2021.1Swrstuden } 2031.1Swrstuden } 2041.1Swrstuden 2051.1Swrstuden /* now write it out */ 2061.5Smrg if (pwrite(fd, &aoh, sizeof(aoh), sizeof(struct filehdr)) 2071.1Swrstuden != sizeof(aoh)) 2081.1Swrstuden err(1, "%s writing modified header", argv[0]); 2091.1Swrstuden close(fd); 2101.1Swrstuden exit(0); 2111.1Swrstuden} 212