This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR ld/3958: ELF linker failed to handle relocation against STN_UNDEF


On Tue, Mar 06, 2007 at 01:22:32PM +1030, Alan Modra wrote:
> The basic approach in the backends is to move ld -r processing after
> we set up sym, sec, h etc. needed for a final link.  Then there is
> just one place in the backend to handle relocs against syms in
> discarded sections.  The x86 patch below also merges relocatable
> link handling of section syms with code for SEC_MERGE section syms.

Ditto for d10v.  I've also converted bfin and frv over to use
RELOC_FOR_GLOBAL_SYMBOL since this was relatively easy to do.  It
would be nice if more ports were done, but this patch is big enough as
it is.

One thing I haven't done is looked at what should be done with mep
complex relocs if a symbol from a discarded section is used.

bfd/
	* elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): No error on relocatable link.
	(elf_discarded_section): Move..
	* bfd-in.h: ..to here.
	* bfd-in2.h: Regenerate.
	* elflink.c (elf_link_input_bfd): Don't zap relocs against symbols
	from discarded sections before relocate_section has done its job.
	* reloc.c (bfd_generic_get_relocated_section_contents): Handle
	relocs against symbols from discarded sections.
	* elf-hppa.h (elf_hppa_howto_table): Set size.  Set dst_mask on
	SECREL32.
	(elf_hppa_relocate_section): Handle relocatable link after setting
	sec, sym, h etc. for final link.  Squash error messages for
	relocatable link.  Clear section contents for relocs against
	symbols in discarded sections, and zero reloc.  Remove existing
	zero r_symndx code.
	* elf-m10200.c (mn10200_elf_relocate_section): Likewise.
	* elf-m10300.c (mn10300_elf_relocate_section): Likewise.
	* elf32-arm.c (elf32_arm_relocate_section): Likewise.
	* elf32-avr.c (elf32_avr_relocate_section): Likewise.
	* elf32-bfin.c (bfinfdpic_relocate_section): Likewise.
	(bfin_relocate_section): Likewise.
	* elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
	* elf32-cris.c (cris_elf_relocate_section): Likewise.
	* elf32-crx.c (elf32_crx_relocate_section): Likewise.
	* elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
	* elf32-fr30.c (fr30_elf_relocate_section): Likewise.
	* elf32-frv.c (elf32_frv_relocate_section): Likewise.
	* elf32-h8300.c (elf32_h8_relocate_section): Likewise.
	* elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
	* elf32-i370.c (i370_elf_relocate_section): Likewise.
	* elf32-i386.c (elf_i386_relocate_section): Likewise.
	* elf32-i860.c (elf32_i860_relocate_section): Likewise.
	* elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
	* elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
	* elf32-m32c.c (m32c_elf_relocate_section): Likewise.
	* elf32-m32r.c (m32r_elf_relocate_section): Likewise.
	* elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
	* elf32-m68k.c (elf_m68k_relocate_section): Likewise.
	* elf32-mcore.c (mcore_elf_relocate_section): Likewise.
	* elf32-mep.c (mep_elf_relocate_section): Likewise.
	* elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
	* elf32-mt.c (mt_elf_relocate_section): Likewise.
	* elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
	* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
	* elf32-s390.c (elf_s390_relocate_section): Likewise.
	* elf32-score.c (_bfd_score_elf_relocate_section): Likewise.
	* elf32-sh.c (sh_elf_relocate_section): Likewise.
	* elf32-spu.c (spu_elf_relocate_section): Likewise.
	* elf32-v850.c (v850_elf_relocate_section): Likewise.
	* elf32-vax.c (elf_vax_relocate_section): Likewise.
	* elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
	* elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
	* elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
	* elf64-alpha.c (elf64_alpha_relocate_section_r): Likewise.
	(elf64_alpha_relocate_section): Likewise.
	* elf64-mmix.c (mmix_elf_relocate_section): Likewise.
	* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
	* elf64-s390.c (elf_s390_relocate_section): Likewise.
	* elf64-sh64.c (sh_elf64_relocate_section): Likewise.
	* elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
	* elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
	* elfxx-mips.c (_bfd_mips_elf_relocate_section): Likewise.
	* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.

	* elf32-arm.c (elf32_arm_relocate_section): Always adjust section
	symbols for relocatable link.  Don't use always-zero st_value.
	(elf_backend_rela_normal): Don't define.
	* elf32-bfin.c (bfinfdpic_relocate_section): Use
	RELOC_FOR_GLOBAL_SYMBOL.
	* elf32-frv.c (elf32_frv_relocate_section): Likewise.
	* elf32-d10v.c (elf32_d10v_relocate_section): Combine SEC_MERGE
	section symbol adjustments with same for relocatable link.
	* elf32-i386.c (elf_i386_relocate_section): Likewise.
	* elf32-m68hc1x.c (m68hc11_get_relocation_value): Move..
	(elf32_m68hc11_check_relocs): ..to here.
	* elf32-score.c (score_elf_final_link_relocate): Remove zero
	r_symndx code.
	* elfxx-mips.c (mips_elf_calculate_relocation): Likewise.

ld/testsuite/
	* ld-elf/linkonce1.d: New.
	* ld-elf/linkonce1a.s: New.
	* ld-elf/linkonce1b.s: New.
	* ld-elf/linkonce2.d: New.
	* ld-i386/pcrel16abs.d: New.
	* ld-i386/pcrel16abs.s: New.
	* ld-i386/i386.exp: Run it.

Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.123
diff -u -p -r1.123 bfd-in.h
--- bfd/bfd-in.h	29 Jan 2007 16:29:21 -0000	1.123
+++ bfd/bfd-in.h	7 Mar 2007 06:09:00 -0000
@@ -350,6 +350,13 @@ typedef struct bfd_section *sec_ptr;
   (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \
    / bfd_octets_per_byte (bfd))
 
