From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gary Thomas To: gas2@cygnus.com Subject: Patches for PowerPC ELF support Date: Tue, 27 Jun 1995 06:39:00 -0000 Message-id: <9506271336.AA11619@godzilla> X-SW-Source: 1995/msg00127.html The attached patches (against the 950626 snapshot) fix some problems I have with ELF support for the PowerPC. Also I have added more complete COFF support for the PowerPC [not a standard, but we need it for continuity]. Also, these patches are basic to a *now working* port of Linux for the PowerPC. Details of the patches (I didn't change any "Change..." files - I'm not familiar with the official procedures):. Add "powerpc-any-xcoff" as a target configuration. Create the files 'bfd/config/ppc-xcoff.mt' and 'bfd/ppc-xcoff.c'. Change 'bfd/elf32-ppc.c': This fixes a problem with incorrect relocation of "partial" addressing modes (like XXX@ha). Changes to 'gas/config/tc-ppc.c': complete support for COFF output (especially partial addressing modes). Change the check & reporting of overflow in partial fields which was incorrect for absolute expressions using partial addressing modes. Changes to 'gas/write.c': Part of above fix. Changes to 'opcodes/ppc-opc.c': Add some 603 specific instructions. TLB maintenance instructions "tlbld" and "tlbli". You may or may not want to incorporate 'ld/emulparams/elf32ppc.sh'. These changes modify the defaults for "ld" for Linux on PowerPC. Any questions or comments, don't hesitate to contact me. Thanks, -------------------------------------------------------------------------- Gary Thomas | email: gdt@mc.com | Mercury Computer Systems | "Fine wine is a necessity of 199 Riverneck Road | life for me" Chelmsford, MA 01824 | (508)256-0052 x278 | Thomas Jefferson ... opinions expressed here are mine | and no one else would claim them! | -------------------------------------------------------------------------- diff -r -c -P gas-950626/bfd/Makefile.in /usr/gary/gnu/gas-950626/bfd/Makefile.in *** gas-950626/bfd/Makefile.in Mon Jun 26 04:20:43 1995 --- /usr/gary/gnu/gas-950626/bfd/Makefile.in Mon Jun 26 22:25:05 1995 *************** *** 143,148 **** --- 143,149 ---- cofflink.o \ ecoff.o \ ecofflink.o \ + ppc-xcoff.o \ elf32-gen.o \ elf32-hppa.o \ elf32-i386.o \ *************** *** 262,268 **** i386lynx.c cf-i386lynx.c m68klynx.c cf-m68klynx.c \ sparclynx.c cf-sparclynx.c aix386-core.c hpux-core.c \ irix-core.c lynx-core.c osf-core.c hash.c linker.c cofflink.c \ ! m68knetbsd.c ns32knetbsd.c sparcnetbsd.c HFILES = aout-target.h aoutf1.h aoutx.h coffcode.h \ coffswap.h ecoffswap.h elf32-hppa.h elf32-target.h elf64-target.h \ --- 263,270 ---- i386lynx.c cf-i386lynx.c m68klynx.c cf-m68klynx.c \ sparclynx.c cf-sparclynx.c aix386-core.c hpux-core.c \ irix-core.c lynx-core.c osf-core.c hash.c linker.c cofflink.c \ ! m68knetbsd.c ns32knetbsd.c sparcnetbsd.c \ ! ppc-xcoff.c HFILES = aout-target.h aoutf1.h aoutx.h coffcode.h \ coffswap.h ecoffswap.h elf32-hppa.h elf32-target.h elf64-target.h \ *************** *** 789,793 **** --- 791,798 ---- sparcnetbsd.o: sparcnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h + ppc-xcoff.o: ppc-xcoff.c $(INCDIR)/coff/internal.h \ + $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \ + coffcode.h coffswap.h # IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff -r -c -P gas-950626/bfd/config/ppc-xcoff.mt /usr/gary/gnu/gas-950626/bfd/config/ppc-xcoff.mt *** gas-950626/bfd/config/ppc-xcoff.mt Wed Dec 31 19:00:00 1969 --- /usr/gary/gnu/gas-950626/bfd/config/ppc-xcoff.mt Mon Jun 26 22:25:05 1995 *************** *** 0 **** --- 1,6 ---- + # Target: PowerPC using XCOFF + + DEFAULT_VECTOR=bfd_xcoff_powerpc_vec + + SELECT_VECS=bfd_elf32_powerpc_vec rs6000coff_vec + SELECT_ARCHITECTURES=bfd_powerpc_arch bfd_rs6000_arch diff -r -c -P gas-950626/bfd/config.bfd /usr/gary/gnu/gas-950626/bfd/config.bfd *** gas-950626/bfd/config.bfd Mon Jun 26 04:20:45 1995 --- /usr/gary/gnu/gas-950626/bfd/config.bfd Mon Jun 26 22:38:14 1995 *************** *** 128,133 **** --- 128,134 ---- powerpcle-*-elf*) bfd_name=ppcle-elf ;; powerpcle-*-sysv4*) bfd_name=ppcle-elf ;; powerpcle-*-eabi*) bfd_name=ppcle-elf ;; + powerpc-*-xcoff*) bfd_name=ppc-xcoff ;; rs6000-*-*) bfd_name=rs6000 ;; sparc-*-lynxos*) bfd_name=sparc-lynx ;; sparc-*-netbsd*) bfd_name=sparc-nbsd strip_underscore=yes;; diff -r -c -P gas-950626/bfd/configure.in /usr/gary/gnu/gas-950626/bfd/configure.in *** gas-950626/bfd/configure.in Mon Jun 26 04:20:46 1995 --- /usr/gary/gnu/gas-950626/bfd/configure.in Mon Jun 26 22:25:05 1995 *************** *** 165,170 **** --- 165,171 ---- target64=true ;; bfd_elf64_sparc_vec) tb="$tb elf64-sparc.o elf64.o elf.o" target64=true ;; + bfd_xcoff_powerpc_vec) tb="$tb ppc-xcoff.o" ;; cisco_core_vec) tb="$tb cisco-core.o" ;; demo_64_vec) tb="$tb demo64.o aout64.o stab-syms.o" target64=true ;; diff -r -c -P gas-950626/bfd/elf32-ppc.c /usr/gary/gnu/gas-950626/bfd/elf32-ppc.c *** gas-950626/bfd/elf32-ppc.c Tue May 9 17:07:01 1995 --- /usr/gary/gnu/gas-950626/bfd/elf32-ppc.c Mon Jun 26 22:25:05 1995 *************** *** 1055,1061 **** + sec->output_section->vma + sec->output_offset + addend); - return (relocation & 0x8000) << 1; } --- 1055,1060 ---- *************** *** 1076,1082 **** if (output_bfd != (bfd *) NULL) return ppc_elf_std_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); - reloc_entry->addend += ppc_elf_addr16_ha_inner (symbol->section, (bfd_is_com_section (symbol->section)) ? 0 : symbol->value, reloc_entry->addend); --- 1075,1080 ---- *************** *** 1171,1176 **** --- 1169,1175 ---- Elf_Internal_Rela *rel = relocs; Elf_Internal_Rela *relend = relocs + input_section->reloc_count; boolean ret = true; + long sym_value; #ifdef DEBUG fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n", *************** *** 1257,1266 **** --- 1256,1268 ---- continue; } + sym_value = 0; + if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; + sym_value = sym->st_value; relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); *************** *** 1272,1277 **** --- 1274,1280 ---- || h->root.type == bfd_link_hash_defweak) { sec = h->root.u.def.section; + sym_value = h->root.u.def.value; relocation = (h->root.u.def.value + sec->output_section->vma + sec->output_offset); *************** *** 1306,1312 **** --- 1309,1321 ---- case (int)R_PPC_ADDR16_HA: /* arithmetic adjust relocations */ BFD_ASSERT (sec != (asection *)0); + #if 0 + /* Note: This caused double-value to be added because of how "ha_inner" works */ addend += ppc_elf_addr16_ha_inner (sec, relocation, addend); + #else + addend += ppc_elf_addr16_ha_inner (sec, sym_value, addend); + + #endif break; } diff -r -c -P gas-950626/bfd/ppc-xcoff.c /usr/gary/gnu/gas-950626/bfd/ppc-xcoff.c *** gas-950626/bfd/ppc-xcoff.c Wed Dec 31 19:00:00 1969 --- /usr/gary/gnu/gas-950626/bfd/ppc-xcoff.c Mon Jun 26 22:25:06 1995 *************** *** 0 **** --- 1,684 ---- + /* BFD back-end for IBM RS/6000 "XCOFF" files. + Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + FIXME: Can someone provide a transliteration of this name into ASCII? + Using the following chars caused a compiler warning on HIUX (so I replaced + them with octal escapes), and isn't useful without an understanding of what + character set it is. + Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, + and John Gilmore. + Archive support from Damon A. Permezel. + Contributed by IBM Corporation and Cygnus Support. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + /* This port currently only handles reading object files, except when + compiled on an RS/6000 host. -- no archive support, no core files. + In all cases, it does not support writing. + + FIXMEmgo comments are left from Metin Ozisik's original port. */ + + /* Internalcoff.h and coffcode.h modify themselves based on this flag. */ + #define RS6000COFF_C 1 + + #include "bfd.h" + #include "sysdep.h" + #include "libbfd.h" + #include "obstack.h" + #include "coff/internal.h" + #include "coff/rs6000.h" + #include "libcoff.h" + + static bfd_reloc_status_type ppc_xcoff_std_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + + static bfd_vma ppc_xcoff_addr16_ha_inner PARAMS ((asection *, bfd_vma, bfd_vma)); + static bfd_reloc_status_type ppc_xcoff_addr16_ha_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + + /* The main body of code is in coffcode.h. */ + + #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) + + /* The XCOFF reloc table. Actually, XCOFF relocations specify the + bitsize and whether they are signed or not, along with a + conventional type. This table is for the types, which are used for + different algorithms for putting in the reloc. Many of these + relocs need special_function entries, which I have not written. */ + + static reloc_howto_type ppc_xcoff_howto_table[] = + { + /* Standard 32 bit relocation. */ + HOWTO (0, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_POS", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation, but store negative value. */ + HOWTO (1, /* type */ + 0, /* rightshift */ + -2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_NEG", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit PC relative relocation. */ + HOWTO (2, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "R_REL", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit TOC relative relocation. */ + HOWTO (3, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "R_TOC", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* I don't really know what this is. */ + HOWTO (4, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RTB", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* External TOC relative symbol. */ + HOWTO (5, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_GL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Local TOC relative symbol. */ + HOWTO (6, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_TCL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + { 7 }, + + /* Non modifiable absolute branch. */ + HOWTO (8, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_BA", /* name */ + true, /* partial_inplace */ + 0x3fffffc, /* src_mask */ + 0x3fffffc, /* dst_mask */ + false), /* pcrel_offset */ + + { 9 }, + + /* Non modifiable relative branch. */ + HOWTO (0xa, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "R_BR", /* name */ + true, /* partial_inplace */ + 0x3fffffc, /* src_mask */ + 0x3fffffc, /* dst_mask */ + false), /* pcrel_offset */ + + { 0xb }, + + /* Indirect load. */ + HOWTO (0xc, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Load address. */ + HOWTO (0xd, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RLA", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + { 0xe }, + + /* Non-relocating reference. */ + HOWTO (0xf, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_REF", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + { 0x10 }, + { 0x11 }, + + /* TOC relative indirect load. */ + HOWTO (0x12, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_TRL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* TOC relative load address. */ + HOWTO (0x13, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_TRLA", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable relative branch. */ + HOWTO (0x14, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RRTBI", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable absolute branch. */ + HOWTO (0x15, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RRTBA", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable call absolute indirect. */ + HOWTO (0x16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_CAI", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable call relative. */ + HOWTO (0x17, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_REL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable branch absolute. */ + HOWTO (0x18, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RBA", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable branch absolute. */ + HOWTO (0x19, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_RBAC", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable branch relative. */ + HOWTO (0x1a, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "R_REL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Modifiable branch absolute. */ + HOWTO (0x1b, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "R_REL", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 16 bit relocation without overflow. */ + HOWTO (0x1C, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + ppc_xcoff_std_reloc, /* special_function */ + "R_PPC_ADDR16_LO", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* The high order 16 bits of an address. */ + HOWTO (0x1D, /* type */ + 16, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + ppc_xcoff_std_reloc, /* special_function */ + "R_PPC_ADDR16_HI", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* The high order 16 bits of an address, plus 1 if the contents of + the low 16 bits, treated as a signed number, is negative. */ + HOWTO (0x1E, /* type */ + 16, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + ppc_xcoff_addr16_ha_reloc, /* special_function */ + "R_PPC_ADDR16_HA", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + }; + + #define RTYPE2HOWTO(cache_ptr, dst) ppc_xcoff_rtype2howto (cache_ptr, dst) + + static void ppc_xcoff_rtype2howto PARAMS ((arelent *, + struct internal_reloc *)); + + static void + ppc_xcoff_rtype2howto (relent, internal) + arelent *relent; + struct internal_reloc *internal; + { + relent->howto = ppc_xcoff_howto_table + internal->r_type; + + /* The r_size field of an XCOFF reloc encodes the bitsize of the + relocation, as well as indicating whether it is signed or not. + Doublecheck that the relocation information gathered from the + type matches this information. */ + if (relent->howto->bitsize != (internal->r_size & 0x1f) + 1) + abort (); + #if 0 + if ((internal->r_size & 0x80) != 0 + ? (relent->howto->complain_on_overflow != complain_overflow_signed) + : (relent->howto->complain_on_overflow != complain_overflow_bitfield)) + abort (); + #endif + } + + #define coff_bfd_reloc_type_lookup ppc_xcoff_reloc_type_lookup + + static reloc_howto_type *ppc_xcoff_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); + + static reloc_howto_type * + ppc_xcoff_reloc_type_lookup (abfd, code) + bfd *abfd; + bfd_reloc_code_real_type code; + { + switch (code) + { + case BFD_RELOC_PPC_B26: + return &ppc_xcoff_howto_table[0xa]; + case BFD_RELOC_PPC_BA26: + return &ppc_xcoff_howto_table[8]; + case BFD_RELOC_PPC_TOC16: + return &ppc_xcoff_howto_table[3]; + case BFD_RELOC_32: + return &ppc_xcoff_howto_table[0]; + case BFD_RELOC_HI16: + return &ppc_xcoff_howto_table[0x1D]; + case BFD_RELOC_HI16_S: + return &ppc_xcoff_howto_table[0x1E]; + case BFD_RELOC_LO16: + return &ppc_xcoff_howto_table[0x1C]; + default: + return NULL; + } + } + + #define SELECT_RELOC(internal, howto) \ + { \ + internal.r_type = howto->type; \ + internal.r_size = \ + ((howto->complain_on_overflow == complain_overflow_signed \ + ? 0x80 \ + : 0) \ + | (howto->bitsize - 1)); \ + } + + /* XCOFF relocs are against symbols. If we are producing relocateable + output, and the reloc is against an external symbol, and nothing + has given us any additional addend, the resulting reloc will also + be against the same symbol. In such a case, we don't want to + change anything about the way the reloc is handled, since it will + all be done at final link time. Rather than put special case code + into bfd_perform_relocation, all the reloc types use this howto + function. It just short circuits the reloc if producing + relocateable output against an external symbol. */ + + /*ARGSUSED*/ + static bfd_reloc_status_type + ppc_xcoff_std_reloc (abfd, + reloc_entry, + symbol, + data, + input_section, + output_bfd, + error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; + { + if (output_bfd != (bfd *) NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && (! reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + return bfd_reloc_continue; + } + + /* Don't pretend we can deal with unsupported relocs. */ + + /*ARGSUSED*/ + static bfd_reloc_status_type + ppc_xcoff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section, + output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; + { + BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); + fprintf (stderr, + "%s: Relocation %s (%d) is not currently supported.\n", + bfd_get_filename (abfd), + reloc_entry->howto->name, + reloc_entry->howto->type); + + return bfd_reloc_notsupported; + } + + /* Internal function to return the adjustment to the addend for relocations + that return the upper 16 bits after sign extending the lower 16 bits, ie + for use with a ORIS instruction followed by a memory reference using the + bottom 16 bits. */ + + INLINE + static bfd_vma + ppc_xcoff_addr16_ha_inner (sec, value, addend) + asection *sec; + bfd_vma value; + bfd_vma addend; + { + bfd_vma relocation = (value + + sec->output_section->vma + + sec->output_offset + + addend); + return (relocation & 0x8000) << 1; + } + + /* Handle the ADDR16_HA reloc by adjusting the reloc addend. */ + + /*ARGSUSED*/ + static bfd_reloc_status_type + ppc_xcoff_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section, + output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; + { + if (output_bfd != (bfd *) NULL) + return ppc_xcoff_std_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + reloc_entry->addend += ppc_xcoff_addr16_ha_inner (symbol->section, + (bfd_is_com_section (symbol->section)) ? 0 : symbol->value, + reloc_entry->addend); + return bfd_reloc_continue; + } + + #define COFF_LONG_FILENAMES + + #include "coffcode.h" + + #define coff_archive_p bfd_generic_archive_p + #define coff_mkarchive _bfd_generic_mkarchive + + + + #define CORE_FILE_P _bfd_dummy_target + + #define coff_core_file_failing_command _bfd_nocore_core_file_failing_command + #define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal + #define coff_core_file_matches_executable_p \ + _bfd_nocore_core_file_matches_executable_p + + /* The transfer vector that leads the outside world to all of the above. */ + + const bfd_target bfd_xcoff_powerpc_vec = + { + "powerpc-xcoff", /* name */ + bfd_target_coff_flavour, + true, /* data byte order is big */ + true, /* header byte order is big */ + + (HAS_RELOC | EXEC_P | /* object flags */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT), + + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ + 0, /* leading char */ + '/', /* ar_pad_char */ + 15, /* ar_max_namelen??? FIXMEmgo */ + 3, /* default alignment power */ + + bfd_getb64, bfd_getb_signed_64, bfd_putb64, + bfd_getb32, bfd_getb_signed_32, bfd_putb32, + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ + bfd_getb64, bfd_getb_signed_64, bfd_putb64, + bfd_getb32, bfd_getb_signed_32, bfd_putb32, + bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ + + {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ + coff_archive_p, CORE_FILE_P}, + {bfd_false, coff_mkobject, coff_mkarchive, /* bfd_set_format */ + bfd_false}, + {bfd_false, coff_write_object_contents, /* bfd_write_contents */ + _bfd_write_archive_contents, bfd_false}, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (coff), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + COFF_SWAP_TABLE, + }; diff -r -c -P gas-950626/bfd/targets.c /usr/gary/gnu/gas-950626/bfd/targets.c *** gas-950626/bfd/targets.c Mon Jun 26 04:20:45 1995 --- /usr/gary/gnu/gas-950626/bfd/targets.c Mon Jun 26 22:25:06 1995 *************** *** 467,472 **** --- 467,473 ---- extern const bfd_target bfd_elf64_big_generic_vec; extern const bfd_target bfd_elf64_little_generic_vec; extern const bfd_target bfd_elf64_sparc_vec; + extern const bfd_target bfd_xcoff_powerpc_vec; extern const bfd_target demo_64_vec; extern const bfd_target ecoff_big_vec; extern const bfd_target ecoff_little_vec; *************** *** 590,595 **** --- 591,597 ---- #if 0 &bfd_elf64_sparc_vec, #endif + &bfd_xcoff_powerpc_vec, /* We don't include cisco_core_vec. Although it has a magic number, the magic number isn't at the beginning of the file, and thus might spuriously match other kinds of files. */ *************** *** 779,784 **** --- 781,787 ---- } bfd_set_error (bfd_error_invalid_target); + fprintf(stderr, "Target = %s\n", target_name); return NULL; } diff -r -c -P gas-950626/config.sub /usr/gary/gnu/gas-950626/config.sub *** gas-950626/config.sub Mon Jun 26 04:28:39 1995 --- /usr/gary/gnu/gas-950626/config.sub Mon Jun 26 22:25:06 1995 *************** *** 806,812 **** | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* | -lites* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ ! | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi | -eabi) ;; # CYGNUS LOCAL -go32 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ --- 806,812 ---- | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* | -lites* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ ! | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi | -eabi | -xcoff) ;; # CYGNUS LOCAL -go32 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ diff -r -c -P gas-950626/gas/config/tc-ppc.c /usr/gary/gnu/gas-950626/gas/config/tc-ppc.c *** gas-950626/gas/config/tc-ppc.c Wed May 17 05:26:51 1995 --- /usr/gary/gnu/gas-950626/gas/config/tc-ppc.c Mon Jun 26 22:25:11 1995 *************** *** 616,621 **** --- 616,652 ---- #endif /* OBJ_ELF */ + #ifdef OBJ_COFF + /* Parse @h, etc. and return the desired relocation. */ + static bfd_reloc_code_real_type + ppc_coff_suffix (str_p) + char **str_p; + { + char *str = *str_p; + + if (*str != '@') + return BFD_RELOC_UNUSED; + + if (strncmp (str, "@L", 2) == 0 || strncmp (str, "@l", 2) == 0) + { + *str_p += 2; + return BFD_RELOC_LO16; + } + else if (strncmp (str, "@HA", 3) == 0 || strncmp (str, "@ha", 3) == 0) + { + *str_p += 3; + return BFD_RELOC_HI16_S; + } + else if (strncmp (str, "@H", 2) == 0 || strncmp (str, "@h", 2) == 0) + { + *str_p += 2; + return BFD_RELOC_HI16; + } + + return BFD_RELOC_UNUSED; + } + #endif + /* We need to keep a list of fixups. We can't simply generate them as we go, because that would require us to first create the frag, and that would screw up references to ``.''. */ *************** *** 793,798 **** --- 824,840 ---- fixups[fc].reloc = reloc; ++fc; } + #else + else if ((reloc = ppc_coff_suffix (&str)) != BFD_RELOC_UNUSED) + { + /* We need to generate a fixup for this expression. */ + if (fc >= MAX_INSN_FIXUPS) + as_fatal ("too many fixups"); + fixups[fc].exp = ex; + fixups[fc].opindex = 0; + fixups[fc].reloc = reloc; + ++fc; + } #endif /* OBJ_ELF */ else *************** *** 2700,2705 **** --- 2742,2748 ---- case BFD_RELOC_16: if (fixp->fx_pcrel) abort (); + fixp->fx_bit_fixP = 1; /* Turn off error check code in 'write.c' */ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where, value, 2); diff -r -c -P gas-950626/gas/config/tc-ppc.h /usr/gary/gnu/gas-950626/gas/config/tc-ppc.h *** gas-950626/gas/config/tc-ppc.h Tue May 9 17:17:24 1995 --- /usr/gary/gnu/gas-950626/gas/config/tc-ppc.h Mon Jun 26 22:25:11 1995 *************** *** 33,39 **** /* The target BFD format. */ #ifdef OBJ_COFF ! #define TARGET_FORMAT "aixcoff-rs6000" #endif #ifdef OBJ_ELF #define TARGET_FORMAT (target_big_endian) ? "elf32-powerpc" : "elf32-powerpcle" --- 33,40 ---- /* The target BFD format. */ #ifdef OBJ_COFF ! /* #define TARGET_FORMAT "aixcoff-rs6000" */ ! #define TARGET_FORMAT "powerpc-xcoff" #endif #ifdef OBJ_ELF #define TARGET_FORMAT (target_big_endian) ? "elf32-powerpc" : "elf32-powerpcle" diff -r -c -P gas-950626/gas/config/te-ppcxcoff.h /usr/gary/gnu/gas-950626/gas/config/te-ppcxcoff.h *** gas-950626/gas/config/te-ppcxcoff.h Wed Dec 31 19:00:00 1969 --- /usr/gary/gnu/gas-950626/gas/config/te-ppcxcoff.h Mon Jun 26 22:25:11 1995 *************** *** 0 **** --- 1,3 ---- + #undef TARGET_FORMAT + #define TARGET_FORMAT "powerpc-xcoff" + diff -r -c -P gas-950626/gas/configure.in /usr/gary/gnu/gas-950626/gas/configure.in *** gas-950626/gas/configure.in Mon Jun 26 04:24:54 1995 --- /usr/gary/gnu/gas-950626/gas/configure.in Mon Jun 26 22:32:38 1995 *************** *** 238,243 **** --- 238,245 ---- esac ;; ppc-*-netware*) fmt=elf em=ppcnw ;; + + ppc-*-xcoff*) fmt=coff em=ppcxcoff ;; sh-*-coff) fmt=coff ;; Only in gas-950626/gas/doc: as.info Only in gas-950626/gas/doc: as.info-1 Only in gas-950626/gas/doc: as.info-2 Only in gas-950626/gas/doc: as.info-3 Only in gas-950626/gas/doc: as.info-4 Only in gas-950626/gas/doc: as.info-5 Only in gas-950626/gas/doc: as.info-6 Only in gas-950626/gas/doc: gasp.info diff -r -c -P gas-950626/gas/write.c /usr/gary/gnu/gas-950626/gas/write.c *** gas-950626/gas/write.c Thu Jun 22 14:44:47 1995 --- /usr/gary/gnu/gas-950626/gas/write.c Mon Jun 26 22:25:12 1995 *************** *** 2346,2351 **** --- 2346,2352 ---- } } + #if 0 /*** If this check is enabled here, some errors are bogus **/ if (!fixP->fx_bit_fixP && size > 0) { valueT mask = 0; *************** *** 2387,2392 **** --- 2388,2394 ---- (unsigned long) (fragP->fr_address + where)); #endif } /* not a bit fix */ + #endif if (!fixP->fx_done) { *************** *** 2408,2413 **** --- 2410,2467 ---- fixP->fx_done = 1; #endif } + + #if 1 /*** This error check can now be performed safely **/ + /* Note: there is probably a better way to handle this. For the PowerPC */ + /* (at least) there are some 16-bit relocations which may involve values */ + /* whose result is known at assembly time to be larger than 16 bits. */ + /* These are OK though, since the result only uses one 16-bit half */ + /* (upper or lower), decided upon at link-time. I have had the "fix3" */ + /* routine set the "fixP" flag to avoid this check since it is incorrect */ + /* for these relocation types. */ + if (!fixP->fx_bit_fixP && size > 0) + { + valueT mask = 0; + if (size < sizeof (mask)) + { + /* set all bits to one */ + mask--; + /* Technically, combining these produces an undefined result + if size is sizeof (valueT), though I think these two + half-way operations should both be defined. And the + compiler should be able to combine them if it's valid on + the host architecture. */ + mask <<= size * 4; + mask <<= size * 4; + if ((add_number & mask) != 0 + && (add_number & mask) != mask) + { + char buf[50], buf2[50]; + sprint_value (buf, fragP->fr_address + where); + if (add_number > 1000) + sprint_value (buf2, add_number); + else + sprintf (buf2, "%ld", (long) add_number); + as_bad_where (fixP->fx_file, fixP->fx_line, + "Value of %s too large for field of %d bytes at %s", + buf2, size, buf); + } /* generic error checking */ + } + #ifdef WARN_SIGNED_OVERFLOW_WORD + /* Warn if a .word value is too large when treated as a signed + number. We already know it is not too negative. This is to + catch over-large switches generated by gcc on the 68k. */ + if (!flag_signed_overflow_ok + && size == 2 + && add_number > 0x7fff) + as_bad_where (fixP->fx_file, fixP->fx_line, + "Signed .word overflow; switch may be too large; %ld at 0x%lx", + (long) add_number, + (unsigned long) (fragP->fr_address + where)); + #endif + } /* not a bit fix */ + #endif + #ifdef TC_VALIDATE_FIX skip: ; #endif Only in gas-950626/gprof: conftest.c diff -r -c -P gas-950626/include/opcode/ppc.h /usr/gary/gnu/gas-950626/include/opcode/ppc.h *** gas-950626/include/opcode/ppc.h Mon Apr 4 13:16:52 1994 --- /usr/gary/gnu/gas-950626/include/opcode/ppc.h Mon Jun 26 22:25:12 1995 *************** *** 77,82 **** --- 77,85 ---- but it also supports many additional POWER instructions. */ #define PPC_OPCODE_601 (040) + /* Opcodes specific to PowerPC 603 */ + #define PPC_OPCODE_603 (0100) + /* A macro to extract the major opcode from an instruction. */ #define PPC_OP(i) (((i) >> 26) & 0x3f) diff -r -c -P gas-950626/ld/Makefile.in /usr/gary/gnu/gas-950626/ld/Makefile.in *** gas-950626/ld/Makefile.in Mon Jun 26 04:27:42 1995 --- /usr/gary/gnu/gas-950626/ld/Makefile.in Mon Jun 26 22:27:18 1995 *************** *** 206,212 **** emipsidt.o emipsidtl.o emipslit.o enews.o ens32knbsd.o eppcnw.o \ eriscix.o esa29200.o eshl.o esh.o esparclynx.o esparcnbsd.o \ est2000.o esun3.o esun4.o evanilla.o evax.o evsta.o \ ! ez8ksim.o ei386pe.o earmpe.o CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \ ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \ --- 206,212 ---- emipsidt.o emipsidtl.o emipslit.o enews.o ens32knbsd.o eppcnw.o \ eriscix.o esa29200.o eshl.o esh.o esparclynx.o esparcnbsd.o \ est2000.o esun3.o esun4.o evanilla.o evax.o evsta.o \ ! ez8ksim.o ei386pe.o earmpe.o excoffppc.o CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \ ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \ *************** *** 466,471 **** --- 466,474 ---- eppcnw.c: $(srcdir)/emulparams/ppcnw.sh \ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS} ${GENSCRIPTS} ppcnw + excoffppc.c: $(srcdir)/emulparams/xcoffppc.sh \ + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/xcoffppc.sc ${GEN_DEPENDS} + ${GENSCRIPTS} xcoffppc ei386nbsd.c: $(srcdir)/emulparams/i386nbsd.sh \ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS} diff -r -c -P gas-950626/ld/config/ppc-xcoff.mt /usr/gary/gnu/gas-950626/ld/config/ppc-xcoff.mt *** gas-950626/ld/config/ppc-xcoff.mt Wed Dec 31 19:00:00 1969 --- /usr/gary/gnu/gas-950626/ld/config/ppc-xcoff.mt Mon Jun 26 22:25:13 1995 *************** *** 0 **** --- 1 ---- + EMUL=xcoffppc diff -r -c -P gas-950626/ld/configure.in /usr/gary/gnu/gas-950626/ld/configure.in *** gas-950626/ld/configure.in Mon Jun 26 04:27:41 1995 --- /usr/gary/gnu/gas-950626/ld/configure.in Mon Jun 26 22:25:13 1995 *************** *** 126,131 **** --- 126,132 ---- powerpc-*-elf* | powerpc-*-eabi*) ld_target=ppc-elf32 ;; powerpcle-*-elf* | powerpcle-*-eabi*) ld_target=ppcle-elf32 ;; powerpc-*-netware*) ld_target=ppc-nw ;; + powerpc-*-xcoff*) ld_target=ppc-xcoff ;; w65-*-*) ld_target=coff-w65 ;; *-*-aout) ld_target=${target_cpu}-${target_vendor} ;; *-*-coff) ld_target=${target_cpu}-${target_vendor} ;; diff -r -c -P gas-950626/ld/emulparams/elf32ppc.sh /usr/gary/gnu/gas-950626/ld/emulparams/elf32ppc.sh *** gas-950626/ld/emulparams/elf32ppc.sh Thu Jan 26 12:59:02 1995 --- /usr/gary/gnu/gas-950626/ld/emulparams/elf32ppc.sh Mon Jun 26 22:25:13 1995 *************** *** 1,7 **** SCRIPT_NAME=elfppc OUTPUT_FORMAT="elf32-powerpc" ! TEXT_START_ADDR=0x0400000 ! DATA_ADDR=0x10000000 ! MAXPAGESIZE=0x40000 NONPAGED_TEXT_START_ADDR=0x0400000 ARCH=powerpc --- 1,6 ---- SCRIPT_NAME=elfppc OUTPUT_FORMAT="elf32-powerpc" ! TEXT_START_ADDR=0x01000 ! MAXPAGESIZE=0x10000 NONPAGED_TEXT_START_ADDR=0x0400000 ARCH=powerpc diff -r -c -P gas-950626/ld/emulparams/xcoffppc.sh /usr/gary/gnu/gas-950626/ld/emulparams/xcoffppc.sh *** gas-950626/ld/emulparams/xcoffppc.sh Wed Dec 31 19:00:00 1969 --- /usr/gary/gnu/gas-950626/ld/emulparams/xcoffppc.sh Mon Jun 26 22:25:13 1995 *************** *** 0 **** --- 1,7 ---- + # XCOFF for PowerPC + SCRIPT_NAME=xcoffppc + OUTPUT_FORMAT="powerpc-xcoff" + TEXT_START_ADDR=0x1000 + PAGE_SIZE=0x1000 + ARCH=powerpc + diff -r -c -P gas-950626/ld/scripttempl/xcoffppc.sc /usr/gary/gnu/gas-950626/ld/scripttempl/xcoffppc.sc *** gas-950626/ld/scripttempl/xcoffppc.sc Wed Dec 31 19:00:00 1969 --- /usr/gary/gnu/gas-950626/ld/scripttempl/xcoffppc.sc Mon Jun 26 22:25:13 1995 *************** *** 0 **** --- 1,37 ---- + # Linker script for PowerPC COFF. + # Based on sparccoff.sc by Gary Thomas + test -z "$ENTRY" && ENTRY=_start + cat <