OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [elf32-h8300.c] - Diff between revs 157 and 225

Show entire file | Details | Blame | View Log

Rev 157 Rev 225
Line 1... Line 1...
/* BFD back-end for Renesas H8/300 ELF binaries.
/* BFD back-end for Renesas H8/300 ELF binaries.
   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
   Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
   2007 Free Software Foundation, Inc.
   2007, 2009 Free Software Foundation, Inc.
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
Line 720... Line 720...
  irelend = internal_relocs + sec->reloc_count;
  irelend = internal_relocs + sec->reloc_count;
  for (irel = internal_relocs; irel < irelend; irel++)
  for (irel = internal_relocs; irel < irelend; irel++)
    {
    {
      bfd_vma symval;
      bfd_vma symval;
 
 
 
      {
 
        arelent bfd_reloc;
 
        reloc_howto_type *h;
 
 
 
        elf32_h8_info_to_howto (abfd, &bfd_reloc, irel);
 
        h = bfd_reloc.howto;
 
      }
      /* Keep track of the previous reloc so that we can delete
      /* Keep track of the previous reloc so that we can delete
         some long jumps created by the compiler.  */
         some long jumps created by the compiler.  */
      if (irel != internal_relocs)
      if (irel != internal_relocs)
        last_reloc = irel - 1;
        last_reloc = irel - 1;
 
 
Line 992... Line 999...
                  }
                  }
                else if (code == 0x5c)
                else if (code == 0x5c)
                  /* This is bsr.  */
                  /* This is bsr.  */
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
                  bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
                else
                else
                  abort ();
                  /* Might be MOVSD.  */
 
                  break;
 
 
                /* Fix the relocation's type.  */
                /* Fix the relocation's type.  */
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                                             R_H8_PCREL8);
                                             R_H8_PCREL8);
                irel->r_offset--;
                irel->r_offset--;
Line 1205... Line 1213...
 
 
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
            if (value <= 0x7fff || value >= 0xffff8000u)
            if (value <= 0x7fff || value >= 0xffff8000u)
              {
              {
                unsigned char code;
                unsigned char code;
 
                unsigned char op0, op1, op2, op3;
 
                unsigned char *op_ptr;
 
 
                /* Note that we've changed the relocs, section contents,
                /* Note that we've changed the relocs, section contents,
                   etc.  */
                   etc.  */
                elf_section_data (sec)->relocs = internal_relocs;
                elf_section_data (sec)->relocs = internal_relocs;
                elf_section_data (sec)->this_hdr.contents = contents;
                elf_section_data (sec)->this_hdr.contents = contents;
                symtab_hdr->contents = (unsigned char *) isymbuf;
                symtab_hdr->contents = (unsigned char *) isymbuf;
 
 
 
                if (irel->r_offset >= 4)
 
                  {
 
                    /* Check for 4-byte MOVA relaxation.  */
 
                    int second_reloc = 0;
 
 
 
                    op_ptr = contents + irel->r_offset - 4;
 
 
 
                    if (last_reloc)
 
                      {
 
                        arelent bfd_reloc;
 
                        reloc_howto_type *h;
 
                        bfd_vma last_reloc_size;
 
 
 
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc);
 
                        h = bfd_reloc.howto;
 
                        last_reloc_size = 1 << h->size;
 
                        if (last_reloc->r_offset + last_reloc_size
 
                            == irel->r_offset)
 
                          {
 
                            op_ptr -= last_reloc_size;
 
                            second_reloc = 1;
 
                          }
 
                      }
 
                    if (irel < irelend)
 
                      {
 
                        Elf_Internal_Rela *next_reloc = irel + 1;
 
                        arelent bfd_reloc;
 
                        reloc_howto_type *h;
 
                        bfd_vma next_reloc_size;
 
 
 
                        elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc);
 
                        h = bfd_reloc.howto;
 
                        next_reloc_size = 1 << h->size;
 
                        if (next_reloc->r_offset + next_reloc_size
 
                            == irel->r_offset)
 
                          {
 
                            op_ptr -= next_reloc_size;
 
                            second_reloc = 1;
 
                          }
 
                      }
 
 
 
                    op0 = bfd_get_8 (abfd, op_ptr + 0);
 
                    op1 = bfd_get_8 (abfd, op_ptr + 1);
 
                    op2 = bfd_get_8 (abfd, op_ptr + 2);
 
                    op3 = bfd_get_8 (abfd, op_ptr + 3);
 
 
 
                    if (op0 == 0x01
 
                        && (op1 & 0xdf) == 0x5f
 
                        && (op2 & 0x40) == 0x40
 
                        && (op3 & 0x80) == 0x80)
 
                      {
 
                        if ((op2 & 0x08) == 0)
 
                          second_reloc = 1;
 
 
 
                        if (second_reloc)
 
                          {
 
                            op3 &= ~0x08;
 
                            bfd_put_8 (abfd, op3, op_ptr + 3);
 
                          }
 
                        else
 
                          {
 
                            op2 &= ~0x08;
 
                            bfd_put_8 (abfd, op2, op_ptr + 2);
 
                          }
 
                        goto r_h8_dir32a16_common;
 
                      }
 
                  }
 
 
 
                /* Now check for short version of MOVA.  */
 
                op_ptr = contents + irel->r_offset - 2;
 
                op0 = bfd_get_8 (abfd, op_ptr + 0);
 
                op1 = bfd_get_8 (abfd, op_ptr + 1);
 
 
 
                if (op0 == 0x7a
 
                    && (op1 & 0x88) == 0x80)
 
                  {
 
                    op1 |= 0x08;
 
                    bfd_put_8 (abfd, op1, op_ptr + 1);
 
                    goto r_h8_dir32a16_common;
 
                  }
 
 
                /* Get the opcode.  */
                /* Get the opcode.  */
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
                code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
 
 
                /* Fix the opcode.  For all the instructions that
                /* Fix the opcode.  For all the instructions that
                   belong to this relaxation, we simply need to turn
                   belong to this relaxation, we simply need to turn
                   off bit 0x20 in the previous byte.  */
                   off bit 0x20 in the previous byte.  */
                code &= ~0x20;
                code &= ~0x20;
 
 
                bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
                bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
 
 
 
              r_h8_dir32a16_common:
                /* Fix the relocation's type.  */
                /* Fix the relocation's type.  */
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                                             R_H8_DIR16);
                                             R_H8_DIR16);
 
 
                /* Delete two bytes of data.  */
                /* Delete two bytes of data.  */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.