| Index: bfd/elf32-m68hc1x.c | 
| diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c | 
| index 961dce482e63f1c47b2f3867aaa79424763f49f7..d862c9fbe326d0dc895d7ea629342c947d6e3092 100644 | 
| --- a/bfd/elf32-m68hc1x.c | 
| +++ b/bfd/elf32-m68hc1x.c | 
| @@ -1,6 +1,6 @@ | 
| /* Motorola 68HC11/HC12-specific support for 32-bit ELF | 
| Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, | 
| -   2009, 2010, 2011  Free Software Foundation, Inc. | 
| +   2009, 2010, 2011, 2012 Free Software Foundation, Inc. | 
| Contributed by Stephane Carrez (stcarrez@nerim.fr) | 
|  | 
| This file is part of BFD, the Binary File Descriptor library. | 
| @@ -20,8 +20,8 @@ | 
| Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 
| MA 02110-1301, USA.  */ | 
|  | 
| -#include "alloca-conf.h" | 
| #include "sysdep.h" | 
| +#include "alloca-conf.h" | 
| #include "bfd.h" | 
| #include "bfdlink.h" | 
| #include "libbfd.h" | 
| @@ -50,7 +50,7 @@ static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info, | 
| static bfd_boolean m68hc11_elf_export_one_stub | 
| (struct bfd_hash_entry *gen_entry, void *in_arg); | 
|  | 
| -static void scan_sections_for_abi (bfd*, asection*, PTR); | 
| +static void scan_sections_for_abi (bfd*, asection*, void *); | 
|  | 
| struct m68hc11_scan_param | 
| { | 
| @@ -214,6 +214,20 @@ elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, | 
| return TRUE; | 
| } | 
|  | 
| +/* Merge non-visibility st_other attributes, STO_M68HC12_FAR and | 
| +   STO_M68HC12_INTERRUPT.  */ | 
| + | 
| +void | 
| +elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h, | 
| +				      const Elf_Internal_Sym *isym, | 
| +				      bfd_boolean definition, | 
| +				      bfd_boolean dynamic ATTRIBUTE_UNUSED) | 
| +{ | 
| +  if (definition) | 
| +    h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) | 
| +		| ELF_ST_VISIBILITY (h->other)); | 
| +} | 
| + | 
| /* External entry points for sizing and building linker stubs.  */ | 
|  | 
| /* Set up various things so that we can make a list of input sections | 
| @@ -935,6 +949,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, | 
| bfd_vma insn_page; | 
| bfd_boolean is_far = FALSE; | 
| struct elf_link_hash_entry *h; | 
| +      bfd_vma val; | 
|  | 
| r_symndx = ELF32_R_SYM (rel->r_info); | 
| r_type = ELF32_R_TYPE (rel->r_info); | 
| @@ -970,9 +985,9 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, | 
| is_far = (h && (h->other & STO_M68HC12_FAR)); | 
| } | 
|  | 
| -      if (sec != NULL && elf_discarded_section (sec)) | 
| +      if (sec != NULL && discarded_section (sec)) | 
| RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, | 
| -					 rel, relend, howto, contents); | 
| +					 rel, 1, relend, howto, 0, contents); | 
|  | 
| if (info->relocatable) | 
| { | 
| @@ -1015,6 +1030,50 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, | 
| phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend); | 
| switch (r_type) | 
| { | 
| +        case R_M68HC12_LO8XG: | 
| +          /* This relocation is specific to XGATE IMM16 calls and will precede | 
| +	     a HI8. tc-m68hc11 only generates them in pairs. | 
| +	     Leave the relocation to the HI8XG step.  */ | 
| +          r = bfd_reloc_ok; | 
| +          r_type = R_M68HC11_NONE; | 
| +          break; | 
| + | 
| +        case R_M68HC12_HI8XG: | 
| +          /* This relocation is specific to XGATE IMM16 calls and must follow | 
| +             a LO8XG. Does not actually check that it was a LO8XG. | 
| +	     Adjusts high and low bytes.  */ | 
| +          relocation = phys_addr; | 
| +          if ((elf_elfheader (input_bfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET) | 
| +	      && (relocation >= 0x2000)) | 
| +	    relocation += 0xc000; /* HARDCODED RAM offset for XGATE.  */ | 
| + | 
| +          /* Fetch 16 bit value including low byte in previous insn.  */ | 
| +          val = (bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset) << 8) | 
| +	    | bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset - 2); | 
| + | 
| +          /* Add on value to preserve carry, then write zero to high byte.  */ | 
| +          relocation += val; | 
| + | 
| +          /* Write out top byte.  */ | 
| +          bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, | 
| +		     (bfd_byte*) contents + rel->r_offset); | 
| + | 
| +          /* Write out low byte to previous instruction.  */ | 
| +          bfd_put_8 (input_bfd, relocation & 0xff, | 
| +		     (bfd_byte*) contents + rel->r_offset - 2); | 
| + | 
| +          /* Mark as relocation completed.  */ | 
| +          r = bfd_reloc_ok; | 
| +          r_type = R_M68HC11_NONE; | 
| +          break; | 
| + | 
| +        /* The HI8 and LO8 relocs are generated by %hi(expr) %lo(expr) | 
| +           assembler directives. %hi does not support carry.  */ | 
| +        case R_M68HC11_HI8: | 
| +        case R_M68HC11_LO8: | 
| +          relocation = phys_addr; | 
| +          break; | 
| + | 
| case R_M68HC11_24: | 
| /* Reloc used by 68HC12 call instruction.  */ | 
| bfd_put_16 (input_bfd, phys_addr, | 
| @@ -1109,10 +1168,18 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, | 
| relocation = phys_addr; | 
| break; | 
| } | 
| + | 
| if (r_type != R_M68HC11_NONE) | 
| -        r = _bfd_final_link_relocate (howto, input_bfd, input_section, | 
| +        { | 
| +          if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10)) | 
| +            r = _bfd_final_link_relocate (howto, input_bfd, input_section, | 
| contents, rel->r_offset, | 
| -                                      relocation, rel->r_addend); | 
| +                                      relocation - 2, rel->r_addend); | 
| +          else | 
| +            r = _bfd_final_link_relocate (howto, input_bfd, input_section, | 
| +                                          contents, rel->r_offset, | 
| +                                          relocation, rel->r_addend); | 
| +        } | 
|  | 
| if (r != bfd_reloc_ok) | 
| { | 
| @@ -1303,6 +1370,9 @@ _bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr) | 
| else | 
| fprintf (file, _(" [memory=flat]")); | 
|  | 
| +  if (elf_elfheader (abfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET) | 
| +    fprintf (file, _(" [XGATE RAM offsetting]")); | 
| + | 
| fputc ('\n', file); | 
|  | 
| return TRUE; | 
|  |