This commit was manufactured by cvs2svn to create tag
'carlton_dictionary-20021011-merge'.

Sprout from drow-cplus-branch 2002-10-04 22:17:37 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'drow-cplus-'
Cherrypick from master 2002-10-11 17:50:10 UTC Martin Hunt <hunt@redhat.com> '2002-10-11  Martin M. Hunt  <hunt@redhat.com>':
    ChangeLog
    bfd/ChangeLog
    bfd/Makefile.am
    bfd/Makefile.in
    bfd/bfd-in2.h
    bfd/coff-arm.c
    bfd/cofflink.c
    bfd/config.bfd
    bfd/configure
    bfd/configure.in
    bfd/doc/ChangeLog
    bfd/doc/Makefile.am
    bfd/doc/Makefile.in
    bfd/ecoff.c
    bfd/elf32-arm.h
    bfd/elf32-i386.c
    bfd/elf32-m32r.c
    bfd/elf32-sh.c
    bfd/elf32-sh64-lin.c
    bfd/elf32-sh64.c
    bfd/elf64-alpha.c
    bfd/elf64-ppc.c
    bfd/elf64-sh64-lin.c
    bfd/elf64-sh64.c
    bfd/elflink.c
    bfd/elflink.h
    bfd/elfxx-ia64.c
    bfd/elfxx-mips.c
    bfd/libbfd.h
    bfd/linker.c
    bfd/opncls.c
    bfd/reloc.c
    bfd/simple.c
    bfd/targets.c
    bfd/version.h
    bfd/xcofflink.c
    configure.in
    gdb/ChangeLog
    gdb/Makefile.in
    gdb/c-exp.y
    gdb/config/djgpp/fnchange.lst
    gdb/config/i386/i386gnu.mt
    gdb/config/i386/i386sco5.mt
    gdb/config/i386/i386v4.mt
    gdb/config/i386/ncr3000.mt
    gdb/config/i386/nm-i386sco.h
    gdb/config/i386/tm-i386sol2.h
    gdb/config/i386/tm-i386v42mp.h
    gdb/config/i386/tm-ptx.h
    gdb/config/i386/xm-i386sco.h
    gdb/config/mips/tm-irix3.h
    gdb/config/mips/tm-irix6.h
    gdb/config/rs6000/tm-rs6000.h
    gdb/config/tm-sysv4.h
    gdb/cp-valprint.c
    gdb/defs.h
    gdb/demangle.c
    gdb/doc/ChangeLog
    gdb/doc/gdb.texinfo
    gdb/doc/gdbint.texinfo
    gdb/dwarf2read.c
    gdb/gdbarch.c
    gdb/gdbarch.h
    gdb/gdbarch.sh
    gdb/infrun.c
    gdb/jv-exp.y
    gdb/mips-tdep.c
    gdb/objc-exp.y
    gdb/p-exp.y
    gdb/stabsread.c
    gdb/utils.c
    gdb/version.in
    include/elf/ChangeLog
    include/elf/sh.h
    libiberty/ChangeLog
    libiberty/cplus-dem.c
    sim/sh/ChangeLog
    sim/sh/gencode.c
    sim/sh/interp.c
Delete:
    gdb/config/i386/tm-i386v4.h
diff --git a/ChangeLog b/ChangeLog
index f01dee3..db8247a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2002-10-07  Svein E. Seldal  <Svein.Seldal@solidas.com>
+
+	* configure.in: Add tic4x target.
+
 2002-10-03  Nathanael Nerode  <neroden@gcc.gnu.org>
 
 	* Makefile.tpl: Make SET_LIB_PATH substitution more autoconfy.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f2c7a38..c5636f2 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,123 @@
+2002-10-11  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* elf32-sh.c (sh_elf_optimized_tls_reloc, sh_elf_mkobject,
+	sh_elf_object_p, dtpoff_base): New functions.
+	(sh_elf_howto_table): Add TLS relocs.
+	(sh_reloc_map): Likewise.
+	(sh_elf_info_to_howto): Support TLS relocs.
+	(elf_sh_link_hash_entry): Add tls_type and tls_tpoff32.
+	(sh_elf_hash_entry, sh_elf_tdata, sh_elf_local_got_tls_type):
+	New macros.
+	(sh_elf_obj_tdata): New.
+	(elf_sh_link_hash_table): Add tls_ldm_got.
+	(sh_elf_link_hash_table_create): Clear refcount of tls_ldm_got.
+	(allocate_dynrelocs): Support TLS relocs.
+	(sh_elf_size_dynamic_sections): Likewise.
+	(sh_elf_relocate_section): Support TLS relocs.  Don't try to find
+	.rela.got section when found already.  Return false after printing
+	error about unresolvable relocation.
+	(sh_elf_gc_sweep_hook): Support TLS relocs.
+	(sh_elf_check_relocs): Likewise.
+	(sh_elf_finish_dynamic_symbol): Likewise.
+	(bfd_elf32_mkobject, elf_backend_object_p): Define for TLS case.
+	* reloc.c: Add SH TLS relocs.
+	* bfd-in2.h, libbfd.h: Regenerate.
+
+2002-10-11  Daniel Jacobowitz  <drow@mvista.com>
+
+	* Makefile.am: Run dep-am.
+	(BFD32_LIBS): Add simple.lo.
+	(BFD32_LIBS_CFILES): Add simple.c.
+	* Makefile.in: Regenerated.
+	* bfd-in2.h: Regenerated.
+	* simple.c: New file.
+
+2002-10-11  Alan Modra  <amodra@bigpond.net.au>
+
+	* coff-arm.c (record_arm_to_thumb_glue): Avoid type-punned pointers.
+	(record_thumb_to_arm_glue): Likewise.
+	* ecoff.c (ecoff_link_add_externals): Likewise.
+	* elf32-arm.h (record_arm_to_thumb_glue): Likewise.
+	(record_thumb_to_arm_glue): Likewise.
+	* elf32-m32r.c (m32r_elf_add_symbol_hook): Likewise.
+	* elf32-sh.c (sh_elf_create_dynamic_sections): Likewise.
+	* elf32-sh64.c (sh64_elf_add_symbol_hook): Likewise.
+	* elf64-alpha.c (elf64_alpha_create_dynamic_sections): Likewise.
+	* elf64-ppc.c (func_desc_adjust): Likewise.
+	* elf64-sh64.c (sh64_elf64_add_symbol_hook): Likewise.
+	(sh64_elf64_create_dynamic_sections): Likewise.
+	* elflink.c (_bfd_elf_create_got_section): Likewise.
+	(_bfd_elf_create_dynamic_sections): Likewise.
+	(_bfd_elf_create_linker_section): Likewise.
+	* elflink.h (elf_add_default_symbol): Likewise.
+	(elf_link_create_dynamic_sections): Likewise.
+	(NAME(bfd_elf,size_dynamic_sections)): Likewise.
+	* elfxx-ia64.c (elfNN_ia64_aix_add_symbol_hook): Likewise.
+	* elfxx-mips.c (mips_elf_create_got_section): Likewise.
+	(_bfd_mips_elf_add_symbol_hook): Likewise.
+	(_bfd_mips_elf_create_dynamic_sections): Likewise.
+	* linker.c (generic_link_add_symbol_list): Likewise.
+	* xcofflink.c (xcoff_link_add_symbols): Likewise.
+
+	* elfxx-ia64.c (oor_brl, oor_ip): Conditionally define.
+
+	* elf64-ppc.c (edit_opd): Only zero opd syms when function is
+	completely removed.  Correct local sym adjustment.
+
+2002-10-10  Stephen Clarke <stephen.clarke@superh.com>
+
+	* elf32-sh.c (elf_sh_pic_plt_entry_be, elf_sh_pic_plt_entry_le):
+	Correct mistake in calculation of address of .got.
+	* elf64-sh64.c (elf_sh64_pic_plt_entry_be,
+	elf_sh64_pic_plt_entry_le): Likewise.
+
+2002-10-09  Richard Shann <richard.shann@superh.com>
+	    Stephen Clarke <stephen.clarke@superh.com>
+
+	* Makefile.am: Add entries for elf32-sh64-lin.c and
+	elf64-sh64-lin.c. Regenerate.
+	* Makefile.in: Regenerate.
+	* config.bfd:  Change sh64eb-*-linux* and sh64-*-linux*
+	to use sh64 vectors rather than sh vectors.
+	* configure.in: Add bfd_elf32_sh64lin_vec, bfd_elf32_sh64blin_vec,
+	bfd_elf64_sh64lin_vec, bfd_elf64_sh64blin_vec.
+	* configure: Regenerate.
+	* elf32-sh64-lin.c: New file.
+	* elf64-sh64-lin.c: New file.
+	* targets.c: Add bfd_elf32_sh64lin_vec, bfd_elf32_sh64blin_vec,
+ 	bfd_elf64_sh64lin_vec, bfd_elf64_sh64blin_vec.
+	
+2002-10-08  H.J. Lu <hjl@gnu.org>
+
+	* elf32-i386.c (elf_i386_relocate_section): Re-arrange the
+	IE->LE transition for R_386_TLS_IE.
+
+2002-10-08  Alan Modra  <amodra@bigpond.net.au>
+
+	* elf64-ppc.c (edit_opd): Correct test for discarded sections.
+
+2002-10-07  Mark Elbrecht  <snowball3@softhome.net>
+
+	* cofflink.c (mark_relocs): Don't mark relocations in excluded
+	sections.
+
+2002-10-07  Alan Modra  <amodra@bigpond.net.au>
+
+	* elflink.h (elf_link_input_bfd): Remove BFD_VERSION_DATE dependent
+	code.
+
+	* elf64-ppc.c (ppc64_elf_build_stubs): Increment .glink indx.
+
+2002-10-06  Alan Modra  <amodra@bigpond.net.au>
+
+	* opncls.c: Formatting.
+	(_bfd_new_bfd): Use a smaller section hash table.
+
+2002-10-05  Alexandre Oliva  <aoliva@redhat.com>
+
+	* elfxx-mips.c (mips_elf_create_dynamic_relocation): Set the type
+	of the other two relocations packed with a REL32 to NONE.
+
 2002-10-02  Stephen Clarke <stephen.clarke@superh.com>
 
 	* elf32-sh.c (elf_sh_link_hash_entry): Add gotplt_refcount.
@@ -9,7 +129,7 @@
 	to correctly adjust got.refcount and plt.refcount.
 	(sh_elf_copy_indirect_symbol): Copy gotplt_refcount across.
 	(sh_elf_check_relocs): Increment gotplt_refcount.
-	
+
 2002-10-01  Jakub Jelinek  <jakub@redhat.com>
 
 	* elf32-i386.c (elf_i386_relocate_section): Fix
@@ -28,10 +148,10 @@
 	R_X86_64_DTPOFF32 to st_value + addend in non-code sections.
 
 2002-09-30  Gavin Romig-Koch  <gavin@redhat.com>
-            Ken Raeburn  <raeburn@cygnus.com>
-            Aldy Hernandez  <aldyh@redhat.com>
-            Eric Christopher  <echristo@redhat.com>
-            Richard Sandiford  <rsandifo@redhat.com>
+	    Ken Raeburn  <raeburn@cygnus.com>
+	    Aldy Hernandez  <aldyh@redhat.com>
+	    Eric Christopher  <echristo@redhat.com>
+	    Richard Sandiford  <rsandifo@redhat.com>
 
 	* archures.c (bfd_mach_mips4120, bfd_mach_mips5400): New.
 	(bfd_mach_mips5500): New.
@@ -233,7 +353,7 @@
 	* elfcode.h (elf_slurp_reloc_table_from_section): Check
 	for overflow.
 
-2002-09-17  Stan Cox <scox@redhat.com>	
+2002-09-17  Stan Cox <scox@redhat.com>
 
 	* elf64-mips.c (mips_elf64_be_swap_reloca_out): Handle type2 and type3.
 	(mips_elf64_final_gp): Don't make up gp value.
@@ -315,7 +435,7 @@
 2002-09-10  Michael Snyder  <msnyder@redhat.com>
 
 	* irix-core.c (do_sections, do_sections64): New functions.
-	(irix_core_core_file_p): Call new functions do_sections, 
+	(irix_core_core_file_p): Call new functions do_sections,
 	do_sections64, depending on corefile (32-bit or 64-bit).
 
 2002-09-09  Richard Henderson  <rth@redhat.com>
@@ -325,8 +445,8 @@
 
 2002-09-04  Kevin Buettner  <kevinb@redhat.com>
 
- 	* config.bfd (mips*-*-irix6*): Add new ABI vectors.  Make n32 default
- 	vector.
+	* config.bfd (mips*-*-irix6*): Add new ABI vectors.  Make n32 default
+	vector.
 
 2002-09-02  Nick Clifton  <nickc@redhat.com>
 
@@ -337,7 +457,7 @@
 	(v850_elf_relax_section): Replace caching of external symbols
 	with caching of internal symbols obtained from calling
 	bfd_elf_get_elf_syms().
-        Fixup problems with freeing cached allocated memory blocks.
+	Fixup problems with freeing cached allocated memory blocks.
 
 2002-09-02  Alan Modra  <amodra@bigpond.net.au>
 
@@ -506,7 +626,7 @@
 	* elf32-sh.c (sh_elf_finish_dynamic_sections): Set LSB of DT_INIT
 	value if .init is an SHmedia function.  Similarly for DT_FINI.
 	* elf64-sh64.c (sh64_elf64_finish_dynamic_sections): Likewise.
-	
+
 2002-08-23  Stephen Clarke <stephen.clarke@superh.com>
 
 	* elf32-sh.c (sh_elf_size_dynamic_sections): Zero initialize
@@ -516,7 +636,7 @@
 2002-08-22  Kaz Kojima <kkojima@rr.iij4u.or.jp>
 
 	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use a simple
-	byte read when reading the return address register column. 
+	byte read when reading the return address register column.
 
 2002-08-22  Nick Clifton  <nickc@redhat.com>
 
@@ -582,9 +702,9 @@
 	argument declaration.
 
 2002-08-19  Elena Zannoni <ezannoni@redhat.com>
- 
-        * archures.c (bfd_mach_ppc_e500): Added.
-        * bfd-in2.h: Rebuilt.
+
+	* archures.c (bfd_mach_ppc_e500): Added.
+	* bfd-in2.h: Rebuilt.
 	* cpu-powerpc.c (bfd_powerpc_archs): Added e500.
 
 2002-08-19  Alan Modra  <amodra@bigpond.net.au>
@@ -594,7 +714,7 @@
 2002-08-17  Andrew Cagney  <ac131313@redhat.com>
 
 	* elf.c (bfd_elf_get_elf_syms): Change type of `esym' to
- 	`bfd_byte'.
+	`bfd_byte'.
 
 2002-08-17  Stan Cox  <scox@redhat.com>
 
@@ -606,7 +726,7 @@
 	* bfd/elf32-sh.c (sh_elf_gc_mark_hook): For sh64, skip indirect
 	symbols when looking for section referred to by a relocation.
 	* bfd/elf64-sh.c (sh_elf64_gc_mark_hook): Likewise.
-	
+
 2002-08-15  Alan Modra  <amodra@bigpond.net.au>
 
 	* elf32-i370.c: Move reloc enum to include/elf/i370.h.
@@ -695,7 +815,7 @@
 
 2002-08-09  Graeme Peterson  <gp@qnx.com>
 
-	* Makefile.am: Add entries for elf32-ppcqnx.c, and add 
+	* Makefile.am: Add entries for elf32-ppcqnx.c, and add
 	elf32-qnx.h dependency to elfarmqnx-nabi.c and elf32-i386qnx.c.
 	* Makefile.in: Regenerate.
 	* config.bfd: Add support for powerpc{le}-*-nto targets.
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 0aa98e3..d55e5c9 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -32,7 +32,7 @@
 	format.lo init.lo libbfd.lo opncls.lo reloc.lo \
 	section.lo syms.lo targets.lo hash.lo linker.lo \
 	srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
-	merge.lo dwarf2.lo
+	merge.lo dwarf2.lo simple.lo
 
 BFD64_LIBS = archive64.lo
 
@@ -41,7 +41,7 @@
 	format.c init.c libbfd.c opncls.c reloc.c \
 	section.c syms.c targets.c hash.c linker.c \
 	srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
-	merge.c dwarf2.c
+	merge.c dwarf2.c simple.c
 
 BFD64_LIBS_CFILES = archive64.c
 
@@ -242,6 +242,7 @@
 	elf32-sh-lin.lo \
 	elf32-sh64.lo \
 	elf32-sh64-com.lo \
+	elf32-sh64-lin.lo \
 	elf32-sh-nbsd.lo \
 	elf32-sh64-nbsd.lo \
 	elf32-shqnx.lo \
@@ -401,6 +402,7 @@
 	elf32-ppcqnx.c \
 	elf32-sh64.c \
 	elf32-sh64-com.c \
+	elf32-sh64-lin.c \
 	elf32-s390.c \
 	elf32-sh.c \
 	elf32-sh-lin.c \
@@ -497,6 +499,7 @@
 	elf64-mips.lo \
 	elf64-mmix.lo \
 	elf64-sh64.lo \
+	elf64-sh64-lin.lo \
 	elf64-sh64-nbsd.lo \
 	elf64-ppc.lo \
 	elf64-s390.lo \
@@ -525,6 +528,7 @@
 	elf64-ppc.c \
 	elf64-s390.c \
 	elf64-sh64.c \
+	elf64-sh64-lin.c \
 	elf64-sh64-nbsd.c \
 	elf64-sparc.c \
 	elf64.c \
@@ -900,6 +904,7 @@
 dwarf2.lo: dwarf2.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/dwarf2.h
+simple.lo: simple.c $(INCDIR)/filenames.h
 archive64.lo: archive64.c $(INCDIR)/filenames.h $(INCDIR)/aout/ar.h
 cpu-a29k.lo: cpu-a29k.c $(INCDIR)/filenames.h
 cpu-alpha.lo: cpu-alpha.c $(INCDIR)/filenames.h
@@ -1260,6 +1265,11 @@
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/sh.h \
   $(INCDIR)/elf/reloc-macros.h $(srcdir)/../opcodes/sh64-opc.h
+elf32-sh64-lin.lo: elf32-sh64-lin.c elf32-sh64.c $(INCDIR)/filenames.h \
+  elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/../opcodes/sh64-opc.h \
+  elf32-sh.c $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h
 elf32-s390.lo: elf32-s390.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h \
@@ -1578,6 +1588,10 @@
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
   elf64-target.h
+elf64-sh64-lin.lo: elf64-sh64-lin.c elf64-sh64.c $(INCDIR)/filenames.h \
+  $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sh.h \
+  $(INCDIR)/elf/reloc-macros.h elf64-target.h
 elf64-sh64-nbsd.lo: elf64-sh64-nbsd.c elf64-sh64.c \
   $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 4816c17..e7518bc 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -156,7 +156,7 @@
 	format.lo init.lo libbfd.lo opncls.lo reloc.lo \
 	section.lo syms.lo targets.lo hash.lo linker.lo \
 	srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
-	merge.lo dwarf2.lo
+	merge.lo dwarf2.lo simple.lo
 
 
 BFD64_LIBS = archive64.lo
@@ -166,7 +166,7 @@
 	format.c init.c libbfd.c opncls.c reloc.c \
 	section.c syms.c targets.c hash.c linker.c \
 	srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
-	merge.c dwarf2.c
+	merge.c dwarf2.c simple.c
 
 
 BFD64_LIBS_CFILES = archive64.c
@@ -370,6 +370,7 @@
 	elf32-sh-lin.lo \
 	elf32-sh64.lo \
 	elf32-sh64-com.lo \
+	elf32-sh64-lin.lo \
 	elf32-sh-nbsd.lo \
 	elf32-sh64-nbsd.lo \
 	elf32-shqnx.lo \
@@ -530,6 +531,7 @@
 	elf32-ppcqnx.c \
 	elf32-sh64.c \
 	elf32-sh64-com.c \
+	elf32-sh64-lin.c \
 	elf32-s390.c \
 	elf32-sh.c \
 	elf32-sh-lin.c \
@@ -627,6 +629,7 @@
 	elf64-mips.lo \
 	elf64-mmix.lo \
 	elf64-sh64.lo \
+	elf64-sh64-lin.lo \
 	elf64-sh64-nbsd.lo \
 	elf64-ppc.lo \
 	elf64-s390.lo \
@@ -656,6 +659,7 @@
 	elf64-ppc.c \
 	elf64-s390.c \
 	elf64-sh64.c \
+	elf64-sh64-lin.c \
 	elf64-sh64-nbsd.c \
 	elf64-sparc.c \
 	elf64.c \
@@ -785,7 +789,7 @@
 libbfd_la_OBJECTS =  archive.lo archures.lo bfd.lo cache.lo coffgen.lo \
 corefile.lo format.lo init.lo libbfd.lo opncls.lo reloc.lo section.lo \
 syms.lo targets.lo hash.lo linker.lo srec.lo binary.lo tekhex.lo \
-ihex.lo stabs.lo stab-syms.lo merge.lo dwarf2.lo archive64.lo
+ihex.lo stabs.lo stab-syms.lo merge.lo dwarf2.lo simple.lo archive64.lo
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -949,7 +953,7 @@
 	dot_seen=no; \
 	rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
 	  rev="$$subdir $$rev"; \
-	  test "$$subdir" != "." || dot_seen=yes; \
+	  test "$$subdir" = "." && dot_seen=yes; \
 	done; \
 	test "$$dot_seen" = "no" && rev=". $$rev"; \
 	target=`echo $@ | sed s/-recursive//`; \
