fixcoff.c revision 1.11
11.11Sdsl/* $NetBSD: fixcoff.c,v 1.11 2009/03/14 15:36:09 dsl 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.11Sdslusage(char *prog) 1251.1Swrstuden{ 1261.1Swrstuden fprintf(stderr, "Usage: %s [-h] | [<file to fix>]\n", prog); 1271.1Swrstuden} 1281.1Swrstuden 1291.1Swrstudenvoid 1301.11Sdslhelp(char *prog) 1311.1Swrstuden{ 1321.5Smrg fprintf(stderr, "%s\tis designed to fix the xcoff headers in a\n",prog); 1331.1Swrstuden fprintf(stderr, 1341.1Swrstuden"\tbinary generated using objcopy from a non-xcoff source.\n"); 1351.1Swrstuden usage(prog); 1361.1Swrstuden exit(0); 1371.1Swrstuden} 1381.1Swrstuden 1391.11Sdslmain(int argc, char * const *argv) 1401.1Swrstuden{ 1411.1Swrstuden int fd, i, n, ch; 1421.5Smrg struct filehdr fh; 1431.5Smrg struct aouthdr aoh; 1441.5Smrg struct sectionhdr sh; 1451.1Swrstuden 1461.1Swrstuden while ((ch = getopt(argc, argv, "h")) != -1) 1471.1Swrstuden switch (ch) { 1481.1Swrstuden case 'h': 1491.3Scgd help(getprogname()); 1501.1Swrstuden } 1511.1Swrstuden 1521.1Swrstuden argc -= optind; 1531.1Swrstuden argv += optind; 1541.1Swrstuden 1551.1Swrstuden if (argc != 1) { 1561.3Scgd usage(getprogname()); 1571.1Swrstuden exit(1); 1581.1Swrstuden } 1591.1Swrstuden 1601.1Swrstuden if ((fd = open(argv[0], O_RDWR, 0)) == -1) 1611.1Swrstuden err(i, "%s", argv[0]); 1621.1Swrstuden 1631.1Swrstuden /* 1641.1Swrstuden * Make sure it looks like an xcoff file.. 1651.1Swrstuden */ 1661.5Smrg if (read(fd, &fh, sizeof(fh)) != sizeof(fh)) 1671.1Swrstuden err(1, "%s reading header", argv[0]); 1681.1Swrstuden 1691.7Smatt i = be16toh(*(uint16_t *)fh.f_magic); 1701.1Swrstuden if ((i != U802WRMAGIC) && (i != U802ROMAGIC) && (i != U802TOCMAGIC)) 1711.1Swrstuden errx(1, "%s: not a valid xcoff file", argv[0]); 1721.1Swrstuden 1731.5Smrg /* Does the AOUT "Optional header" make sense? */ 1741.7Smatt i = be16toh(*(uint16_t *)fh.f_opthdr); 1751.1Swrstuden 1761.1Swrstuden if (i == SMALL_AOUTSZ) 1771.3Scgd errx(1, "%s: file has small \"optional\" header, inappropriate for use with %s", argv[0], getprogname()); 1781.5Smrg else if (i != sizeof(aoh)) 1791.1Swrstuden errx(1, "%s: invalid \"optional\" header", argv[0]); 1801.1Swrstuden 1811.1Swrstuden if (read(fd, &aoh, i) != i) 1821.1Swrstuden err(1, "%s reading \"optional\" header", argv[0]); 1831.1Swrstuden 1841.1Swrstuden /* Now start filing in the AOUT header */ 1851.7Smatt *(uint16_t *)aoh.magic = htobe16(RS6K_AOUTHDR_ZMAGIC); 1861.7Smatt n = be16toh(*(uint16_t *)fh.f_nsect); 1871.1Swrstuden 1881.1Swrstuden for (i = 0; i < n; i++) { 1891.5Smrg if (read(fd, &sh, sizeof(sh)) != sizeof(sh)) 1901.1Swrstuden err(1, "%s reading section headers", argv[0]); 1911.5Smrg if (strcmp(sh.s_name, ".text") == 0) { 1921.7Smatt *(uint16_t *)(aoh.o_snentry) = htobe16(i+1); 1931.7Smatt *(uint16_t *)(aoh.o_sntext) = htobe16(i+1); 1941.5Smrg } else if (strcmp(sh.s_name, ".data") == 0) { 1951.7Smatt *(uint16_t *)(aoh.o_sndata) = htobe16(i+1); 1961.5Smrg } else if (strcmp(sh.s_name, ".bss") == 0) { 1971.7Smatt *(uint16_t *)(aoh.o_snbss) = htobe16(i+1); 1981.1Swrstuden } 1991.1Swrstuden } 2001.1Swrstuden 2011.1Swrstuden /* now write it out */ 2021.5Smrg if (pwrite(fd, &aoh, sizeof(aoh), sizeof(struct filehdr)) 2031.1Swrstuden != sizeof(aoh)) 2041.1Swrstuden err(1, "%s writing modified header", argv[0]); 2051.1Swrstuden close(fd); 2061.1Swrstuden exit(0); 2071.1Swrstuden} 208