gdb: objc-lang: check symbol name before accessing memory
[deliverable/binutils-gdb.git] / bfd / elf32-avr.c
index fffd0409663839e5842fbb9f6626a5e583631994..92c5be9d17de4b9b7bc558dbca07cf0f6de2d148 100644 (file)
@@ -1,6 +1,6 @@
 /* AVR-specific support for 32-bit ELF
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008
-   Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010  Free Software Foundation, Inc.
    Contributed by Denis Chertykov <denisc@overta.ru>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -38,7 +38,7 @@ static bfd_boolean debug_stubs = FALSE;
 
 /* We use two hash tables to hold information for linking avr objects.
 
-   The first is the elf32_avr_link_hash_tablse which is derived from the
+   The first is the elf32_avr_link_hash_table which is derived from the
    stanard ELF linker hash table.  We use this as a place to attach the other
    hash table and some static information.
 
@@ -104,8 +104,8 @@ struct elf32_avr_link_hash_table
 /* Various hash macros and functions.  */
 #define avr_link_hash_table(p) \
   /* PR 3874: Check that we have an AVR style hash table before using it.  */\
-  ((p)->hash->table.newfunc != elf32_avr_link_hash_newfunc ? NULL : \
-   ((struct elf32_avr_link_hash_table *) ((p)->hash)))
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+  == AVR_ELF_DATA ? ((struct elf32_avr_link_hash_table *) ((p)->hash)) : NULL)
 
 #define avr_stub_hash_entry(ent) \
   ((struct elf32_avr_stub_hash_entry *)(ent))
@@ -473,7 +473,7 @@ static reloc_howto_type elf_avr_howto_table[] =
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
   /* A low 8 bit absolute relocation of 24 bit program memory address.
-     For LDI command.  Will be changed when linker stubs are needed. */
+     For LDI command.  Will be changed when linker stubs are needed.  */
   HOWTO (R_AVR_LO8_LDI_GS,      /* type */
          1,                     /* rightshift */
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -488,7 +488,7 @@ static reloc_howto_type elf_avr_howto_table[] =
          0xffff,                /* dst_mask */
          FALSE),                /* pcrel_offset */
   /* A low 8 bit absolute relocation of 24 bit program memory address.
-     For LDI command.  Will be changed when linker stubs are needed. */
+     For LDI command.  Will be changed when linker stubs are needed.  */
   HOWTO (R_AVR_HI8_LDI_GS,      /* type */
          9,                     /* rightshift */
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -501,7 +501,21 @@ static reloc_howto_type elf_avr_howto_table[] =
          FALSE,                 /* partial_inplace */
          0xffff,                /* src_mask */
          0xffff,                /* dst_mask */
-         FALSE)                 /* pcrel_offset */
+         FALSE),                /* pcrel_offset */
+  /* 8 bit offset.  */
+  HOWTO (R_AVR_8,              /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_AVR_8",             /* name */
+        FALSE,                 /* partial_inplace */
+        0x000000ff,            /* src_mask */
+        0x000000ff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
 };
 
 /* Map BFD reloc types to AVR ELF reloc types.  */
@@ -539,7 +553,8 @@ static const struct avr_reloc_map avr_reloc_map[] =
   { BFD_RELOC_AVR_CALL,             R_AVR_CALL },
   { BFD_RELOC_AVR_LDI,              R_AVR_LDI  },
   { BFD_RELOC_AVR_6,                R_AVR_6    },