@@ -1430,6 +1434,7 @@
 dwarf2.lo: dwarf2.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/dwarf2.h
+simple.lo: simple.c $(INCDIR)/filenames.h
 archive64.lo: archive64.c $(INCDIR)/filenames.h $(INCDIR)/aout/ar.h
 cpu-a29k.lo: cpu-a29k.c $(INCDIR)/filenames.h
 cpu-alpha.lo: cpu-alpha.c $(INCDIR)/filenames.h
@@ -1790,6 +1795,11 @@
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/sh.h \
   $(INCDIR)/elf/reloc-macros.h $(srcdir)/../opcodes/sh64-opc.h
+elf32-sh64-lin.lo: elf32-sh64-lin.c elf32-sh64.c $(INCDIR)/filenames.h \
+  elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/../opcodes/sh64-opc.h \
+  elf32-sh.c $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h
 elf32-s390.lo: elf32-s390.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/s390.h $(INCDIR)/elf/reloc-macros.h \
@@ -2108,6 +2118,10 @@
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h \
   elf64-target.h
+elf64-sh64-lin.lo: elf64-sh64-lin.c elf64-sh64.c $(INCDIR)/filenames.h \
+  $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sh.h \
+  $(INCDIR)/elf/reloc-macros.h elf64-target.h
 elf64-sh64-nbsd.lo: elf64-sh64-nbsd.c elf64-sh64.c \
   $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 38e5459..5f226d4 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1,7 +1,7 @@
 /* DO NOT EDIT!  -*- buffer-read-only: t -*-  This file is automatically 
    generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", 
    "section.c", "archures.c", "reloc.c", "syms.c", "bfd.c", "archive.c", 
-   "corefile.c", "targets.c" and "format.c".
+   "corefile.c", "targets.c", "format.c", "linker.c" and "simple.c".
    Run "make headers" in your build bfd/ to regenerate.  */
 
 /* Main header file for the bfd library -- portable access to object files.
@@ -2505,6 +2505,14 @@
   BFD_RELOC_SH_IMM_HI16,
   BFD_RELOC_SH_IMM_HI16_PCREL,
   BFD_RELOC_SH_PT_16,
+  BFD_RELOC_SH_TLS_GD_32,
+  BFD_RELOC_SH_TLS_LD_32,
+  BFD_RELOC_SH_TLS_LDO_32,
+  BFD_RELOC_SH_TLS_IE_32,
+  BFD_RELOC_SH_TLS_LE_32,
+  BFD_RELOC_SH_TLS_DTPMOD32,
+  BFD_RELOC_SH_TLS_DTPOFF32,
+  BFD_RELOC_SH_TLS_TPOFF32,
 
 /* Thumb 23-, 12- and 9-bit pc-relative branches.  The lowest bit must
 be zero and is not stored in the instruction.  */
@@ -4121,6 +4129,17 @@
 const char *
 bfd_format_string PARAMS ((bfd_format format));
 
+/* Extracted from linker.c.  */
+boolean
+bfd_link_split_section PARAMS ((bfd *abfd, asection *sec));
+
+#define bfd_link_split_section(abfd, sec) \
+       BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
+
+/* Extracted from simple.c.  */
+bfd_byte *
+bfd_simple_get_relocated_section_contents PARAMS ((bfd *abfd, asection *sec, bfd_byte *outbuf));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index 5e7f907..25256a8 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -1881,6 +1881,7 @@
   register asection *               s;
   char *                            tmp_name;
   struct coff_link_hash_entry *     myh;
+  struct bfd_link_hash_entry *      bh;
   struct coff_arm_link_hash_table * globals;
   bfd_vma val;
   bfd_size_type amt;
@@ -1915,10 +1916,10 @@
      though the section isn't allocated yet, this is where we will be putting
      it.  */
 
+  bh = NULL;
   val = globals->arm_glue_size + 1;
   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
-				BSF_GLOBAL, s, val, NULL, true, false,
-				(struct bfd_link_hash_entry **) & myh);
+				BSF_GLOBAL, s, val, NULL, true, false, &bh);
 
   free (tmp_name);
 
@@ -1937,6 +1938,7 @@
   register asection *                s;
   char *                             tmp_name;
   struct coff_link_hash_entry *      myh;
+  struct bfd_link_hash_entry *       bh;
   struct coff_arm_link_hash_table *  globals;
   bfd_vma val;
   bfd_size_type amt;
@@ -1967,12 +1969,13 @@
       return; /* we've already seen this guy */
     }
 
+  bh = NULL;
   val = globals->thumb_glue_size + 1;
   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
-				BSF_GLOBAL, s, val, NULL, true, false,
-				(struct bfd_link_hash_entry **) &myh);
+				BSF_GLOBAL, s, val, NULL, true, false, &bh);
 
   /* If we mark it 'thumb', the disassembler will do a better job.  */
+  myh = (struct coff_link_hash_entry *) bh;
   myh->class = C_THUMBEXTFUNC;
 
   free (tmp_name);
@@ -1989,11 +1992,10 @@
 
   sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
 
-  myh = NULL;
+  bh = NULL;
   val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
   bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
-				BSF_LOCAL, s, val, NULL, true, false,
-				(struct bfd_link_hash_entry **) & myh);
+				BSF_LOCAL, s, val, NULL, true, false, &bh);
 
   free (tmp_name);
 
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index eb9388f..c1302ee 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -1322,6 +1322,9 @@
 
       if ((a->flags & SEC_RELOC) == 0 || a->reloc_count  < 1)
 	continue;
+      /* Don't mark relocs in excluded sections.  */
+      if (a->output_section == bfd_abs_section_ptr)
+	continue;
 
       /* Read in the relocs.  */
       internal_relocs = _bfd_coff_read_internal_relocs
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 4aabfed..85f1ea2 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -934,12 +934,12 @@
     targ_underscore=yes
     ;;
   sh64eb-*-linux*)
-    targ_defvec=bfd_elf32_shblin_vec
-    targ_selvecs="bfd_elf32_shblin_vec bfd_elf32_sh64_vec bfd_elf64_sh64_vec bfd_elf32_sh_vec"
+    targ_defvec=bfd_elf32_sh64blin_vec
+    targ_selvecs="bfd_elf32_sh64lin_vec bfd_elf64_sh64blin_vec bfd_elf64_sh64lin_vec bfd_elf32_shblin_vec bfd_elf32_shlin_vec"
     ;;
   sh64-*-linux*)
-    targ_defvec=bfd_elf32_shlin_vec
-    targ_selvecs="bfd_elf32_shlin_vec bfd_elf32_sh64l_vec bfd_elf64_sh64l_vec bfd_elf32_shl_vec"
+    targ_defvec=bfd_elf32_sh64lin_vec
+    targ_selvecs="bfd_elf32_sh64blin_vec bfd_elf64_sh64lin_vec bfd_elf64_sh64blin_vec bfd_elf32_shlin_vec bfd_elf32_shblin_vec"
     ;;
 #endif /* BFD64 */
 
diff --git a/bfd/configure b/bfd/configure
index 2ca10f7..997eb74 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -6117,6 +6117,8 @@
     # which needs it but does not list it.  Should be fixed in right place.
     bfd_elf32_sh64_vec)		tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
     bfd_elf32_sh64l_vec)	tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+    bfd_elf32_sh64lin_vec)	tb="$tb elf32-sh64-lin.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+    bfd_elf32_sh64blin_vec)	tb="$tb elf32-sh64-lin.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
     bfd_elf32_sh64lnbsd_vec)	tb="$tb elf32-sh64-nbsd.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" ;;
     bfd_elf32_sh64nbsd_vec)	tb="$tb elf32-sh64-nbsd.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" ;;
     bfd_elf32_sh_vec)		tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo" ;;
@@ -6153,6 +6155,8 @@
     bfd_elf64_s390_vec)		tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_sh64_vec)		tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64l_vec)	tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+    bfd_elf64_sh64lin_vec)	tb="$tb elf64-sh64-lin.lo elf64.lo $elf" target_size=64 ;;
+    bfd_elf64_sh64blin_vec)	tb="$tb elf64-sh64-lin.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64lnbsd_vec)	tb="$tb elf64-sh64-nbsd.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64nbsd_vec)	tb="$tb elf64-sh64-nbsd.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sparc_vec)	tb="$tb elf64-sparc.lo elf64.lo $elf"; target_size=64 ;;
diff --git a/bfd/configure.in b/bfd/configure.in
index ba38dd4..e6b4f9c 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -618,6 +618,8 @@
     # which needs it but does not list it.  Should be fixed in right place.
     bfd_elf32_sh64_vec)		tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
     bfd_elf32_sh64l_vec)	tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+    bfd_elf32_sh64lin_vec)	tb="$tb elf32-sh64-lin.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+    bfd_elf32_sh64blin_vec)	tb="$tb elf32-sh64-lin.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
     bfd_elf32_sh64lnbsd_vec)	tb="$tb elf32-sh64-nbsd.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" ;;
     bfd_elf32_sh64nbsd_vec)	tb="$tb elf32-sh64-nbsd.lo elf32-sh64-com.lo elf32.lo $elf cofflink.lo" ;;
     bfd_elf32_sh_vec)		tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo" ;;
@@ -654,6 +656,8 @@
     bfd_elf64_s390_vec)		tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_sh64_vec)		tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64l_vec)	tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+    bfd_elf64_sh64lin_vec)	tb="$tb elf64-sh64-lin.lo elf64.lo $elf" target_size=64 ;;
+    bfd_elf64_sh64blin_vec)	tb="$tb elf64-sh64-lin.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64lnbsd_vec)	tb="$tb elf64-sh64-nbsd.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64nbsd_vec)	tb="$tb elf64-sh64-nbsd.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sparc_vec)	tb="$tb elf64-sparc.lo elf64.lo $elf"; target_size=64 ;;
diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog
index f20113c..b04830c 100644
--- a/bfd/doc/ChangeLog
+++ b/bfd/doc/ChangeLog
@@ -1,3 +1,8 @@
+2002-10-11  Daniel Jacobowitz  <drow@mvista.com>
+
+	* Makefile.am (BFD_H_DEP): Add simple.c and linker.c.
+	* Makefile.in: Regenerated.
+
 2002-08-29  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
 	* chew.c (paramstuff, outputdots, perform, bang and usage): Remove
diff --git a/bfd/doc/Makefile.am b/bfd/doc/Makefile.am
index 0787143..da51daf 100644
--- a/bfd/doc/Makefile.am
+++ b/bfd/doc/Makefile.am
@@ -248,6 +248,8 @@
 	$(srcdir)/../corefile.c		\
 	$(srcdir)/../targets.c		\
 	$(srcdir)/../format.c		\
+	$(srcdir)/../linker.c		\
+	$(srcdir)/../simple.c		\
 	$(srcdir)/header.sed		\
 	$(srcdir)/proto.str		\
 	$(srcdir)/../version.h		\
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index 66a19d1..d4599e2 100644
--- a/bfd/doc/Makefile.in
+++ b/bfd/doc/Makefile.in
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -216,6 +216,8 @@
 	$(srcdir)/../corefile.c		\
 	$(srcdir)/../targets.c		\
 	$(srcdir)/../format.c		\
+	$(srcdir)/../linker.c		\
+	$(srcdir)/../simple.c		\
 	$(srcdir)/header.sed		\
 	$(srcdir)/proto.str		\
 	$(srcdir)/../version.h		\
@@ -244,7 +246,7 @@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gtar
+TAR = tar
 GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
@@ -330,7 +332,7 @@
 	else ii=; fi; \
 	list='$(INFO_DEPS)'; \
 	for file in $$list; do \
-	  test -z "$$ii" \
+	  test -z "$ii" \
 	    || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
 	done
 	@$(NORMAL_UNINSTALL)
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 47b6582..4f129f6 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -3837,7 +3837,7 @@
     = backend->debug_swap.swap_ext_in;
   bfd_size_type external_ext_size = backend->debug_swap.external_ext_size;
   unsigned long ext_count;
-  struct ecoff_link_hash_entry **sym_hash;
+  struct bfd_link_hash_entry **sym_hash;
   char *ext_ptr;
   char *ext_end;
   bfd_size_type amt;
@@ -3846,10 +3846,10 @@
 
   amt = ext_count;
   amt *= sizeof (struct bfd_link_hash_entry *);
-  sym_hash = (struct ecoff_link_hash_entry **) bfd_alloc (abfd, amt);
+  sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt);
   if (!sym_hash)
     return false;
-  ecoff_data (abfd)->sym_hashes = sym_hash;
+  ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash;
 
   ext_ptr = (char *) external_ext;
   ext_end = ext_ptr + ext_count * external_ext_size;
@@ -3980,15 +3980,13 @@
 
       name = ssext + esym.asym.iss;
 
-      h = NULL;
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, name,
 	      (flagword) (esym.weakext ? BSF_WEAK : BSF_GLOBAL),
-	      section, value, (const char *) NULL, true, true,
-	      (struct bfd_link_hash_entry **) &h)))
+	      section, value, (const char *) NULL, true, true, sym_hash)))
 	return false;
 
-      *sym_hash = h;
+      h = (struct ecoff_link_hash_entry *) *sym_hash;
 
       /* If we are building an ECOFF hash table, save the external
 	 symbol information.  */
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 2d59601..029bbe2 100644
--- a/bfd/elf32-arm.h
+++ b/bfd/elf32-arm.h
@@ -427,6 +427,7 @@
   asection * s;
   char * tmp_name;
   struct elf_link_hash_entry * myh;
+  struct bfd_link_hash_entry * bh;
   struct elf32_arm_link_hash_table * globals;
   bfd_vma val;
 
@@ -460,11 +461,11 @@
   /* The only trick here is using hash_table->arm_glue_size as the value. Even
      though the section isn't allocated yet, this is where we will be putting
      it.  */
+  bh = NULL;
   val = globals->arm_glue_size + 1;
   _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
 				    tmp_name, BSF_GLOBAL, s, val,
-				    NULL, true, false,
-				    (struct bfd_link_hash_entry **) &myh);
+				    NULL, true, false, &bh);
 
   free (tmp_name);
 
@@ -482,6 +483,7 @@
   asection *s;
   char *tmp_name;
   struct elf_link_hash_entry *myh;
+  struct bfd_link_hash_entry *bh;
   struct elf32_arm_link_hash_table *hash_table;
   char bind;
   bfd_vma val;
@@ -513,13 +515,14 @@
       return;
     }
 
+  bh = NULL;
   val = hash_table->thumb_glue_size + 1;
   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
 				    tmp_name, BSF_GLOBAL, s, val,
-				    NULL, true, false,
-				    (struct bfd_link_hash_entry **) &myh);
+				    NULL, true, false, &bh);
 
   /* If we mark it 'Thumb', the disassembler will do a better job.  */
+  myh = (struct elf_link_hash_entry *) bh;
   bind = ELF_ST_BIND (myh->type);
   myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC);
 
@@ -536,13 +539,11 @@
 
   sprintf (tmp_name, CHANGE_TO_ARM, name);
 
-  myh = NULL;
-
+  bh = NULL;
   val = hash_table->thumb_glue_size + 4,
   _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
 				    tmp_name, BSF_LOCAL, s, val,
-				    NULL, true, false,
-				    (struct bfd_link_hash_entry **) &myh);
+				    NULL, true, false, &bh);
 
   free (tmp_name);
 
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 87e1e76..483b8a5 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2617,36 +2617,40 @@
 		  BFD_ASSERT (rel->r_offset >= 1);
 		  val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
 		  BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size);
-		  if (val != 0xa1)
-		    {
-		      BFD_ASSERT (rel->r_offset >= 2);
-		      type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
-		    }
 		  if (val == 0xa1)
 		    {
 		      /* movl foo, %eax.  */
 		      bfd_put_8 (output_bfd, 0xb8, contents + rel->r_offset - 1);
 		    }
-		  else if (type == 0x8b)
-		    {
-		      /* movl */
-		      BFD_ASSERT ((val & 0xc7) == 0x05);
-		      bfd_put_8 (output_bfd, 0xc7,
-				 contents + rel->r_offset - 2);
-		      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
-				 contents + rel->r_offset - 1);
-		    }
-		  else if (type == 0x03)
-		    {
-		      /* addl */
-		      BFD_ASSERT ((val & 0xc7) == 0x05);
-		      bfd_put_8 (output_bfd, 0x81,
-				 contents + rel->r_offset - 2);
-		      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
-				 contents + rel->r_offset - 1);
-		    }
 		  else
-		    BFD_FAIL ();
+		    {
+		      BFD_ASSERT (rel->r_offset >= 2);
+		      type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+		      switch (type)
+		        {
+			case 0x8b:
+			  /* movl */
+			  BFD_ASSERT ((val & 0xc7) == 0x05);
+			  bfd_put_8 (output_bfd, 0xc7,
+				     contents + rel->r_offset - 2);
+			  bfd_put_8 (output_bfd,
+				     0xc0 | ((val >> 3) & 7),
+				     contents + rel->r_offset - 1);
+			  break;
+			case 0x03:
+			  /* addl */
+			  BFD_ASSERT ((val & 0xc7) == 0x05);
+			  bfd_put_8 (output_bfd, 0x81,
+				     contents + rel->r_offset - 2);
+			  bfd_put_8 (output_bfd,
+				     0xc0 | ((val >> 3) & 7),
+				     contents + rel->r_offset - 1);
+			  break;
+			default:
+			  BFD_FAIL ();
+			  break;
+		        }
+		    }
 		  bfd_put_32 (output_bfd, -tpoff (info, relocation),
 			      contents + rel->r_offset);
 		  continue;
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index a2e9e0b..8adb1e2 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -847,6 +847,7 @@
 	 section already exists a new one is created that follows it which
 	 screws of _SDA_BASE_ address calcs because output_offset != 0.  */
       struct elf_link_hash_entry *h;
+      struct bfd_link_hash_entry *bh;
       asection *s = bfd_get_section_by_name (abfd, ".sdata");
 
       /* The following code was cobbled from elf32-ppc.c and elflink.c.  */
@@ -863,10 +864,10 @@
 	  bfd_set_section_alignment (abfd, s, 2);
 	}
 
-      h = (struct elf_link_hash_entry *)
-	bfd_link_hash_lookup (info->hash, "_SDA_BASE_", false, false, false);
+      bh = bfd_link_hash_lookup (info->hash, "_SDA_BASE_",
+				 false, false, false);
 
-      if ((h == NULL || h->root.type == bfd_link_hash_undefined)
+      if ((bh == NULL || bh->type == bfd_link_hash_undefined)
 	  && !(_bfd_generic_link_add_one_symbol (info,
 						 abfd,
 						 "_SDA_BASE_",
@@ -876,8 +877,9 @@
 						 (const char *) NULL,
 						 false,
 						 get_elf_backend_data (abfd)->collect,
-						 (struct bfd_link_hash_entry **) &h)))
+						 &bh)))
 	return false;
+      h = (struct elf_link_hash_entry *) bh;
       h->type = STT_OBJECT;
     }
 
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 703ac40..53d2841 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -59,6 +59,12 @@
 static void sh_elf_copy_indirect_symbol
   PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
 	   struct elf_link_hash_entry *));
+static int sh_elf_optimized_tls_reloc
+  PARAMS ((struct bfd_link_info *, int, int));
+static boolean sh_elf_mkobject
+  PARAMS((bfd *));
+static boolean sh_elf_object_p
+  PARAMS((bfd *));
 static boolean sh_elf_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
 	   const Elf_Internal_Rela *));
@@ -82,6 +88,8 @@
   PARAMS((bfd *, struct bfd_link_info *));
 static boolean sh_elf_create_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
+static bfd_vma dtpoff_base
+  PARAMS ((struct bfd_link_info *));
 static asection * sh_elf_gc_mark_hook
   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
 	   struct elf_link_hash_entry *, Elf_Internal_Sym *));
@@ -713,14 +721,119 @@
   EMPTY_HOWTO (141),
   EMPTY_HOWTO (142),
   EMPTY_HOWTO (143),