+/* Return TRUE if section has been discarded.  */
+#define elf_discarded_section(sec)				\
+  (!bfd_is_abs_section (sec)					\
+   && bfd_is_abs_section ((sec)->output_section)		\
+   && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE		\
+   && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
+
 /* Forward define.  */
 struct stat;
 
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.228
diff -u -p -r1.228 elf-bfd.h
--- bfd/elf-bfd.h	22 Feb 2007 17:03:59 -0000	1.228
+++ bfd/elf-bfd.h	7 Mar 2007 06:09:04 -0000
@@ -1213,13 +1213,6 @@ struct bfd_elf_section_data
 #define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
 #define elf_sec_group(sec)	(elf_section_data(sec)->sec_group)
 
-/* Return TRUE if section has been discarded.  */
-#define elf_discarded_section(sec)				\
-  (!bfd_is_abs_section (sec)					\
-   && bfd_is_abs_section ((sec)->output_section)		\
-   && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE		\
-   && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
-
 #define xvec_get_elf_backend_data(xvec) \
   ((struct elf_backend_data *) (xvec)->backend_data)
 
@@ -2003,7 +1996,7 @@ extern bfd_boolean _sh_elf_set_mach_from
       else if (info->unresolved_syms_in_objects == RM_IGNORE		\
 	       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)		\
 	;								\
-      else								\
+      else if (!info->relocatable)					\
 	{								\
 	  bfd_boolean err;						\
 	  err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR	\
Index: bfd/elf-hppa.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-hppa.h,v
retrieving revision 1.82
diff -u -p -r1.82 elf-hppa.h
--- bfd/elf-hppa.h	24 May 2006 11:05:42 -0000	1.82
+++ bfd/elf-hppa.h	7 Mar 2007 06:09:06 -0000
@@ -1,5 +1,5 @@
 /* Common code for PA ELF implementations.
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -54,58 +54,58 @@ static reloc_howto_type elf_hppa_howto_t
      _bfd_stab_section_find_nearest_line.  */
   { R_PARISC_DIR32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR32", FALSE, 0, 0xffffffff, FALSE },
-  { R_PARISC_DIR21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR17R, 0, 0, 17, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR17R, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR17R", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR17F, 0, 0, 17, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR17F, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR17F", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR14F", FALSE, 0, 0, FALSE },
   /* 8 */
-  { R_PARISC_PCREL12F, 0, 0, 12, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL12F, 0, 2, 12, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL12F", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL32, 0, 0, 32, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL32", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL21L, 0, 0, 21, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL21L, 0, 2, 21, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL17R, 0, 0, 17, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL17R, 0, 2, 17, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL17R", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL17F, 0, 0, 17, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL17F, 0, 2, 17, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL17F", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL17C, 0, 0, 17, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL17C, 0, 2, 17, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL17C", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL14R, 0, 0, 14, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL14R, 0, 2, 14, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL14F, 0, 0, 14, TRUE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL14F, 0, 2, 14, TRUE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL14F", FALSE, 0, 0, FALSE },
   /* 16 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DPREL21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DPREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DPREL21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_DPREL14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DPREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DPREL14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_DPREL14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DPREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DPREL14DR", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DPREL14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DPREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DPREL14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_DPREL14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DPREL14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DPREL14F", FALSE, 0, 0, FALSE },
   /* 24 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTREL21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTREL21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -113,16 +113,16 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTREL14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTREL14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTREL14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTREL14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTREL14F", FALSE, 0, 0, FALSE },
   /* 32 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTIND21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTIND21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTIND21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -130,33 +130,33 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTIND14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTIND14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTIND14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTIND14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTIND14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTIND14F", FALSE, 0, 0, FALSE },
   /* 40 */
   { R_PARISC_SETBASE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_SETBASE", FALSE, 0, 0, FALSE },
-  { R_PARISC_SECREL32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
-    bfd_elf_generic_reloc, "R_PARISC_SECREL32", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_SECREL32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+    bfd_elf_generic_reloc, "R_PARISC_SECREL32", FALSE, 0, 0xffffffff, FALSE },
+  { R_PARISC_BASEREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL17R, 0, 0, 17, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_BASEREL17R, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL17R", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL17F, 0, 0, 17, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_BASEREL17F, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL17F", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_BASEREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_BASEREL14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL14F", FALSE, 0, 0, FALSE },
   /* 48 */
   { R_PARISC_SEGBASE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_SEGBASE", FALSE, 0, 0, FALSE },
-  { R_PARISC_SEGREL32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_SEGREL32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_SEGREL32", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -164,16 +164,16 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF14F", FALSE, 0, 0, FALSE },
   /* 56 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR32", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -181,16 +181,16 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14R", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   /* 64 */
-  { R_PARISC_FPTR64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_FPTR64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_FPTR64", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLABEL32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLABEL32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLABEL32", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLABEL21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLABEL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLABEL21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -198,86 +198,86 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLABEL14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLABEL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLABEL14R", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   /* 72 */
-  { R_PARISC_PCREL64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL64", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL22C, 0, 0, 22, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL22C, 0, 2, 22, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL22C", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL22F, 0, 0, 22, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL22F, 0, 2, 22, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL22F", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_PCREL16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PCREL16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PCREL16DF", FALSE, 0, 0, FALSE },
   /* 80 */
-  { R_PARISC_DIR64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR64", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_DIR16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DIR16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DIR16DF", FALSE, 0, 0, FALSE },
   /* 88 */
-  { R_PARISC_GPREL64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_GPREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_GPREL64", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTREL14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTREL14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTREL14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTREL14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_GPREL16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_GPREL16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_GPREL16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_GPREL16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_GPREL16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_GPREL16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_GPREL16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_GPREL16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_GPREL16DF", FALSE, 0, 0, FALSE },
   /* 96 */
-  { R_PARISC_LTOFF64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF64", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTIND14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTIND14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTIND14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_DLTIND14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_DLTIND14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_DLTIND14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF", FALSE, 0, 0, FALSE },
   /* 104 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_BASEREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_BASEREL14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_BASEREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_BASEREL14DR", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -288,38 +288,38 @@ static reloc_howto_type elf_hppa_howto_t
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   /* 112 */
-  { R_PARISC_SEGREL64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_SEGREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_SEGREL64", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_PLTOFF16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_PLTOFF16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_PLTOFF16DF", FALSE, 0, 0, FALSE },
   /* 120 */
-  { R_PARISC_LTOFF_FPTR64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_FPTR16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_FPTR16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   /* 128 */
   { R_PARISC_COPY, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
@@ -375,9 +375,9 @@ static reloc_howto_type elf_hppa_howto_t
   /* 152 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL32, 0, 0, 32, FALSE, 0, complain_overflow_dont,
+  { R_PARISC_TPREL32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_TPREL32", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TPREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TPREL21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -385,7 +385,7 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TPREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TPREL14R", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -394,7 +394,7 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP21L", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
@@ -402,9 +402,9 @@ static reloc_howto_type elf_hppa_howto_t
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP14F, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14F", FALSE, 0, 0, FALSE },
   /* 168 */
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
@@ -509,68 +509,68 @@ static reloc_howto_type elf_hppa_howto_t
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   /* 216 */
-  { R_PARISC_TPREL64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TPREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TPREL64", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL14WR, 0, 0, 14, FALSE, 0, complain_overflow_dont,
+  { R_PARISC_TPREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_TPREL14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TPREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TPREL14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL16F, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TPREL16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TPREL16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL16WF, 0, 0, 16, FALSE, 0, complain_overflow_dont,
+  { R_PARISC_TPREL16WF, 0, 2, 16, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_TPREL16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_TPREL16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TPREL16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TPREL16DF", FALSE, 0, 0, FALSE },
   /* 224 */
-  { R_PARISC_LTOFF_TP64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP64", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
   { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP14WR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14WR", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP14DR, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14DR", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP16F, 0, 0, 16, FALSE, 0, complain_overflow_dont,
+  { R_PARISC_LTOFF_TP16F, 0, 2, 16, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16F", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP16WF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16WF", FALSE, 0, 0, FALSE },
-  { R_PARISC_LTOFF_TP16DF, 0, 0, 16, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_LTOFF_TP16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16DF", FALSE, 0, 0, FALSE },
   /* 232 */
   { R_PARISC_GNU_VTENTRY, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_GNU_VTENTRY", FALSE, 0, 0, FALSE },
   { R_PARISC_GNU_VTINHERIT, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_GNU_VTINHERIT", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_GD21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_GD21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_GD21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_GD14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_GD14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_GD14R", FALSE, 0, 0, FALSE },
   { R_PARISC_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_TLS_GDCALL", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_LDM21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_LDM21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_LDM21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_LDM14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_LDM14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_LDM14R", FALSE, 0, 0, FALSE },
   { R_PARISC_TLS_LDMCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
     bfd_elf_generic_reloc, "R_PARISC_TLS_LDMCALL", FALSE, 0, 0, FALSE },
   /* 240 */
-  { R_PARISC_TLS_LDO21L, 0, 0, 21, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_LDO21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_LDO21L", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_LDO14R, 0, 0, 14, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_LDO14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_LDO14R", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_DTPMOD32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_DTPMOD32", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_DTPMOD64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_DTPMOD64", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_DTPOFF32, 0, 0, 32, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_DTPOFF32", FALSE, 0, 0, FALSE },
-  { R_PARISC_TLS_DTPOFF64, 0, 0, 64, FALSE, 0, complain_overflow_bitfield,
+  { R_PARISC_TLS_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
     bfd_elf_generic_reloc, "R_PARISC_TLS_DTPOFF64", FALSE, 0, 0, FALSE },
 };
 
@@ -2097,9 +2097,6 @@ elf_hppa_relocate_section (bfd *output_b
   Elf_Internal_Rela *relend;
   struct elf64_hppa_link_hash_table *hppa_info;
 
-  if (info->relocatable)
-    return TRUE;
-
   hppa_info = elf64_hppa_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
@@ -2152,6 +2149,7 @@ elf_hppa_relocate_section (bfd *output_b
 	  /* This is not a local symbol.  */
 	  long indx;
 
+	  relocation = 0;
 	  indx = r_symndx - symtab_hdr->sh_info;
 	  h = elf_sym_hashes (input_bfd)[indx];
 	  while (h->root.type == bfd_link_hash_indirect
@@ -2172,7 +2170,8 @@ elf_hppa_relocate_section (bfd *output_b
 	      /* If we have a relocation against a symbol defined in a
 		 shared library and we have not created an entry in the
 		 PA64 dynamic symbol hash table for it, then we lose.  */
-	      if (sym_sec->output_section == NULL && dyn_h == NULL)
+	      if (!info->relocatable
+		  && sym_sec->output_section == NULL && dyn_h == NULL)
 		{
 		  (*_bfd_error_handler)
 		    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
@@ -2181,16 +2180,11 @@ elf_hppa_relocate_section (bfd *output_b
 		     (long) rel->r_offset,
 		     howto->name,
 		     h->root.root.string);
-		  relocation = 0;
 		}
 	      else if (sym_sec->output_section)
 		relocation = (h->root.u.def.value
 			      + sym_sec->output_offset
 			      + sym_sec->output_section->vma);
-	      /* Value will be provided via one of the offsets in the
-		 dyn_h hash table entry.  */
-	      else
-		relocation = 0;
 	    }
 	  else if (info->unresolved_syms_in_objects == RM_IGNORE
 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
@@ -2202,13 +2196,12 @@ elf_hppa_relocate_section (bfd *output_b
 	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
 						  dyn_name, FALSE, FALSE);
 
-	      if (dyn_h == NULL)
+	      if (!info->relocatable && dyn_h == NULL)
 		{
 		  (*_bfd_error_handler)
 		    (_("%B(%A): warning: unresolvable relocation against symbol `%s'"),
 		     input_bfd, input_section, h->root.root.string);
 		}
-	      relocation = 0;
 	    }
 	  else if (h->root.type == bfd_link_hash_undefweak)
             {
@@ -2217,20 +2210,17 @@ elf_hppa_relocate_section (bfd *output_b
 	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
 						  dyn_name, FALSE, FALSE);
 
-	      if (dyn_h == NULL)
+	      if (!info->relocatable && dyn_h == NULL)
 		{
 		  (*_bfd_error_handler)
 		    (_("%B(%A): warning: unresolvable relocation against symbol `%s'"),
 		     input_bfd, input_section, h->root.root.string);
 		}
-	      relocation = 0;
 	    }
-	  else
+	  else if (!info->relocatable)
 	    {
 	      /* Ignore dynamic loader defined symbols.  */
-	      if (elf_hppa_is_dynamic_loader_symbol (h->root.root.string))
-		relocation = 0;
-	      else
+	      if (!elf_hppa_is_dynamic_loader_symbol (h->root.root.string))
 		{
 		  if (!((*info->callbacks->undefined_symbol)
 			(info, h->root.root.string, input_bfd,
@@ -2243,6 +2233,20 @@ elf_hppa_relocate_section (bfd *output_b
 	    }
 	}
 
+      if (sym_sec != NULL && elf_discarded_section (sym_sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
 					input_section, contents,
 					relocation, info, sym_sec,
Index: bfd/elf-m10200.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10200.c,v
retrieving revision 1.30
diff -u -p -r1.30 elf-m10200.c
--- bfd/elf-m10200.c	4 May 2005 15:53:08 -0000	1.30
+++ bfd/elf-m10200.c	7 Mar 2007 06:09:07 -0000
@@ -1,5 +1,5 @@
 /* Matsushita 10200 specific support for 32-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
    Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -343,9 +343,6 @@ mn10200_elf_relocate_section (output_bfd
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -385,6 +382,20 @@ mn10200_elf_relocate_section (output_bfd
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
 					   input_section,
 					   contents, rel->r_offset,
Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.78
diff -u -p -r1.78 elf-m10300.c
--- bfd/elf-m10300.c	31 Jan 2007 06:11:48 -0000	1.78
+++ bfd/elf-m10300.c	7 Mar 2007 06:09:09 -0000
@@ -1,6 +1,6 @@
 /* Matsushita 10300 specific support for 32-bit ELF
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006 Free Software Foundation, Inc.
+   2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1362,9 +1362,6 @@ mn10300_elf_relocate_section (output_bfd
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -1440,7 +1437,7 @@ mn10300_elf_relocate_section (output_bfd
 	       obscure cases sec->output_section will be NULL.  */
 	    relocation = 0;
 
-	  else if (unresolved_reloc)
+	  else if (!info->relocatable && unresolved_reloc)
 	    (*_bfd_error_handler)
 	      (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
 	       input_bfd,
@@ -1450,6 +1447,20 @@ mn10300_elf_relocate_section (output_bfd
 	       h->root.root.root.string);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
 					   input_section,
 					   contents, rel->r_offset,
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.105
diff -u -p -r1.105 elf32-arm.c
--- bfd/elf32-arm.c	22 Feb 2007 17:03:59 -0000	1.105
+++ bfd/elf32-arm.c	7 Mar 2007 06:09:16 -0000
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -4524,15 +4524,6 @@ elf32_arm_final_link_relocate (reloc_how
     case R_ARM_XPC25:
     case R_ARM_PREL31:
     case R_ARM_PLT32:
-      /* r_symndx will be zero only for relocs against symbols
-	 from removed linkonce sections, or sections discarded by
-	 a linker script.  */
-      if (r_symndx == 0)
-	{
-	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	  return bfd_reloc_ok;
-	}
-
       /* Handle relocations which should use the PLT entry.  ABS32/REL32
 	 will use the symbol's value, which may point to a PLT entry, but we
 	 don't need to handle that here.  If we created a PLT entry, all
@@ -6501,8 +6492,6 @@ elf32_arm_relocate_section (bfd *       
   struct elf32_arm_link_hash_table * globals;
 
   globals = elf32_arm_hash_table (info);
-  if (info->relocatable && !globals->use_rel)
-    return TRUE;
 
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -6535,29 +6524,6 @@ elf32_arm_relocate_section (bfd *       
       bfd_reloc.howto = elf32_arm_howto_from_type (r_type);
       howto = bfd_reloc.howto;
 
-      if (info->relocatable && globals->use_rel)
-	{
-	  /* This is a relocatable link.  We don't have to change
-	     anything, unless the reloc is against a section symbol,
-	     in which case we have to adjust according to where the
-	     section symbol winds up in the output section.  */
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      sym = local_syms + r_symndx;
-	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-		{
-		  sec = local_sections[r_symndx];
-		  arm_add_to_rel (input_bfd, contents + rel->r_offset,
-				  howto,
-				  (bfd_signed_vma) (sec->output_offset
-						    + sym->st_value));
-		}
-	    }
-
-	  continue;
-	}
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -6572,8 +6538,9 @@ elf32_arm_relocate_section (bfd *       
 	      relocation = (sec->output_section->vma
 			    + sec->output_offset
 			    + sym->st_value);
-	      if ((sec->flags & SEC_MERGE)
-		       && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	      if (!info->relocatable
+		  && (sec->flags & SEC_MERGE)
+		  && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
 		{
 		  asection *msec;
 		  bfd_vma addend, value;
@@ -6623,6 +6590,34 @@ elf32_arm_relocate_section (bfd *       
 	  sym_type = h->type;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	{
+	  /* This is a relocatable link.  We don't have to change
+	     anything, unless the reloc is against a section symbol,
+	     in which case we have to adjust according to where the
+	     section symbol winds up in the output section.  */
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      if (globals->use_rel)
+		arm_add_to_rel (input_bfd, contents + rel->r_offset,
+				howto, (bfd_signed_vma) sec->output_offset);
+	      else
+		rel->r_addend += sec->output_offset;
+	    }
+	  continue;
+	}
+
       if (h != NULL)
 	name = h->root.root.string;
       else
@@ -10613,7 +10608,6 @@ const struct elf_size_info elf32_arm_siz
 #define elf_backend_may_use_rel_p   1
 #define elf_backend_may_use_rela_p  0
 #define elf_backend_default_use_rela_p 0
-#define elf_backend_rela_normal     0
 
 #define elf_backend_got_header_size	12
 
@@ -10677,8 +10671,6 @@ elf32_arm_vxworks_final_write_processing
 #define elf_backend_may_use_rela_p	1
 #undef elf_backend_default_use_rela_p
 #define elf_backend_default_use_rela_p	1
-#undef elf_backend_rela_normal
-#define elf_backend_rela_normal		1
 #undef elf_backend_want_plt_sym
 #define elf_backend_want_plt_sym	1
 #undef ELF_MAXPAGESIZE
@@ -10831,8 +10823,6 @@ elf32_arm_symbian_modify_segment_map (bf
 #define elf_backend_may_use_rela_p	0
 #undef elf_backend_default_use_rela_p
 #define elf_backend_default_use_rela_p	0
-#undef elf_backend_rela_normal
-#define elf_backend_rela_normal		0
 #undef elf_backend_want_plt_sym
 #define elf_backend_want_plt_sym	0
 #undef ELF_MAXPAGESIZE
Index: bfd/elf32-avr.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-avr.c,v
retrieving revision 1.28
diff -u -p -r1.28 elf32-avr.c
--- bfd/elf32-avr.c	25 Jan 2007 09:32:41 -0000	1.28
+++ bfd/elf32-avr.c	7 Mar 2007 06:09:16 -0000
@@ -1153,9 +1153,6 @@ elf32_avr_relocate_section (bfd *output_
   Elf_Internal_Rela *           relend;
   struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
 
-  if (info == NULL || info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -1172,7 +1169,6 @@ elf32_avr_relocate_section (bfd *output_
       const char *                 name;
       int                          r_type;
 
-      /* This is a final link.  */
       r_type = ELF32_R_TYPE (rel->r_info);
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto  = elf_avr_howto_table + ELF32_R_TYPE (rel->r_info);
@@ -1202,6 +1198,20 @@ elf32_avr_relocate_section (bfd *output_
 	  name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = avr_final_link_relocate (howto, input_bfd, input_section,
 				   contents, rel, relocation, htab);
 
Index: bfd/elf32-bfin.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-bfin.c,v
retrieving revision 1.17
diff -u -p -r1.17 elf32-bfin.c
--- bfd/elf32-bfin.c	28 Sep 2006 13:27:33 -0000	1.17
+++ bfd/elf32-bfin.c	7 Mar 2007 06:09:18 -0000
@@ -1,5 +1,5 @@
 /* ADI Blackfin BFD support for 32-bit ELF.
-   Copyright 2005, 2006 Free Software Foundation, Inc.
+   Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2109,9 +2109,6 @@ bfinfdpic_relocate_section (bfd * output
     check_segment[2];
   int silence_segment_error = !(info->shared || info->pie);
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -2152,7 +2149,6 @@ bfinfdpic_relocate_section (bfd * output
 	  || r_type == R_BFIN_GNU_VTENTRY)
 	continue;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto = bfin_reloc_type_lookup (input_bfd, r_type);
       if (howto == NULL)
@@ -2177,48 +2173,37 @@ bfinfdpic_relocate_section (bfd * output
 	}
       else
 	{
-	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+	  bfd_boolean warned;
+	  bfd_boolean unresolved_reloc;
 
-	  while (h->root.type == bfd_link_hash_indirect
-		 || h->root.type == bfd_link_hash_warning)
-	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation,
+				   unresolved_reloc, warned);
+	  osec = sec;
+	}
 
-	  name = h->root.root.string;
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
 
-	  if ((h->root.type == bfd_link_hash_defined
-	       || h->root.type == bfd_link_hash_defweak)
-	      && ! BFINFDPIC_SYM_LOCAL (info, h))
-	    {
-	      sec = NULL;
-	      relocation = 0;
-	    }
-	  else
-	    if (h->root.type == bfd_link_hash_defined
-		|| h->root.type == bfd_link_hash_defweak)
-	      {
-		sec = h->root.u.def.section;
-		relocation = (h->root.u.def.value
-			      + sec->output_section->vma
-			      + sec->output_offset);
-	      }
-	    else if (h->root.type == bfd_link_hash_undefweak)
-	      {
-		relocation = 0;
-	      }
-	    else if (info->unresolved_syms_in_objects == RM_IGNORE
-		     && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-	      relocation = 0;
-	    else
-	      {
-		if (! ((*info->callbacks->undefined_symbol)
-		       (info, h->root.root.string, input_bfd,
-			input_section, rel->r_offset,
-			(info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-			 || ELF_ST_VISIBILITY (h->other)))))
-		  return FALSE;
-		relocation = 0;
-	      }
-	  osec = sec;
+      if (info->relocatable)
+	continue;
+
+      if (h != NULL
+	  && (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak)
+	  && !BFINFDPIC_SYM_LOCAL (info, h))
+	{
+	  osec = sec = NULL;
+	  relocation = 0;
 	}
 
       switch (r_type)
@@ -2831,9 +2816,6 @@ bfin_relocate_section (bfd * output_bfd,
   Elf_Internal_Rela *relend;
   int i = 0;
 
-  if (info->relocatable)
-    return TRUE;
-
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -2890,13 +2872,27 @@ bfin_relocate_section (bfd * output_bfd,
       else
 	{
 	  bfd_boolean warned;
-	  h = NULL;
+
 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
 				   r_symndx, symtab_hdr, sym_hashes,
 				   h, sec, relocation,
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       address = rel->r_offset;
 
       /* Then, process normally.  */
Index: bfd/elf32-cr16c.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cr16c.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-cr16c.c
--- bfd/elf32-cr16c.c	28 Sep 2006 13:27:33 -0000	1.8
+++ bfd/elf32-cr16c.c	7 Mar 2007 06:09:19 -0000
@@ -1,5 +1,5 @@
 /* BFD back-end for National Semiconductor's CR16C ELF
-   Copyright 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -692,26 +692,6 @@ elf32_cr16c_relocate_section (bfd *outpu
       r_type = ELF32_R_TYPE (rel->r_info);
       howto = elf_howto_table + r_type;
 
-      if (info->relocatable)
-	{
-	  /* This is a relocatable link.  We don't have to change
-	     anything, unless the reloc is against a section symbol,
-	     in which case we have to adjust according to where the
-	     section symbol winds up in the output section.  */
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      sym = local_syms + r_symndx;
-	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-		{
-		  sec = local_sections[r_symndx];
-		  rel->r_addend += sec->output_offset + sym->st_value;
-		}
-	    }
-
-	  continue;
-	}
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -731,6 +711,28 @@ elf32_cr16c_relocate_section (bfd *outpu
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	{
+	  /* This is a relocatable link.  We don't have to change
+	     anything, unless the reloc is against a section symbol,
+	     in which case we have to adjust according to where the
+	     section symbol winds up in the output section.  */
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    rel->r_addend += sec->output_offset;
+	  continue;
+	}
+
       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
 					 input_section,
 					 contents, rel->r_offset,
Index: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.77
diff -u -p -r1.77 elf32-cris.c
--- bfd/elf32-cris.c	31 Jan 2007 14:28:03 -0000	1.77
+++ bfd/elf32-cris.c	7 Mar 2007 06:09:20 -0000
@@ -1,5 +1,5 @@
 /* CRIS-specific support for 32-bit ELF.
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Axis Communications AB.
    Written by Hans-Peter Nilsson, based on elf32-fr30.c
@@ -927,9 +927,6 @@ cris_elf_relocate_section (output_bfd, i
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
@@ -964,7 +961,6 @@ cris_elf_relocate_section (output_bfd, i
 	  || r_type == R_CRIS_GNU_VTENTRY)
 	continue;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto  = cris_elf_howto_table + r_type;
       h      = NULL;
@@ -1042,7 +1038,7 @@ cris_elf_relocate_section (output_bfd, i
 		      || r_type == R_CRIS_16_PCREL
 		      || r_type == R_CRIS_32_PCREL))
 		relocation = 0;
-	      else if (unresolved_reloc)
+	      else if (!info->relocatable && unresolved_reloc)
 		{
 		  _bfd_error_handler
 		    (_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
@@ -1056,6 +1052,20 @@ cris_elf_relocate_section (output_bfd, i
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_CRIS_16_GOTPLT:
Index: bfd/elf32-crx.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-crx.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-crx.c
--- bfd/elf32-crx.c	28 Sep 2006 13:27:33 -0000	1.8
+++ bfd/elf32-crx.c	7 Mar 2007 06:09:21 -0000
@@ -1,5 +1,5 @@
 /* BFD back-end for National Semiconductor's CRX ELF
-   Copyright 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Written by Tomer Levi, NSC, Israel.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -821,9 +821,6 @@ elf32_crx_relocate_section (bfd *output_
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -863,6 +860,20 @@ elf32_crx_relocate_section (bfd *output_
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
 					input_section,
 					contents, rel->r_offset,
Index: bfd/elf32-d10v.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-d10v.c,v
retrieving revision 1.32
diff -u -p -r1.32 elf32-d10v.c
--- bfd/elf32-d10v.c	3 Nov 2006 00:58:09 -0000	1.32
+++ bfd/elf32-d10v.c	7 Mar 2007 06:09:22 -0000
@@ -1,6 +1,6 @@
 /* D10V-specific support for 32-bit ELF
-   Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2007 Free Software Foundation, Inc.
    Contributed by Martin Hunt (hunt@cygnus.com).
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -405,35 +405,6 @@ elf32_d10v_relocate_section (bfd *output
         continue;
 
       howto = elf_d10v_howto_table + r_type;
-
-      if (info->relocatable)
-	{
-	  bfd_vma val;
-	  bfd_byte *where;
-
-	  /* This is a relocatable link.  We don't have to change
-	     anything, unless the reloc is against a section symbol,
-	     in which case we have to adjust according to where the
-	     section symbol winds up in the output section.  */
-	  if (r_symndx >= symtab_hdr->sh_info)
-	    continue;
-
-	  sym = local_syms + r_symndx;
-	  if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
-	    continue;
-
-	  sec = local_sections[r_symndx];
-	  val = sec->output_offset;
-	  if (val == 0)
-	    continue;
-
-	  where = contents + rel->r_offset;
-	  val += extract_rel_addend (input_bfd, where, howto);
-	  insert_rel_addend (input_bfd, where, howto, val);
-	  continue;
-	}
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -444,18 +415,26 @@ elf32_d10v_relocate_section (bfd *output
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
-	  if ((sec->flags & SEC_MERGE)
-	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
+	      && ((sec->flags & SEC_MERGE) != 0
+		  || (info->relocatable
+		      && sec->output_offset != 0)))
 	    {
-	      asection *msec;
 	      bfd_vma addend;
 	      bfd_byte *where = contents + rel->r_offset;
 
 	      addend = extract_rel_addend (input_bfd, where, howto);
-	      msec = sec;
-	      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
-	      addend -= relocation;
-	      addend += msec->output_section->vma + msec->output_offset;
+
+	      if (info->relocatable)
+		addend += sec->output_offset;
+	      else
+		{
+		  asection *msec = sec;
+		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
+						   addend);
+		  addend -= relocation;
+		  addend += msec->output_section->vma + msec->output_offset;
+		}
 	      insert_rel_addend (input_bfd, where, howto, addend);
 	    }
 	}
@@ -469,16 +448,20 @@ elf32_d10v_relocate_section (bfd *output
 				   unresolved_reloc, warned);
 	}
 
-      if (r_symndx == 0)
+      if (sec != NULL && elf_discarded_section (sec))
 	{
-	  /* r_symndx will be zero only for relocs against symbols from
-	     removed linkonce sections, or sections discarded by a linker
-	     script.  For these relocs, we just want the section contents
-	     zeroed.  Avoid any special processing.  */
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
 	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
 	  continue;
 	}
 
+      if (info->relocatable)
+	continue;
+
       if (h != NULL)
 	name = h->root.root.string;
       else
Index: bfd/elf32-fr30.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-fr30.c,v
retrieving revision 1.31
diff -u -p -r1.31 elf32-fr30.c
--- bfd/elf32-fr30.c	28 Sep 2006 13:27:33 -0000	1.31
+++ bfd/elf32-fr30.c	7 Mar 2007 06:09:22 -0000
@@ -1,5 +1,5 @@
 /* FR30-specific support for 32-bit ELF.
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -510,9 +510,6 @@ fr30_elf_relocate_section (output_bfd, i
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -564,6 +561,20 @@ fr30_elf_relocate_section (output_bfd, i
 	  name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = fr30_final_link_relocate (howto, input_bfd, input_section,
 				     contents, rel, relocation);
 
Index: bfd/elf32-frv.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-frv.c,v
retrieving revision 1.49
diff -u -p -r1.49 elf32-frv.c
--- bfd/elf32-frv.c	28 Sep 2006 13:27:33 -0000	1.49
+++ bfd/elf32-frv.c	7 Mar 2007 06:09:25 -0000
@@ -1,5 +1,6 @@
 /* FRV-specific support for 32-bit ELF.
-   Copyright 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+   Copyright 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -2722,9 +2723,6 @@ elf32_frv_relocate_section (output_bfd, 
   int silence_segment_error = !(info->shared || info->pie);
   unsigned long insn;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -2776,7 +2774,6 @@ elf32_frv_relocate_section (output_bfd, 
 	  || r_type == R_FRV_GNU_VTENTRY)
 	continue;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto  = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
@@ -2795,50 +2792,38 @@ elf32_frv_relocate_section (output_bfd, 
 	}
       else
 	{
-	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+	  bfd_boolean warned;
+	  bfd_boolean unresolved_reloc;
 
-	  while (h->root.type == bfd_link_hash_indirect
-		 || h->root.type == bfd_link_hash_warning)
-	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation,
+				   unresolved_reloc, warned);
+	  osec = sec;
+	}
 
-	  name = h->root.root.string;
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
 
-	  if ((h->root.type == bfd_link_hash_defined
-	       || h->root.type == bfd_link_hash_defweak))
-	    {
-	      if (/* TLSMOFF forces local binding.  */
-		  r_type != R_FRV_TLSMOFF
-		  && ! FRVFDPIC_SYM_LOCAL (info, h))
-		{
-		  sec = NULL;
-		  relocation = 0;
-		}
-	      else
-		{
-		  sec = h->root.u.def.section;
-		  relocation = (h->root.u.def.value
-				+ sec->output_section->vma
-				+ sec->output_offset);
-		}
-	    }
-	  else if (h->root.type == bfd_link_hash_undefweak)
-	    {
-	      relocation = 0;
-	    }
-	  else if (info->unresolved_syms_in_objects == RM_IGNORE
-		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-	    relocation = 0;
-	  else
-	    {
-	      if (! ((*info->callbacks->undefined_symbol)
-		     (info, h->root.root.string, input_bfd,
-		      input_section, rel->r_offset,
-		      (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-		       || ELF_ST_VISIBILITY (h->other)))))
-		return FALSE;
-	      relocation = 0;
-	    }
-	  osec = sec;
+      if (info->relocatable)
+	continue;
+
+      if (r_type != R_FRV_TLSMOFF
+	  && h != NULL
+	  && (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak)
+	  && !FRVFDPIC_SYM_LOCAL (info, h))
+	{
+	  osec = sec = NULL;
+	  relocation = 0;
 	}
 
       switch (r_type)
Index: bfd/elf32-h8300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-h8300.c,v
retrieving revision 1.49
diff -u -p -r1.49 elf32-h8300.c
--- bfd/elf32-h8300.c	28 Sep 2006 13:27:33 -0000	1.49
+++ bfd/elf32-h8300.c	7 Mar 2007 06:09:25 -0000
@@ -1,6 +1,6 @@
 /* BFD back-end for Renesas H8/300 ELF binaries.
-   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
+   2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -402,9 +402,6 @@ elf32_h8_relocate_section (bfd *output_b
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -419,8 +416,12 @@ elf32_h8_relocate_section (bfd *output_b
       struct elf_link_hash_entry *h;
       bfd_vma relocation;
       bfd_reloc_status_type r;
+      arelent bfd_reloc;
+      reloc_howto_type *howto;
+
+      elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
+      howto = bfd_reloc.howto;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
       h = NULL;
@@ -442,6 +443,20 @@ elf32_h8_relocate_section (bfd *output_b
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
 					input_section,
 					contents, rel->r_offset,
@@ -452,11 +467,6 @@ elf32_h8_relocate_section (bfd *output_b
 	{
 	  const char *name;
 	  const char *msg = (const char *) 0;
-	  arelent bfd_reloc;
-	  reloc_howto_type *howto;
-
-	  elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
-	  howto = bfd_reloc.howto;
 
 	  if (h != NULL)
 	    name = h->root.root.string;
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.150
diff -u -p -r1.150 elf32-hppa.c
--- bfd/elf32-hppa.c	27 Jan 2007 22:43:49 -0000	1.150
+++ bfd/elf32-hppa.c	7 Mar 2007 06:09:28 -0000
@@ -1,6 +1,6 @@
 /* BFD back-end for HP PA-RISC ELF files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    Original code by
 	Center for Software Science
@@ -3651,9 +3651,6 @@ elf32_hppa_relocate_section (bfd *output
   Elf_Internal_Rela *rela;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   htab = hppa_link_hash_table (info);
@@ -3685,7 +3682,6 @@ elf32_hppa_relocate_section (bfd *output
 	  || r_type == (unsigned int) R_PARISC_GNU_VTINHERIT)
 	continue;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rela->r_info);
       hh = NULL;
       sym = NULL;
@@ -3709,7 +3705,8 @@ elf32_hppa_relocate_section (bfd *output
 				   eh, sym_sec, relocation,
 				   unresolved_reloc, warned_undef);
 
-	  if (relocation == 0
+	  if (!info->relocatable
+	      && relocation == 0
 	      && eh->root.type != bfd_link_hash_defined
 	      && eh->root.type != bfd_link_hash_defweak
 	      && eh->root.type != bfd_link_hash_undefweak)
@@ -3728,6 +3725,22 @@ elf32_hppa_relocate_section (bfd *output
 	  hh = hppa_elf_hash_entry (eh);
 	}
 
+      if (sym_sec != NULL && elf_discarded_section (sym_sec))
+	{
+	  /* For relocs against symbols from removed linkonce
+	     sections, or sections discarded by a linker script,
+	     we just want the section contents zeroed.  Avoid any
+	     special processing.  */
+	  _bfd_clear_contents (elf_hppa_howto_table + r_type, input_bfd,
+			       contents + rela->r_offset);
+	  rela->r_info = 0;
+	  rela->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       /* Do any required modifications to the relocation value, and
 	 determine what types of dynamic info we need to output, if
 	 any.  */
@@ -3939,16 +3952,6 @@ elf32_hppa_relocate_section (bfd *output
 	case R_PARISC_DPREL14R:
 	case R_PARISC_DPREL21L:
 	case R_PARISC_DIR32:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (elf_hppa_howto_table + r_type, input_bfd,
-				   contents + rela->r_offset);
-	      break;
-	    }
-
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
Index: bfd/elf32-i370.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i370.c,v
retrieving revision 1.56
diff -u -p -r1.56 elf32-i370.c
--- bfd/elf32-i370.c	17 Oct 2006 13:41:47 -0000	1.56
+++ bfd/elf32-i370.c	7 Mar 2007 06:09:29 -0000
@@ -1077,9 +1077,6 @@ i370_elf_relocate_section (bfd *output_b
   bfd_vma *local_got_offsets;
   bfd_boolean ret = TRUE;
 
-  if (info->relocatable)
-    return TRUE;
-
 #ifdef DEBUG
   _bfd_error_handler ("i370_elf_relocate_section called for %B section %A, %ld relocations%s",
 		      input_bfd, input_section,
@@ -1122,6 +1119,7 @@ i370_elf_relocate_section (bfd *output_b
 
       howto = i370_elf_howto_table[(int) r_type];
       r_symndx = ELF32_R_SYM (rel->r_info);
+      relocation = 0;
 
       if (r_symndx < symtab_hdr->sh_info)
 	{
@@ -1154,18 +1152,18 @@ i370_elf_relocate_section (bfd *output_b
 		/* In these cases, we don't need the relocation
 		   value.  We check specially because in some
 		   obscure cases sec->output_section will be NULL.  */
-		relocation = 0;
+		;
 	      else
 		relocation = (h->root.u.def.value
 			      + sec->output_section->vma
 			      + sec->output_offset);
 	    }
 	  else if (h->root.type == bfd_link_hash_undefweak)
-	    relocation = 0;
+	    ;
 	  else if (info->unresolved_syms_in_objects == RM_IGNORE
 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-	    relocation = 0;
-	  else
+	    ;
+	  else if (!info->relocatable)
 	    {
 	      if ((*info->callbacks->undefined_symbol)
 		  (info, h->root.root.string, input_bfd,
@@ -1176,10 +1174,23 @@ i370_elf_relocate_section (bfd *output_b
 		  ret = FALSE;
 		  continue;
 		}
-	      relocation = 0;
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch ((int) r_type)
 	{
 	default:
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.168
diff -u -p -r1.168 elf32-i386.c
--- bfd/elf32-i386.c	3 Nov 2006 00:58:09 -0000	1.168
+++ bfd/elf32-i386.c	7 Mar 2007 06:09:31 -0000
@@ -1,6 +1,6 @@
 /* Intel 80386/80486-specific support for 32-bit ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2264,51 +2264,6 @@ elf_i386_relocate_section (bfd *output_b
       howto = elf_howto_table + indx;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
-
-      if (info->relocatable)
-	{
-	  bfd_vma val;
-	  bfd_byte *where;
-
-	  /* This is a relocatable link.  We don't have to change
-	     anything, unless the reloc is against a section symbol,
-	     in which case we have to adjust according to where the
-	     section symbol winds up in the output section.  */
-	  if (r_symndx >= symtab_hdr->sh_info)
-	    continue;
-
-	  sym = local_syms + r_symndx;
-	  if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
-	    continue;
-
-	  sec = local_sections[r_symndx];
-	  val = sec->output_offset;
-	  if (val == 0)
-	    continue;
-
-	  where = contents + rel->r_offset;
-	  switch (howto->size)
-	    {
-	      /* FIXME: overflow checks.  */
-	    case 0:
-	      val += bfd_get_8 (input_bfd, where);
-	      bfd_put_8 (input_bfd, val, where);
-	      break;
-	    case 1:
-	      val += bfd_get_16 (input_bfd, where);
-	      bfd_put_16 (input_bfd, val, where);
-	      break;
-	    case 2:
-	      val += bfd_get_32 (input_bfd, where);
-	      bfd_put_32 (input_bfd, val, where);
-	      break;
-	    default:
-	      abort ();
-	    }
-	  continue;
-	}
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -2320,10 +2275,12 @@ elf_i386_relocate_section (bfd *output_b
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
-	  if ((sec->flags & SEC_MERGE)
-	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+
+	  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
+	      && ((sec->flags & SEC_MERGE) != 0
+		  || (info->relocatable
+		      && sec->output_offset != 0)))
 	    {
-	      asection *msec;
 	      bfd_vma addend;
 	      bfd_byte *where = contents + rel->r_offset;
 
@@ -2357,10 +2314,16 @@ elf_i386_relocate_section (bfd *output_b
 		  abort ();
 		}
 
-	      msec = sec;
-	      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
-	      addend -= relocation;
-	      addend += msec->output_section->vma + msec->output_offset;
+	      if (info->relocatable)
+		addend += sec->output_offset;
+	      else
+		{
+		  asection *msec = sec;
+		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
+						   addend);
+		  addend -= relocation;
+		  addend += msec->output_section->vma + msec->output_offset;
+		}
 
 	      switch (howto->size)
 		{
@@ -2393,16 +2356,20 @@ elf_i386_relocate_section (bfd *output_b
 				   unresolved_reloc, warned);
 	}
 
-      if (r_symndx == 0)
+      if (sec != NULL && elf_discarded_section (sec))
 	{
-	  /* r_symndx will be zero only for relocs against symbols from
-	     removed linkonce sections, or sections discarded by a linker
-	     script.  For these relocs, we just want the section contents
-	     zeroed.  Avoid any special processing.  */
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
 	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
 	  continue;
 	}
 
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_386_GOT32:
Index: bfd/elf32-i860.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i860.c,v
retrieving revision 1.37
diff -u -p -r1.37 elf32-i860.c
--- bfd/elf32-i860.c	4 May 2005 15:53:15 -0000	1.37
+++ bfd/elf32-i860.c	7 Mar 2007 06:09:31 -0000
@@ -1,5 +1,5 @@
 /* Intel i860 specific support for 32-bit ELF.
-   Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
    Free Software Foundation, Inc.
 
    Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
@@ -1066,9 +1066,6 @@ elf32_i860_relocate_section (bfd *output
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -1113,6 +1110,20 @@ elf32_i860_relocate_section (bfd *output
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	default:
Index: bfd/elf32-ip2k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ip2k.c,v
retrieving revision 1.21
diff -u -p -r1.21 elf32-ip2k.c
--- bfd/elf32-ip2k.c	28 Sep 2006 13:27:33 -0000	1.21
+++ bfd/elf32-ip2k.c	7 Mar 2007 06:09:32 -0000
@@ -1,5 +1,5 @@
 /* Ubicom IP2xxx specific support for 32-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -1399,9 +1399,6 @@ ip2k_elf_relocate_section (bfd *output_b
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -1418,7 +1415,6 @@ ip2k_elf_relocate_section (bfd *output_b
       const char *                 name = NULL;
       int                          r_type;
 
-      /* This is a final link.  */
       r_type = ELF32_R_TYPE (rel->r_info);
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto  = ip2k_elf_howto_table + ELF32_R_TYPE (rel->r_info);
@@ -1449,6 +1445,20 @@ ip2k_elf_relocate_section (bfd *output_b
 	  name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       /* Finally, the sole IP2K-specific part.  */
       r = ip2k_final_link_relocate (howto, input_bfd, input_section,
 				     contents, rel, relocation);
Index: bfd/elf32-iq2000.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-iq2000.c,v
retrieving revision 1.17
diff -u -p -r1.17 elf32-iq2000.c
--- bfd/elf32-iq2000.c	28 Sep 2006 13:27:33 -0000	1.17
+++ bfd/elf32-iq2000.c	7 Mar 2007 06:09:32 -0000
@@ -1,5 +1,6 @@
 /* IQ2000-specific support for 32-bit ELF.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -521,9 +522,6 @@ iq2000_elf_relocate_section (bfd *		    
   Elf_Internal_Rela *		rel;
   Elf_Internal_Rela *		relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -548,7 +546,6 @@ iq2000_elf_relocate_section (bfd *		    
       
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      /* This is a final link.	*/
       howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h	     = NULL;
       sym    = NULL;
@@ -579,6 +576,20 @@ iq2000_elf_relocate_section (bfd *		    
 	  name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_IQ2000_HI16:
Index: bfd/elf32-m32c.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32c.c,v
retrieving revision 1.10
diff -u -p -r1.10 elf32-m32c.c
--- bfd/elf32-m32c.c	26 Jan 2007 00:00:47 -0000	1.10
+++ bfd/elf32-m32c.c	7 Mar 2007 06:09:33 -0000
@@ -1,5 +1,5 @@
 /* M16C/M32C specific support for 32-bit ELF.
-   Copyright (C) 2005, 2006
+   Copyright (C) 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -372,31 +372,11 @@ m32c_elf_relocate_section
       
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      if (info->relocatable)
-	{
-	  /* This is a relocatable link.  We don't have to change
-             anything, unless the reloc is against a section symbol,
-             in which case we have to adjust according to where the
-             section symbol winds up in the output section.  */
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      sym = local_syms + r_symndx;
-	      
-	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-		{
-		  sec = local_sections [r_symndx];
-		  rel->r_addend += sec->output_offset + sym->st_value;
-		}
-	    }
-
-	  continue;
-	}
-
-      /* This is a final link.  */
       howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
       sym    = NULL;
       sec    = NULL;
+      relocation = 0;
 
       if (r_symndx < symtab_hdr->sh_info)
 	{
@@ -429,19 +409,38 @@ m32c_elf_relocate_section
 			    + sec->output_offset);
 	    }
 	  else if (h->root.type == bfd_link_hash_undefweak)
-	    {
-	      relocation = 0;
-	    }
-	  else
+	    ;
+	  else if (!info->relocatable)
 	    {
 	      if (! ((*info->callbacks->undefined_symbol)
 		     (info, h->root.root.string, input_bfd,
 		      input_section, rel->r_offset, TRUE)))
 		return FALSE;
-	      relocation = 0;
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	{
+	  /* This is a relocatable link.  We don't have to change
+             anything, unless the reloc is against a section symbol,
+             in which case we have to adjust according to where the
+             section symbol winds up in the output section.  */
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    rel->r_addend += sec->output_offset;
+	  continue;
+	}
+
       switch (ELF32_R_TYPE (rel->r_info))
 	{
 	case R_M32C_16:
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.83
diff -u -p -r1.83 elf32-m32r.c
--- bfd/elf32-m32r.c	17 Oct 2006 13:41:46 -0000	1.83
+++ bfd/elf32-m32r.c	7 Mar 2007 06:09:36 -0000
@@ -1,6 +1,6 @@
 /* M32R-specific support for 32-bit ELF.
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006 Free Software Foundation, Inc.
+   2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2477,6 +2477,7 @@ m32r_elf_relocate_section (bfd *output_b
          `r_addend'.  */
       bfd_vma addend = rel->r_addend;
       bfd_vma offset = rel->r_offset;
+      bfd_vma relocation;
       Elf_Internal_Sym *sym;
       asection *sec;
       const char *sym_name;
@@ -2509,27 +2510,152 @@ m32r_elf_relocate_section (bfd *output_b
       howto = m32r_elf_howto_table + r_type;
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      if (info->relocatable && use_rel)
+      sym = NULL;
+      sec = NULL;
+      h = NULL;
+
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  /* Local symbol.  */
+	  sym = local_syms + r_symndx;
+	  sec = local_sections[r_symndx];
+	  sym_name = "<local symbol>";
+
+	  if (!use_rel)
+	    {
+	      relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+	      addend = rel->r_addend;
+	    }
+	  else
+	    {
+	      relocation = (sec->output_section->vma
+			    + sec->output_offset
+			    + sym->st_value);
+	    }
+	}
+      else
+	{
+	  /* External symbol.  */
+	  relocation = 0;
+
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  while (h->root.type == bfd_link_hash_indirect
+		 || h->root.type == bfd_link_hash_warning)
+	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+	  sym_name = h->root.root.string;
+
+	  if (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak)
+	    {
+	      bfd_boolean dyn;
+	      sec = h->root.u.def.section;
+
+	      dyn = htab->root.dynamic_sections_created;
+	      sec = h->root.u.def.section;
+	      if (r_type == R_M32R_GOTPC24
+		  || (r_type == R_M32R_GOTPC_HI_ULO
+		      || r_type == R_M32R_GOTPC_HI_SLO
+		      || r_type == R_M32R_GOTPC_LO)
+		  || (r_type == R_M32R_26_PLTREL
+		      && h->plt.offset != (bfd_vma) -1)
+		  || ((r_type == R_M32R_GOT24
+		       || r_type == R_M32R_GOT16_HI_ULO
+		       || r_type == R_M32R_GOT16_HI_SLO
+		       || r_type == R_M32R_GOT16_LO)
+		      && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+							  info->shared, h)
+		      && (! info->shared
+			  || (! info->symbolic && h->dynindx != -1)
+			  || !h->def_regular))
+		  || (info->shared
+		      && ((! info->symbolic && h->dynindx != -1)
+			  || !h->def_regular)
+		      && (((r_type == R_M32R_16_RELA
+			    || r_type == R_M32R_32_RELA
+			    || r_type == R_M32R_24_RELA
+			    || r_type == R_M32R_HI16_ULO_RELA
+			    || r_type == R_M32R_HI16_SLO_RELA
+			    || r_type == R_M32R_LO16_RELA)
+			   && !h->forced_local)
+			  || r_type == R_M32R_REL32
+			  || r_type == R_M32R_10_PCREL_RELA
+			  || r_type == R_M32R_18_PCREL_RELA
+			  || r_type == R_M32R_26_PCREL_RELA)
+		      && ((input_section->flags & SEC_ALLOC) != 0
+			  /* DWARF will emit R_M32R_16(24,32) relocations
+			     in its sections against symbols defined
+			     externally in shared libraries.  We can't do
+			     anything with them here.  */
+			  || ((input_section->flags & SEC_DEBUGGING) != 0
+			      && h->def_dynamic))))
+		{
+		  /* In these cases, we don't need the relocation
+		     value.  We check specially because in some
+		     obscure cases sec->output_section will be NULL.  */
+		}
+	      else if (sec->output_section != NULL)
+		relocation = (h->root.u.def.value
+			      + sec->output_section->vma
+			      + sec->output_offset);
+	      else if (!info->relocatable)
+		{
+		  (*_bfd_error_handler)
+		    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+		     input_bfd,
+		     input_section,
+		     (long) rel->r_offset,
+		     howto->name,
+		     h->root.root.string);
+		}
+	    }
+	  else if (h->root.type == bfd_link_hash_undefweak)
+	    ;
+	  else if (info->unresolved_syms_in_objects == RM_IGNORE
+		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+	    ;
+	  else if (!info->relocatable)
+	    {
+	      if (! ((*info->callbacks->undefined_symbol)
+		     (info, h->root.root.string, input_bfd,
+		      input_section, offset,
+		      (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+		       || ELF_ST_VISIBILITY (h->other)))))
+		return FALSE;
+	    }
+	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable && !use_rel)
 	{
 	  /* This is a relocatable link.  We don't have to change
 	     anything, unless the reloc is against a section symbol,
 	     in which case we have to adjust according to where the
 	     section symbol winds up in the output section.  */
-	  sec = NULL;
-	  if (r_symndx >= symtab_hdr->sh_info)
-	    /* External symbol.  */
-	    continue;
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    rel->r_addend += sec->output_offset;
+	  continue;
+	}
 
-	  /* Local symbol.  */
-	  sym = local_syms + r_symndx;
-	  sym_name = "<local symbol>";
-	  /* STT_SECTION: symbol is associated with a section.  */
-	  if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
-	    /* Symbol isn't associated with a section.  Nothing to do.  */
+      if (info->relocatable && use_rel)
+	{
+	  /* This is a relocatable link.  We don't have to change
+	     anything, unless the reloc is against a section symbol,
+	     in which case we have to adjust according to where the
+	     section symbol winds up in the output section.  */
+	  if (sym == NULL || ELF_ST_TYPE (sym->st_info) != STT_SECTION)
 	    continue;
 
-	  sec = local_sections[r_symndx];
-	  addend += sec->output_offset + sym->st_value;
+	  addend += sec->output_offset;
 
 	  /* If partial_inplace, we need to store any additional addend
 	     back in the section.  */
@@ -2567,140 +2693,6 @@ m32r_elf_relocate_section (bfd *output_b
 	}
       else
 	{
-	  bfd_vma relocation;
-
-	  /* This is a final link.  */
-	  sym = NULL;
-	  sec = NULL;
-          h = NULL;
-
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      /* Local symbol.  */
-	      sym = local_syms + r_symndx;
-	      sec = local_sections[r_symndx];
-	      sym_name = "<local symbol>";
-
-              if (!use_rel)
-                {
-	          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
-	          addend = rel->r_addend;
-
-                  if (info->relocatable)
-                    {
-                      /* This is a relocatable link.  We don't have to change
-                         anything, unless the reloc is against a section symbol,
-                         in which case we have to adjust according to where the
-                         section symbol winds up in the output section.  */
-                      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-                        rel->r_addend += sec->output_offset + sym->st_value;
-
-                      continue;
-                    }
-                }
-              else
-                {
-	          relocation = (sec->output_section->vma
-			        + sec->output_offset
-			        + sym->st_value);
-                }
-	    }
-	  else
-	    {
-	      /* External symbol.  */
-              if (info->relocatable && !use_rel)
-                continue;
-
-	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-	      while (h->root.type == bfd_link_hash_indirect
-		     || h->root.type == bfd_link_hash_warning)
-		h = (struct elf_link_hash_entry *) h->root.u.i.link;
-	      sym_name = h->root.root.string;
-
-	      if (h->root.type == bfd_link_hash_defined
-		  || h->root.type == bfd_link_hash_defweak)
-		{
-	          bfd_boolean dyn;
-		  sec = h->root.u.def.section;
-
-	          dyn = htab->root.dynamic_sections_created;
-                  sec = h->root.u.def.section;
-                  if (r_type == R_M32R_GOTPC24
-                      || (r_type == R_M32R_GOTPC_HI_ULO
-                          || r_type == R_M32R_GOTPC_HI_SLO
-                          || r_type == R_M32R_GOTPC_LO)
-                      || (r_type == R_M32R_26_PLTREL
-                          && h->plt.offset != (bfd_vma) -1)
-                      || ((r_type == R_M32R_GOT24
-                           || r_type == R_M32R_GOT16_HI_ULO
-                           || r_type == R_M32R_GOT16_HI_SLO
-                           || r_type == R_M32R_GOT16_LO)
-                          && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
-							      info->shared, h)
-                          && (! info->shared
-                              || (! info->symbolic && h->dynindx != -1)
-                              || !h->def_regular))
-                      || (info->shared
-                          && ((! info->symbolic && h->dynindx != -1)
-                              || !h->def_regular)
-                          && (((r_type == R_M32R_16_RELA
-                              || r_type == R_M32R_32_RELA
-                              || r_type == R_M32R_24_RELA
-                              || r_type == R_M32R_HI16_ULO_RELA
-                              || r_type == R_M32R_HI16_SLO_RELA
-                              || r_type == R_M32R_LO16_RELA)
-			          && !h->forced_local)
-                              || r_type == R_M32R_REL32
-                              || r_type == R_M32R_10_PCREL_RELA
-                              || r_type == R_M32R_18_PCREL_RELA
-                              || r_type == R_M32R_26_PCREL_RELA)
-                          && ((input_section->flags & SEC_ALLOC) != 0
-                              /* DWARF will emit R_M32R_16(24,32) relocations
-                                 in its sections against symbols defined
-                                 externally in shared libraries.  We can't do
-                                 anything with them here.  */
-                              || ((input_section->flags & SEC_DEBUGGING) != 0
-                                  && h->def_dynamic))))
-                    {
-                      /* In these cases, we don't need the relocation
-                         value.  We check specially because in some
-                         obscure cases sec->output_section will be NULL.  */
-                      relocation = 0;
-                    }
-		  else if (sec->output_section == NULL)
-                    {
-                      (*_bfd_error_handler)
-                        (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
-			 input_bfd,
-			 input_section,
-			 (long) rel->r_offset,
-			 howto->name,
-			 h->root.root.string);
-
-		       relocation = 0;
-                    }
-		  else
-		    relocation = (h->root.u.def.value
-				  + sec->output_section->vma
-				  + sec->output_offset);
-		}
-	      else if (h->root.type == bfd_link_hash_undefweak)
-		relocation = 0;
-              else if (info->unresolved_syms_in_objects == RM_IGNORE
-                       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-                relocation = 0;
-	      else
-		{
-		  if (! ((*info->callbacks->undefined_symbol)
-			 (info, h->root.root.string, input_bfd,
-			  input_section, offset,
-                          (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-                           || ELF_ST_VISIBILITY (h->other)))))
-		    return FALSE;
-		  relocation = 0;
-		}
-	    }
-
 	  /* Sanity check the address.  */
 	  if (offset > high_address)
 	    {
Index: bfd/elf32-m68hc1x.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68hc1x.c,v
retrieving revision 1.26
diff -u -p -r1.26 elf32-m68hc1x.c
--- bfd/elf32-m68hc1x.c	28 Sep 2006 13:27:33 -0000	1.26
+++ bfd/elf32-m68hc1x.c	7 Mar 2007 06:09:36 -0000
@@ -1,5 +1,5 @@
 /* Motorola 68HC11/HC12-specific support for 32-bit ELF
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Stephane Carrez (stcarrez@nerim.fr)
 
@@ -873,86 +873,6 @@ elf32_m68hc11_check_relocs (bfd *abfd, s
   return TRUE;
 }
 
-static bfd_boolean
-m68hc11_get_relocation_value (bfd *input_bfd, struct bfd_link_info *info,
-			      asection *input_section,
-                              asection **local_sections,
-                              Elf_Internal_Sym *local_syms,
-                              Elf_Internal_Rela *rel,
-                              const char **name,
-                              bfd_vma *relocation, bfd_boolean *is_far)
-{
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  unsigned long r_symndx;
-  asection *sec;
-  struct elf_link_hash_entry *h;
-  Elf_Internal_Sym *sym;
-  const char* stub_name = 0;
-
-  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
-  sym_hashes = elf_sym_hashes (input_bfd);
-
-  r_symndx = ELF32_R_SYM (rel->r_info);
-
-  /* This is a final link.  */
-  h = NULL;
-  sym = NULL;
-  sec = NULL;
-  if (r_symndx < symtab_hdr->sh_info)
-    {
-      sym = local_syms + r_symndx;
-      sec = local_sections[r_symndx];
-      *relocation = (sec->output_section->vma
-                     + sec->output_offset
-                     + sym->st_value);
-      *is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
-      if (*is_far)
-        stub_name = (bfd_elf_string_from_elf_section
-                     (input_bfd, symtab_hdr->sh_link,
-                      sym->st_name));
-    }
-  else
-    {
-      bfd_boolean unresolved_reloc, warned;
-
-      RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
-			       r_symndx, symtab_hdr, sym_hashes,
-			       h, sec, *relocation, unresolved_reloc, warned);
-
-      *is_far = (h && (h->other & STO_M68HC12_FAR));
-      stub_name = h->root.root.string;
-    }
-
-  if (h != NULL)
-    *name = h->root.root.string;
-  else
-    {
-      *name = (bfd_elf_string_from_elf_section
-               (input_bfd, symtab_hdr->sh_link, sym->st_name));
-      if (*name == NULL || **name == '\0')
-        *name = bfd_section_name (input_bfd, sec);
-    }
-
-  if (*is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
-    {
-      struct elf32_m68hc11_stub_hash_entry* stub;
-      struct m68hc11_elf_link_hash_table *htab;
-
-      htab = m68hc11_elf_hash_table (info);
-      stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
-                                       *name, FALSE, FALSE);
-      if (stub)
-        {
-          *relocation = stub->stub_offset
-            + stub->stub_sec->output_section->vma
-            + stub->stub_sec->output_offset;
-          *is_far = FALSE;
-        }
-    }
-  return TRUE;
-}
-
 /* Relocate a 68hc11/68hc12 ELF section.  */
 bfd_boolean
 elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
@@ -993,6 +913,8 @@ elf32_m68hc11_relocate_section (bfd *out
       bfd_vma insn_addr;
       bfd_vma insn_page;
       bfd_boolean is_far = FALSE;
+      struct elf_link_hash_entry *h;
+      const char* stub_name = 0;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -1001,30 +923,86 @@ elf32_m68hc11_relocate_section (bfd *out
           || r_type == R_M68HC11_GNU_VTINHERIT )
         continue;
 
+      (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
+      howto = arel.howto;
+
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  sym = local_syms + r_symndx;
+	  sec = local_sections[r_symndx];
+	  relocation = (sec->output_section->vma
+			+ sec->output_offset
+			+ sym->st_value);
+	  is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
+	  if (is_far)
+	    stub_name = (bfd_elf_string_from_elf_section
+			 (input_bfd, symtab_hdr->sh_link,
+			  sym->st_name));
+	}
+      else
+	{
+	  bfd_boolean unresolved_reloc, warned;
+
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation, unresolved_reloc,
+				   warned);
+
+	  is_far = (h && (h->other & STO_M68HC12_FAR));
+	  stub_name = h->root.root.string;
+	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
       if (info->relocatable)
 	{
 	  /* This is a relocatable link.  We don't have to change
 	     anything, unless the reloc is against a section symbol,
 	     in which case we have to adjust according to where the
 	     section symbol winds up in the output section.  */
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      sym = local_syms + r_symndx;
-	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-		{
-		  sec = local_sections[r_symndx];
-		  rel->r_addend += sec->output_offset + sym->st_value;
-		}
-	    }
-
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    rel->r_addend += sec->output_offset;
 	  continue;
 	}
-      (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
-      howto = arel.howto;
 
-      m68hc11_get_relocation_value (input_bfd, info, input_section, 
-				    local_sections, local_syms,
-                                    rel, &name, &relocation, &is_far);
+      if (h != NULL)
+	name = h->root.root.string;
+      else
+	{
+	  name = (bfd_elf_string_from_elf_section
+		  (input_bfd, symtab_hdr->sh_link, sym->st_name));
+	  if (name == NULL || *name == '\0')
+	    name = bfd_section_name (input_bfd, sec);
+	}
+
+      if (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
+	{
+	  struct elf32_m68hc11_stub_hash_entry* stub;
+	  struct m68hc11_elf_link_hash_table *htab;
+
+	  htab = m68hc11_elf_hash_table (info);
+	  stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
+					   name, FALSE, FALSE);
+	  if (stub)
+	    {
+	      relocation = stub->stub_offset
+		+ stub->stub_sec->output_section->vma
+		+ stub->stub_sec->output_offset;
+	      is_far = FALSE;
+	    }
+	}
 
       /* Do the memory bank mapping.  */
       phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
Index: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.97
diff -u -p -r1.97 elf32-m68k.c
--- bfd/elf32-m68k.c	8 Jan 2007 18:42:36 -0000	1.97
+++ bfd/elf32-m68k.c	7 Mar 2007 06:09:37 -0000
@@ -1,6 +1,6 @@
 /* Motorola 68k series support for 32-bit ELF
    Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1565,9 +1565,6 @@ elf_m68k_relocate_section (output_bfd, i
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -1622,6 +1619,20 @@ elf_m68k_relocate_section (output_bfd, i
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_68K_GOT8:
Index: bfd/elf32-mcore.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-mcore.c,v
retrieving revision 1.46
diff -u -p -r1.46 elf32-mcore.c
--- bfd/elf32-mcore.c	28 Sep 2006 13:27:32 -0000	1.46
+++ bfd/elf32-mcore.c	7 Mar 2007 06:09:38 -0000
@@ -1,6 +1,6 @@
 /* Motorola MCore specific support for 32-bit ELF
-   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -387,9 +387,6 @@ mcore_elf_relocate_section (bfd * output
      (info->relocatable) ? " (relocatable)" : "");
 #endif
 
-  if (info->relocatable)
-    return TRUE;
-
   if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])	/* Initialize howto table if needed */
     mcore_elf_howto_init ();
 
@@ -452,6 +449,20 @@ mcore_elf_relocate_section (bfd * output
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	default:
Index: bfd/elf32-mep.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-mep.c,v
retrieving revision 1.1
diff -u -p -r1.1 elf32-mep.c
--- bfd/elf32-mep.c	5 Feb 2007 19:50:12 -0000	1.1
+++ bfd/elf32-mep.c	7 Mar 2007 06:09:38 -0000
@@ -1,5 +1,5 @@
 /* MeP-specific support for 32-bit ELF.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -499,28 +499,8 @@ mep_elf_relocate_section
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      if (info->relocatable)
-	{
-	  /* This is a relocatable link.  We don't have to change
-             anything, unless the reloc is against a section symbol,
-             in which case we have to adjust according to where the
-             section symbol winds up in the output section.  */
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      sym = local_syms + r_symndx;
-
-	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-		{
-		  sec = local_sections [r_symndx];
-		  rel->r_addend += sec->output_offset + sym->st_value;
-		}
-	    }
-
-	  continue;
-	}
-
       /* Is this a complex relocation?  */
-      if (ELF32_R_TYPE (rel->r_info) == R_RELC)
+      if (!info->relocatable && ELF32_R_TYPE (rel->r_info) == R_RELC)
 	{
 	  bfd_elf_perform_complex_relocation (output_bfd, info,
 					      input_bfd, input_section, contents,
@@ -528,7 +508,6 @@ mep_elf_relocate_section
 	  continue;
 	}
 
-      /* This is a final link.  */
       howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
       sym    = NULL;
@@ -552,6 +531,7 @@ mep_elf_relocate_section
 	}
       else
 	{
+	  relocation = 0;
 	  h = sym_hashes [r_symndx];
 
 	  while (h->root.type == bfd_link_hash_indirect
@@ -580,9 +560,8 @@ mep_elf_relocate_section
 	      fprintf (stderr, "undefined: sec: %s, name: %s\n",
 		       sec->name, name);
 #endif
-	      relocation = 0;
 	    }
-	  else
+	  else if (!info->relocatable)
 	    {
 	      if (! ((*info->callbacks->undefined_symbol)
 		     (info, h->root.root.string, input_bfd,
@@ -592,10 +571,31 @@ mep_elf_relocate_section
 #if 0
 	      fprintf (stderr, "unknown: name: %s\n", name);
 #endif
-	      relocation = 0;
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	{
+	  /* This is a relocatable link.  We don't have to change
+             anything, unless the reloc is against a section symbol,
+             in which case we have to adjust according to where the
+             section symbol winds up in the output section.  */
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    rel->r_addend += sec->output_offset;
+	  continue;
+	}
+
       switch (r_type)
 	{
 	default:
Index: bfd/elf32-msp430.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-msp430.c,v
retrieving revision 1.14
diff -u -p -r1.14 elf32-msp430.c
--- bfd/elf32-msp430.c	28 Sep 2006 13:27:33 -0000	1.14
+++ bfd/elf32-msp430.c	7 Mar 2007 06:09:39 -0000
@@ -1,5 +1,5 @@
 /*  MSP430-specific support for 32-bit ELF
-    Copyright (C) 2002, 2003, 2004, 2005, 2006
+    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
     Free Software Foundation, Inc.
     Contributed by Dmitry Diky <diwil@mail.ru>
 
@@ -413,8 +413,6 @@ elf32_msp430_relocate_section (bfd * out
       const char *name = NULL;
       int r_type;
 
-      /* This is a final link.  */
-
       r_type = ELF32_R_TYPE (rel->r_info);
       r_symndx = ELF32_R_SYM (rel->r_info);
       howto = elf_msp430_howto_table + ELF32_R_TYPE (rel->r_info);
@@ -442,6 +440,20 @@ elf32_msp430_relocate_section (bfd * out
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = msp430_final_link_relocate (howto, input_bfd, input_section,
 				      contents, rel, relocation);
 
Index: bfd/elf32-mt.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-mt.c,v
retrieving revision 1.5
diff -u -p -r1.5 elf32-mt.c
--- bfd/elf32-mt.c	28 Sep 2006 13:27:33 -0000	1.5
+++ bfd/elf32-mt.c	7 Mar 2007 06:09:39 -0000
@@ -1,5 +1,5 @@
 /* Morpho Technologies MT specific support for 32-bit ELF
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -309,7 +309,6 @@ mt_elf_relocate_section
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      /* This is a final link.  */
       howto  = mt_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
       sym    = NULL;
@@ -338,6 +337,19 @@ mt_elf_relocate_section
 	  name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
 
       /* Finally, the sole MT-specific part.  */
       switch (r_type)
Index: bfd/elf32-openrisc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-openrisc.c,v
retrieving revision 1.24
diff -u -p -r1.24 elf32-openrisc.c
--- bfd/elf32-openrisc.c	28 Sep 2006 13:27:33 -0000	1.24
+++ bfd/elf32-openrisc.c	7 Mar 2007 06:09:40 -0000
@@ -1,5 +1,5 @@
 /* OpenRISC-specific support for 32-bit ELF.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Johan Rydberg, jrydberg@opencores.org
 
@@ -304,9 +304,6 @@ openrisc_elf_relocate_section (bfd *outp
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend = relocs + input_section->reloc_count;
@@ -334,7 +331,6 @@ openrisc_elf_relocate_section (bfd *outp
 	  (sizeof openrisc_elf_howto_table / sizeof (reloc_howto_type)))
 	abort ();
 
-      /* This is a final link.  */
       howto = openrisc_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h = NULL;
       sym = NULL;
@@ -360,6 +356,20 @@ openrisc_elf_relocate_section (bfd *outp
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = openrisc_final_link_relocate (howto, input_bfd, input_section,
 					contents, rel, relocation);
 
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.209
diff -u -p -r1.209 elf32-ppc.c
--- bfd/elf32-ppc.c	1 Feb 2007 05:35:58 -0000	1.209
+++ bfd/elf32-ppc.c	7 Mar 2007 06:09:43 -0000
@@ -1,6 +1,6 @@
 /* PowerPC-specific support for 32-bit ELF
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -5564,29 +5564,6 @@ ppc_elf_relocate_section (bfd *output_bf
 
   got2 = bfd_get_section_by_name (input_bfd, ".got2");
 
-  if (info->relocatable)
-    {
-      if (got2 == NULL)
-	return TRUE;
-
-      rel = relocs;
-      relend = relocs + input_section->reloc_count;
-      for (; rel < relend; rel++)
-	{
-	  enum elf_ppc_reloc_type r_type;
-
-	  r_type = ELF32_R_TYPE (rel->r_info);
-	  if (r_type == R_PPC_PLTREL24
-	      && rel->r_addend >= 32768)
-	    {
-	      /* R_PPC_PLTREL24 is rather special.  If non-zero, the
-		 addend specifies the GOT pointer offset within .got2.  */
-	      rel->r_addend += got2->output_offset;
-	    }
-	}
-      return TRUE;
-    }
-
   /* Initialize howto table if not already done.  */
   if (!ppc_elf_howto_table[R_PPC_ADDR32])
     ppc_elf_howto_init ();
@@ -5640,6 +5617,33 @@ ppc_elf_relocate_section (bfd *output_bf
 	  sym_name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  howto = NULL;
+	  if (r_type < R_PPC_max)
+	    howto = ppc_elf_howto_table[r_type];
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	{
+	  if (got2 != NULL
+	      && r_type == R_PPC_PLTREL24
+	      && rel->r_addend >= 32768)
+	    {
+	      /* R_PPC_PLTREL24 is rather special.  If non-zero, the
+		 addend specifies the GOT pointer offset within .got2.  */
+	      rel->r_addend += got2->output_offset;
+	    }
+	  continue;
+	}
+
       /* TLS optimizations.  Replace instruction sequences and relocs
 	 based on information we collected in tls_optimize.  We edit
 	 RELOCS so that --emit-relocs will output something sensible
@@ -6225,17 +6229,7 @@ ppc_elf_relocate_section (bfd *output_bf
 	case R_PPC_ADDR14_BRNTAKEN:
 	case R_PPC_UADDR32:
 	case R_PPC_UADDR16:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
 	dodyn:
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	      break;
-	    }
-	  /* Fall thru.  */
-
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 	  /* Fall thru.  */
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.89
diff -u -p -r1.89 elf32-s390.c
--- bfd/elf32-s390.c	3 Nov 2006 00:58:09 -0000	1.89
+++ bfd/elf32-s390.c	7 Mar 2007 06:09:44 -0000
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for 32-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Carl B. Pedersen and Martin Schwidefsky.
 
@@ -2266,9 +2266,6 @@ elf_s390_relocate_section (output_bfd, i
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   htab = elf_s390_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -2303,7 +2300,6 @@ elf_s390_relocate_section (output_bfd, i
       howto = elf_howto_table + r_type;
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -2324,6 +2320,20 @@ elf_s390_relocate_section (output_bfd, i
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_390_GOTPLT12:
@@ -2540,15 +2550,6 @@ elf_s390_relocate_section (output_bfd, i
 	case R_390_PC16DBL:
 	case R_390_PC32DBL:
 	case R_390_PC32:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	      break;
-	    }
-
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
Index: bfd/elf32-score.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-score.c,v
retrieving revision 1.7
diff -u -p -r1.7 elf32-score.c
--- bfd/elf32-score.c	29 Jan 2007 16:29:21 -0000	1.7
+++ bfd/elf32-score.c	7 Mar 2007 06:09:46 -0000
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for S+core.
-   Copyright 2006 Free Software Foundation, Inc.
+   Copyright 2006, 2007 Free Software Foundation, Inc.
    Contributed by
    Mei Ligang (ligang@sunnorth.com.cn)
    Pei-Lin Tsai (pltsai@sunplus.com)
@@ -2006,11 +2006,6 @@ score_elf_final_link_relocate (reloc_how
 						    input_section))
 	    return bfd_reloc_undefined;
 	}
-      else if (r_symndx == 0)
-        /* r_symndx will be zero only for relocs against symbols
-           from removed linkonce sections, or sections discarded by
-           a linker script.  */
-        value = 0;
       else
 	{
 	  if (r_type != R_SCORE_REL32)
@@ -2213,11 +2208,6 @@ _bfd_score_elf_relocate_section (bfd *ou
   size_t extsymoff;
   bfd_boolean gp_disp_p = FALSE;
 
-#ifndef USE_REL
-  if (info->relocatable)
-    return TRUE;
-#endif
-
   /* Sort dynsym.  */
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -2261,26 +2251,6 @@ _bfd_score_elf_relocate_section (bfd *ou
       _bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
       howto = bfd_reloc.howto;
 
-      if (info->relocatable)
-        {
-          /* This is a relocatable link.  We don't have to change
-             anything, unless the reloc is against a section symbol,
-             in which case we have to adjust according to where the
-             section symbol winds up in the output section.  */
-          if (r_symndx < symtab_hdr->sh_info)
-            {
-              sym = local_syms + r_symndx;
-              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-                {
-                  sec = local_sections[r_symndx];
-                  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
-                                    howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
-                }
-            }
-          continue;
-        }
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -2294,7 +2264,8 @@ _bfd_score_elf_relocate_section (bfd *ou
 			+ sym->st_value);
           name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
 
-          if ((sec->flags & SEC_MERGE)
+          if (!info->relocatable
+	      && (sec->flags & SEC_MERGE) != 0
 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
             {
               asection *msec;
@@ -2416,7 +2387,7 @@ _bfd_score_elf_relocate_section (bfd *ou
 	      BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
 	      relocation = 0;
 	    }
-	  else
+	  else if (!info->relocatable)
 	    {
 	      if (! ((*info->callbacks->undefined_symbol)
 		     (info, h->root.root.root.string, input_bfd,
@@ -2428,6 +2399,29 @@ _bfd_score_elf_relocate_section (bfd *ou
 	    }
         }
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+        {
+          /* This is a relocatable link.  We don't have to change
+             anything, unless the reloc is against a section symbol,
+             in which case we have to adjust according to where the
+             section symbol winds up in the output section.  */
+          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
+				  howto, (bfd_signed_vma) sec->output_offset);
+          continue;
+        }
+
       r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                          input_section, contents, rel, relocs,
                                          relocation, info, name,
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.145
diff -u -p -r1.145 elf32-sh.c
--- bfd/elf32-sh.c	3 Nov 2006 00:58:09 -0000	1.145
+++ bfd/elf32-sh.c	7 Mar 2007 06:09:50 -0000
@@ -1,6 +1,6 @@
 /* Renesas / SuperH SH specific support for 32-bit ELF
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006 Free Software Foundation, Inc.
+   2006, 2007 Free Software Foundation, Inc.
    Contributed by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -3240,13 +3240,16 @@ sh_elf_relocate_section (bfd *output_bfd
 	     (info,
 	      _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
 	      input_bfd, input_section, rel->r_offset));
-	  if (info->relocatable)
+
+	  if (sec != NULL && elf_discarded_section (sec))
+	    /* Handled below.  */
+	    ;
+	  else if (info->relocatable)
 	    {
 	      /* This is a relocatable link.  We don't have to change
 		 anything, unless the reloc is against a section symbol,
 		 in which case we have to adjust according to where the
 		 section symbol winds up in the output section.  */
-	      sym = local_syms + r_symndx;
 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
 		{
 		  if (! howto->partial_inplace)
@@ -3255,7 +3258,7 @@ sh_elf_relocate_section (bfd *output_bfd
 			 relocation, we need just to update the addend.
 			 All real relocs are of type partial_inplace; this
 			 code is mostly for completeness.  */
-		      rel->r_addend += sec->output_offset + sym->st_value;
+		      rel->r_addend += sec->output_offset;
 
 		      continue;
 		    }
@@ -3310,12 +3313,7 @@ sh_elf_relocate_section (bfd *output_bfd
 	{
 	  /* FIXME: Ought to make use of the RELOC_FOR_GLOBAL_SYMBOL macro.  */
 
-	  /* Section symbol are never (?) placed in the hash table, so
-	     we can just ignore hash relocations when creating a
-	     relocatable object file.  */
-	  if (info->relocatable)
-	    continue;
-
+	  relocation = 0;
 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	  while (h->root.type == bfd_link_hash_indirect
 		 || h->root.type == bfd_link_hash_warning)
@@ -3386,8 +3384,17 @@ sh_elf_relocate_section (bfd *output_bfd
 		  || (sec->output_section == NULL
 		      && (sh_elf_hash_entry (h)->tls_type == GOT_TLS_IE
 			  || sh_elf_hash_entry (h)->tls_type == GOT_TLS_GD)))
-		relocation = 0;
-	      else if (sec->output_section == NULL)
+		;
+	      else if (sec->output_section != NULL)
+		relocation = ((h->root.u.def.value
+			      + sec->output_section->vma
+			      + sec->output_offset)
+			      /* A STO_SH5_ISA32 causes a "bitor 1" to the
+				 symbol value, unless we've seen
+				 STT_DATALABEL on the way to it.  */
+			      | ((h->other & STO_SH5_ISA32) != 0
+				 && ! seen_stt_datalabel));
+	      else if (!info->relocatable)
 		{
 		  (*_bfd_error_handler)
 		    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
@@ -3398,22 +3405,13 @@ sh_elf_relocate_section (bfd *output_bfd
 		     h->root.root.string);
 		  return FALSE;
 		}
-	      else
-		relocation = ((h->root.u.def.value
-			      + sec->output_section->vma
-			      + sec->output_offset)
-			      /* A STO_SH5_ISA32 causes a "bitor 1" to the
-				 symbol value, unless we've seen
-				 STT_DATALABEL on the way to it.  */
-			      | ((h->other & STO_SH5_ISA32) != 0
-				 && ! seen_stt_datalabel));
 	    }
 	  else if (h->root.type == bfd_link_hash_undefweak)
-	    relocation = 0;
+	    ;
 	  else if (info->unresolved_syms_in_objects == RM_IGNORE
 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-	    relocation = 0;
-	  else
+	    ;
+	  else if (!info->relocatable)
 	    {
 	      if (! info->callbacks->undefined_symbol
 		  (info, h->root.root.string, input_bfd,
@@ -3421,10 +3419,23 @@ sh_elf_relocate_section (bfd *output_bfd
 		   (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
 		    || ELF_ST_VISIBILITY (h->other))))
 		return FALSE;
-	      relocation = 0;
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch ((int) r_type)
 	{
 	final_link_relocate:
@@ -3557,15 +3568,6 @@ sh_elf_relocate_section (bfd *output_bfd
 	case R_SH_IMM_MEDHI16_PCREL:
 	case R_SH_IMM_HI16_PCREL:
 #endif
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	      continue;
-	    }
-
 	  if (info->shared
 	      && (h == NULL
 		  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.4
diff -u -p -r1.4 elf32-spu.c
--- bfd/elf32-spu.c	27 Feb 2007 08:29:52 -0000	1.4
+++ bfd/elf32-spu.c	7 Mar 2007 06:09:51 -0000
@@ -1351,9 +1351,6 @@ spu_elf_relocate_section (bfd *output_bf
   struct spu_link_hash_table *htab;
   bfd_boolean ret = TRUE;
 
-  if (info->relocatable)
-    return TRUE;
-
   htab = spu_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = (struct elf_link_hash_entry **) (elf_sym_hashes (input_bfd));
@@ -1400,6 +1397,20 @@ spu_elf_relocate_section (bfd *output_bf
 	  sym_name = h->root.root.string;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       if (unresolved_reloc)
 	{
 	  (*_bfd_error_handler)
Index: bfd/elf32-v850.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-v850.c,v
retrieving revision 1.64
diff -u -p -r1.64 elf32-v850.c
--- bfd/elf32-v850.c	28 Sep 2006 13:27:33 -0000	1.64
+++ bfd/elf32-v850.c	7 Mar 2007 06:09:52 -0000
@@ -1,6 +1,6 @@
 /* V850-specific support for 32-bit ELF
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006 Free Software Foundation, Inc.
+   2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1567,9 +1567,6 @@ v850_elf_relocate_section (bfd *output_b
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -1598,7 +1595,6 @@ v850_elf_relocate_section (bfd *output_b
           || r_type == R_V850_GNU_VTINHERIT)
         continue;
 
-      /* This is a final link.  */
       howto = v850_elf_howto_table + r_type;
       h = NULL;
       sym = NULL;
@@ -1631,6 +1627,20 @@ v850_elf_relocate_section (bfd *output_b
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       /* FIXME: We should use the addend, but the COFF relocations don't.  */
       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
 					input_section,
Index: bfd/elf32-vax.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-vax.c,v
retrieving revision 1.39
diff -u -p -r1.39 elf32-vax.c
--- bfd/elf32-vax.c	17 Oct 2006 13:41:47 -0000	1.39
+++ bfd/elf32-vax.c	7 Mar 2007 06:09:53 -0000
@@ -1377,9 +1377,6 @@ elf_vax_relocate_section (bfd *output_bf
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -1411,7 +1408,6 @@ elf_vax_relocate_section (bfd *output_bf
 	}
       howto = howto_table + r_type;
 
-      /* This is a final link.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       h = NULL;
       sym = NULL;
@@ -1467,6 +1463,20 @@ elf_vax_relocate_section (bfd *output_bf
 	    relocation = 0;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_VAX_GOT32:
Index: bfd/elf32-xc16x.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xc16x.c,v
retrieving revision 1.1
diff -u -p -r1.1 elf32-xc16x.c
--- bfd/elf32-xc16x.c	17 Feb 2006 14:36:21 -0000	1.1
+++ bfd/elf32-xc16x.c	7 Mar 2007 06:09:53 -0000
@@ -1,5 +1,5 @@
 /* Infineon XC16X-specific support for 16-bit ELF.
-   Copyright 2006  Free Software Foundation, Inc.
+   Copyright 2006, 2007  Free Software Foundation, Inc.
    Contributed by KPIT Cummins Infosystems 
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -328,9 +328,6 @@ elf32_xc16x_relocate_section (bfd *outpu
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -368,11 +365,27 @@ elf32_xc16x_relocate_section (bfd *outpu
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  reloc_howto_type *howto;
+	  howto = xc16x_reloc_type_lookup (input_bfd, r_type);
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       r = elf32_xc16x_final_link_relocate (r_type, input_bfd, output_bfd,
-					input_section,
-					contents, rel->r_offset,
-					relocation, rel->r_addend,
-					info, sec, h == NULL);
+					   input_section,
+					   contents, rel->r_offset,
+					   relocation, rel->r_addend,
+					   info, sec, h == NULL);
     }
 
   return TRUE;
Index: bfd/elf32-xstormy16.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xstormy16.c,v
retrieving revision 1.36
diff -u -p -r1.36 elf32-xstormy16.c
--- bfd/elf32-xstormy16.c	17 Oct 2006 13:41:47 -0000	1.36
+++ bfd/elf32-xstormy16.c	7 Mar 2007 06:09:53 -0000
@@ -1,5 +1,5 @@
 /* Xstormy16-specific support for 32-bit ELF.
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -755,9 +755,6 @@ xstormy16_elf_relocate_section (bfd *   
   bfd *dynobj;
   asection *splt;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -807,6 +804,20 @@ xstormy16_elf_relocate_section (bfd *   
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       if (h != NULL)
 	name = h->root.root.string;
       else
Index: bfd/elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.81
diff -u -p -r1.81 elf32-xtensa.c
--- bfd/elf32-xtensa.c	1 Mar 2007 23:38:03 -0000	1.81
+++ bfd/elf32-xtensa.c	7 Mar 2007 06:09:58 -0000
@@ -1986,6 +1986,53 @@ elf_xtensa_relocate_section (bfd *output
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+      is_weak_undef = FALSE;
+      unresolved_reloc = FALSE;
+      warned = FALSE;
+
+      if (howto->partial_inplace && !info->relocatable)
+	{
+	  /* Because R_XTENSA_32 was made partial_inplace to fix some
+	     problems with DWARF info in partial links, there may be
+	     an addend stored in the contents.  Take it out of there
+	     and move it back into the addend field of the reloc.  */
+	  rel->r_addend += bfd_get_32 (input_bfd, contents + rel->r_offset);
+	  bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
+	}
+
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  sym = local_syms + r_symndx;
+	  sec = local_sections[r_symndx];
+	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+	}
+      else
+	{
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation,
+				   unresolved_reloc, warned);
+
+	  if (relocation == 0
+	      && !unresolved_reloc
+	      && h->root.type == bfd_link_hash_undefweak)
+	    is_weak_undef = TRUE;
+	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
       if (info->relocatable)
 	{
 	  /* This is a relocatable link.
@@ -2067,42 +2114,6 @@ elf_xtensa_relocate_section (bfd *output
 
       /* This is a final link.  */
 
-      h = NULL;
-      sym = NULL;
-      sec = NULL;
-      is_weak_undef = FALSE;
-      unresolved_reloc = FALSE;
-      warned = FALSE;
-
-      if (howto->partial_inplace)
-	{
-	  /* Because R_XTENSA_32 was made partial_inplace to fix some
-	     problems with DWARF info in partial links, there may be
-	     an addend stored in the contents.  Take it out of there
-	     and move it back into the addend field of the reloc.  */
-	  rel->r_addend += bfd_get_32 (input_bfd, contents + rel->r_offset);
-	  bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
-	}
-
-      if (r_symndx < symtab_hdr->sh_info)
-	{
-	  sym = local_syms + r_symndx;
-	  sec = local_sections[r_symndx];
-	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
-	}
-      else
-	{
-	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
-				   r_symndx, symtab_hdr, sym_hashes,
-				   h, sec, relocation,
-				   unresolved_reloc, warned);
-
-	  if (relocation == 0
-	      && !unresolved_reloc
-	      && h->root.type == bfd_link_hash_undefweak)
-	    is_weak_undef = TRUE;
-	}
-
       if (relaxing_section)
 	{
 	  /* Check if this references a section in another input file.  */
@@ -2241,16 +2252,6 @@ elf_xtensa_relocate_section (bfd *output
 	  return FALSE;
 	}
 
-      if (r_symndx == 0)
-	{
-	  /* r_symndx will be zero only for relocs against symbols from
-	     removed linkonce sections, or sections discarded by a linker
-	     script.  For these relocs, we just want the section contents
-	     zeroed.  Avoid any special processing.  */
-	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	  continue;
-	}
-
       /* There's no point in calling bfd_perform_relocation here.
 	 Just go directly to our "special function".  */
       r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.155
diff -u -p -r1.155 elf64-alpha.c
--- bfd/elf64-alpha.c	6 Dec 2006 07:25:29 -0000	1.155
+++ bfd/elf64-alpha.c	7 Mar 2007 06:10:01 -0000
@@ -1,6 +1,6 @@
 /* Alpha specific support for 64-bit ELF
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006 Free Software Foundation, Inc.
+   2006, 2007 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@tamu.edu>.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -3912,9 +3912,11 @@ elf64_alpha_relocate_section_r (bfd *out
   unsigned long symtab_hdr_sh_info;
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
+  struct elf_link_hash_entry **sym_hashes;
   bfd_boolean ret_val = TRUE;
 
   symtab_hdr_sh_info = elf_tdata (input_bfd)->symtab_hdr.sh_info;
+  sym_hashes = elf_sym_hashes (input_bfd);
 
   relend = relocs + input_section->reloc_count;
   for (rel = relocs; rel < relend; rel++)
@@ -3924,7 +3926,7 @@ elf64_alpha_relocate_section_r (bfd *out
       asection *sec;
       unsigned long r_type;
 
-      r_type = ELF64_R_TYPE(rel->r_info);
+      r_type = ELF64_R_TYPE (rel->r_info);
       if (r_type >= R_ALPHA_max)
 	{
 	  (*_bfd_error_handler)
@@ -3935,22 +3937,49 @@ elf64_alpha_relocate_section_r (bfd *out
 	  continue;
 	}
 
-      r_symndx = ELF64_R_SYM(rel->r_info);
-
       /* The symbol associated with GPDISP and LITUSE is
 	 immaterial.  Only the addend is significant.  */
       if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
 	continue;
 
+      r_symndx = ELF64_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr_sh_info)
 	{
 	  sym = local_syms + r_symndx;
-	  if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
-	    {
-	      sec = local_sections[r_symndx];
-	      rel->r_addend += sec->output_offset + sym->st_value;
-	    }
+	  sec = local_sections[r_symndx];
+	}
+      else
+	{
+	  struct elf_link_hash_entry *h;
+
+	  h = sym_hashes[r_symndx - symtab_hdr_sh_info];
+
+	  while (h->root.type == bfd_link_hash_indirect
+		 || h->root.type == bfd_link_hash_warning)
+	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+	  if (h->root.type != bfd_link_hash_defined
+	      && h->root.type != bfd_link_hash_defweak)
+	    continue;
+
+	  sym = NULL;
+	  sec = h->root.u.def.section;
 	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  */
+	  _bfd_clear_contents (elf64_alpha_howto_table + r_type,
+			       input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	rel->r_addend += sec->output_offset;
     }
 
   return ret_val;
@@ -4150,6 +4179,17 @@ elf64_alpha_relocate_section (bfd *outpu
 	  gotent = h->got_entries;
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
       addend = rel->r_addend;
       value += addend;
 
@@ -4209,18 +4249,6 @@ elf64_alpha_relocate_section (bfd *outpu
 	  goto default_reloc;
 
 	case R_ALPHA_GPREL32:
-	  /* If the target section was a removed linkonce section,
-	     r_symndx will be zero.  In this case, assume that the
-	     switch will not be used, so don't fill it in.  If we
-	     do nothing here, we'll get relocation truncated messages,
-	     due to the placement of the application above 4GB.  */
-	  if (r_symndx == 0)
-	    {
-	      r = bfd_reloc_ok;
-	      break;
-	    }
-	  /* FALLTHRU */
-
 	case R_ALPHA_GPREL16:
 	case R_ALPHA_GPRELLOW:
 	  if (dynamic_symbol_p)
Index: bfd/elf64-mmix.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mmix.c,v
retrieving revision 1.51
diff -u -p -r1.51 elf64-mmix.c
--- bfd/elf64-mmix.c	17 Oct 2006 13:41:47 -0000	1.51
+++ bfd/elf64-mmix.c	7 Mar 2007 06:10:03 -0000
@@ -1,5 +1,5 @@
 /* MMIX-specific support for 64-bit ELF.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Hans-Peter Nilsson <hp@bitrange.com>
 
@@ -1365,22 +1365,53 @@ mmix_elf_relocate_section (output_bfd, i
 
       r_symndx = ELF64_R_SYM (rel->r_info);
 
+      howto = elf_mmix_howto_table + ELF64_R_TYPE (rel->r_info);
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  sym = local_syms + r_symndx;
+	  sec = local_sections [r_symndx];
+	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+	  name = bfd_elf_string_from_elf_section (input_bfd,
+						  symtab_hdr->sh_link,
+						  sym->st_name);
+	  if (name == NULL)
+	    name = bfd_section_name (input_bfd, sec);
+	}
+      else
+	{
+	  bfd_boolean unresolved_reloc;
+
+	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+				   r_symndx, symtab_hdr, sym_hashes,
+				   h, sec, relocation,
+				   unresolved_reloc, undefined_signalled);
+	  name = h->root.root.string;
+	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
       if (info->relocatable)
 	{
 	  /* This is a relocatable link.  For most relocs we don't have to
 	     change anything, unless the reloc is against a section
 	     symbol, in which case we have to adjust according to where
 	     the section symbol winds up in the output section.  */
-	  if (r_symndx < symtab_hdr->sh_info)
-	    {
-	      sym = local_syms + r_symndx;
-
-	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-		{
-		  sec = local_sections [r_symndx];
-		  rel->r_addend += sec->output_offset + sym->st_value;
-		}
-	    }
+	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    rel->r_addend += sec->output_offset;
 
 	  /* For PUSHJ stub relocs however, we may need to change the
 	     reloc and the section contents, if the reloc doesn't reach
@@ -1454,35 +1485,6 @@ mmix_elf_relocate_section (output_bfd, i
 	  continue;
 	}
 
-      /* This is a final link.  */
-      howto = elf_mmix_howto_table + ELF64_R_TYPE (rel->r_info);
-      h = NULL;
-      sym = NULL;
-      sec = NULL;
-
-      if (r_symndx < symtab_hdr->sh_info)
-	{
-	  sym = local_syms + r_symndx;
-	  sec = local_sections [r_symndx];
-	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
-
-	  name = bfd_elf_string_from_elf_section (input_bfd,
-						  symtab_hdr->sh_link,
-						  sym->st_name);
-	  if (name == NULL)
-	    name = bfd_section_name (input_bfd, sec);
-	}
-      else
-	{
-	  bfd_boolean unresolved_reloc;
-
-	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
-				   r_symndx, symtab_hdr, sym_hashes,
-				   h, sec, relocation,
-				   unresolved_reloc, undefined_signalled);
-	  name = h->root.root.string;
-	}
-
       r = mmix_final_link_relocate (howto, input_section,
 				    contents, rel->r_offset,
 				    rel->r_addend, relocation, name, sec);
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.258
diff -u -p -r1.258 elf64-ppc.c
--- bfd/elf64-ppc.c	19 Feb 2007 12:44:18 -0000	1.258
+++ bfd/elf64-ppc.c	7 Mar 2007 06:10:08 -0000
@@ -9896,13 +9896,9 @@ ppc64_elf_relocate_section (bfd *output_
 		    relocation += adjust;
 		}
 	    }
-	  if (info->relocatable)
-	    continue;
 	}
       else
 	{
-	  if (info->relocatable)
-	    continue;
 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
 				   r_symndx, symtab_hdr, sym_hashes,
 				   h_elf, sec, relocation,
@@ -9912,6 +9908,21 @@ ppc64_elf_relocate_section (bfd *output_
 	}
       h = (struct ppc_link_hash_entry *) h_elf;
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (ppc64_elf_howto_table[r_type], input_bfd,
+			       contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       /* TLS optimizations.  Replace instruction sequences and relocs
 	 based on information we collected in tls_optimize.  We edit
 	 RELOCS so that --emit-relocs will output something sensible
@@ -10731,7 +10742,7 @@ ppc64_elf_relocate_section (bfd *output_
 	    relocation += htab->stub_group[sec->id].toc_off;
 	  else
 	    unresolved_reloc = TRUE;
-	  goto dodyn2;
+	  goto dodyn;
 
 	  /* TOC16 relocs.  We want the offset relative to the TOC base,
 	     which is the address of the start of the TOC plus 0x8000.
@@ -10831,19 +10842,7 @@ ppc64_elf_relocate_section (bfd *output_
 	case R_PPC64_UADDR16:
 	case R_PPC64_UADDR32:
 	case R_PPC64_UADDR64:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
 	dodyn:
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (ppc64_elf_howto_table[r_type], input_bfd,
-				   contents + rel->r_offset);
-	      break;
-	    }
-	  /* Fall thru.  */
-
-	dodyn2:
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.89
diff -u -p -r1.89 elf64-s390.c
--- bfd/elf64-s390.c	3 Nov 2006 00:58:09 -0000	1.89
+++ bfd/elf64-s390.c	7 Mar 2007 06:10:10 -0000
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed Martin Schwidefsky (schwidefsky@de.ibm.com).
 
@@ -2238,9 +2238,6 @@ elf_s390_relocate_section (output_bfd, i
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   htab = elf_s390_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -2275,7 +2272,6 @@ elf_s390_relocate_section (output_bfd, i
       howto = elf_howto_table + r_type;
       r_symndx = ELF64_R_SYM (rel->r_info);
 
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -2296,6 +2292,20 @@ elf_s390_relocate_section (output_bfd, i
 				   unresolved_reloc, warned);
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_390_GOTPLT12:
@@ -2519,15 +2529,6 @@ elf_s390_relocate_section (output_bfd, i
 	case R_390_PC32:
 	case R_390_PC32DBL:
 	case R_390_PC64:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	      break;
-	    }
-
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
Index: bfd/elf64-sh64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sh64.c,v
retrieving revision 1.72
diff -u -p -r1.72 elf64-sh64.c
--- bfd/elf64-sh64.c	31 Jan 2007 14:28:03 -0000	1.72
+++ bfd/elf64-sh64.c	7 Mar 2007 06:10:12 -0000
@@ -1,5 +1,5 @@
 /* SuperH SH64-specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -1487,10 +1487,10 @@ sh_elf64_relocate_section (bfd *output_b
 
       howto = sh_elf64_howto_table + r_type;
 
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
+      relocation = 0;
       if (r_symndx < symtab_hdr->sh_info)
 	{
 	  sym = local_syms + r_symndx;
@@ -1509,13 +1509,15 @@ sh_elf64_relocate_section (bfd *output_b
 	      _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
 	      input_bfd, input_section, rel->r_offset));
 
-	  if (info->relocatable)
+	  if (sec != NULL && elf_discarded_section (sec))
+	    /* Handled below.  */
+	    ;
+	  else if (info->relocatable)
 	    {
 	      /* This is a relocatable link.  We don't have to change
 		 anything, unless the reloc is against a section symbol,
 		 in which case we have to adjust according to where the
 		 section symbol winds up in the output section.  */
-	      sym = local_syms + r_symndx;
 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
 		goto final_link_relocate;
 
@@ -1554,12 +1556,6 @@ sh_elf64_relocate_section (bfd *output_b
 	{
 	  /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ?  */
 
-	  /* Section symbols are never (?) placed in the hash table, so
-	     we can just ignore hash relocations when creating a
-	     relocatable object file.  */
-	  if (info->relocatable)
-	    continue;
-
 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	  while (h->root.type == bfd_link_hash_indirect
 		 || h->root.type == bfd_link_hash_warning)
@@ -1619,8 +1615,17 @@ sh_elf64_relocate_section (bfd *output_b
 		  || (sec->output_section == NULL
 		      && ((input_section->flags & SEC_DEBUGGING) != 0
 			  && h->def_dynamic)))
-		relocation = 0;
-	      else if (sec->output_section == NULL)
+		;
+	      else if (sec->output_section != NULL)
+		relocation = ((h->root.u.def.value
+			       + sec->output_section->vma
+			       + sec->output_offset)
+			      /* A STO_SH5_ISA32 causes a "bitor 1" to the
+				 symbol value, unless we've seen
+				 STT_DATALABEL on the way to it.  */
+			      | ((h->other & STO_SH5_ISA32) != 0
+				 && ! seen_stt_datalabel));
+	      else if (!info->relocatable)
 		{
 		  (*_bfd_error_handler)
 		    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
@@ -1629,24 +1634,14 @@ sh_elf64_relocate_section (bfd *output_b
 		     (long) rel->r_offset,
 		     howto->name,
 		     h->root.root.string);
-		  relocation = 0;
 		}
-	      else
-		relocation = ((h->root.u.def.value
-			       + sec->output_section->vma
-			       + sec->output_offset)
-			      /* A STO_SH5_ISA32 causes a "bitor 1" to the
-				 symbol value, unless we've seen
-				 STT_DATALABEL on the way to it.  */
-			      | ((h->other & STO_SH5_ISA32) != 0
-				 && ! seen_stt_datalabel));
 	    }
 	  else if (h->root.type == bfd_link_hash_undefweak)
-	    relocation = 0;
+	    ;
 	  else if (info->unresolved_syms_in_objects == RM_IGNORE
 		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-	    relocation = 0;
-	  else
+	    ;
+	  else if (!info->relocatable)
 	    {
 	      if (! ((*info->callbacks->undefined_symbol)
 		     (info, h->root.root.string, input_bfd,
@@ -1654,10 +1649,23 @@ sh_elf64_relocate_section (bfd *output_b
 		      (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
 		       || ELF_ST_VISIBILITY (h->other)))))
 		return FALSE;
-	      relocation = 0;
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       disp = (relocation
 	      - input_section->output_section->vma
 	      - input_section->output_offset
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.128
diff -u -p -r1.128 elf64-x86-64.c
--- bfd/elf64-x86-64.c	3 Nov 2006 00:58:09 -0000	1.128
+++ bfd/elf64-x86-64.c	7 Mar 2007 06:10:13 -0000
@@ -1,5 +1,5 @@
 /* X86-64 specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Jan Hubicka <jh@suse.cz>.
 
@@ -2062,9 +2062,6 @@ elf64_x86_64_relocate_section (bfd *outp
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   htab = elf64_x86_64_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -2120,6 +2117,21 @@ elf64_x86_64_relocate_section (bfd *outp
 				   h, sec, relocation,
 				   unresolved_reloc, warned);
 	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       /* When generating a shared object, the relocations handled here are
 	 copied into the output file to be resolved at run time.  */
       switch (r_type)
@@ -2367,15 +2379,6 @@ elf64_x86_64_relocate_section (bfd *outp
 	  /* FIXME: The ABI says the linker should make sure the value is
 	     the same when it's zeroextended to 64 bit.	 */
 
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	      break;
-	    }
-
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.252
diff -u -p -r1.252 elflink.c
--- bfd/elflink.c	22 Feb 2007 17:03:59 -0000	1.252
+++ bfd/elflink.c	7 Mar 2007 06:10:20 -0000
@@ -8394,16 +8394,6 @@ elf_link_input_bfd (struct elf_final_lin
 			      continue;
 			    }
 			}
-
-		      /* Remove the symbol reference from the reloc, but
-			 don't kill the reloc completely.  This is so that
-			 a zero value will be written into the section,
-			 which may have non-zero contents put there by the
-			 assembler.  Zero in things like an eh_frame fde
-			 pc_begin allows stack unwinders to recognize the
-			 fde as bogus.  */
-		      rel->r_info &= r_type_mask;
-		      rel->r_addend = 0;
 		    }
 		}
 	    }
@@ -8557,8 +8547,10 @@ elf_link_input_bfd (struct elf_final_lin
 
 			  /* If we have discarded a section, the output
 			     section will be the absolute section.  In
-			     case of discarded link-once and discarded
-			     SEC_MERGE sections, use the kept section.  */
+			     case of discarded SEC_MERGE sections, use
+			     the kept section.  relocate_section should
+			     have already handled discarded linkonce
+			     sections.  */
 			  if (bfd_is_abs_section (osec)
 			      && sec->kept_section != NULL
 			      && sec->kept_section->output_section != NULL)
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.193
diff -u -p -r1.193 elfxx-ia64.c
--- bfd/elfxx-ia64.c	3 Nov 2006 00:58:10 -0000	1.193
+++ bfd/elfxx-ia64.c	7 Mar 2007 06:10:23 -0000
@@ -1,5 +1,5 @@
 /* IA-64 support for 64-bit ELF
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
@@ -4557,7 +4557,6 @@ elfNN_ia64_relocate_section (output_bfd,
 
       elf_section_data(input_section->output_section)
 	->this_hdr.sh_flags |= flags;
-      return TRUE;
     }
 
   gp_val = _bfd_get_gp_value (output_bfd);
@@ -4606,7 +4605,8 @@ elfNN_ia64_relocate_section (output_bfd,
 	  sym_sec = local_sections[r_symndx];
 	  msec = sym_sec;
 	  value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
-	  if ((sym_sec->flags & SEC_MERGE)
+	  if (!info->relocatable
+	      && (sym_sec->flags & SEC_MERGE) != 0
 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
 	      && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
  	    {
@@ -4660,6 +4660,20 @@ elfNN_ia64_relocate_section (output_bfd,
 	    continue;
 	}
 
+      /* For relocs against symbols from removed linkonce sections,
+	 or sections discarded by a linker script, we just want the
+	 section contents zeroed.  Avoid any special processing.  */
+      if (sym_sec != NULL && elf_discarded_section (sym_sec))
+	{
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       hit_addr = contents + rel->r_offset;
       value += rel->r_addend;
       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
@@ -4751,12 +4765,6 @@ elfNN_ia64_relocate_section (output_bfd,
 	case R_IA64_LTV32LSB:
 	case R_IA64_LTV64MSB:
 	case R_IA64_LTV64LSB:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    value = 0;
-
 	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
 	  break;
 
@@ -4997,13 +5005,6 @@ elfNN_ia64_relocate_section (output_bfd,
 	case R_IA64_SEGREL32LSB:
 	case R_IA64_SEGREL64MSB:
 	case R_IA64_SEGREL64LSB:
-	  if (r_symndx == 0)
-	    {
-	      /* If the input section was discarded from the output, then
-		 do nothing.  */
-	      r = bfd_reloc_ok;
-	    }
-	  else
 	    {
 	      struct elf_segment_map *m;
 	      Elf_Internal_Phdr *p;
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.195
diff -u -p -r1.195 elfxx-mips.c
--- bfd/elfxx-mips.c	20 Feb 2007 12:35:19 -0000	1.195
+++ bfd/elfxx-mips.c	7 Mar 2007 06:10:29 -0000
@@ -4323,11 +4323,6 @@ mips_elf_calculate_relocation (bfd *abfd
 						   input_section))
 	    return bfd_reloc_undefined;
 	}
-      else if (r_symndx == 0)
-	/* r_symndx will be zero only for relocs against symbols
-	   from removed linkonce sections, or sections discarded by
-	   a linker script.  */
-	value = 0;
       else
 	{
 	  if (r_type != R_MIPS_REL32)
@@ -7759,8 +7754,51 @@ _bfd_mips_elf_relocate_section (bfd *out
       bfd_boolean rela_relocation_p = TRUE;
       unsigned int r_type = ELF_R_TYPE (output_bfd, rel->r_info);
       const char *msg;
+      unsigned long r_symndx;
+      asection *sec;
 
       /* Find the relocation howto for this relocation.  */
+      howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type,
+				       NEWABI_P (input_bfd)
+				       && (MIPS_RELOC_RELA_P
+					   (input_bfd, input_section,
+					    rel - relocs)));
+
+      r_symndx = ELF_R_SYM (input_bfd, rel->r_info);
+      if (mips_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE))
+	sec = local_sections[r_symndx];
+      else
+	{
+	  Elf_Internal_Shdr *symtab_hdr;
+	  unsigned long extsymoff;
+	  struct elf_link_hash_entry *h;
+
+	  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+	  extsymoff = 0;
+	  if (!elf_bad_symtab (input_bfd))
+	    extsymoff = symtab_hdr->sh_info;
+	  h = elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
+	  while (h->root.type == bfd_link_hash_indirect
+		 || h->root.type == bfd_link_hash_warning)
+	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+	  sec = NULL;
+	  if (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak)
+	    sec = h->root.u.def.section;
+	}
+
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce sections,
+	     or sections discarded by a linker script, we just want the
+	     section contents zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
       if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd))
 	{
 	  /* Some 32-bit code uses R_MIPS_64.  In particular, people use
@@ -7776,13 +7814,6 @@ _bfd_mips_elf_relocate_section (bfd *out
 	  if (bfd_big_endian (input_bfd))
 	    rel->r_offset += 4;
 	}
-      else
-	/* NewABI defaults to RELA relocations.  */
-	howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type,
-					 NEWABI_P (input_bfd)
-					 && (MIPS_RELOC_RELA_P
-					     (input_bfd, input_section,
-					      rel - relocs)));
 
       if (!use_saved_addend_p)
 	{
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.28
diff -u -p -r1.28 elfxx-sparc.c
--- bfd/elfxx-sparc.c	3 Nov 2006 00:58:10 -0000	1.28
+++ bfd/elfxx-sparc.c	7 Mar 2007 06:10:31 -0000
@@ -1,5 +1,5 @@
 /* SPARC-specific support for ELF
-   Copyright 2005, 2006 Free Software Foundation, Inc.
+   Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2471,10 +2471,14 @@ tpoff (struct bfd_link_info *info, bfd_v
 /* Relocate a SPARC ELF section.  */
 
 bfd_boolean
-_bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
-				 bfd *input_bfd, asection *input_section,
-				 bfd_byte *contents, Elf_Internal_Rela *relocs,
-				 Elf_Internal_Sym *local_syms, asection **local_sections)
+_bfd_sparc_elf_relocate_section (bfd *output_bfd,
+				 struct bfd_link_info *info,
+				 bfd *input_bfd,
+				 asection *input_section,
+				 bfd_byte *contents,
+				 Elf_Internal_Rela *relocs,
+				 Elf_Internal_Sym *local_syms,
+				 asection **local_sections)
 {
   struct _bfd_sparc_elf_link_hash_table *htab;
   Elf_Internal_Shdr *symtab_hdr;
@@ -2486,9 +2490,6 @@ _bfd_sparc_elf_relocate_section (bfd *ou
   Elf_Internal_Rela *relend;
   int num_relocs;
 
-  if (info->relocatable)
-    return TRUE;
-
   htab = _bfd_sparc_elf_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
@@ -2532,7 +2533,6 @@ _bfd_sparc_elf_relocate_section (bfd *ou
 	}
       howto = _bfd_sparc_elf_howto_table + r_type;
 
-      /* This is a final link.  */
       r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
       h = NULL;
       sym = NULL;
@@ -2564,6 +2564,21 @@ _bfd_sparc_elf_relocate_section (bfd *ou
 	    }
 	}
 
+      if (sec != NULL && elf_discarded_section (sec))
+	{
+	  /* For relocs against symbols from removed linkonce
+	     sections, or sections discarded by a linker script, we
+	     just want the section contents zeroed.  Avoid any
+	     special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  rel->r_info = 0;
+	  rel->r_addend = 0;
+	  continue;
+	}
+
+      if (info->relocatable)
+	continue;
+
       switch (r_type)
 	{
 	case R_SPARC_GOT10:
@@ -2752,15 +2767,6 @@ _bfd_sparc_elf_relocate_section (bfd *ou
 	case R_SPARC_L44:
 	case R_SPARC_UA64:
 	r_sparc_plt32:
-	  /* r_symndx will be zero only for relocs against symbols
-	     from removed linkonce sections, or sections discarded by
-	     a linker script.  */
-	  if (r_symndx == 0)
-	    {
-	      _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-	      break;
-	    }
-
 	  if ((input_section->flags & SEC_ALLOC) == 0)
 	    break;
 
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.161
diff -u -p -r1.161 reloc.c
--- bfd/reloc.c	5 Feb 2007 19:50:12 -0000	1.161
+++ bfd/reloc.c	7 Mar 2007 06:10:33 -0000
@@ -5148,13 +5148,31 @@ bfd_generic_get_relocated_section_conten
       for (parent = reloc_vector; *parent != NULL; parent++)
 	{
 	  char *error_message = NULL;
-	  bfd_reloc_status_type r =
-	    bfd_perform_relocation (input_bfd,
-				    *parent,
-				    data,
-				    input_section,
-				    relocatable ? abfd : NULL,
-				    &error_message);
+	  asymbol *symbol;
+	  bfd_reloc_status_type r;
+
+	  symbol = *(*parent)->sym_ptr_ptr;
+	  if (symbol->section && elf_discarded_section (symbol->section))
+	    {
+	      bfd_byte *p;
+	      static const reloc_howto_type none_howto
+		= HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL,
+			 "unused", FALSE, 0, 0, FALSE);
+
+	      p = data + (*parent)->address * bfd_octets_per_byte (input_bfd);
+	      _bfd_clear_contents ((*parent)->howto, input_bfd, p);
+	      (*parent)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+	      (*parent)->addend = 0;
+	      (*parent)->howto = &none_howto;
+	      r = bfd_reloc_ok;
+	    }
+	  else
+	    r = bfd_perform_relocation (input_bfd,
+					*parent,
+					data,
+					input_section,
+					relocatable ? abfd : NULL,
+					&error_message);
 
 	  if (relocatable)
 	    {
Index: ld/testsuite/ld-elf/linkonce1.d
===================================================================
RCS file: ld/testsuite/ld-elf/linkonce1.d
diff -N ld/testsuite/ld-elf/linkonce1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/linkonce1.d	7 Mar 2007 06:34:43 -0000
@@ -0,0 +1,12 @@
+#source: linkonce1a.s
+#source: linkonce1b.s
+#ld: -r
+#objdump: -r
+
+.*:     file format .*
+
+RELOCATION RECORDS FOR \[.debug_frame\]:
+OFFSET[ 	]+TYPE[ 	]+VALUE[ 	]*
+.*(NONE|unused).*\*ABS\*
+
+#pass
Index: ld/testsuite/ld-elf/linkonce1a.s
===================================================================
RCS file: ld/testsuite/ld-elf/linkonce1a.s
diff -N ld/testsuite/ld-elf/linkonce1a.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/linkonce1a.s	7 Mar 2007 06:34:43 -0000
@@ -0,0 +1,3 @@
+        .section .gnu.linkonce.d.dummy,"aw"
+bar:
+        .long    0
Index: ld/testsuite/ld-elf/linkonce1b.s
===================================================================
RCS file: ld/testsuite/ld-elf/linkonce1b.s
diff -N ld/testsuite/ld-elf/linkonce1b.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/linkonce1b.s	7 Mar 2007 06:34:43 -0000
@@ -0,0 +1,17 @@
+	.globl main
+	.globl start
+	.globl _start
+	.globl __start
+	.text
+main:
+start:
+_start:
+__start:
+	.long	0
+
+        .section .gnu.linkonce.d.dummy,"aw"
+        .long    0
+foo:
+        .long    0
+ 	.section        .debug_frame,"",%progbits
+        .long    foo
Index: ld/testsuite/ld-elf/linkonce2.d
===================================================================
RCS file: ld/testsuite/ld-elf/linkonce2.d
diff -N ld/testsuite/ld-elf/linkonce2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/linkonce2.d	7 Mar 2007 06:34:43 -0000
@@ -0,0 +1,12 @@
+#source: linkonce1a.s
+#source: linkonce1b.s
+#ld: -emit-relocs
+#objdump: -r
+
+.*:     file format .*
+
+RELOCATION RECORDS FOR \[.debug_frame\]:
+OFFSET[ 	]+TYPE[ 	]+VALUE[ 	]*
+.*(NONE|unused).*\*ABS\*
+
+#pass
Index: ld/testsuite/ld-i386/i386.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-i386/i386.exp,v
retrieving revision 1.15
diff -u -p -r1.15 i386.exp
--- ld/testsuite/ld-i386/i386.exp	3 Mar 2006 09:32:01 -0000	1.15
+++ ld/testsuite/ld-i386/i386.exp	7 Mar 2007 06:34:43 -0000
@@ -113,3 +113,4 @@ run_ld_link_tests $i386tests
 run_dump_test "abs"
 run_dump_test "pcrel8"
 run_dump_test "pcrel16"
+run_dump_test "pcrel16abs"
Index: ld/testsuite/ld-i386/pcrel16abs.d
===================================================================
RCS file: ld/testsuite/ld-i386/pcrel16abs.d
diff -N ld/testsuite/ld-i386/pcrel16abs.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/pcrel16abs.d	7 Mar 2007 06:34:43 -0000
@@ -0,0 +1,12 @@
+#name: PCREL16 absolute reloc
+#as: --32
+#ld: -melf_i386 -Ttext 0xfffffff0
+#objdump: -drj.text -m i8086
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+f+0 <_start>:
+f+0:	e9 0d e0[ 	]+jmp[ 	]+ffffe000 <SEGMENT_SIZE\+0xfffee000>
+#pass
Index: ld/testsuite/ld-i386/pcrel16abs.s
===================================================================
RCS file: ld/testsuite/ld-i386/pcrel16abs.s
diff -N ld/testsuite/ld-i386/pcrel16abs.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-i386/pcrel16abs.s	7 Mar 2007 06:34:43 -0000
@@ -0,0 +1,6 @@
+SEGMENT_SIZE = 0x10000
+RVECTOR = 0x00010
+.code16
+ .globl _start
+_start:
+ jmp SEGMENT_SIZE-(0x1f00 +0xf0 +RVECTOR)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]