-  { BFD_RELOC_AVR_6_ADIW,           R_AVR_6_ADIW }
+  { BFD_RELOC_AVR_6_ADIW,           R_AVR_6_ADIW },
+  { BFD_RELOC_8,                    R_AVR_8 }
 };
 
 /* Meant to be filled one day with the wrap around address for the
@@ -617,7 +632,8 @@ elf32_avr_link_hash_table_create (bfd *abfd)
 
   if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
                                       elf32_avr_link_hash_newfunc,
-                                      sizeof (struct elf_link_hash_entry)))
+                                      sizeof (struct elf_link_hash_entry),
+                                     AVR_ELF_DATA))
     {
       free (htab);
       return NULL;
@@ -775,14 +791,14 @@ static bfd_vma
 avr_get_stub_addr (bfd_vma srel,
                    struct elf32_avr_link_hash_table *htab)
 {
-  unsigned int index;
+  unsigned int sindex;
   bfd_vma stub_sec_addr =
               (htab->stub_sec->output_section->vma +
               htab->stub_sec->output_offset);
 
-  for (index = 0; index < htab->amt_max_entry_cnt; index ++)
-    if (htab->amt_destination_addr[index] == srel)
-      return htab->amt_stub_offsets[index] + stub_sec_addr;
+  for (sindex = 0; sindex < htab->amt_max_entry_cnt; sindex ++)
+    if (htab->amt_destination_addr[sindex] == srel)
+      return htab->amt_stub_offsets[sindex] + stub_sec_addr;
 
   /* Return an address that could not be reached by 16 bit relocs.  */
   return 0x020000;