-  EMPTY_HOWTO (144),
-  EMPTY_HOWTO (145),
-  EMPTY_HOWTO (146),
-  EMPTY_HOWTO (147),
-  EMPTY_HOWTO (148),
-  EMPTY_HOWTO (149),
-  EMPTY_HOWTO (150),
-  EMPTY_HOWTO (151),
+
+  HOWTO (R_SH_TLS_GD_32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_GD_32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_LD_32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_LD_32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_LDO_32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_LDO_32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_IE_32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_IE_32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_LE_32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_LE_32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_DTPMOD32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_DTPMOD32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_DTPOFF32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_DTPOFF32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO (R_SH_TLS_TPOFF32,	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 32,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_bitfield, /* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* */
+	 "R_SH_TLS_TPOFF32",	/* name */
+	 true,			/* partial_inplace */
+	 0xffffffff,		/* src_mask */
+	 0xffffffff,		/* dst_mask */
+	 false),		/* pcrel_offset */
+
   EMPTY_HOWTO (152),
   EMPTY_HOWTO (153),
   EMPTY_HOWTO (154),
@@ -1776,6 +1889,14 @@
   { BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
   { BFD_RELOC_SH_LOOP_START, R_SH_LOOP_START },
   { BFD_RELOC_SH_LOOP_END, R_SH_LOOP_END },
+  { BFD_RELOC_SH_TLS_GD_32, R_SH_TLS_GD_32 },
+  { BFD_RELOC_SH_TLS_LD_32, R_SH_TLS_LD_32 },
+  { BFD_RELOC_SH_TLS_LDO_32, R_SH_TLS_LDO_32 },
+  { BFD_RELOC_SH_TLS_IE_32, R_SH_TLS_IE_32 },
+  { BFD_RELOC_SH_TLS_LE_32, R_SH_TLS_LE_32 },
+  { BFD_RELOC_SH_TLS_DTPMOD32, R_SH_TLS_DTPMOD32 },
+  { BFD_RELOC_SH_TLS_DTPOFF32, R_SH_TLS_DTPOFF32 },
+  { BFD_RELOC_SH_TLS_TPOFF32, R_SH_TLS_TPOFF32 },
   { BFD_RELOC_32_GOT_PCREL, R_SH_GOT32 },
   { BFD_RELOC_32_PLT_PCREL, R_SH_PLT32 },
   { BFD_RELOC_SH_COPY, R_SH_COPY },
@@ -1874,6 +1995,7 @@
   BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_2 || r > R_SH_LAST_INVALID_RELOC_2);
   BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_LAST_INVALID_RELOC_3);
   BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
+  BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_5 || r > R_SH_LAST_INVALID_RELOC_5);
 
   cache_ptr->howto = &sh_elf_howto_table[r];
 }
@@ -3047,7 +3169,7 @@
   0x6f, 0xf0, 0xff, 0xf0, /* nop */
   0x6f, 0xf0, 0xff, 0xf0, /* nop */
   0xce, 0x00, 0x01, 0x10, /* movi  -GOT_BIAS, r17 */
-  0x00, 0xca, 0x45, 0x10, /* sub.l r12, r17, r17 */
+  0x00, 0xc8, 0x45, 0x10, /* add.l r12, r17, r17 */
   0x89, 0x10, 0x09, 0x90, /* ld.l  r17, 8, r25 */
   0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
   0x89, 0x10, 0x05, 0x10, /* ld.l  r17, 4, r17 */
@@ -3067,7 +3189,7 @@
   0xf0, 0xff, 0xf0, 0x6f, /* nop */
   0xf0, 0xff, 0xf0, 0x6f, /* nop */
   0x10, 0x01, 0x00, 0xce, /* movi  -GOT_BIAS, r17 */
-  0x10, 0x45, 0xca, 0x00, /* sub.l r12, r17, r17 */
+  0x10, 0x45, 0xc8, 0x00, /* add.l r12, r17, r17 */
   0x90, 0x09, 0x10, 0x89, /* ld.l  r17, 8, r25 */
   0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
   0x10, 0x05, 0x10, 0x89, /* ld.l  r17, 4, r17 */
@@ -3390,8 +3512,45 @@
   struct elf_sh_dyn_relocs *dyn_relocs;
 
   bfd_signed_vma gotplt_refcount;
+
+  enum {
+    GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE
+  } tls_type;
+
+  /* If true, R_SH_TLS_TPOFF32 relocation is generated.  */
+  boolean tls_tpoff32;
 };
 
+#define sh_elf_hash_entry(ent) ((struct elf_sh_link_hash_entry *)(ent))
+
+struct sh_elf_obj_tdata
+{
+  struct elf_obj_tdata root;
+
+  /* tls_type for each local got entry.  */
+  char *local_got_tls_type;
+};
+
+#define sh_elf_tdata(abfd) \
+  ((struct sh_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define sh_elf_local_got_tls_type(abfd) \
+  (sh_elf_tdata (abfd)->local_got_tls_type)
+
+/* Override the generic function because we need to store sh_elf_obj_tdata
+   as the specific tdata.  */
+
+static boolean
+sh_elf_mkobject (abfd)
+     bfd *abfd;
+{
+  bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
+  abfd->tdata.any = bfd_zalloc (abfd, amt);
+  if (abfd->tdata.any == NULL)
+    return false;
+  return true;
+}
+                 
 /* sh ELF linker hash table.  */
 
 struct elf_sh_link_hash_table
@@ -3409,6 +3568,13 @@
 
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
+
+  /* A counter or offset to track a TLS got entry.  */
+  union
+    {
+      bfd_signed_vma refcount;
+      bfd_vma offset;
+    } tls_ldm_got;
 };
 
 /* Traverse an sh ELF linker hash table.  */
@@ -3458,6 +3624,8 @@
 #ifdef INCLUDE_SHMEDIA
       ret->datalabel_got_offset = (bfd_vma) -1;
 #endif
+      ret->tls_type = GOT_UNKNOWN;
+      ret->tls_tpoff32 = false;
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -3491,6 +3659,7 @@
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
   ret->sym_sec.abfd = NULL;
+  ret->tls_ldm_got.refcount = 0;
 
   return &ret->root.root;
 }
@@ -3582,13 +3751,16 @@
     {
       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
 	 .plt section.  */
-      struct elf_link_hash_entry *h = NULL;
+      struct elf_link_hash_entry *h;
+      struct bfd_link_hash_entry *bh = NULL;
+
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
 	      (bfd_vma) 0, (const char *) NULL, false,
-	      get_elf_backend_data (abfd)->collect,
-	      (struct bfd_link_hash_entry **) &h)))
+	      get_elf_backend_data (abfd)->collect, &bh)))
 	return false;
+
+      h = (struct elf_link_hash_entry *) bh;
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_OBJECT;
 
@@ -3943,6 +4115,7 @@
     {
       asection *s;
       boolean dyn;
+      int tls_type = sh_elf_hash_entry (h)->tls_type;
 
       /* Make sure this symbol is output as a dynamic symbol.
 	 Undefined weak syms won't yet be marked as dynamic.  */
@@ -3969,8 +4142,18 @@
       h->got.offset = s->_raw_size;
 #endif
       s->_raw_size += 4;
+      /* R_SH_TLS_GD needs 2 consecutive GOT slots.  */
+      if (tls_type == GOT_TLS_GD)
+	s->_raw_size += 4;
       dyn = htab->root.dynamic_sections_created;
-      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
+      /* R_SH_TLS_IE_32 needs one dynamic relocation,
+	 R_SH_TLS_GD needs one if local symbol and two if global.  */
+      if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+	  || tls_type == GOT_TLS_IE)
+	htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+      else if (tls_type == GOT_TLS_GD)
+	htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela);
+      else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
 	htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
     }
   else
@@ -4006,6 +4189,9 @@
     }
   else
     {
+      if (sh_elf_hash_entry (h)->tls_tpoff32)
+	goto keep;
+
       /* For the non-shared case, discard space for relocs against
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
@@ -4113,6 +4299,7 @@
     {
       bfd_signed_vma *local_got;
       bfd_signed_vma *end_local_got;
+      char *local_tls_type;
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
       asection *srel;
@@ -4158,6 +4345,7 @@
       locsymcount *= 2;
 #endif
       end_local_got = local_got + locsymcount;
+      local_tls_type = sh_elf_local_got_tls_type (ibfd);
       s = htab->sgot;
       srel = htab->srelgot;
       for (; local_got < end_local_got; ++local_got)
@@ -4166,14 +4354,28 @@
 	    {
 	      *local_got = s->_raw_size;
 	      s->_raw_size += 4;
+	      if (*local_tls_type == GOT_TLS_GD)
+		s->_raw_size += 4;
 	      if (info->shared)
 		srel->_raw_size += sizeof (Elf32_External_Rela);
 	    }
 	  else
 	    *local_got = (bfd_vma) -1;
+	  ++local_tls_type;
 	}
     }
 
+  if (htab->tls_ldm_got.refcount > 0)
+    {
+      /* Allocate 2 got entries and 1 dynamic reloc for R_SH_TLS_LD_32
+	 relocs.  */
+      htab->tls_ldm_got.offset = htab->sgot->_raw_size;
+      htab->sgot->_raw_size += 8;
+      htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+    }
+  else
+    htab->tls_ldm_got.offset = -1;
+
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info);
@@ -4309,6 +4511,7 @@
   asection *sgotplt;
   asection *splt;
   asection *sreloc;
+  asection *srelgot;
 
   htab = sh_elf_hash_table (info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -4320,6 +4523,7 @@
   sgotplt = htab->sgotplt;
   splt = htab->splt;
   sreloc = NULL;
+  srelgot = NULL;
 
   rel = relocs;
   relend = relocs + input_section->reloc_count;
@@ -4335,6 +4539,8 @@
       bfd_vma addend = (bfd_vma) 0;
       bfd_reloc_status_type r;
       int seen_stt_datalabel = 0;
+      bfd_vma off;
+      int tls_type;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
@@ -4356,6 +4562,8 @@
 	      && r_type <= (int) R_SH_LAST_INVALID_RELOC_3)
 	  || (   r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
 	      && r_type <= (int) R_SH_LAST_INVALID_RELOC_4)
+	  || (   r_type >= (int) R_SH_FIRST_INVALID_RELOC_5
+	      && r_type <= (int) R_SH_LAST_INVALID_RELOC_5)
 	  || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
 	      && r_type <= (int) R_SH_LAST_INVALID_RELOC_2))
 	{
@@ -4526,15 +4734,18 @@
 			     with them here.  */
 			  || ((input_section->flags & SEC_DEBUGGING) != 0
 			      && (h->elf_link_hash_flags
-				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))
+				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))
+		  || (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)
 		{
 		  (*_bfd_error_handler)
-		    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
+		    (_("%s: unresolvable relocation against symbol `%s' from %s section"),
 		     bfd_archive_filename (input_bfd), h->root.root.string,
 		     bfd_get_section_name (input_bfd, input_section));
-		  relocation = 0;
+		  return false;
 		}
 	      else
 		relocation = ((h->root.u.def.value
@@ -4779,7 +4990,6 @@
 
 	  if (h != NULL)
 	    {
-	      bfd_vma off;
 	      boolean dyn;
 
 	      off = h->got.offset;
@@ -4837,8 +5047,6 @@
 	    }
 	  else
 	    {
-	      bfd_vma off;
-
 #ifdef INCLUDE_SHMEDIA
 	      if (rel->r_addend)
 		{
@@ -4872,11 +5080,14 @@
 
 		  if (info->shared)
 		    {
-		      asection *srelgot;
 		      Elf_Internal_Rela outrel;
 
-		      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
-		      BFD_ASSERT (srelgot != NULL);
+		      if (srelgot == NULL)
+			{
+			  srelgot = bfd_get_section_by_name (dynobj,
+							     ".rela.got");
+			  BFD_ASSERT (srelgot != NULL);
+			}
 
 		      outrel.r_offset = (sgot->output_section->vma
 					 + sgot->output_offset
@@ -5010,6 +5221,450 @@
 				   rel->r_offset, sec, start, end);
 	    break;
 	  }
+
+	case R_SH_TLS_GD_32:
+	case R_SH_TLS_IE_32:
+	  r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
+	  tls_type = GOT_UNKNOWN;
+	  if (h == NULL && local_got_offsets)
+	    tls_type = sh_elf_local_got_tls_type (input_bfd) [r_symndx];
+	  else if (h != NULL)
+	    {
+	      tls_type = sh_elf_hash_entry (h)->tls_type;
+	      if (! info->shared
+		  && (h->dynindx == -1
+		      || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+		  && (tls_type == GOT_TLS_IE
+		      || sh_elf_hash_entry (h)->tls_tpoff32))
+		r_type = R_SH_TLS_LE_32;
+	    }
+
+	  if (r_type == R_SH_TLS_GD_32 && tls_type == GOT_TLS_IE)
+	    r_type = R_SH_TLS_IE_32;
+
+	  if (r_type == R_SH_TLS_LE_32)
+	    {
+	      bfd_vma offset;
+	      unsigned short insn;
+	      int indx;
+	      Elf_Internal_Rela outrel;
+
+	      if (ELF32_R_TYPE (rel->r_info) == R_SH_TLS_GD_32)
+		{
+		  /* GD->LE transition:
+		       mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+		       jsr @r1; add r12,r4; bra 3f; nop; .align 2; 
+		       1: .long x$TLSGD; 2: .long __tls_get_addr@PLT; 3:
+		     We change it into:
+		       mov.l 1f,r4; stc gbr,r0; add r4,r0; nop;
+		       nop; nop; ...
+		       1: .long x@TPOFF; 2: .long __tls_get_addr@PLT; 3:.  */
+
+		  offset = rel->r_offset;
+		  BFD_ASSERT (offset >= 16);
+		  /* Size of GD instructions is 16 or 18.  */
+		  offset -= 16;
+		  insn = bfd_get_16 (input_bfd, contents + offset + 0);
+		  if ((insn & 0xff00) == 0xc700)
+		    {
+		      BFD_ASSERT (offset >= 2);
+		      offset -= 2;
+		      insn = bfd_get_16 (input_bfd, contents + offset + 0);
+		    }
+
+		  BFD_ASSERT ((insn & 0xff00) == 0xd400);
+		  insn = bfd_get_16 (input_bfd, contents + offset + 2);
+		  BFD_ASSERT ((insn & 0xff00) == 0xc700);
+		  insn = bfd_get_16 (input_bfd, contents + offset + 4);
+		  BFD_ASSERT ((insn & 0xff00) == 0xd100);
+		  insn = bfd_get_16 (input_bfd, contents + offset + 6);
+		  BFD_ASSERT (insn == 0x310c);
+		  insn = bfd_get_16 (input_bfd, contents + offset + 8);
+		  BFD_ASSERT (insn == 0x410b);
+		  insn = bfd_get_16 (input_bfd, contents + offset + 10);
+		  BFD_ASSERT (insn == 0x34cc);
+
+		  bfd_put_16 (output_bfd, 0x0012, contents + offset + 2);
+		  bfd_put_16 (output_bfd, 0x304c, contents + offset + 4);
+		  bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
+		  bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+		  bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+		}
+	      else
+		{
+		  int index;
+
+		  /* IE->LE transition:
+		     mov.l 1f,r0; stc gbr,rN; mov.l @(r0,r12),rM;
+		     bra 2f; add ...; .align 2; 1: x@GOTTPOFF; 2:
+		     We change it into:
+		     mov.l .Ln,rM; stc gbr,rN; nop; ...;
+		     1: x@TPOFF; 2:.  */
+
+		  offset = rel->r_offset;
+		  BFD_ASSERT (offset >= 16);
+		  /* Size of IE instructions is 10 or 12.  */
+		  offset -= 10;
+		  insn = bfd_get_16 (input_bfd, contents + offset + 0);
+		  if ((insn & 0xf0ff) == 0x0012)
+		    {
+		      BFD_ASSERT (offset >= 2);
+		      offset -= 2;
+		      insn = bfd_get_16 (input_bfd, contents + offset + 0);
+		    }
+
+		  BFD_ASSERT ((insn & 0xff00) == 0xd000);
+		  index = insn & 0x00ff;
+		  insn = bfd_get_16 (input_bfd, contents + offset + 2);
+		  BFD_ASSERT ((insn & 0xf0ff) == 0x0012);
+		  insn = bfd_get_16 (input_bfd, contents + offset + 4);
+		  BFD_ASSERT ((insn & 0xf0ff) == 0x00ce);
+		  insn = 0xd000 | (insn & 0x0f00) | index;
+		  bfd_put_16 (output_bfd, insn, contents + offset + 0);
+		  bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
+		}
+
+	      if (sreloc == NULL)
+		{
+		  const char *name;
+
+		  name = (bfd_elf_string_from_elf_section
+			  (input_bfd,
+			   elf_elfheader (input_bfd)->e_shstrndx,
+			   elf_section_data (input_section)->rel_hdr.sh_name));
+		  if (name == NULL)
+		    return false;
+
+		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+			      && strcmp (bfd_get_section_name (input_bfd,
+							       input_section),
+					 name + 5) == 0);
+
+		  sreloc = bfd_get_section_by_name (dynobj, name);
+		  BFD_ASSERT (sreloc != NULL);
+		}
+
+	      indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+	      outrel.r_offset = (input_section->output_section->vma
+				 + input_section->output_offset
+				 + rel->r_offset);
+	      outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+	      if (indx == 0)
+		outrel.r_addend = relocation - dtpoff_base (info);
+	      else
+		outrel.r_addend = 0;
+	      bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+					 (((Elf32_External_Rela *)
+					   sreloc->contents)
+					  + sreloc->reloc_count));
+	      ++sreloc->reloc_count;
+
+	      continue;
+	    }
+
+	  sgot = htab->sgot;
+	  if (sgot == NULL)
+	    abort ();
+
+	  if (h != NULL)
+	    off = h->got.offset;
+	  else
+	    {
+	      if (local_got_offsets == NULL)
+		abort ();
+
+	      off = local_got_offsets[r_symndx];
+	    }
+
+	  if ((off & 1) != 0)
+	    off &= ~1;
+          else
+	    {
+	      Elf_Internal_Rela outrel;
+	      Elf32_External_Rela *loc;
+	      int dr_type, indx;
+
+	      if (srelgot == NULL)
+		{
+		  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+		  BFD_ASSERT (srelgot != NULL);
+		}
+
+	      outrel.r_offset = (sgot->output_section->vma
+				 + sgot->output_offset + off);
+
+	      indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+	      dr_type = (r_type == R_SH_TLS_GD_32 ? R_SH_TLS_DTPMOD32 :
+			 R_SH_TLS_TPOFF32);
+	      if (dr_type == R_SH_TLS_TPOFF32 && indx == 0)
+		outrel.r_addend = relocation - dtpoff_base (info);
+	      else
+		outrel.r_addend = 0;
+	      outrel.r_info = ELF32_R_INFO (indx, dr_type);
+	      loc = (Elf32_External_Rela *) srelgot->contents;
+	      loc += srelgot->reloc_count++;
+	      bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+	      if (r_type == R_SH_TLS_GD_32)
+		{
+		  if (indx == 0)
+		    {
+		      bfd_put_32 (output_bfd,
+				  relocation - dtpoff_base (info),
+				  sgot->contents + off + 4);
+		    }
+		  else
+		    {
+		      outrel.r_info = ELF32_R_INFO (indx,
+						    R_SH_TLS_DTPOFF32);
+		      outrel.r_offset += 4;
+		      outrel.r_addend = 0;
+		      srelgot->reloc_count++;
+		      loc++;
+		      bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+						loc);
+		    }
+		}
+
+	      if (h != NULL)
+		h->got.offset |= 1;
+	      else
+		local_got_offsets[r_symndx] |= 1;
+	    }
+
+	  if (off >= (bfd_vma) -2)
+	    abort ();
+
+	  if (r_type == (int) ELF32_R_TYPE (rel->r_info))
+	    relocation = sgot->output_offset + off;
+	  else
+	    {
+	      bfd_vma offset;
+	      unsigned short insn;
+
+	      /* GD->IE transition:
+		   mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+		   jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+		   1: .long x$TLSGD; 2: .long __tls_get_addr@PLT; 3:
+		 We change it into:
+		   mov.l 1f,r0; stc gbr,r4; mov.l @(r0,r12),r0; add r4,r0;
+		   nop; nop; bra 3f; nop; .align 2;
+		   1: .long x@TPOFF; 2:...; 3:.  */
+
+	      offset = rel->r_offset;
+	      BFD_ASSERT (offset >= 16);
+	      /* Size of GD instructions is 16 or 18.  */
+	      offset -= 16;
+	      insn = bfd_get_16 (input_bfd, contents + offset + 0);
+	      if ((insn & 0xff00) == 0xc700)
+		{
+		  BFD_ASSERT (offset >= 2);
+		  offset -= 2;
+		  insn = bfd_get_16 (input_bfd, contents + offset + 0);
+		}
+
+	      BFD_ASSERT ((insn & 0xff00) == 0xd400);
+
+	      /* Replace mov.l 1f,R4 with mov.l 1f,r0.  */
+	      bfd_put_16 (output_bfd, insn & 0xf0ff, contents + offset);
+
+	      insn = bfd_get_16 (input_bfd, contents + offset + 2);
+	      BFD_ASSERT ((insn & 0xff00) == 0xc700);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 4);
+	      BFD_ASSERT ((insn & 0xff00) == 0xd100);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 6);
+	      BFD_ASSERT (insn == 0x310c);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 8);
+	      BFD_ASSERT (insn == 0x410b);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 10);
+	      BFD_ASSERT (insn == 0x34cc);
+
+	      bfd_put_16 (output_bfd, 0x0412, contents + offset + 2);
+	      bfd_put_16 (output_bfd, 0x00ce, contents + offset + 4);
+	      bfd_put_16 (output_bfd, 0x304c, contents + offset + 6);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+
+	      bfd_put_32 (output_bfd, sgot->output_offset + off,
+			  contents + rel->r_offset);
+
+	      continue;
+	  }
+
+	  addend = rel->r_addend;
+
+	  goto final_link_relocate;
+
+	case R_SH_TLS_LD_32:
+	  if (! info->shared)
+	    {
+	      bfd_vma offset;
+	      unsigned short insn;
+
+	      /* LD->LE transition:
+		   mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+		   jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+		   1: .long x$TLSLD; 2: .long __tls_get_addr@PLT; 3:
+		 We change it into:
+		   stc gbr,r0; nop; nop; nop;
+		   nop; nop; bra 3f; ...; 3:.  */
+
+	      offset = rel->r_offset;
+	      BFD_ASSERT (offset >= 16);
+	      /* Size of LD instructions is 16 or 18.  */
+	      offset -= 16;
+	      insn = bfd_get_16 (input_bfd, contents + offset + 0);
+	      if ((insn & 0xff00) == 0xc700)
+		{
+		  BFD_ASSERT (offset >= 2);
+		  offset -= 2;
+		  insn = bfd_get_16 (input_bfd, contents + offset + 0);
+		}
+
+	      BFD_ASSERT ((insn & 0xff00) == 0xd400);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 2);
+	      BFD_ASSERT ((insn & 0xff00) == 0xc700);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 4);
+	      BFD_ASSERT ((insn & 0xff00) == 0xd100);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 6);
+	      BFD_ASSERT (insn == 0x310c);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 8);
+	      BFD_ASSERT (insn == 0x410b);
+	      insn = bfd_get_16 (input_bfd, contents + offset + 10);
+	      BFD_ASSERT (insn == 0x34cc);
+
+	      bfd_put_16 (output_bfd, 0x0012, contents + offset + 0);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 2);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+	      bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+
+	      continue;
+	    }
+
+	  sgot = htab->sgot;
+	  if (sgot == NULL)
+	    abort ();
+
+	  off = htab->tls_ldm_got.offset;
+	  if (off & 1)
+	    off &= ~1;
+	  else
+	    {
+	      Elf_Internal_Rela outrel;
+	      Elf32_External_Rela *loc;
+
+	      srelgot = htab->srelgot;
+	      if (srelgot == NULL)
+		abort ();
+
+	      outrel.r_offset = (sgot->output_section->vma
+				 + sgot->output_offset + off);
+	      outrel.r_addend = 0;
+	      outrel.r_info = ELF32_R_INFO (0, R_SH_TLS_DTPMOD32);
+	      loc = (Elf32_External_Rela *) srelgot->contents;
+	      loc += srelgot->reloc_count++;
+	      bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+	      htab->tls_ldm_got.offset |= 1;
+	    }
+
+	  relocation = sgot->output_offset + off;
+	  addend = rel->r_addend;
+
+	  goto final_link_relocate;
+
+	case R_SH_TLS_LDO_32:
+	  if (! info->shared)
+	    {
+	      int indx;
+	      Elf_Internal_Rela outrel;
+
+	      if (sreloc == NULL)
+		{
+		  const char *name;
+
+		  name = (bfd_elf_string_from_elf_section
+			  (input_bfd,
+			   elf_elfheader (input_bfd)->e_shstrndx,
+			   elf_section_data (input_section)->rel_hdr.sh_name));
+		  if (name == NULL)
+		    return false;
+
+		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+			      && strcmp (bfd_get_section_name (input_bfd,
+							       input_section),
+					 name + 5) == 0);
+
+		  sreloc = bfd_get_section_by_name (dynobj, name);
+		  BFD_ASSERT (sreloc != NULL);
+		}
+
+	      indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+	      outrel.r_offset = (input_section->output_section->vma
+				 + input_section->output_offset
+				 + rel->r_offset);
+	      outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+	      if (indx == 0)
+		outrel.r_addend = relocation - dtpoff_base (info);
+	      else
+		outrel.r_addend = 0;
+	      bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+					 (((Elf32_External_Rela *)
+					   sreloc->contents)
+					  + sreloc->reloc_count));
+	      ++sreloc->reloc_count;
+
+	      continue;
+	    }
+	  else
+	    relocation -= dtpoff_base (info);
+
+	  addend = rel->r_addend;
+	  goto final_link_relocate;
+
+	case R_SH_TLS_LE_32:
+	  {
+	    int indx;
+	    Elf_Internal_Rela outrel;
+
+	    if (sreloc == NULL)
+	      {
+		const char *name;
+
+		name = (bfd_elf_string_from_elf_section
+			(input_bfd,
+			 elf_elfheader (input_bfd)->e_shstrndx,
+			 elf_section_data (input_section)->rel_hdr.sh_name));
+		if (name == NULL)
+		  return false;
+
+		BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+			    && strcmp (bfd_get_section_name (input_bfd,
+							     input_section),
+				       name + 5) == 0);
+
+		sreloc = bfd_get_section_by_name (dynobj, name);
+		BFD_ASSERT (sreloc != NULL);
+	      }
+
+	    indx = (h && h->dynindx != -1) ? h->dynindx : 0;
+	    outrel.r_offset = (input_section->output_section->vma
+			       + input_section->output_offset
+			       + rel->r_offset);
+	    outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+	    if (indx == 0)
+	      outrel.r_addend = relocation - dtpoff_base (info);
+	    else
+	      outrel.r_addend = 0;
+	    bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+				       (((Elf32_External_Rela *)
+					 sreloc->contents)
+					+ sreloc->reloc_count));
+	    ++sreloc->reloc_count;
+
+	    continue;
+	  }
 	}
 
     relocation_done:
@@ -5157,6 +5812,20 @@
   return NULL;
 }
 
+/* Return the base VMA address which should be subtracted from real addresses
+   when resolving @dtpoff relocation.
+   This is PT_TLS segment p_vaddr.  */
+
+static bfd_vma
+dtpoff_base (info)
+     struct bfd_link_info *info;
+{
+ /* If tls_segment is NULL, we should have signalled an error already.  */
+ if (elf_hash_table (info)->tls_segment == NULL)
+   return 0;
+  return elf_hash_table (info)->tls_segment->start;
+}
+
 static asection *
 sh_elf_gc_mark_hook (sec, info, rel, h, sym)
      asection *sec;
@@ -5224,8 +5893,15 @@
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
-    switch (ELF32_R_TYPE (rel->r_info))
+    switch (sh_elf_optimized_tls_reloc (info, ELF32_R_TYPE (rel->r_info),
+				   ELF32_R_SYM (rel->r_info)
+				   >= symtab_hdr->sh_info))
       {
+      case R_SH_TLS_LD_32:
+	if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
+	  sh_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
+	break;
+
       case R_SH_GOT32:
       case R_SH_GOTOFF:
       case R_SH_GOTPC:
@@ -5245,6 +5921,8 @@
       case R_SH_GOTPC_MEDHI16:
       case R_SH_GOTPC_HI16:
 #endif
+      case R_SH_TLS_GD_32:
+      case R_SH_TLS_IE_32:
 	r_symndx = ELF32_R_SYM (rel->r_info);
 	if (r_symndx >= symtab_hdr->sh_info)
 	  {
@@ -5388,9 +6066,39 @@
   edir->gotplt_refcount = eind->gotplt_refcount;
   eind->gotplt_refcount = 0;
 
+  if (ind->root.type == bfd_link_hash_indirect
+      && dir->got.refcount <= 0)
+    {
+      edir->tls_type = eind->tls_type;
+      eind->tls_type = GOT_UNKNOWN;
+    }
+
   _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 
+static int
+sh_elf_optimized_tls_reloc (info, r_type, is_local)
+     struct bfd_link_info *info;
+     int r_type;
+     int is_local;
+{
+  if (info->shared)
+    return r_type;
+
+  switch (r_type)
+    {
+    case R_SH_TLS_GD_32:
+    case R_SH_TLS_IE_32:
+      if (is_local)
+	return R_SH_TLS_LE_32;
+      return R_SH_TLS_IE_32;
+    case R_SH_TLS_LD_32:
+      return R_SH_TLS_LE_32;
+    }
+
+  return r_type;
+}
+
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.  */
@@ -5412,6 +6120,8 @@
   asection *sgot;
   asection *srelgot;
   asection *sreloc;
+  unsigned int r_type;
+  int tls_type, old_tls_type;
 
   sgot = NULL;
   srelgot = NULL;
@@ -5437,15 +6147,27 @@
       unsigned long r_symndx;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
+      r_type = ELF32_R_TYPE (rel->r_info);
+
       if (r_symndx < symtab_hdr->sh_info)
 	h = NULL;
       else
 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
+      r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
+      if (! info->shared
+	  && r_type == R_SH_TLS_IE_32
+	  && h != NULL
+	  && h->root.type != bfd_link_hash_undefined
+	  && h->root.type != bfd_link_hash_undefweak
+	  && (h->dynindx == -1
+	      || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+	r_type = R_SH_TLS_LE_32;
+
       /* Some relocs require a global offset table.  */
       if (htab->sgot == NULL)
 	{
-	  switch (ELF32_R_TYPE (rel->r_info))
+	  switch (r_type)
 	    {
 	    case R_SH_GOTPLT32:
 	    case R_SH_GOT32:
@@ -5473,6 +6195,9 @@
 	    case R_SH_GOTPC_MEDHI16:
 	    case R_SH_GOTPC_HI16:
 #endif
+	    case R_SH_TLS_GD_32:
+	    case R_SH_TLS_LD_32:
+	    case R_SH_TLS_IE_32:
 	      if (dynobj == NULL)
 		htab->root.dynobj = dynobj = abfd;
 	      if (! create_got_section (dynobj, info))
@@ -5484,7 +6209,7 @@
 	    }
 	}
 
-      switch (ELF32_R_TYPE (rel->r_info))
+      switch (r_type)
 	{
 	  /* This relocation describes the C++ object vtable hierarchy.
 	     Reconstruct it for later use during GC.  */
@@ -5501,6 +6226,12 @@
 	  break;
 
 	force_got:
+	case R_SH_TLS_IE_32:
+	  if (info->shared)
+	    info->flags |= DF_STATIC_TLS;
+
+	  /* FALLTHROUGH */
+	case R_SH_TLS_GD_32:
 	case R_SH_GOT32:
 #ifdef INCLUDE_SHMEDIA
 	case R_SH_GOT_LOW16:
@@ -5510,8 +6241,24 @@
 	case R_SH_GOT10BY4:
 	case R_SH_GOT10BY8:
 #endif
+	  switch (r_type)
+	    {
+	    default:
+	      tls_type = GOT_NORMAL;
+	      break;
+	    case R_SH_TLS_GD_32:
+	      tls_type = GOT_TLS_GD;
+	      break;
+	    case R_SH_TLS_IE_32:
+	      tls_type = GOT_TLS_IE;
+	      break;
+	    }
+
 	  if (h != NULL)
-	    h->got.refcount += 1;
+	    {
+	      h->got.refcount += 1;
+	      old_tls_type = sh_elf_hash_entry (h)->tls_type;
+	    }
 	  else
 	    {
 	      bfd_signed_vma *local_got_refcounts;
@@ -5530,14 +6277,54 @@
 		     codelabel local GOT offsets.  */
 		  size *= 2;
 #endif
+		  size += symtab_hdr->sh_info;
 		  local_got_refcounts = ((bfd_signed_vma *)
 					 bfd_zalloc (abfd, size));
 		  if (local_got_refcounts == NULL)
 		    return false;
 		  elf_local_got_refcounts (abfd) = local_got_refcounts;
+#ifdef 	INCLUDE_SHMEDIA
+		  /* Take care of both the datalabel and codelabel local
+		     GOT offsets.  */
+		  sh_elf_local_got_tls_type (abfd)
+		    = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
+#else
+		  sh_elf_local_got_tls_type (abfd)
+		    = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+#endif
 		}
 	      local_got_refcounts[r_symndx] += 1;
+	      old_tls_type = sh_elf_local_got_tls_type (abfd) [r_symndx];
 	    }
+
+	  /* If a TLS symbol is accessed using IE at least once,
+	     there is no point to use dynamic model for it.  */
+	  if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+	      && (old_tls_type != GOT_TLS_GD || tls_type != GOT_TLS_IE))
+	    {
+	      if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+		tls_type = GOT_TLS_IE;
+	      else
+		{
+		  (*_bfd_error_handler)
+		    (_("%s: `%s' accessed both as normal and thread local symbol"),
+		     bfd_archive_filename (abfd), h->root.root.string);
+		  return false;
+		}
+	    }
+
+	  if (old_tls_type != tls_type)
+	    {
+	      if (h != NULL)
+		sh_elf_hash_entry (h)->tls_type = tls_type;
+	      else
+		sh_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
+	    }
+
+	  break;
+
+	case R_SH_TLS_LD_32:
+	  sh_elf_hash_table(info)->tls_ldm_got.refcount += 1;
 	  break;
 
 	case R_SH_GOTPLT32:
@@ -5620,7 +6407,7 @@
 	     symbol.  */
 	  if ((info->shared
 	       && (sec->flags & SEC_ALLOC) != 0
-	       && (ELF32_R_TYPE (rel->r_info) != R_SH_REL32
+	       && (r_type != R_SH_REL32
 		   || (h != NULL
 		       && (! info->symbolic
 			   || h->root.type == bfd_link_hash_defweak
@@ -5710,11 +6497,110 @@
 		}
 
 	      p->count += 1;
-	      if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32)
+	      if (r_type == R_SH_REL32)
 		p->pc_count += 1;
 	    }
 
 	  break;
+
+	case R_SH_TLS_LE_32:
+	  if (info->shared)
+	    {
+	      (*_bfd_error_handler) (_("%s: TLS local exec code cannot be linked into shared objects"),
+				     bfd_archive_filename (abfd));
+	      return false;
+	    }
+
+	  if (ELF32_R_TYPE (rel->r_info) == R_SH_TLS_LD_32)
+	    break;
+
+	  /* FALLTHROUGH */
+	case R_SH_TLS_LDO_32:
+	  /* We make a R_SH_TLS_TPOFF32 relocation. Count it as a
+	     copy relocation.  */
+	  if (! info->shared)
+	    {
+	      struct elf_sh_dyn_relocs *p;
+	      struct elf_sh_dyn_relocs **head;
+
+	      if (dynobj == NULL)
+		htab->root.dynobj = dynobj = abfd;
+
+	      if (sreloc == NULL)
+		{
+		  const char *name;
+
+		  name = (bfd_elf_string_from_elf_section
+			  (abfd,
+			   elf_elfheader (abfd)->e_shstrndx,
+			   elf_section_data (sec)->rel_hdr.sh_name));
+		  if (name == NULL)
+		    return false;
+
+		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+			      && strcmp (bfd_get_section_name (abfd, sec),
+					 name + 5) == 0);
+
+		  sreloc = bfd_get_section_by_name (dynobj, name);
+		  if (sreloc == NULL)
+		    {
+		      flagword flags;
+
+		      sreloc = bfd_make_section (dynobj, name);
+		      flags = (SEC_HAS_CONTENTS | SEC_READONLY
+			       | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+		      if ((sec->flags & SEC_ALLOC) != 0)
+			flags |= SEC_ALLOC | SEC_LOAD;
+		      if (sreloc == NULL
+			  || ! bfd_set_section_flags (dynobj, sreloc, flags)
+			  || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+			return false;
+		    }
+		  elf_section_data (sec)->sreloc = sreloc;
+		  if (sec->flags & SEC_READONLY)
+		    info->flags |= DF_TEXTREL;
+		}
+
+	      /* If this is a global symbol, we count the number of
+		 relocations we need for this symbol.  */
+	      if (h != NULL)
+		head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs;
+	      else
+		{
+		  asection *s;
+
+		  /* Track dynamic relocs needed for local syms too.  */
+		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
+						 sec, r_symndx);
+		  if (s == NULL)
+		    return false;
+
+		  head = ((struct elf_sh_dyn_relocs **)
+			  &elf_section_data (s)->local_dynrel);
+		}
+
+	      p = *head;
+	      if (p == NULL || p->sec != sec)
+		{
+		  bfd_size_type amt = sizeof (*p);
+		  p = ((struct elf_sh_dyn_relocs *) bfd_alloc (dynobj, amt));
+		  if (p == NULL)
+		    return false;
+		  p->next = *head;
+		  *head = p;
+		  p->sec = sec;
+		  p->count = 0;
+		  p->pc_count = 0;
+		}
+
+	      p->count += 1;
+	      if (h)
+		sh_elf_hash_entry (h)->tls_tpoff32 = true;
+	    }
+	  break;
+
+	default:
+	  break;
 	}
     }
 
@@ -5835,6 +6721,29 @@
 }
 #endif /* not sh_elf_merge_private_data */
 
+/* Override the generic function because we need to store sh_elf_obj_tdata
+   as the specific tdata.  We set also the machine architecture from flags
+   here.  */
+
+static boolean
+sh_elf_object_p (abfd)
+  bfd *abfd;
+{
+  struct sh_elf_obj_tdata *new_tdata;
+  bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
+
+  if (sh_elf_set_mach_from_flags (abfd) == false)
+    return false;
+
+  /* Allocate our special target data.  */
+  new_tdata = bfd_zalloc (abfd, amt);
+  if (new_tdata == NULL)
+    return false;
+  new_tdata->root = *abfd->tdata.elf_obj_data;
+  abfd->tdata.any = new_tdata;
+  return true;
+}
+
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
 
@@ -5991,7 +6900,9 @@
 	}
     }
 
-  if (h->got.offset != (bfd_vma) -1)
+  if (h->got.offset != (bfd_vma) -1
+      && sh_elf_hash_entry (h)->tls_type != GOT_TLS_GD
+      && sh_elf_hash_entry (h)->tls_type != GOT_TLS_IE)
     {
       asection *sgot;
       asection *srel;
@@ -6280,7 +7191,8 @@
 #define elf_backend_relocate_section	sh_elf_relocate_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
 					sh_elf_get_relocated_section_contents
-#define elf_backend_object_p		sh_elf_set_mach_from_flags
+#define bfd_elf32_mkobject		sh_elf_mkobject
+#define elf_backend_object_p		sh_elf_object_p
 #define bfd_elf32_bfd_set_private_bfd_flags \
 					sh_elf_set_private_flags
 #define bfd_elf32_bfd_copy_private_bfd_data \
diff --git a/bfd/elf32-sh64-lin.c b/bfd/elf32-sh64-lin.c
new file mode 100644
index 0000000..bb8e45b
--- /dev/null
+++ b/bfd/elf32-sh64-lin.c
@@ -0,0 +1,29 @@
+/* Hitachi SH specific support for 64-bit Linux
+   Copyright 2000 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define TARGET_BIG_SYM bfd_elf32_sh64blin_vec
+#define TARGET_BIG_NAME "elf32-sh64big-linux"
+#define TARGET_LITTLE_SYM bfd_elf32_sh64lin_vec
+#define TARGET_LITTLE_NAME "elf32-sh64-linux"
+#define ELF_ARCH bfd_arch_sh
+#define ELF_MACHINE_CODE EM_SH
+#define ELF_MAXPAGESIZE 0x10000
+#define elf_symbol_leading_char 0
+
+#include "elf32-sh64.c"
diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c
index 7a38fb22..844a6a4 100644
--- a/bfd/elf32-sh64.c
+++ b/bfd/elf32-sh64.c
@@ -411,16 +411,19 @@
       if (h == NULL)
 	{
 	  /* No previous datalabel symbol.  Make one.  */
+	  struct bfd_link_hash_entry *bh = NULL;
+	  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
 	  if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
 						  flags, *secp, *valp,
 						  *namep, false,
-						  get_elf_backend_data (abfd)->collect,
-						  (struct bfd_link_hash_entry **) &h))
+						  bed->collect, &bh))
 	    {
 	      free (dl_name);
 	      return false;
 	    }
 
+	  h = (struct elf_link_hash_entry *) bh;
 	  h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
 	  h->type = STT_DATALABEL;
 	}
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index e1d095d..5973017 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -2480,6 +2480,7 @@
 {
   asection *s;
   struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *bh;
 
   /* We need to create .plt, .rela.plt, .got, and .rela.got sections.  */
 
@@ -2495,13 +2496,13 @@
 
   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
      .plt section.  */
-  h = NULL;
+  bh = NULL;
   if (! (_bfd_generic_link_add_one_symbol
 	 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
 	  (bfd_vma) 0, (const char *) NULL, false,
-	  get_elf_backend_data (abfd)->collect,
-	  (struct bfd_link_hash_entry **) &h)))
+	  get_elf_backend_data (abfd)->collect, &bh)))
     return false;
+  h = (struct elf_link_hash_entry *) bh;
   h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
   h->type = STT_OBJECT;
 
@@ -2539,13 +2540,13 @@
      dynobj's .got section.  We don't do this in the linker script
      because we don't want to define the symbol if we are not creating
      a global offset table.  */
-  h = NULL;
+  bh = NULL;
   if (!(_bfd_generic_link_add_one_symbol
 	(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL,
 	 alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL,
-	 false, get_elf_backend_data (abfd)->collect,
-	 (struct bfd_link_hash_entry **) &h)))
+	 false, get_elf_backend_data (abfd)->collect, &bh)))
     return false;