@@ -854,10 +870,11 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
        {
           /* Relative distance is too large.  */
 
-         /* Always apply WRAPAROUND for avr2 and avr4.  */
+         /* Always apply WRAPAROUND for avr2, avr25, and avr4.  */
          switch (bfd_get_mach (input_bfd))
            {
            case bfd_mach_avr2:
+           case bfd_mach_avr25:
            case bfd_mach_avr4:
              break;
 
@@ -1166,6 +1183,9 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
   Elf_Internal_Rela *           relend;
   struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
 
+  if (htab == NULL)
+    return FALSE;
+
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
@@ -1298,6 +1318,7 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
 
     case bfd_mach_avr25:
       val = E_AVR_MACH_AVR25;
+      break;
 
     case bfd_mach_avr3:
       val = E_AVR_MACH_AVR3;
@@ -1305,9 +1326,11 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
 
     case bfd_mach_avr31:
       val = E_AVR_MACH_AVR31;
+      break;
 
     case bfd_mach_avr35:
       val = E_AVR_MACH_AVR35;
+      break;
 
     case bfd_mach_avr4:
       val = E_AVR_MACH_AVR4;
@@ -1411,7 +1434,6 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
   Elf_Internal_Rela *irelalign;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymbuf = NULL;
-  Elf_Internal_Sym *isymend;
   bfd_vma toaddr;
   struct elf_link_hash_entry **sym_hashes;
   struct elf_link_hash_entry **end_hashes;
@@ -1507,7 +1529,6 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
            if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
              {
                /* A local symbol.  */
-               Elf_Internal_Sym *isym;
                asection *sym_sec;
 
                isym = isymbuf + ELF32_R_SYM (irel->r_info);
@@ -1549,13 +1570,19 @@ elf32_avr_relax_delete_bytes (bfd *abfd,
 
   /* Adjust the local symbols defined in this section.  */
   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
-  isymend = isym + symtab_hdr->sh_info;
-  for (; isym < isymend; isym++)
+  /* Fix PR 9841, there may be no local symbols.  */
+  if (isym != NULL)
     {
-      if (isym->st_shndx == sec_shndx
-          && isym->st_value > addr
-          && isym->st_value < toaddr)
-        isym->st_value -= count;
+      Elf_Internal_Sym *isymend;
+
+      isymend = isym + symtab_hdr->sh_info;
+      for (; isym < isymend; isym++)
+       {
+         if (isym->st_shndx == sec_shndx
+             && isym->st_value > addr
+             && isym->st_value < toaddr)
+           isym->st_value -= count;
+       }
     }
 
   /* Now adjust the global symbols defined in this section.  */
@@ -1625,6 +1652,10 @@ elf32_avr_relax_section (bfd *abfd,
   static Elf_Internal_Rela *last_reloc = NULL;
   struct elf32_avr_link_hash_table *htab;
 
+  if (link_info->relocatable)
+    (*link_info->callbacks->einfo)
+      (_("%P%F: --relax and -r may not be used together\n"));
+
   htab = avr_link_hash_table (link_info);
   if (htab == NULL)
     return FALSE;
@@ -1690,8 +1721,8 @@ elf32_avr_relax_section (bfd *abfd,
       bfd_vma symval;
 
       if (   ELF32_R_TYPE (irel->r_info) != R_AVR_13_PCREL
-          && ELF32_R_TYPE (irel->r_info) != R_AVR_7_PCREL
-          && ELF32_R_TYPE (irel->r_info) != R_AVR_CALL)
+            && ELF32_R_TYPE (irel->r_info) != R_AVR_7_PCREL
+            && ELF32_R_TYPE (irel->r_info) != R_AVR_CALL)
         continue;
 
       /* Get the section contents if we haven't done so already.  */
@@ -1708,7 +1739,7 @@ elf32_avr_relax_section (bfd *abfd,
             }
         }
 
-     /* Read this BFD's local symbols if we haven't done so already.  */
+      /* Read this BFD's local symbols if we haven't done so already.  */
       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
         {
           isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
@@ -1767,9 +1798,9 @@ elf32_avr_relax_section (bfd *abfd,
          the linker is run.  */
       switch (ELF32_R_TYPE (irel->r_info))
         {
-         /* Try to turn a 22-bit absolute call/jump into an 13-bit
-            pc-relative rcall/rjmp.  */
-         case R_AVR_CALL:
+         /* Try to turn a 22-bit absolute call/jump into an 13-bit
+            pc-relative rcall/rjmp.  */
+       case R_AVR_CALL:
           {
             bfd_vma value = symval + irel->r_addend;
             bfd_vma dot, gap;
@@ -1794,27 +1825,27 @@ elf32_avr_relax_section (bfd *abfd,
                vaiable avr_pc_wrap_around with the appropriate value.
                I.e. 0x4000 for a 16k device.  */
             {
-               /* Shrinking the code size makes the gaps larger in the
-                  case of wrap-arounds.  So we use a heuristical safety
-                  margin to avoid that during relax the distance gets
-                  again too large for the short jumps.  Let's assume
-                  a typical code-size reduction due to relax for a
-                  16k device of 600 bytes.  So let's use twice the
-                  typical value as safety margin.  */
-               int rgap;
-               int safety_margin;
-
-               int assumed_shrink = 600;
-               if (avr_pc_wrap_around > 0x4000)
-                 assumed_shrink = 900;
-
-               safety_margin = 2 * assumed_shrink;
-
-               rgap = avr_relative_distance_considering_wrap_around (gap);
-
-               if (rgap >= (-4092 + safety_margin)
-                   && rgap <= (4094 - safety_margin))
-                distance_short_enough = 1;
+             /* Shrinking the code size makes the gaps larger in the
+                case of wrap-arounds.  So we use a heuristical safety
+                margin to avoid that during relax the distance gets
+                again too large for the short jumps.  Let's assume
+                a typical code-size reduction due to relax for a
+                16k device of 600 bytes.  So let's use twice the
+                typical value as safety margin.  */
+             int rgap;
+             int safety_margin;
+
+             int assumed_shrink = 600;
+             if (avr_pc_wrap_around > 0x4000)
+               assumed_shrink = 900;
+
+             safety_margin = 2 * assumed_shrink;
+
+             rgap = avr_relative_distance_considering_wrap_around (gap);
+
+             if (rgap >= (-4092 + safety_margin)
+                 && rgap <= (4094 - safety_margin))
+               distance_short_enough = 1;
             }
 
             if (distance_short_enough)
@@ -1908,9 +1939,9 @@ elf32_avr_relax_section (bfd *abfd,
                 if (irel->r_offset + 3 < sec->size)
                   {
                     next_insn_msb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 3);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 3);
                     next_insn_lsb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 2);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 2);
                   }
 
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
@@ -1938,9 +1969,9 @@ elf32_avr_relax_section (bfd *abfd,
                 if (irel->r_offset + 5 < sec->size)
                   {
                     next_insn_msb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 5);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 5);
                     next_insn_lsb =
-                        bfd_get_8 (abfd, contents + irel->r_offset + 4);
+                     bfd_get_8 (abfd, contents + irel->r_offset + 4);
                   }
 
                 if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
@@ -1975,11 +2006,11 @@ elf32_avr_relax_section (bfd *abfd,
                 if (irel->r_offset + insn_size + 1 < sec->size)
                   {
                     next_insn_msb =
-                        bfd_get_8 (abfd, contents + irel->r_offset
-                                         + insn_size + 1);
+                     bfd_get_8 (abfd, contents + irel->r_offset
+                                + insn_size + 1);
                     next_insn_lsb =
-                        bfd_get_8 (abfd, contents + irel->r_offset
-                                         + insn_size);
+                     bfd_get_8 (abfd, contents + irel->r_offset
+                                + insn_size);
                   }
 
                 if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
@@ -2006,9 +2037,9 @@ elf32_avr_relax_section (bfd *abfd,
                         unsigned char preceeding_msb;
                         unsigned char preceeding_lsb;
                         preceeding_msb =
-                            bfd_get_8 (abfd, contents + irel->r_offset - 1);
+                         bfd_get_8 (abfd, contents + irel->r_offset - 1);
                         preceeding_lsb =
-                            bfd_get_8 (abfd, contents + irel->r_offset - 2);
+                         bfd_get_8 (abfd, contents + irel->r_offset - 2);
 
                         /* sbic.  */
                         if (0x99 == preceeding_msb)
@@ -2020,12 +2051,12 @@ elf32_avr_relax_section (bfd *abfd,
 
                         /* sbrc */
                         if ((0xfc == (preceeding_msb & 0xfe)
-                            && (0x00 == (preceeding_lsb & 0x08))))
+                            && (0x00 == (preceeding_lsb & 0x08))))
                           there_is_preceeding_non_skip_insn = 0;
 
                         /* sbrs */
                         if ((0xfe == (preceeding_msb & 0xfe)
-                            && (0x00 == (preceeding_lsb & 0x08))))
+                            && (0x00 == (preceeding_lsb & 0x08))))
                           there_is_preceeding_non_skip_insn = 0;
 
                         /* cpse */
@@ -2053,7 +2084,7 @@ elf32_avr_relax_section (bfd *abfd,
 
                         int deleting_ret_is_safe = 1;
                         unsigned int section_offset_of_ret_insn =
-                                          irel->r_offset + insn_size;
+                         irel->r_offset + insn_size;
                         Elf_Internal_Sym *isym, *isymend;
                         unsigned int sec_shndx;
 
@@ -2065,145 +2096,140 @@ elf32_avr_relax_section (bfd *abfd,
                         isymend = isym + symtab_hdr->sh_info;
                        /* PR 6019: There may not be any local symbols.  */
                         for (; isym != NULL && isym < isymend; isym++)
-                         {
-                           if (isym->st_value == section_offset_of_ret_insn
-                               && isym->st_shndx == sec_shndx)
-                             {
-                               deleting_ret_is_safe = 0;
-                               if (debug_relax)
-                                 printf ("local label prevents deletion of ret "
-                                         "insn at address 0x%x\n",
-                                         (int) dot + insn_size);
-                             }
-                         }
-
-                         /* Now check for global symbols.  */
-                         {
-                           int symcount;
-                           struct elf_link_hash_entry **sym_hashes;
-                           struct elf_link_hash_entry **end_hashes;
-
-                           symcount = (symtab_hdr->sh_size
-                                       / sizeof (Elf32_External_Sym)
-                                       - symtab_hdr->sh_info);
-                           sym_hashes = elf_sym_hashes (abfd);
-                           end_hashes = sym_hashes + symcount;
-                           for (; sym_hashes < end_hashes; sym_hashes++)
-                            {
-                              struct elf_link_hash_entry *sym_hash =
-                                                                 *sym_hashes;
-                              if ((sym_hash->root.type == bfd_link_hash_defined
-                                  || sym_hash->root.type ==
+                         {
+                           if (isym->st_value == section_offset_of_ret_insn
+                               && isym->st_shndx == sec_shndx)
+                             {
+                               deleting_ret_is_safe = 0;
+                               if (debug_relax)
+                                 printf ("local label prevents deletion of ret "
+                                         "insn at address 0x%x\n",
+                                         (int) dot + insn_size);
+                             }
+                         }
+
+                       /* Now check for global symbols.  */
+                       {
+                         int symcount;
+                         struct elf_link_hash_entry **sym_hashes;
+                         struct elf_link_hash_entry **end_hashes;
+
+                         symcount = (symtab_hdr->sh_size
+                                     / sizeof (Elf32_External_Sym)
+                                     - symtab_hdr->sh_info);
+                         sym_hashes = elf_sym_hashes (abfd);
+                         end_hashes = sym_hashes + symcount;
+                         for (; sym_hashes < end_hashes; sym_hashes++)
+                           {
+                             struct elf_link_hash_entry *sym_hash =
+                               *sym_hashes;
+                             if ((sym_hash->root.type == bfd_link_hash_defined
+                                  || sym_hash->root.type ==
                                   bfd_link_hash_defweak)
-                                  && sym_hash->root.u.def.section == sec
-                                  && sym_hash->root.u.def.value == section_offset_of_ret_insn)
-                                {
-                                  deleting_ret_is_safe = 0;
-                                  if (debug_relax)
-                                    printf ("global label prevents deletion of "
-                                            "ret insn at address 0x%x\n",
-                                            (int) dot + insn_size);
-                                }
-                            }
-                         }
-                         /* Now we check for relocations pointing to ret.  */
-                         {
-                           Elf_Internal_Rela *irel;
-                           Elf_Internal_Rela *relend;
-                           Elf_Internal_Shdr *symtab_hdr;
-
-                           symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-                           relend = elf_section_data (sec)->relocs
-                                    + sec->reloc_count;
-
-                           for (irel = elf_section_data (sec)->relocs;
-                                irel < relend; irel++)
-                             {
-                               bfd_vma reloc_target = 0;
-                               bfd_vma symval;
-                               Elf_Internal_Sym *isymbuf = NULL;
-
-                               /* Read this BFD's local symbols if we haven't
-                                  done so already.  */
-                               if (isymbuf == NULL && symtab_hdr->sh_info != 0)
-                                 {
-                                   isymbuf = (Elf_Internal_Sym *)
-                                             symtab_hdr->contents;
-                                   if (isymbuf == NULL)
-                                     isymbuf = bfd_elf_get_elf_syms
-                                      (abfd,
-                                       symtab_hdr,
-                                       symtab_hdr->sh_info, 0,
-                                       NULL, NULL, NULL);
-                                   if (isymbuf == NULL)
-                                     break;
-                                  }
-
-                               /* Get the value of the symbol referred to
-                                  by the reloc.  */
-                               if (ELF32_R_SYM (irel->r_info)
-                                   < symtab_hdr->sh_info)
-                                 {
-                                   /* A local symbol.  */
-                                   Elf_Internal_Sym *isym;
-                                   asection *sym_sec;
-
-                                   isym = isymbuf
-                                          + ELF32_R_SYM (irel->r_info);
-                                   sym_sec = bfd_section_from_elf_index
-                                    (abfd, isym->st_shndx);
-                                   symval = isym->st_value;
-
-                                   /* If the reloc is absolute, it will not
-                                      have a symbol or section associated
-                                      with it.  */
-
-                                   if (sym_sec)
-                                     {
-                                       symval +=
-                                           sym_sec->output_section->vma
-                                           + sym_sec->output_offset;
-                                       reloc_target = symval + irel->r_addend;
-                                     }
-                                   else
-                                     {
-                                       reloc_target = symval + irel->r_addend;
-                                       /* Reference symbol is absolute.  */
-                                     }
-                                 }
-                              /* else ... reference symbol is extern.  */
-
-                               if (address_of_ret == reloc_target)
-                                 {
-                                   deleting_ret_is_safe = 0;
-                                   if (debug_relax)
-                                     printf ("ret from "
-                                             "rjmp/jmp ret sequence at address"
-                                             " 0x%x could not be deleted. ret"
-                                             " is target of a relocation.\n",
-                                             (int) address_of_ret);
-                                 }
-                             }
-                         }
-
-                         if (deleting_ret_is_safe)
-                           {
-                             if (debug_relax)
-                               printf ("unreachable ret instruction "
-                                       "at address 0x%x deleted.\n",
-                                       (int) dot + insn_size);
-
-                             /* Delete two bytes of data.  */
-                             if (!elf32_avr_relax_delete_bytes (abfd, sec,
-                                        irel->r_offset + insn_size, 2))
-                               goto error_return;
-
-                             /* That will change things, so, we should relax
-                                again. Note that this is not required, and it
-                                may be slow.  */
-                             *again = TRUE;
-                             break;
-                           }
+                                 && sym_hash->root.u.def.section == sec
+                                 && sym_hash->root.u.def.value == section_offset_of_ret_insn)
+                               {
+                                 deleting_ret_is_safe = 0;
+                                 if (debug_relax)
+                                   printf ("global label prevents deletion of "
+                                           "ret insn at address 0x%x\n",
+                                           (int) dot + insn_size);
+                               }
+                           }
+                       }
+                       /* Now we check for relocations pointing to ret.  */
+                       {
+                         Elf_Internal_Rela *rel;
+                         Elf_Internal_Rela *relend;
+
+                         relend = elf_section_data (sec)->relocs
+                           + sec->reloc_count;
+
+                         for (rel = elf_section_data (sec)->relocs;
+                              rel < relend; rel++)
+                           {
+                             bfd_vma reloc_target = 0;
+
+                             /* Read this BFD's local symbols if we haven't
+                                done so already.  */
+                             if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+                               {
+                                 isymbuf = (Elf_Internal_Sym *)
+                                   symtab_hdr->contents;
+                                 if (isymbuf == NULL)
+                                   isymbuf = bfd_elf_get_elf_syms
+                                     (abfd,
+                                      symtab_hdr,
+                                      symtab_hdr->sh_info, 0,
+                                      NULL, NULL, NULL);
+                                 if (isymbuf == NULL)
+                                   break;
+                               }
+
+                             /* Get the value of the symbol referred to
+                                by the reloc.  */
+                             if (ELF32_R_SYM (rel->r_info)
+                                 < symtab_hdr->sh_info)
+                               {
+                                 /* A local symbol.  */
+                                 asection *sym_sec;
+
+                                 isym = isymbuf
+                                   + ELF32_R_SYM (rel->r_info);
+                                 sym_sec = bfd_section_from_elf_index
+                                   (abfd, isym->st_shndx);
+                                 symval = isym->st_value;
+
+                                 /* If the reloc is absolute, it will not
+                                    have a symbol or section associated
+                                    with it.  */
+
+                                 if (sym_sec)
+                                   {
+                                     symval +=
+                                       sym_sec->output_section->vma
+                                       + sym_sec->output_offset;
+                                     reloc_target = symval + rel->r_addend;
+                                   }
+                                 else
+                                   {
+                                     reloc_target = symval + rel->r_addend;
+                                     /* Reference symbol is absolute.  */
+                                   }
+                               }
+                             /* else ... reference symbol is extern.  */
+
+                             if (address_of_ret == reloc_target)
+                               {
+                                 deleting_ret_is_safe = 0;
+                                 if (debug_relax)
+                                   printf ("ret from "
+                                           "rjmp/jmp ret sequence at address"
+                                           " 0x%x could not be deleted. ret"
+                                           " is target of a relocation.\n",
+                                           (int) address_of_ret);
+                               }
+                           }
+                       }
+
+                       if (deleting_ret_is_safe)
+                         {
+                           if (debug_relax)
+                             printf ("unreachable ret instruction "
+                                     "at address 0x%x deleted.\n",
+                                     (int) dot + insn_size);
+
+                           /* Delete two bytes of data.  */
+                           if (!elf32_avr_relax_delete_bytes (abfd, sec,
+                                                              irel->r_offset + insn_size, 2))
+                             goto error_return;
+
+                           /* That will change things, so, we should relax
+                              again. Note that this is not required, and it
+                              may be slow.  */
+                           *again = TRUE;
+                           break;
+                         }
                       }
 
                   }
@@ -2556,7 +2582,7 @@ elf32_avr_setup_section_lists (bfd *output_bfd,
   asection *section;
   asection **input_list, **list;
   bfd_size_type amt;
-  struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
+  struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
 
   if (htab == NULL || htab->no_stubs)
     return 0;
This page took 0.033371 seconds and 4 git commands to generate.