+  h = (struct elf_link_hash_entry *) bh;
   h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
   h->type = STT_OBJECT;
 
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 91610aa..da7c53f 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -3166,6 +3166,7 @@
 	{
 	  bfd *abfd;
 	  asymbol *newsym;
+	  struct bfd_link_hash_entry *bh;
 
 	  abfd = h->root.u.undef.abfd;
 	  newsym = bfd_make_empty_symbol (abfd);
@@ -3176,13 +3177,14 @@
 	  if (h->root.type == bfd_link_hash_undefweak)
 	    newsym->flags |= BSF_WEAK;
 
+	  bh = &fdh->root;
 	  if ( !(_bfd_generic_link_add_one_symbol
 		 (info, abfd, newsym->name, newsym->flags,
-		  newsym->section, newsym->value, NULL, false, false,
-		  (struct bfd_link_hash_entry **) &fdh)))
+		  newsym->section, newsym->value, NULL, false, false, &bh)))
 	    {
 	      return false;
 	    }
+	  fdh = (struct elf_link_hash_entry *) bh;
 	  fdh->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
 	}
 
@@ -3675,12 +3677,16 @@
 	      break;
 	    }
 
-	  if (sym_sec->output_section == bfd_abs_section_ptr)
-	    {
-	      /* OK, we've found a function that's excluded from the
-		 link.  */
-	      need_edit = true;
-	    }
+	  /* opd entries are always for functions defined in the
+	     current input bfd.  If the symbol isn't defined in the
+	     input bfd, then we won't be using the function in this
+	     bfd;  It must be defined in a linkonce section in another
+	     bfd, or is weak.  It's also possible that we are
+	     discarding the function due to a linker script /DISCARD/,
+	     which we test for via the output_section.  */
+	  if (sym_sec->owner != ibfd
+	      || sym_sec->output_section == bfd_abs_section_ptr)
+	    need_edit = true;
 
 	  offset += 24;
 	}
@@ -3754,10 +3760,11 @@
 							      sym->st_shndx);
 		    }
 
-		  skip = sym_sec->output_section == bfd_abs_section_ptr;
+		  skip = (sym_sec->owner != ibfd
+			  || sym_sec->output_section == bfd_abs_section_ptr);
 		  if (skip)
 		    {
-		      if (h != NULL)
+		      if (h != NULL && sym_sec->owner == ibfd)
 			{
 			  /* Arrange for the function descriptor sym
 			     to be dropped.  */
@@ -3797,8 +3804,7 @@
 			     for the function descriptor sym which we
 			     don't have at the moment.  So keep an
 			     array of adjustments.  */ 
-			  adjust[(rel->r_offset + wptr - rptr) / 24]
-			    = wptr - rptr;
+			  adjust[rel->r_offset / 24] = wptr - rptr;
 			}
 
 		      if (wptr != rptr)
@@ -5161,6 +5167,7 @@
 	    }
 	  bfd_put_32 (htab->sglink->owner,
 		      B_DOT | ((htab->sglink->contents - p) & 0x3fffffc), p);
+	  indx++;
 	  p += 4;
 	}
       htab->sglink->_cooked_size = p - htab->sglink->contents;
diff --git a/bfd/elf64-sh64-lin.c b/bfd/elf64-sh64-lin.c
new file mode 100644
index 0000000..772417b
--- /dev/null
+++ b/bfd/elf64-sh64-lin.c
@@ -0,0 +1,29 @@
+/* Hitachi SH specific support for 64-bit Linux
+   Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define TARGET_BIG_SYM bfd_elf64_sh64blin_vec
+#define TARGET_BIG_NAME "elf64-sh64big-linux"
+#define TARGET_LITTLE_SYM bfd_elf64_sh64lin_vec
+#define TARGET_LITTLE_NAME "elf64-sh64-linux"
+#define ELF_ARCH bfd_arch_sh
+#define ELF_MACHINE_CODE EM_SH
+#define ELF_MAXPAGESIZE 0x10000
+#define elf_symbol_leading_char 0
+
+#include "elf64-sh64.c"
diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c
index 4fb695f..67a04ad 100644
--- a/bfd/elf64-sh64.c
+++ b/bfd/elf64-sh64.c
@@ -2915,16 +2915,19 @@
       if (h == NULL)
 	{
 	  /* No previous datalabel symbol.  Make one.  */
+	  struct bfd_link_hash_entry *bh = NULL;
+	  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
 	  if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
 						  flags, *secp, *valp,
 						  *namep, false,
-						  get_elf_backend_data (abfd)->collect,
-						  (struct bfd_link_hash_entry **) &h))
+						  bed->collect, &bh))
 	    {
 	      free (dl_name);
 	      return false;
 	    }
 
+	  h = (struct elf_link_hash_entry *) bh;
 	  h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
 	  h->type = STT_DATALABEL;
 	}
@@ -3108,7 +3111,7 @@
   0x6f, 0xf0, 0xff, 0xf0, /* nop */
   0x6f, 0xf0, 0xff, 0xf0, /* nop */
   0xce, 0x00, 0x01, 0x10, /* movi  -GOT_BIAS, r17 */
-  0x00, 0xcb, 0x45, 0x10, /* sub   r12, r17, r17 */
+  0x00, 0xc9, 0x45, 0x10, /* add   r12, r17, r17 */
   0x8d, 0x10, 0x09, 0x90, /* ld.q  r17, 16, r25 */
   0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
   0x8d, 0x10, 0x05, 0x10, /* ld.q  r17, 8, r17 */
@@ -3128,7 +3131,7 @@
   0xf0, 0xff, 0xf0, 0x6f, /* nop */
   0xf0, 0xff, 0xf0, 0x6f, /* nop */
   0x10, 0x01, 0x00, 0xce, /* movi  -GOT_BIAS, r17 */
-  0x10, 0x45, 0xcb, 0x00, /* sub   r12, r17, r17 */
+  0x10, 0x45, 0xc9, 0x00, /* add   r12, r17, r17 */
   0x90, 0x09, 0x10, 0x8d, /* ld.q  r17, 16, r25 */
   0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
   0x10, 0x05, 0x10, 0x8d, /* ld.q  r17, 8, r17 */
@@ -3287,13 +3290,15 @@
     {
       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
 	 .plt section.  */
-      struct elf_link_hash_entry *h = NULL;
+      struct elf_link_hash_entry *h;
+      struct bfd_link_hash_entry *bh = NULL;
+
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
-	      (bfd_vma) 0, (const char *) NULL, false,
-	      get_elf_backend_data (abfd)->collect,
-	      (struct bfd_link_hash_entry **) &h)))
+	      (bfd_vma) 0, (const char *) NULL, false, bed->collect, &bh)))
 	return false;
+
+      h = (struct elf_link_hash_entry *) bh;
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_OBJECT;
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f8cc645..d6da588 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -33,6 +33,7 @@
   flagword flags;
   register asection *s;
   struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *bh;
   struct elf_backend_data *bed = get_elf_backend_data (abfd);
   int ptralign;
 
@@ -79,12 +80,13 @@
 	 (or .got.plt) section.  We don't do this in the linker script
 	 because we don't want to define the symbol if we are not creating
 	 a global offset table.  */
-      h = NULL;
+      bh = NULL;
       if (!(_bfd_generic_link_add_one_symbol
 	    (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
 	     bed->got_symbol_offset, (const char *) NULL, false,
-	     bed->collect, (struct bfd_link_hash_entry **) &h)))
+	     bed->collect, &bh)))
 	return false;
+      h = (struct elf_link_hash_entry *) bh;
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_OBJECT;
 
@@ -151,13 +153,15 @@
     {
       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
 	 .plt section.  */
-      struct elf_link_hash_entry *h = NULL;
+      struct elf_link_hash_entry *h;
+      struct bfd_link_hash_entry *bh = NULL;
+
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
 	      (bfd_vma) 0, (const char *) NULL, false,
-	      get_elf_backend_data (abfd)->collect,
-	      (struct bfd_link_hash_entry **) &h)))
+	      get_elf_backend_data (abfd)->collect, &bh)))
 	return false;
+      h = (struct elf_link_hash_entry *) bh;
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_OBJECT;
 
@@ -546,29 +550,27 @@
 
       if (lsect->sym_name)
 	{
-	  struct elf_link_hash_entry *h = NULL;
+	  struct elf_link_hash_entry *h;
+	  struct bfd_link_hash_entry *bh;
+
 #ifdef DEBUG
 	  fprintf (stderr, "Adding %s to section %s\n",
 		   lsect->sym_name,
 		   lsect->name);
 #endif
-	  h = (struct elf_link_hash_entry *)
-	    bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);
+	  bh = bfd_link_hash_lookup (info->hash, lsect->sym_name,
+				     false, false, false);
 
-	  if ((h == NULL || h->root.type == bfd_link_hash_undefined)
-	      && !(_bfd_generic_link_add_one_symbol (info,
-						     abfd,
-						     lsect->sym_name,
-						     BSF_GLOBAL,
-						     s,
-						     ((lsect->hole_size)
-						      ? s->_raw_size - lsect->hole_size + lsect->sym_offset
-						      : lsect->sym_offset),
-						     (const char *) NULL,
-						     false,
-						     get_elf_backend_data (abfd)->collect,
-						     (struct bfd_link_hash_entry **) &h)))
-	    return (elf_linker_section_t *)0;
+	  if ((bh == NULL || bh->type == bfd_link_hash_undefined)
+	      && !(_bfd_generic_link_add_one_symbol
+		   (info, abfd, lsect->sym_name, BSF_GLOBAL, s,
+		    (lsect->hole_size
+		     ? s->_raw_size - lsect->hole_size + lsect->sym_offset
+		     : lsect->sym_offset),
+		    (const char *) NULL, false,
+		    get_elf_backend_data (abfd)->collect, &bh)))
+	    return (elf_linker_section_t *) 0;
+	  h = (struct elf_link_hash_entry *) bh;
 
 	  if ((defaults->which != LINKER_SECTION_SDATA)
 	      && (defaults->which != LINKER_SECTION_SDATA2))
@@ -579,7 +581,7 @@
 
 	  if (info->shared
 	      && ! _bfd_elf_link_record_dynamic_symbol (info, h))
-	    return (elf_linker_section_t *)0;
+	    return (elf_linker_section_t *) 0;
 	}
     }
 
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 85160e9..23ea241 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -921,6 +921,7 @@
   boolean size_change_ok;
   char *shortname;
   struct elf_link_hash_entry *hi;
+  struct bfd_link_hash_entry *bh;
   struct elf_backend_data *bed;
   boolean collect;
   boolean dynamic;
@@ -979,11 +980,12 @@
 
   if (! override)
     {
+      bh = &hi->root;
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr,
-	      (bfd_vma) 0, name, false, collect,
-	      (struct bfd_link_hash_entry **) &hi)))
+	      (bfd_vma) 0, name, false, collect, &bh)))
 	return false;
+      hi = (struct elf_link_hash_entry *) bh;
     }
   else
     {
@@ -1098,11 +1100,12 @@
     }
   else
     {
+      bh = &hi->root;
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, shortname, BSF_INDIRECT,
-	      bfd_ind_section_ptr, (bfd_vma) 0, name, false,
-	      collect, (struct bfd_link_hash_entry **) &hi)))
+	      bfd_ind_section_ptr, (bfd_vma) 0, name, false, collect, &bh)))
 	return false;
+      hi = (struct elf_link_hash_entry *) bh;
 
       /* If there is a duplicate definition somewhere, then HI may not
 	 point to an indirect symbol.  We will have reported an error
@@ -2292,6 +2295,7 @@
   flagword flags;
   register asection *s;
   struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *bh;
   struct elf_backend_data *bed;
 
   if (! is_elf_hash_table (info))
@@ -2384,12 +2388,12 @@
      creating a .dynamic section.  We don't want to define it if there
      is no .dynamic section, since on some ELF platforms the start up
      code examines it to decide how to initialize the process.  */
-  h = NULL;
+  bh = NULL;
   if (! (_bfd_generic_link_add_one_symbol
 	 (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, (bfd_vma) 0,
-	  (const char *) NULL, false, get_elf_backend_data (abfd)->collect,
-	  (struct bfd_link_hash_entry **) &h)))
+	  (const char *) 0, false, get_elf_backend_data (abfd)->collect, &bh)))
     return false;
+  h = (struct elf_link_hash_entry *) bh;
   h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
   h->type = STT_OBJECT;
 
@@ -3326,19 +3330,20 @@
 	      unsigned int cdeps;
 	      struct bfd_elf_version_deps *n;
 	      struct elf_link_hash_entry *h;
+	      struct bfd_link_hash_entry *bh;
 
 	      cdeps = 0;
 	      for (n = t->deps; n != NULL; n = n->next)
 		++cdeps;
 
 	      /* Add a symbol representing this version.  */
-	      h = NULL;
+	      bh = NULL;
 	      if (! (_bfd_generic_link_add_one_symbol
 		     (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
 		      (bfd_vma) 0, (const char *) NULL, false,
-		      get_elf_backend_data (dynobj)->collect,
-		      (struct bfd_link_hash_entry **) &h)))
+		      get_elf_backend_data (dynobj)->collect, &bh)))
 		return false;
+	      h = (struct elf_link_hash_entry *) bh;
 	      h->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
 	      h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
 	      h->type = STT_OBJECT;
@@ -6815,20 +6820,12 @@
 			   || h->root.type == bfd_link_hash_defweak)
 			  && elf_discarded_section (h->root.u.def.section))
 			{
-#if BFD_VERSION_DATE < 20031005
 			  if ((o->flags & SEC_DEBUGGING) != 0)
 			    {
-#if BFD_VERSION_DATE > 20021005
-			      (*finfo->info->callbacks->warning)
-				(finfo->info,
-				 _("warning: relocation against removed section; zeroing"),
-				 NULL, input_bfd, o, rel->r_offset);
-#endif
 			      BFD_ASSERT (r_symndx != 0);
 			      memset (rel, 0, sizeof (*rel));
 			    }
 			  else
-#endif
 			    {
 			      if (! ((*finfo->info->callbacks->undefined_symbol)
 				     (finfo->info, h->root.root.string,
@@ -6844,23 +6841,15 @@
 
 		      if (sec != NULL && elf_discarded_section (sec))
 			{
-#if BFD_VERSION_DATE < 20031005
 			  if ((o->flags & SEC_DEBUGGING) != 0
 			      || (sec->flags & SEC_LINK_ONCE) != 0)
 			    {
-#if BFD_VERSION_DATE > 20021005
-			      (*finfo->info->callbacks->warning)
-				(finfo->info,
-				 _("warning: relocation against removed section"),
-				 NULL, input_bfd, o, rel->r_offset);
-#endif
 			      BFD_ASSERT (r_symndx != 0);
 			      rel->r_info
 				= ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
 			      rel->r_addend = 0;
 			    }
 			  else
-#endif
 			    {
 			      boolean ok;
 			      const char *msg
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
index 2a29347..5da8e43 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -647,13 +647,14 @@
    not support brl, and so it gets emulated by the kernel.  */
 #undef USE_BRL
 
+#ifdef USE_BRL
 static const bfd_byte oor_brl[16] =
 {
   0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
   0x00, 0x00, 0x00, 0xc0
 };
-
+#else
 static const bfd_byte oor_ip[48] =
 {
   0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
@@ -666,6 +667,7 @@
   0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
   0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
 };
+#endif
 
 /* These functions do relaxation for IA-64 ELF.
 
@@ -1282,6 +1284,7 @@
 	{
 	  struct elf_backend_data *bed;
 	  struct elfNN_ia64_link_hash_table *ia64_info;
+	  struct bfd_link_hash_entry *bh = NULL;
 
 	  bed = get_elf_backend_data (abfd);
 	  ia64_info = elfNN_ia64_hash_table (info);
@@ -1290,9 +1293,10 @@
 		(info, abfd, *namep, BSF_GLOBAL,
 		 bfd_get_section_by_name (abfd, ".bss"),
 		 bed->got_symbol_offset, (const char *) NULL, false,
-		 bed->collect, (struct bfd_link_hash_entry **) &h)))
+		 bed->collect, &bh)))
 	    return false;
 
+	  h = (struct elf_link_hash_entry *) bh;
 	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
 	  h->type = STT_OBJECT;
 
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 3c8bb5d..9584bde 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -1901,6 +1901,7 @@
   flagword flags;
   register asection *s;
   struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *bh;
   struct mips_got_info *g;
   bfd_size_type amt;
 
@@ -1920,13 +1921,14 @@
   /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
      linker script because we don't want to define the symbol if we
      are not creating a global offset table.  */
-  h = NULL;
+  bh = NULL;
   if (! (_bfd_generic_link_add_one_symbol
 	 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
 	  (bfd_vma) 0, (const char *) NULL, false,
-	  get_elf_backend_data (abfd)->collect,
-	  (struct bfd_link_hash_entry **) &h)))
+	  get_elf_backend_data (abfd)->collect, &bh)))
     return false;
+
+  h = (struct elf_link_hash_entry *) bh;
   h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
   h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
   h->type = STT_OBJECT;
@@ -2938,6 +2940,10 @@
 	 know where the shared library will wind up at load-time.  */
       outrel[0].r_info = ELF_R_INFO (output_bfd, (unsigned long) indx,
 				     R_MIPS_REL32);
+      outrel[1].r_info = ELF_R_INFO (output_bfd, (unsigned long) 0,
+				     R_MIPS_NONE);
+      outrel[2].r_info = ELF_R_INFO (output_bfd, (unsigned long) 0,
+				     R_MIPS_NONE);
 
       /* Adjust the output offset of the relocation to reference the
 	 correct location in the output file.  */
@@ -3825,15 +3831,17 @@
       && strcmp (*namep, "__rld_obj_head") == 0)
     {
       struct elf_link_hash_entry *h;
+      struct bfd_link_hash_entry *bh;
 
       /* Mark __rld_obj_head as dynamic.  */
-      h = NULL;
+      bh = NULL;
       if (! (_bfd_generic_link_add_one_symbol
 	     (info, abfd, *namep, BSF_GLOBAL, *secp,
 	      (bfd_vma) *valp, (const char *) NULL, false,
-	      get_elf_backend_data (abfd)->collect,
-	      (struct bfd_link_hash_entry **) &h)))
+	      get_elf_backend_data (abfd)->collect, &bh)))
 	return false;
+
+      h = (struct elf_link_hash_entry *) bh;
       h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_OBJECT;
@@ -3889,6 +3897,7 @@
      struct bfd_link_info *info;
 {
   struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *bh;
   flagword flags;
   register asection *s;
   const char * const *namep;
@@ -3947,13 +3956,14 @@
     {
       for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
 	{
-	  h = NULL;
+	  bh = NULL;
 	  if (! (_bfd_generic_link_add_one_symbol
 		 (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr,
 		  (bfd_vma) 0, (const char *) NULL, false,
-		  get_elf_backend_data (abfd)->collect,
-		  (struct bfd_link_hash_entry **) &h)))
+		  get_elf_backend_data (abfd)->collect, &bh)))
 	    return false;
+
+	  h = (struct elf_link_hash_entry *) bh;
 	  h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
 	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
 	  h->type = STT_SECTION;
@@ -3989,26 +3999,17 @@
 
   if (!info->shared)
     {
-      h = NULL;
-      if (SGI_COMPAT (abfd))
-	{
-	  if (!(_bfd_generic_link_add_one_symbol
-		(info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr,
-		 (bfd_vma) 0, (const char *) NULL, false,
-		 get_elf_backend_data (abfd)->collect,
-		 (struct bfd_link_hash_entry **) &h)))
-	    return false;
-	}
-      else
-	{
-	  /* For normal mips it is _DYNAMIC_LINKING.  */
-	  if (!(_bfd_generic_link_add_one_symbol
-		(info, abfd, "_DYNAMIC_LINKING", BSF_GLOBAL,
-		 bfd_abs_section_ptr, (bfd_vma) 0, (const char *) NULL, false,
-		 get_elf_backend_data (abfd)->collect,
-		 (struct bfd_link_hash_entry **) &h)))
-	    return false;
-	}
+      const char *name;
+
+      name = SGI_COMPAT (abfd) ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING";
+      bh = NULL;
+      if (!(_bfd_generic_link_add_one_symbol
+	    (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
+	     (bfd_vma) 0, (const char *) NULL, false,
+	     get_elf_backend_data (abfd)->collect, &bh)))
+	return false;
+
+      h = (struct elf_link_hash_entry *) bh;
       h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_SECTION;
@@ -4025,26 +4026,15 @@
 	  s = bfd_get_section_by_name (abfd, ".rld_map");
 	  BFD_ASSERT (s != NULL);
 
-	  h = NULL;
-	  if (SGI_COMPAT (abfd))
-	    {
-	      if (!(_bfd_generic_link_add_one_symbol
-		    (info, abfd, "__rld_map", BSF_GLOBAL, s,
-		     (bfd_vma) 0, (const char *) NULL, false,
-		     get_elf_backend_data (abfd)->collect,
-		     (struct bfd_link_hash_entry **) &h)))
-		return false;
-	    }
-	  else
-	    {
-	      /* For normal mips the symbol is __RLD_MAP.  */
-	      if (!(_bfd_generic_link_add_one_symbol
-		    (info, abfd, "__RLD_MAP", BSF_GLOBAL, s,
-		     (bfd_vma) 0, (const char *) NULL, false,
-		     get_elf_backend_data (abfd)->collect,
-		     (struct bfd_link_hash_entry **) &h)))
-		return false;
-	    }
+	  name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP";
+	  bh = NULL;
+	  if (!(_bfd_generic_link_add_one_symbol
+		(info, abfd, name, BSF_GLOBAL, s,
+		 (bfd_vma) 0, (const char *) NULL, false,
+		 get_elf_backend_data (abfd)->collect, &bh)))
+	    return false;
+
+	  h = (struct elf_link_hash_entry *) bh;
 	  h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
 	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
 	  h->type = STT_OBJECT;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 96e55d7..ef001f3 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1005,6 +1005,14 @@
   "BFD_RELOC_SH_IMM_HI16",
   "BFD_RELOC_SH_IMM_HI16_PCREL",
   "BFD_RELOC_SH_PT_16",
+  "BFD_RELOC_SH_TLS_GD_32",
+  "BFD_RELOC_SH_TLS_LD_32",
+  "BFD_RELOC_SH_TLS_LDO_32",
+  "BFD_RELOC_SH_TLS_IE_32",
+  "BFD_RELOC_SH_TLS_LE_32",
+  "BFD_RELOC_SH_TLS_DTPMOD32",
+  "BFD_RELOC_SH_TLS_DTPOFF32",
+  "BFD_RELOC_SH_TLS_TPOFF32",
   "BFD_RELOC_THUMB_PCREL_BRANCH9",
   "BFD_RELOC_THUMB_PCREL_BRANCH12",
   "BFD_RELOC_THUMB_PCREL_BRANCH23",
diff --git a/bfd/linker.c b/bfd/linker.c
index 242f8bd..e44ac6c 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1305,6 +1305,7 @@
 	  const char *name;
 	  const char *string;
 	  struct generic_link_hash_entry *h;
+	  struct bfd_link_hash_entry *bh;
 
 	  name = bfd_asymbol_name (p);
 	  if (((p->flags & BSF_INDIRECT) != 0
@@ -1326,12 +1327,12 @@
 	  else
 	    string = NULL;
 
-	  h = NULL;
+	  bh = NULL;
 	  if (! (_bfd_generic_link_add_one_symbol
 		 (info, abfd, name, p->flags, bfd_get_section (p),
-		  p->value, string, false, collect,
-		  (struct bfd_link_hash_entry **) &h)))
+		  p->value, string, false, collect, &bh)))
 	    return false;
+	  h = (struct generic_link_hash_entry *) bh;
 
 	  /* If this is a constructor symbol, and the linker didn't do
              anything with it, then we want to just pass the symbol
diff --git a/bfd/opncls.c b/bfd/opncls.c
index cdf08df..af8ff7e 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -63,7 +63,9 @@
   nbfd->direction = no_direction;
   nbfd->iostream = NULL;
   nbfd->where = 0;
-  if (!bfd_hash_table_init (&nbfd->section_htab, bfd_section_hash_newfunc))
+  if (!bfd_hash_table_init_n (&nbfd->section_htab,
+			      bfd_section_hash_newfunc,
+			      251))
     {
       free (nbfd);
       return NULL;
@@ -124,7 +126,7 @@
 	bfd_openr
 
 SYNOPSIS
-        bfd *bfd_openr(const char *filename, const char *target);
+	bfd *bfd_openr(const char *filename, const char *target);
 
 DESCRIPTION
 	Open the file @var{filename} (using <<fopen>>) with the target
@@ -134,7 +136,8 @@
 	that function.
 
 	If <<NULL>> is returned then an error has occured.   Possible errors
-	are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
+	are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
+	<<system_call>> error.
 */
 
 bfd *
@@ -179,28 +182,28 @@
        the file descriptor too, even though we didn't open it.  */
 /*
 FUNCTION
-         bfd_fdopenr
+	bfd_fdopenr
 
 SYNOPSIS
-         bfd *bfd_fdopenr(const char *filename, const char *target, int fd);
+	bfd *bfd_fdopenr(const char *filename, const char *target, int fd);
 
 DESCRIPTION
-         <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
-	 It opens a BFD on a file already described by the @var{fd}
-	 supplied.
+	<<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to
+	<<fopen>>.  It opens a BFD on a file already described by the
+	@var{fd} supplied.
 
-	 When the file is later <<bfd_close>>d, the file descriptor will be closed.
+	When the file is later <<bfd_close>>d, the file descriptor will
+	be closed.  If the caller desires that this file descriptor be
+	cached by BFD (opened as needed, closed as needed to free
+	descriptors for other opens), with the supplied @var{fd} used as
+	an initial file descriptor (but subject to closure at any time),
+	call bfd_set_cacheable(bfd, 1) on the returned BFD.  The default
+	is to assume no cacheing; the file descriptor will remain open
+	until <<bfd_close>>, and will not be affected by BFD operations
+	on other files.
 
-	 If the caller desires that this file descriptor be cached by BFD
-	 (opened as needed, closed as needed to free descriptors for
-	 other opens), with the supplied @var{fd} used as an initial
-	 file descriptor (but subject to closure at any time), call
-	 bfd_set_cacheable(bfd, 1) on the returned BFD.  The default is to
-	 assume no cacheing; the file descriptor will remain open until
-	 <<bfd_close>>, and will not be affected by BFD operations on other
-	 files.
-
-         Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
+	Possible errors are <<bfd_error_no_memory>>,
+	<<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
 */
 
 bfd *
@@ -389,10 +392,10 @@
 
 DESCRIPTION
 
-	Close a BFD. If the BFD was open for writing,
-	then pending operations are completed and the file written out
-	and closed. If the created file is executable, then
-	<<chmod>> is called to mark it as such.
+	Close a BFD. If the BFD was open for writing, then pending
+	operations are completed and the file written out and closed.
+	If the created file is executable, then <<chmod>> is called
+	to mark it as such.
 
 	All memory attached to the BFD is released.
 
@@ -431,7 +434,7 @@
 
       if (stat (abfd->filename, &buf) == 0)
 	{
- 	  unsigned int mask = umask (0);
+	  unsigned int mask = umask (0);
 
 	  umask (mask);
 	  chmod (abfd->filename,
@@ -453,10 +456,10 @@
 	boolean bfd_close_all_done(bfd *);
 
 DESCRIPTION
-	Close a BFD.  Differs from <<bfd_close>>
-	since it does not complete any pending operations.  This
-	routine would be used if the application had just used BFD for
-	swapping and didn't want to use any of the writing code.
+	Close a BFD.  Differs from <<bfd_close>> since it does not
+	complete any pending operations.  This routine would be used
+	if the application had just used BFD for swapping and didn't
+	want to use any of the writing code.
 
 	If the created file is executable, then <<chmod>> is called
 	to mark it as such.
@@ -507,10 +510,9 @@
 	bfd *bfd_create(const char *filename, bfd *templ);
 
 DESCRIPTION
-	Create a new BFD in the manner of
-	<<bfd_openw>>, but without opening a file. The new BFD
-	takes the target from the target used by @var{template}. The
-	format is always set to <<bfd_object>>.
+	Create a new BFD in the manner of <<bfd_openw>>, but without
+	opening a file. The new BFD takes the target from the target
+	used by @var{template}. The format is always set to <<bfd_object>>.
 */
 
 bfd *
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 71f1740..23e4934 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2575,6 +2575,22 @@
   BFD_RELOC_SH_IMM_HI16_PCREL
 ENUMX
   BFD_RELOC_SH_PT_16
+ENUMX
+  BFD_RELOC_SH_TLS_GD_32
+ENUMX
+  BFD_RELOC_SH_TLS_LD_32
+ENUMX
+  BFD_RELOC_SH_TLS_LDO_32
+ENUMX
+  BFD_RELOC_SH_TLS_IE_32
+ENUMX
+  BFD_RELOC_SH_TLS_LE_32
+ENUMX
+  BFD_RELOC_SH_TLS_DTPMOD32
+ENUMX
+  BFD_RELOC_SH_TLS_DTPOFF32
+ENUMX
+  BFD_RELOC_SH_TLS_TPOFF32
 ENUMDOC
   Hitachi SH relocs.  Not all of these appear in object files.
 
diff --git a/bfd/simple.c b/bfd/simple.c
new file mode 100644
index 0000000..f2ee576
--- /dev/null
+++ b/bfd/simple.c
@@ -0,0 +1,168 @@
+/* simple.c -- BFD simple client routines
+   Copyright 2002
+   Free Software Foundation, Inc.
+   Contributed by MontaVista Software, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+
+static boolean
+simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+		      const char *warning ATTRIBUTE_UNUSED,
+		      const char *symbol ATTRIBUTE_UNUSED,
+		      bfd *abfd ATTRIBUTE_UNUSED,
+		      asection *section ATTRIBUTE_UNUSED,
+		      bfd_vma address ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+static boolean
+simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+			       const char *name ATTRIBUTE_UNUSED,
+			       bfd *abfd ATTRIBUTE_UNUSED,
+			       asection *section ATTRIBUTE_UNUSED,
+			       bfd_vma address ATTRIBUTE_UNUSED,
+			       boolean fatal ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+static boolean
+simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+			     const char *name ATTRIBUTE_UNUSED,
+			     const char *reloc_name ATTRIBUTE_UNUSED,
+			     bfd_vma addend ATTRIBUTE_UNUSED,
+			     bfd *abfd ATTRIBUTE_UNUSED,
+			     asection *section ATTRIBUTE_UNUSED,
+			     bfd_vma address ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+static boolean
+simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+			      const char *message ATTRIBUTE_UNUSED,
+			      bfd *abfd ATTRIBUTE_UNUSED,
+			      asection *section ATTRIBUTE_UNUSED,
+			      bfd_vma address ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+static boolean
+simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+			       const char *name ATTRIBUTE_UNUSED,
+			       bfd *abfd ATTRIBUTE_UNUSED,
+			       asection *section ATTRIBUTE_UNUSED,
+			       bfd_vma address ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+/*
+FUNCTION
+	bfd_simple_relocate_secton
+
+SYNOPSIS
+	bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf);
+
+DESCRIPTION
+	Returns the relocated contents of section @var{sec}.  Only symbols
+	from @var{abfd} and the output offsets assigned to sections in
+	@var{abfd} are used.  The result will be stored at @var{outbuf}
+	or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
+
+	Generally all sections in @var{abfd} should have their
+	@code{output_section} pointing back to the original section.
+
+	Returns @code{NULL} on a fatal error; ignores errors applying
+	particular relocations.
+*/
+
+bfd_byte *
+bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec,
+					   bfd_byte *outbuf)
+{
+  struct bfd_link_info link_info;
+  struct bfd_link_order link_order;
+  struct bfd_link_callbacks callbacks;
+  bfd_byte *contents, *data;
+  int storage_needed, number_of_symbols;
+  asymbol **symbol_table;
+
+  /* In order to use bfd_get_relocated_section_contents, we need
+     to forge some data structures that it expects.  */
+
+  /* Fill in the bare minimum number of fields for our purposes.  */
+  memset (&link_info, 0, sizeof (link_info));
+  link_info.input_bfds = abfd;
+
+  link_info.hash = bfd_link_hash_table_create (abfd);
+  link_info.callbacks = &callbacks;
+  callbacks.warning = simple_dummy_warning;
+  callbacks.undefined_symbol = simple_dummy_undefined_symbol;
+  callbacks.reloc_overflow = simple_dummy_reloc_overflow;
+  callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
+  callbacks.unattached_reloc = simple_dummy_unattached_reloc;
+
+  memset (&link_order, 0, sizeof (link_order));
+  link_order.next = NULL;
+  link_order.type = bfd_indirect_link_order;
+  link_order.offset = 0;
+  link_order.size = bfd_section_size (abfd, sec);
+  link_order.u.indirect.section = sec;
+
+  data = NULL;
+  if (outbuf == NULL)
+    {
+      data = bfd_malloc (bfd_section_size (abfd, sec));
+      if (data == NULL)
+	return NULL;
+      outbuf = data;
+    }
+  bfd_link_add_symbols (abfd, &link_info);
+
+  storage_needed = bfd_get_symtab_upper_bound (abfd);
+  symbol_table = (asymbol **) bfd_malloc (storage_needed);
+  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
+
+  contents = bfd_get_relocated_section_contents (abfd,
+						 &link_info,
+						 &link_order,
+						 outbuf,
+						 0,
+						 symbol_table);
+  if (contents == NULL && data != NULL)
+    free (data);
+
+  /* Foul hack to prevent bfd_section_size aborts.  This flag only controls
+     that macro (and the related size macros), selecting between _raw_size
+     and _cooked_size.  Debug sections won't change size while we're only
+     relocating.  There may be trouble here someday if it tries to run
+     relaxation unexpectedly, so make sure.  */
+  BFD_ASSERT (sec->_raw_size == sec->_cooked_size);
+  sec->reloc_done = 0;
+
+  bfd_link_hash_table_free (abfd, link_info.hash);
+
+  return contents;
+}
diff --git a/bfd/targets.c b/bfd/targets.c
index b9be8e7..adc8bd6 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -559,6 +559,8 @@
 extern const bfd_target bfd_elf32_s390_vec;
 extern const bfd_target bfd_elf32_sh64_vec;
 extern const bfd_target bfd_elf32_sh64l_vec;
+extern const bfd_target bfd_elf32_sh64lin_vec;
+extern const bfd_target bfd_elf32_sh64blin_vec;
 extern const bfd_target bfd_elf32_sh64lnbsd_vec;
 extern const bfd_target bfd_elf32_sh64nbsd_vec;
 extern const bfd_target bfd_elf32_sh_vec;
@@ -595,6 +597,8 @@
 extern const bfd_target bfd_elf64_s390_vec;
 extern const bfd_target bfd_elf64_sh64_vec;
 extern const bfd_target bfd_elf64_sh64l_vec;
+extern const bfd_target bfd_elf64_sh64lin_vec;
+extern const bfd_target bfd_elf64_sh64blin_vec;
 extern const bfd_target bfd_elf64_sh64lnbsd_vec;
 extern const bfd_target bfd_elf64_sh64nbsd_vec;
 extern const bfd_target bfd_elf64_sparc_vec;
diff --git a/bfd/version.h b/bfd/version.h
index 83fd085..a440678 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -1 +1 @@
-#define BFD_VERSION_DATE 20021004
+#define BFD_VERSION_DATE 20021011
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index a869d7d..e4e4755 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -1986,6 +1986,7 @@
 		      && h->descriptor == NULL)
 		    {
 		      struct xcoff_link_hash_entry *hds;
+		      struct bfd_link_hash_entry *bh;
 
 		      hds = xcoff_link_hash_lookup (xcoff_hash_table (info),
 						    h->root.root.string + 1,
@@ -1994,13 +1995,14 @@
 			goto error_return;
 		      if (hds->root.type == bfd_link_hash_new)
 			{
+			  bh = &hds->root;
 			  if (! (_bfd_generic_link_add_one_symbol
 				 (info, abfd, hds->root.root.string,
 				  (flagword) 0, bfd_und_section_ptr,
 				  (bfd_vma) 0, (const char *) NULL, false,
-				  true,
-				  (struct bfd_link_hash_entry **) &hds)))
+				  true, &bh)))
 			    goto error_return;
+			  hds = (struct xcoff_link_hash_entry *) bh;
 			}
 		      hds->flags |= XCOFF_DESCRIPTOR;
 		      BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0
diff --git a/configure.in b/configure.in
index 8988bef..87dd2c6 100644
--- a/configure.in
+++ b/configure.in
@@ -361,7 +361,7 @@
   avr-*-*)
     noconfigdirs="$noconfigdirs target-libiberty ${libstdcxx_version} ${libgcj}"
     ;;
-  c4x-*-*)
+  c4x-*-* | tic4x-*-*)
     noconfigdirs="$noconfigdirs ${libstdcxx_version} target-libgloss ${libgcj}"
     ;;
   c54x*-*-* | tic54x-*-*)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6a70cf4..8a77109 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,98 @@
+2002-10-11  Martin M. Hunt  <hunt@redhat.com>
+
+	* utils.c (string_to_core_addr): After turning string into
+	a number, convert to a CORE_ADDR using INTEGER_TO_ADDRESS
+	which will do necessary sign-extension, etc.
+
+2002-10-11  Daniel Jacobowitz  <drow@mvista.com>
+
+	* c-exp.y (THIS): Delete token and grammar rule.
+	(yylex): Don't return THIS.
+	* cp-valprint.c (vtbl_ptr_name_old): Delete.
+	(cp_is_vtbl_ptr_type): Don't check vtbl_ptr_name_old.
+	* demangle.c (cplus_markers): Update comment.  Put '$'
+	first.  Remove CPLUS_MARKER.
+	(_initialize_demangler): Don't call set_cplus_marker_for_demangling.
+	* jv-exp.y (THIS): Delete token and grammar rule.
+	(yylex): Don't return THIS.
+	* mips-tdep.c (mips_dump_tdep): Don't dump CPLUS_MARKER.
+	* objc-exp.y (THIS): Delete token and grammar rule.
+	(yylex): Don't return THIS.
+	* p-exp.y (yylex): Remove reference to CPLUS_MARKER.
+	* stabsread.c (vptr_name, vb_name): Replace CPLUS_MARKER with '$'.
+	(read_member_functions): Likewise for opname.
+	(read_tilde_fields): Use is_cplus_marker.
+
+	* defs.h (CPLUS_MARKER): Don't define.
+	* config/tm-sysv4.h (CPLUS_MARKER): Likewise.
+	* config/i386/xm-i386sco.h (CPLUS_MARKER): Likewise.
+	* config/mips/tm-irix3.h (CPLUS_MARKER): Likewise.
+	* config/mips/tm-irix6.h (CPLUS_MARKER): Likewise.
+	* config/rs6000/tm-rs6000.h (CPLUS_MARKER): Likewise.
+
+	* config/i386/tm-i386v4.h: Delete file.
+	* config/djgpp/fnchange.lst: Delete tm-i386v4.h.
+	* config/i386/tm-i386sol2.h: Include "i386/tm-i386.h" instead.
+	* config/i386/tm-i386v42mp.h: Include "i386/tm-i386.h" instead.
+	* config/i386/tm-ptx.h: Include "i386/tm-i386.h" instead.
+	* config/i386/i386gnu.mt (TM_FILE): Use tm-i386.h.
+	* config/i386/i386sco5.mt (TM_FILE): Likewise.
+	* config/i386/i386v4.mt (TM_FILE): Likewise.
+	* config/i386/ncr3000.mt (TM_FILE): Likewise.
+
+2002-10-10  Marko Mlinar  <markom@opencores.org>
+
+	* infrun.c (resume): Convert #ifdef HAVE_NONSTEPPABLE_WATCHPOINT into C,
+	accidentially not commited 2002-10-09
+	* gdbarch.h, gdbarch.c: Re-generate.
+
+2002-10-09  Marko Mlinar  <markom@opencores.org>
+
+	* infrun.c (resume): Convert #ifdef HAVE_NONSTEPPABLE_WATCHPOINT into C.
+	* gdbarch.sh (HAVE_NONSTEPPABLE_WATCHPOINT): Add.
+	* gdbarch.h, gdbarch.c: Re-generate.
+
+2002-10-08  Petr Sorfa <petrs@caldera.com>
+
+	Revised and re-submitted by John Wolfe <jlw@caldera.com>
+
+	Move the Dwarf 2 abbrev table to a per-compilation-unit structure,
+	so we can work on more than one compilation unit at a time.  This
+	helps prepare GDB to handle inter-CU die references.
+	* dwarf2read.c (ABBREV_HASH_SIZE): moved definition forward in
+	the code to be defined before struct comp_unit_head.
+	(comp_unit_head): Added new members - offset, cu_head,
+	begin_die, next and dwarf2_abbrevs.
+	(dwarf2_abbrevs): Removed single static var; now member of
+	struct comp_unit_head.
+	dwarf2_build_psymtabs_hard): Complete new struct comp_unit_head
+	members.
+	(psymtab_to_symtab_1): Changed to work with the new
+	struct comp_unit_head.
+	(dwarf2_read_abbrevs): Now accepts a cu_header parameter and
+	constructs the dwarf2_abbrevs[] inside the cu_header.
+	(dwarf2_empty_abbrev_table): Now expects a ptr to a
+	dwarf2_abbrev table to clean up.
+	(dwarf2_lookup_abbrev): Now accepts a cu_header parameter and
+	handling of dwarf2_abbrevs inside the cu_header.
+	(read_partial_die): Now supports the call to the new
+	dwarf2_lookup_abbrev.
+	(read_full_die): Now supports the call to the new
+	dwarf2_lookup_abbrev.
+
+2002-10-06  Christopher Faylor  <cgf@redhat.com>
+
+	* Makefile.in (install-gdbtk): Add missing continuation backslash to
+	insure that shell variables, such as "transformed_name" are propagated
+	to later shell statements in rule.
+
+2002-10-06  Mark Kettenis  <kettenis@gnu.org>
+
+	* config/i386/nm-i386sco.h: Add protection against
+	multiple-inclusion.  Include "i386/nm-i386v.h".
+	(REGISTER_U_ADDR): Remove define.
+	(i386_register_u_addr): Remove prototype.
+
 2002-10-04  Michael Snyder  <msnyder@redhat.com>
 
 	* m32r-stub.c (handle_exception): Make sure exception is "trap"
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 95330c0..416706a 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2341,7 +2341,7 @@
 	else \
 	  true ; \
 	fi ; \
-	$(SHELL) $(srcdir)/../mkinstalldirs $(bindir)
+	$(SHELL) $(srcdir)/../mkinstalldirs $(bindir); \
 	$(INSTALL_PROGRAM) insight$(EXEEXT) $(bindir)/$$transformed_name$(EXEEXT) ; \
 	$(SHELL) $(srcdir)/../mkinstalldirs $(GDBTK_LIBRARY) ; \
 	$(SHELL) $(srcdir)/../mkinstalldirs $(libdir)/insight$(GDBTK_VERSION) ; \
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 376f6d5..1f344c4 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -199,7 +199,6 @@
 %token <opcode> ASSIGN_MODIFY
 
 /* C++ */
-%token THIS
 %token TRUEKEYWORD
 %token FALSEKEYWORD
 
@@ -532,11 +531,6 @@
 	;
 
 /* C++.  */
-exp	:	THIS
-			{ write_exp_elt_opcode (OP_THIS);
-			  write_exp_elt_opcode (OP_THIS); }
-	;
-
 exp     :       TRUEKEYWORD    
                         { write_exp_elt_opcode (OP_LONG);
                           write_exp_elt_type (builtin_type_bool);
@@ -1615,17 +1609,6 @@
           {
             if (STREQN (tokstart, "true", 4))
               return TRUEKEYWORD;
-
-            if (STREQN (tokstart, "this", 4))
-              {
-                static const char this_name[] =
-                { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
-                
-                if (lookup_symbol (this_name, expression_context_block,
-                                   VAR_NAMESPACE, (int *) NULL,
-                                   (struct symtab **) NULL))
-                  return THIS;
-              }
           }
       break;
     case 3:
diff --git a/gdb/config/djgpp/fnchange.lst b/gdb/config/djgpp/fnchange.lst
index 0cb63a5..4d9fa83 100644
--- a/gdb/config/djgpp/fnchange.lst
+++ b/gdb/config/djgpp/fnchange.lst
@@ -88,7 +88,6 @@
 @V@/gdb/config/i386/nm-i386v42mp.h @V@/gdb/config/i386/nm-v42mp.h
 @V@/gdb/config/i386/tm-i386mk.h @V@/gdb/config/i386/tm-mk.h
 @V@/gdb/config/i386/tm-i386sol2.h @V@/gdb/config/i386/tm-sol2.h
-@V@/gdb/config/i386/tm-i386v4.h @V@/gdb/config/i386/tm-v4.h
 @V@/gdb/config/i386/tm-i386v42mp.h @V@/gdb/config/i386/tm-v42mp.h
 @V@/gdb/config/i386/xm-i386mach.h @V@/gdb/config/i386/xm-mach.h
 @V@/gdb/config/i386/xm-i386mk.h @V@/gdb/config/i386/xm-mk.h
diff --git a/gdb/config/i386/i386gnu.mt b/gdb/config/i386/i386gnu.mt
index dc3edd2..2029e99 100644
--- a/gdb/config/i386/i386gnu.mt
+++ b/gdb/config/i386/i386gnu.mt
@@ -1,3 +1,3 @@
 # Target: Intel 386 running the GNU Hurd
 TDEPFILES= i386-tdep.o i387-tdep.o i386gnu-tdep.o
-TM_FILE= tm-i386v4.h
+TM_FILE= tm-i386.h
diff --git a/gdb/config/i386/i386sco5.mt b/gdb/config/i386/i386sco5.mt
index ace2258..11ab55f 100644
--- a/gdb/config/i386/i386sco5.mt
+++ b/gdb/config/i386/i386sco5.mt
@@ -1,3 +1,3 @@
 # Target: Intel 386 running SCO Open Server 5
 TDEPFILES= i386-tdep.o i387-tdep.o
-TM_FILE= tm-i386v4.h
+TM_FILE= tm-i386.h
diff --git a/gdb/config/i386/i386v4.mt b/gdb/config/i386/i386v4.mt
index c22b675..d1b8c26 100644
--- a/gdb/config/i386/i386v4.mt
+++ b/gdb/config/i386/i386v4.mt
@@ -1,3 +1,3 @@
 # Target: Intel 386 running SVR4
 TDEPFILES= i386-tdep.o i387-tdep.o
-TM_FILE= tm-i386v4.h
+TM_FILE= tm-i386.h
diff --git a/gdb/config/i386/ncr3000.mt b/gdb/config/i386/ncr3000.mt
index 11bc474..4773dae 100644
--- a/gdb/config/i386/ncr3000.mt
+++ b/gdb/config/i386/ncr3000.mt
@@ -1,3 +1,3 @@
 # Target: Intel 386 running SVR4
 TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-svr4.o solib-legacy.o
-TM_FILE= tm-i386v4.h
+TM_FILE= tm-i386.h
diff --git a/gdb/config/i386/nm-i386sco.h b/gdb/config/i386/nm-i386sco.h
index e3bdc2d..ec7a3bd 100644
--- a/gdb/config/i386/nm-i386sco.h
+++ b/gdb/config/i386/nm-i386sco.h
@@ -20,12 +20,14 @@
    Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#define REGISTER_U_ADDR(addr, blockend, regno) \
-	(addr) = i386_register_u_addr ((blockend),(regno));
+#ifndef NM_I386SCO_H
+#define NM_I386SCO_H
 
-extern int i386_register_u_addr (int, int);
+#include "i386/nm-i386v.h"
 
 /* When calling functions on SCO, sometimes we get an error writing some
    of the segment registers.  This would appear to be a kernel
    bug/non-feature.  */
 #define CANNOT_STORE_REGISTER(regno) ((regno) == 14 || (regno) == 15)
+
+#endif /* nm-i386sco.h */
diff --git a/gdb/config/i386/tm-i386sol2.h b/gdb/config/i386/tm-i386sol2.h
index 35d63d1..5a79f67 100644
--- a/gdb/config/i386/tm-i386sol2.h
+++ b/gdb/config/i386/tm-i386sol2.h
@@ -21,7 +21,7 @@
 #ifndef TM_I386SOL2_H
 #define TM_I386SOL2_H 1
 
-#include "i386/tm-i386v4.h"
+#include "i386/tm-i386.h"
 
 /* The SunPRO compiler puts out 0 instead of the address in N_SO symbols,
    and for SunPRO 3.0, N_FUN symbols too.  */
diff --git a/gdb/config/i386/tm-i386v4.h b/gdb/config/i386/tm-i386v4.h
deleted file mode 100644
index 9363327..0000000
--- a/gdb/config/i386/tm-i386v4.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Macro definitions for GDB on an Intel i386 running SVR4.
-   Copyright 1991, 1994, 1995, 1998, 1999, 2000, 2002
-   Free Software Foundation, Inc.
-   Written by Fred Fish at Cygnus Support (fnf@cygnus.com)
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#ifndef TM_I386V4_H
-#define TM_I386V4_H 1
-
-/* Pick up most of what we need from the generic i386 target include file.  */
-#include "i386/tm-i386.h"
-
-/* It is unknown which, if any, SVR4 assemblers do not accept dollar signs
-   in identifiers.  The default in G++ is to use dots instead, for all SVR4
-   systems, so we make that our default also.  FIXME: There should be some
-   way to get G++ to tell us what CPLUS_MARKER it is using, perhaps by
-   stashing it in the debugging information as part of the name of an
-   invented symbol ("gcc_cplus_marker$" for example). */
-
-#undef CPLUS_MARKER
-#define CPLUS_MARKER '.'
-
-#endif /* ifndef TM_I386V4_H */
diff --git a/gdb/config/i386/tm-i386v42mp.h b/gdb/config/i386/tm-i386v42mp.h
index 5671e42..527fdbb 100644
--- a/gdb/config/i386/tm-i386v42mp.h
+++ b/gdb/config/i386/tm-i386v42mp.h
@@ -24,7 +24,7 @@
 
 /* pick up more generic x86 sysv4 stuff */
 
-#include "i386/tm-i386v4.h"
+#include "i386/tm-i386.h"
 
 /* define to select for other sysv4.2mp weirdness (see procfs.c) */
 
diff --git a/gdb/config/i386/tm-ptx.h b/gdb/config/i386/tm-ptx.h
index 8d773c8..2b7a86c 100644
--- a/gdb/config/i386/tm-ptx.h
+++ b/gdb/config/i386/tm-ptx.h
@@ -30,7 +30,7 @@
 #include <sys/reg.h>
 
 #ifdef SEQUENT_PTX4
-#include "i386/tm-i386v4.h"
+#include "i386/tm-i386.h"
 #else /* !SEQUENT_PTX4 */
 #include "i386/tm-i386.h"
 #endif
diff --git a/gdb/config/i386/xm-i386sco.h b/gdb/config/i386/xm-i386sco.h
index 920ebbb..72552c9 100644
--- a/gdb/config/i386/xm-i386sco.h
+++ b/gdb/config/i386/xm-i386sco.h
@@ -33,8 +33,3 @@
    GDB does not currently support the termio/job control combination.  */
 #undef HAVE_TERMIO
 #define HAVE_TERMIOS
-
-/* SCO's assembler doesn't grok dollar signs in identifiers.
-   So we use dots instead.  This item must be coordinated with G++. */
-#undef CPLUS_MARKER
-#define CPLUS_MARKER '.'
diff --git a/gdb/config/mips/tm-irix3.h b/gdb/config/mips/tm-irix3.h
index 11859e5..c298a39 100644
--- a/gdb/config/mips/tm-irix3.h
+++ b/gdb/config/mips/tm-irix3.h
@@ -21,11 +21,6 @@
 
 #include "mips/tm-bigmips.h"
 
-/* SGI's assembler doesn't grok dollar signs in identifiers.
-   So we use dots instead.  This item must be coordinated with G++. */
-#undef CPLUS_MARKER
-#define CPLUS_MARKER '.'
-
 /* Redefine register numbers for SGI. */
 
 #undef NUM_REGS
diff --git a/gdb/config/mips/tm-irix6.h b/gdb/config/mips/tm-irix6.h
index 58b97e1..ce9c226 100644
--- a/gdb/config/mips/tm-irix6.h
+++ b/gdb/config/mips/tm-irix6.h
@@ -22,11 +22,6 @@
 #include "mips/tm-bigmips64.h"
 #include "solib.h"
 
-/* SGI's assembler doesn't grok dollar signs in identifiers.
-   So we use dots instead.  This item must be coordinated with G++. */
-#undef CPLUS_MARKER
-#define CPLUS_MARKER '.'
-
 /* Redefine register numbers for SGI. */
 
 #undef NUM_REGS
diff --git a/gdb/config/rs6000/tm-rs6000.h b/gdb/config/rs6000/tm-rs6000.h
index ea0c073..478e9bd 100644
--- a/gdb/config/rs6000/tm-rs6000.h
+++ b/gdb/config/rs6000/tm-rs6000.h
@@ -27,11 +27,6 @@
 
 #define TEXT_SEGMENT_BASE	0x10000000
 
-/* AIX's assembler doesn't grok dollar signs in identifiers.
-   So we use dots instead.  This item must be coordinated with G++. */
-#undef CPLUS_MARKER
-#define CPLUS_MARKER '.'
-
 /* Return whether PC in function NAME is in code that should be skipped when
    single-stepping.  */
 
diff --git a/gdb/config/tm-sysv4.h b/gdb/config/tm-sysv4.h
index 35b95eb..9a39af2 100644
--- a/gdb/config/tm-sysv4.h
+++ b/gdb/config/tm-sysv4.h
@@ -35,13 +35,3 @@
    where the function itself actually starts.  If not, return 0.  */
 
 #define SKIP_TRAMPOLINE_CODE(pc)  find_solib_trampoline_target (pc)
-
-/* It is unknown which, if any, SVR4 assemblers do not accept dollar signs
-   in identifiers.  The default in G++ is to use dots instead, for all SVR4
-   systems, so we make that our default also.  FIXME: There should be some
-   way to get G++ to tell us what CPLUS_MARKER it is using, perhaps by
-   stashing it in the debugging information as part of the name of an
-   invented symbol ("gcc_cplus_marker$" for example). */
-
-#undef CPLUS_MARKER
-#define CPLUS_MARKER '.'
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 28dc025..f362d84 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -161,21 +161,13 @@
     }
 }
 
-/* This was what it was for gcc 2.4.5 and earlier.  */
-static const char vtbl_ptr_name_old[] =
-{
-  CPLUS_MARKER, 'v', 't', 'b', 'l', '_', 'p', 't', 'r', '_', 
-  't', 'y', 'p', 'e', 0
-};
-
-/* It was changed to this after 2.4.5.  */
+/* GCC versions after 2.4.5 use this.  */
 const char vtbl_ptr_name[] = "__vtbl_ptr_type";
 
-/* HP aCC uses different names */
+/* HP aCC uses different names.  */
 const char hpacc_vtbl_ptr_name[] = "__vfp";
 const char hpacc_vtbl_ptr_type_name[] = "__vftyp";
 
-
 /* Return truth value for assertion that TYPE is of the type
    "pointer to virtual function".  */
 
@@ -184,9 +176,7 @@
 {
   char *typename = type_name_no_tag (type);
 
-  return (typename != NULL
-	  && (STREQ (typename, vtbl_ptr_name)
-	      || STREQ (typename, vtbl_ptr_name_old)));
+  return (typename != NULL && !strcmp (typename, vtbl_ptr_name));
 }
 
 /* Return truth value for the assertion that TYPE is of the type
diff --git a/gdb/defs.h b/gdb/defs.h
index d13cd69..7491727 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -157,10 +157,6 @@
 #define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0)
 #define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0)
 
-/* The character GNU C++ uses to build identifiers that must be unique from
-   the program's identifiers (such as $this and $$vptr).  */
-#define CPLUS_MARKER '$'	/* May be overridden to '.' for SysV */
-
 /* Check if a character is one of the commonly used C++ marker characters.  */
 extern int is_cplus_marker (int);
 
diff --git a/gdb/demangle.c b/gdb/demangle.c
index 1fd69be..2b9579b 100644
--- a/gdb/demangle.c
+++ b/gdb/demangle.c
@@ -150,24 +150,18 @@
   set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
 }
 
-/* In order to allow a single demangler executable to demangle strings
-   using various common values of CPLUS_MARKER, as well as any specific
-   one set at compile time, we maintain a string containing all the
-   commonly used ones, and check to see if the marker we are looking for
-   is in that string.  CPLUS_MARKER is usually '$' on systems where the
-   assembler can deal with that.  Where the assembler can't, it's usually
-   '.' (but on many systems '.' is used for other things).  We put the
-   current defined CPLUS_MARKER first (which defaults to '$'), followed
-   by the next most common value, followed by an explicit '$' in case
-   the value of CPLUS_MARKER is not '$'.
+/* G++ uses a special character to indicate certain internal names.  Which
+   character it is depends on the platform:
+   - Usually '$' on systems where the assembler will accept that
+   - Usually '.' otherwise (this includes most sysv4-like systems and most
+     ELF targets)
+   - Occasionally '_' if neither of the above is usable
 
-   We could avoid this if we could just get g++ to tell us what the actual
-   cplus marker character is as part of the debug information, perhaps by
-   ensuring that it is the character that terminates the gcc<n>_compiled
-   marker symbol (FIXME). */
+   We check '$' first because it is the safest, and '.' often has another
+   meaning.  We don't currently try to handle '_' because the precise forms
+   of the names are different on those targets.  */
 
-static char cplus_markers[] =
-{CPLUS_MARKER, '.', '$', '\0'};
+static char cplus_markers[] = {'$', '.', '\0'};
 
 int
 is_cplus_marker (int c)
@@ -204,5 +198,4 @@
 
   /* Set the default demangling style chosen at compilation time. */
   set_demangling_style (DEFAULT_DEMANGLING_STYLE);
-  set_cplus_marker_for_demangling (CPLUS_MARKER);
 }
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 749f181..72544a0 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,13 @@
+2002-10-11  Klee Dienes  <kdienes@apple.com>
+
+	* gdb.texinfo (Registers): Mention vector registers as well as
+	floating registers in the documentation for 'info registers' and
+	'info all-registers'.
+
+2002-10-11  Daniel Jacobowitz  <drow@mvista.com>
+
+	* gdbint.texinfo (CPLUS_MARKER): Remove item.
+
 2002-10-03  Jeff Johnston  <jjohnstn@redhat.com>
 
 	* gdbint.texinfo (Item Output Functions): Add new ui_out_field_fmt_int
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 9269c5d..56db6ca 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5557,13 +5557,13 @@
 @kindex info registers
 @item info registers
 Print the names and values of all registers except floating-point
-registers (in the selected stack frame).
+and vector registers (in the selected stack frame).
 
 @kindex info all-registers
 @cindex floating point registers
 @item info all-registers
 Print the names and values of all registers, including floating-point
-registers.
+and vector registers (in the selected stack frame).
 
 @item info registers @var{regname} @dots{}
 Print the @dfn{relativized} value of each specified register @var{regname}.
diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo
index 01587ec..87dd5b6 100644
--- a/gdb/doc/gdbint.texinfo
+++ b/gdb/doc/gdbint.texinfo
@@ -3069,13 +3069,6 @@
 non-standard form.
 @xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}.
 
-@item CPLUS_MARKER
-@findex CPLUS_MARKERz
-Define this to expand into the character that G@t{++} uses to distinguish
-compiler-generated identifiers from programmer-specified identifiers.
-By default, this expands into @code{'$'}.  Most System V targets should
-define this to @code{'.'}.
-
 @item DBX_PARM_SYMBOL_CLASS
 @findex DBX_PARM_SYMBOL_CLASS
 Hook for the @code{SYMBOL_CLASS} of a parameter when decoding DBX symbol
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index b62b028..8edbd86 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -162,6 +162,11 @@
 
 /* local data types */
 
+/* We hold several abbreviation tables in memory at the same time. */
+#ifndef ABBREV_HASH_SIZE
+#define ABBREV_HASH_SIZE 121
+#endif
+
 /* The data in a compilation unit header, after target2host
    translation, looks like this.  */
 struct comp_unit_head
@@ -174,6 +179,29 @@
     unsigned int offset_size;	/* size of file offsets; either 4 or 8 */
     unsigned int initial_length_size; /* size of the length field; either
                                          4 or 12 */
+
+    /* Offset to the first byte of this compilation unit header in the 
+     * .debug_info section, for resolving relative reference dies. */
+
+    unsigned int offset;
+
+    /* Pointer to this compilation unit header in the .debug_info
+     * section */
+
+    char *cu_head_ptr;
+
+    /* Pointer to the first die of this compilatio unit.  This will
+     * be the first byte following the compilation unit header. */
+
+    char *first_die_ptr;
+
+    /* Pointer to the next compilation unit header in the program. */
+
+    struct comp_unit_head *next;
+
+    /* DWARF abbreviation table associated with this compilation unit */
+
+    struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
   };
 
 /* The line number information for a compilation unit (found in the
@@ -312,17 +340,10 @@
     char *data;
   };
 
-/* We only hold one compilation unit's abbrevs in
-   memory at any one time.  */
-#ifndef ABBREV_HASH_SIZE
-#define ABBREV_HASH_SIZE 121
-#endif
 #ifndef ATTR_ALLOC_CHUNK
 #define ATTR_ALLOC_CHUNK 4
 #endif
 
-static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
-
 /* A hash table of die offsets for following references.  */
 #ifndef REF_HASH_SIZE
 #define REF_HASH_SIZE 1021
@@ -686,11 +707,12 @@
 
 char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
 
-static void dwarf2_read_abbrevs (bfd *, unsigned int);
+static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header);
 
 static void dwarf2_empty_abbrev_table (PTR);
 
-static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int);
+static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
+                                         const struct comp_unit_head *cu_header);
 
 static char *read_partial_die (struct partial_die_info *,
 			       bfd *, char *,
@@ -1211,9 +1233,14 @@
 		 (long) (beg_of_comp_unit - dwarf_info_buffer));
 	  return;
 	}
+      /* Complete the cu_header */
+      cu_header.offset = beg_of_comp_unit - dwarf_info_buffer;
+      cu_header.first_die_ptr = info_ptr;
+      cu_header.cu_head_ptr = beg_of_comp_unit;
+
       /* Read the abbrevs for this compilation unit into a table */
-      dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
-      make_cleanup (dwarf2_empty_abbrev_table, NULL);
+      dwarf2_read_abbrevs (abfd, &cu_header);
+      make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs);
 
       /* Read the compilation unit die */
       info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
@@ -1560,8 +1587,8 @@
   info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd);
 
   /* Read the abbrevs for this compilation unit  */
-  dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
-  make_cleanup (dwarf2_empty_abbrev_table, NULL);
+  dwarf2_read_abbrevs (abfd, &cu_header);
+  make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs);
 
   dies = read_comp_unit (info_ptr, abfd, &cu_header);
 
@@ -3345,17 +3372,18 @@
    in a hash table.  */
 
 static void
-dwarf2_read_abbrevs (bfd *abfd, unsigned int offset)
+dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header)
 {
   char *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
   unsigned int abbrev_form, hash_number;
 
-  /* empty the table */
-  dwarf2_empty_abbrev_table (NULL);
+  /* Initialize dwarf2 abbrevs */
+  memset (cu_header->dwarf2_abbrevs, 0,
+          ABBREV_HASH_SIZE*sizeof (struct abbrev_info *));
 
-  abbrev_ptr = dwarf_abbrev_buffer + offset;
+  abbrev_ptr = dwarf_abbrev_buffer + cu_header->abbrev_offset;
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
@@ -3394,8 +3422,8 @@
 	}
 
       hash_number = abbrev_number % ABBREV_HASH_SIZE;
-      cur_abbrev->next = dwarf2_abbrevs[hash_number];
-      dwarf2_abbrevs[hash_number] = cur_abbrev;
+      cur_abbrev->next = cu_header->dwarf2_abbrevs[hash_number];
+      cu_header->dwarf2_abbrevs[hash_number] = cur_abbrev;
 
       /* Get next abbreviation.
          Under Irix6 the abbreviations for a compilation unit are not
@@ -3409,7 +3437,7 @@
 	break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
-      if (dwarf2_lookup_abbrev (abbrev_number) != NULL)
+      if (dwarf2_lookup_abbrev (abbrev_number, cu_header) != NULL)
 	break;
     }
 }
@@ -3418,15 +3446,18 @@
 
 /* ARGSUSED */
 static void
-dwarf2_empty_abbrev_table (PTR ignore)
+dwarf2_empty_abbrev_table (PTR ptr_to_abbrevs_table)
 {
   int i;
   struct abbrev_info *abbrev, *next;
+  struct abbrev_info **abbrevs;
+
+  abbrevs = (struct abbrev_info **)ptr_to_abbrevs_table;
 
   for (i = 0; i < ABBREV_HASH_SIZE; ++i)
     {
       next = NULL;
-      abbrev = dwarf2_abbrevs[i];
+      abbrev = abbrevs[i];
       while (abbrev)
 	{
 	  next = abbrev->next;
@@ -3434,20 +3465,20 @@
 	  xfree (abbrev);
 	  abbrev = next;
 	}
-      dwarf2_abbrevs[i] = NULL;
+      abbrevs[i] = NULL;
     }
 }
 
 /* Lookup an abbrev_info structure in the abbrev hash table.  */
 
 static struct abbrev_info *
-dwarf2_lookup_abbrev (unsigned int number)
+dwarf2_lookup_abbrev (unsigned int number, const struct comp_unit_head *cu_header)
 {
   unsigned int hash_number;
   struct abbrev_info *abbrev;
 
   hash_number = number % ABBREV_HASH_SIZE;
-  abbrev = dwarf2_abbrevs[hash_number];
+  abbrev = cu_header->dwarf2_abbrevs[hash_number];
 
   while (abbrev)
     {
@@ -3479,7 +3510,7 @@
   if (!abbrev_number)
     return info_ptr;
 
-  abbrev = dwarf2_lookup_abbrev (abbrev_number);
+  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
   if (!abbrev)
     {
       error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
@@ -3623,7 +3654,7 @@
       return info_ptr;
     }
 
-  abbrev = dwarf2_lookup_abbrev (abbrev_number);
+  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
   if (!abbrev)
     {
       error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index c0c4f9f..fe40062 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -270,6 +270,7 @@
   gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special;
   const char * name_of_malloc;
   int cannot_step_breakpoint;
+  int have_nonsteppable_watchpoint;
 };
 
 
@@ -429,6 +430,7 @@
   0,
   "malloc",
   0,
+  0,
   /* startup_gdbarch() */
 };
 
@@ -807,6 +809,7 @@
   /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */
   /* Skip verify of name_of_malloc, invalid_p == 0 */
   /* Skip verify of cannot_step_breakpoint, invalid_p == 0 */
+  /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */
   buf = ui_file_xstrdup (log, &dummy);
   make_cleanup (xfree, buf);
   if (strlen (buf) > 0)
@@ -1383,6 +1386,14 @@
                         (long) current_gdbarch->get_saved_register
                         /*GET_SAVED_REGISTER ()*/);
 #endif
+#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: HAVE_NONSTEPPABLE_WATCHPOINT # %s\n",
+                      XSTRING (HAVE_NONSTEPPABLE_WATCHPOINT));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: HAVE_NONSTEPPABLE_WATCHPOINT = %d\n",
+                      HAVE_NONSTEPPABLE_WATCHPOINT);
+#endif
 #ifdef INIT_EXTRA_FRAME_INFO
 #if GDB_MULTI_ARCH
   /* Macro might contain `[{}]' when not multi-arch */
@@ -5052,6 +5063,23 @@
   gdbarch->cannot_step_breakpoint = cannot_step_breakpoint;
 }
 
+int
+gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_have_nonsteppable_watchpoint called\n");
+  return gdbarch->have_nonsteppable_watchpoint;
+}
+
+void
+set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch,
+                                          int have_nonsteppable_watchpoint)
+{
+  gdbarch->have_nonsteppable_watchpoint = have_nonsteppable_watchpoint;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index b14d3c1..c204cf0 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -2595,6 +2595,22 @@
 #endif
 #endif
 
+/* Default (value) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (HAVE_NONSTEPPABLE_WATCHPOINT)
+#define HAVE_NONSTEPPABLE_WATCHPOINT (0)
+#endif
+
+extern int gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch);
+extern void set_gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch, int have_nonsteppable_watchpoint);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (HAVE_NONSTEPPABLE_WATCHPOINT)
+#error "Non multi-arch definition of HAVE_NONSTEPPABLE_WATCHPOINT"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (HAVE_NONSTEPPABLE_WATCHPOINT)
+#define HAVE_NONSTEPPABLE_WATCHPOINT (gdbarch_have_nonsteppable_watchpoint (current_gdbarch))
+#endif
+#endif
+
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
 
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 79c7fe5..c18639e 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -663,6 +663,7 @@
 f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct minimal_symbol *msym:val, msym:::default_coff_make_msymbol_special::0
 v::NAME_OF_MALLOC:const char *:name_of_malloc::::"malloc":"malloc"::0
 v::CANNOT_STEP_BREAKPOINT:int:cannot_step_breakpoint::::0:0::0
+v::HAVE_NONSTEPPABLE_WATCHPOINT:int:have_nonsteppable_watchpoint::::0:0::0
 EOF
 }
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 89a1d23..0de1a66 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -231,13 +231,6 @@
 #define HAVE_STEPPABLE_WATCHPOINT 1
 #endif
 
-#ifndef HAVE_NONSTEPPABLE_WATCHPOINT
-#define HAVE_NONSTEPPABLE_WATCHPOINT 0
-#else
-#undef  HAVE_NONSTEPPABLE_WATCHPOINT
-#define HAVE_NONSTEPPABLE_WATCHPOINT 1
-#endif
-
 #ifndef HAVE_CONTINUABLE_WATCHPOINT
 #define HAVE_CONTINUABLE_WATCHPOINT 0
 #else
diff --git a/gdb/jv-exp.y b/gdb/jv-exp.y
index 70c228b..b4ae340 100644
--- a/gdb/jv-exp.y
+++ b/gdb/jv-exp.y
@@ -179,7 +179,7 @@
 
 %token <opcode> ASSIGN_MODIFY
 
-%token THIS SUPER NEW
+%token SUPER NEW
 
 %left ','
 %right '=' ASSIGN_MODIFY
@@ -365,9 +365,6 @@
 
 PrimaryNoNewArray:
 	Literal
-|	THIS
-		{ write_exp_elt_opcode (OP_THIS);
-		  write_exp_elt_opcode (OP_THIS); }
 |	'(' Expression ')'
 |	ClassInstanceCreationExpression
 |	FieldAccess
@@ -1167,17 +1164,6 @@
 	  yylval.lval = 1;
 	  return BOOLEAN_LITERAL;
 	}
-      if (current_language->la_language == language_cplus
-	  && STREQN (tokstart, "this", 4))
-	{
-	  static const char this_name[] =
-				 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
-
-	  if (lookup_symbol (this_name, expression_context_block,
-			     VAR_NAMESPACE, (int *) NULL,
-			     (struct symtab **) NULL))
-	    return THIS;
-	}
       break;
     case 3:
       if (STREQN (tokstart, "int", 3))
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index fd61c5b..3908606 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -6194,9 +6194,6 @@
 		      "mips_dump_tdep: CAUSE_REGNUM = %d\n",
 		      CAUSE_REGNUM);
   fprintf_unfiltered (file,
-		      "mips_dump_tdep: CPLUS_MARKER = %c\n",
-		      CPLUS_MARKER);
-  fprintf_unfiltered (file,
 		      "mips_dump_tdep: DO_REGISTERS_INFO # %s\n",
 		      XSTRING (DO_REGISTERS_INFO));
   fprintf_unfiltered (file,
diff --git a/gdb/objc-exp.y b/gdb/objc-exp.y
index 54b99b0..2ccc882 100644
--- a/gdb/objc-exp.y
+++ b/gdb/objc-exp.y
@@ -203,9 +203,6 @@
 
 %token <opcode> ASSIGN_MODIFY
 
-/* C++ */
-%token THIS
-
 %left ','
 %left ABOVE_COMMA
 %right '=' ASSIGN_MODIFY
@@ -613,14 +610,6 @@
 			  write_exp_elt_opcode (OP_NSSTRING); }
 	;
 
-/* C++.  */
-exp	:	THIS
-			{ write_exp_elt_opcode (OP_THIS);
-			  write_exp_elt_opcode (OP_THIS); }
-	;
-
-/* end of C++.  */
-
 block	:	BLOCKNAME
 			{
 			  if ($1.sym != 0)
@@ -1631,18 +1620,6 @@
 	return ENUM;
       if (STREQN (tokstart, "long", 4))
 	return LONG;
-      if (current_language->la_language == language_cplus
-	  && STREQN (tokstart, "this", 4))
-	{
-	  static const char this_name[] = {
-	    CPLUS_MARKER, 't', 'h', 'i', 's', '\0' 
-	  };
-
-	  if (lookup_symbol (this_name, expression_context_block,
-			     VAR_NAMESPACE, (int *) NULL,
-			     (struct symtab **) NULL))
-	    return THIS;
-	}
       break;
     case 3:
       if (STREQN (tokstart, "int", 3))
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index f0939e7..4dc99be 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -1358,8 +1358,7 @@
         {
           /* here we search for 'this' like
              inserted in FPC stabs debug info */
-	  static const char this_name[] =
-				 { /* CPLUS_MARKER,*/ 't', 'h', 'i', 's', '\0' };
+	  static const char this_name[] = "this";
 
 	  if (lookup_symbol (this_name, expression_context_block,
 			     VAR_NAMESPACE, (int *) NULL,
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 4697b40..00634ac 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -185,10 +185,8 @@
 
 void stabsread_clear_cache (void);
 
-static const char vptr_name[] =
-{'_', 'v', 'p', 't', 'r', CPLUS_MARKER, '\0'};
-static const char vb_name[] =
-{'_', 'v', 'b', CPLUS_MARKER, '\0'};
+static const char vptr_name[] = "_vptr$";
+static const char vb_name[] = "_vb$";
 
 /* Define this as 1 if a pcc declaration of a char or short argument
    gives the correct address.  Otherwise assume pcc gives the
@@ -3179,8 +3177,7 @@
 	  /* This lets the user type "break operator+".
 	     We could just put in "+" as the name, but that wouldn't
 	     work for "*".  */
-	  static char opname[32] =
-	  {'o', 'p', CPLUS_MARKER};
+	  static char opname[32] = "op$";
 	  char *o = opname + 3;
 
 	  /* Skip past '::'.  */
@@ -4138,8 +4135,9 @@
 		   i >= TYPE_N_BASECLASSES (t);
 		   --i)
 		{
-		  if (!strncmp (TYPE_FIELD_NAME (t, i), vptr_name,
-				sizeof (vptr_name) - 1))
+		  char *name = TYPE_FIELD_NAME (t, i);
+		  if (!strncmp (name, vptr_name, sizeof (vptr_name) - 2)
+		      && is_cplus_marker (name[sizeof (vptr_name) - 1]))
 		    {
 		      TYPE_VPTR_FIELDNO (type) = i;
 		      goto gotit;
diff --git a/gdb/utils.c b/gdb/utils.c
index 9aab625..d1b4c99 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -2649,6 +2649,8 @@
 	    internal_error (__FILE__, __LINE__, "invalid decimal");
 	}
     }
+  if (INTEGER_TO_ADDRESS_P ())
+    addr = INTEGER_TO_ADDRESS (builtin_type_void_data_ptr, &addr); 
   return addr;
 }
 
diff --git a/gdb/version.in b/gdb/version.in
index a00b4a3..ccef576 100644
--- a/gdb/version.in
+++ b/gdb/version.in
@@ -1 +1 @@
-2002-10-04-cvs
+2002-10-11-cvs
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
index 254b2c4..65f3160 100644
--- a/include/elf/ChangeLog
+++ b/include/elf/ChangeLog
@@ -1,3 +1,7 @@
+2002-10-11  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sh.h: Add SH TLS relocs.
+
 2002-09-30  Gavin Romig-Koch  <gavin@redhat.com>
             Ken Raeburn  <raeburn@cygnus.com>
             Aldy Hernandez  <aldyh@redhat.com>
diff --git a/include/elf/sh.h b/include/elf/sh.h
index af78c9b..ef964d6 100644
--- a/include/elf/sh.h
+++ b/include/elf/sh.h
@@ -167,7 +167,17 @@
   RELOC_NUMBER (R_SH_DIR10SL, 50)
   RELOC_NUMBER (R_SH_DIR10SQ, 51)
   FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_3, 52)
-  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_3, 159)
+  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_3, 143)
+  RELOC_NUMBER (R_SH_TLS_GD_32, 144)
+  RELOC_NUMBER (R_SH_TLS_LD_32, 145)
+  RELOC_NUMBER (R_SH_TLS_LDO_32, 146)
+  RELOC_NUMBER (R_SH_TLS_IE_32, 147)
+  RELOC_NUMBER (R_SH_TLS_LE_32, 148)
+  RELOC_NUMBER (R_SH_TLS_DTPMOD32, 149)
+  RELOC_NUMBER (R_SH_TLS_DTPOFF32, 150)
+  RELOC_NUMBER (R_SH_TLS_TPOFF32, 151)
+  FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_4, 152)
+  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_4, 159)
   RELOC_NUMBER (R_SH_GOT32, 160)
   RELOC_NUMBER (R_SH_PLT32, 161)
   RELOC_NUMBER (R_SH_COPY, 162)
@@ -205,8 +215,8 @@
   RELOC_NUMBER (R_SH_GLOB_DAT64, 194)
   RELOC_NUMBER (R_SH_JMP_SLOT64, 195)
   RELOC_NUMBER (R_SH_RELATIVE64, 196)
-  FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_4, 197)
-  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_4, 241)
+  FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_5, 197)
+  FAKE_RELOC (R_SH_LAST_INVALID_RELOC_5, 241)
   RELOC_NUMBER (R_SH_SHMEDIA_CODE, 242)
   RELOC_NUMBER (R_SH_PT_16, 243)
   RELOC_NUMBER (R_SH_IMMS16, 244)
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index bde129c..10e7740 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,9 @@
+2002-10-06  Andreas Jaeger  <aj@suse.de>
+
+	* libiberty/cplus-dem.c (ada_demangle): Get rid of unneeded
+	variable and of strict-aliasing warning.
+	(grow_vect): Use char as first parameter.
+
 2002-09-22  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
 	* Makefile.in (all): Fix multilib parallel build.
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 4c47783..f42d618 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -514,7 +514,7 @@
 			      int));
 
 static void
-grow_vect PARAMS ((void **, size_t *, size_t, int));
+grow_vect PARAMS ((char **, size_t *, size_t, int));
 
 /* Translate count to integer, consuming tokens in the process.
    Conversion terminates on the first non-digit character.
@@ -936,7 +936,7 @@
 
 static void
 grow_vect (old_vect, size, min_size, element_size)
-     void **old_vect;
+     char **old_vect;
      size_t *size;
      size_t min_size;
      int element_size;
@@ -969,8 +969,7 @@
   char *demangled = NULL;
   int at_start_name;
   int changed;
-  char *demangling_buffer = NULL;
-  size_t demangling_buffer_size = 0;
+  size_t demangled_size = 0;
   
   changed = 0;
 
@@ -998,10 +997,9 @@
     }
   
   /* Make demangled big enough for possible expansion by operator name.  */
-  grow_vect ((void **) &(demangling_buffer),
-	     &demangling_buffer_size,  2 * len0 + 1,
+  grow_vect (&demangled,
+	     &demangled_size,  2 * len0 + 1,
 	     sizeof (char));
-  demangled = demangling_buffer;
   
   if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
     for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
@@ -1051,10 +1049,10 @@
     return demangled;
   
  Suppress:
-  grow_vect ((void **) &(demangling_buffer),
-	     &demangling_buffer_size,  strlen (mangled) + 3,
+  grow_vect (&demangled,
+	     &demangled_size,  strlen (mangled) + 3,
 	     sizeof (char));
-  demangled = demangling_buffer;
+
   if (mangled[0] == '<')
      strcpy (demangled, mangled);
   else
diff --git a/sim/sh/ChangeLog b/sim/sh/ChangeLog
index ec58759..60b41f7 100644
--- a/sim/sh/ChangeLog
+++ b/sim/sh/ChangeLog
@@ -1,3 +1,11 @@
+Fri Oct 11 16:22:28 2002  J"orn Rennecke <joern.rennecke@superh.com>
+
+	* interp.c (trap): Return int.  Take extra parameter for address
+	of the trap instruction.  Changed all callers.
+	Add case 33 for profiling.
+	* gencode.c (trapa): Handle trap 33 using the trap function.
+	Add read of vector for generic traps.
+
 Wed Jul 17 19:36:38 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
 	* Makefile.in (interp.o): Depend on $(srcroot)/include/gdb/sim-sh.h.
diff --git a/sim/sh/gencode.c b/sim/sh/gencode.c
index ba6ee4c..8e2445a 100644
--- a/sim/sh/gencode.c
+++ b/sim/sh/gencode.c
@@ -577,7 +577,7 @@
   },
 
   { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
-    "trap (255,R0,memory,maskl,maskw, endianw);",
+    "trap (255, R0, PC, memory, maskl, maskw, endianw);",
     "/* FIXME: mac.l support */",
   },
 
@@ -951,8 +951,7 @@
   },
 
   { "", "", "sleep", "0000000000011011",
-    "nip = PC;",
-    "trap (0xc3, R0, memory, maskl, maskw, endianw);",
+    "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
   },
 
   { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
@@ -1029,37 +1028,25 @@
   },
 
   { "0", "", "trapa #<imm>", "11000011i8*1....", 
-#if 0
-    /* SH-[12] */
     "long imm = 0xff & i;",
-    "if (i==0xc3)",
-    "  PC-=2;",
-    "if (i<20||i==34||i==0xc3)",
-    "  trap(i,R,memory,maskl,maskw,endianw);",
+    "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
+    "  nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
+#if 0
     "else {",
+    /* SH-[12] */
     "  R[15]-=4;",
-    "  WLAT(R[15],GET_SR());",
+    "  WLAT (R[15], GET_SR());",
     "  R[15]-=4;",
-    "  WLAT(R[15],PC+2);",
-    "  PC=RLAT(VBR+(imm<<2))-2;",
-    "}",
+    "  WLAT (R[15], PH2T (PC + 2));",
 #else
-    "if (i == 0xc3)",
-    "  {",
-    "    nip = PC;",
-    "    trap (i, R, memory, maskl, maskw,endianw);",
-    "  }",
-    "else if (i < 20 || i==34 || i==0xc3)",
-    "  trap (i, R, memory, maskl, maskw,endianw);",
     "else if (!SR_BL) {",
-    "  /* FIXME: TRA = (imm << 2); */",
     "  SSR = GET_SR();",
     "  SPC = PH2T (PC + 2);",
     "  SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
     "  /* FIXME: EXPEVT = 0x00000160; */",
-    "  SET_NIP (PT2H (VBR + 0x00000100));",
-    "}",
 #endif
+    "  SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
+    "}",
   },
 
   { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
diff --git a/sim/sh/interp.c b/sim/sh/interp.c
index 2f5d1d3..8c2f359 100644
--- a/sim/sh/interp.c
+++ b/sim/sh/interp.c
@@ -954,12 +954,14 @@
   while (start < end);
 }
 
-/* Simulate a monitor trap, put the result into r0 and errno into r1 */
+/* Simulate a monitor trap, put the result into r0 and errno into r1
+   return offset by which to adjust pc.  */
 
-static void
-trap (i, regs, memory, maskl, maskw, endianw)
+static int
+trap (i, regs, insn_ptr, memory, maskl, maskw, endianw)
      int i;
      int *regs;
+     unsigned char *insn_ptr;
      unsigned char *memory;
 {
   switch (i)
@@ -971,6 +973,13 @@
       raise_exception (SIGQUIT);
       break;
     case 3:			/* FIXME: for backwards compat, should be removed */
+    case 33:
+      {
+	unsigned int countp = * (unsigned int *) (insn_ptr + 4);
+
+	WLAT (countp, RLAT (countp) + 1);
+	return 6;
+      }
     case 34:
       {
 	extern int errno;
@@ -1154,9 +1163,11 @@
     case 0xc3:
     case 255:
       raise_exception (SIGTRAP);
+      if (i == 0xc3)
+	return -2;
       break;
     }
-
+  return 0;
 }
 
 void