* ld.texinfo: Document that fill values now use the four least
[deliverable/binutils-gdb.git] / bfd / elf32-arm.h
index 7bd0cceab2b54aa39cd99312f0f34fad7ffc329b..f8f94d66b8351d3d27f68e69b3664e12534556f3 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM
-   Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -17,7 +17,6 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-
 typedef unsigned long int insn32;
 typedef unsigned short int insn16;
 
@@ -56,7 +55,7 @@ static int elf32_thumb_to_arm_stub
   PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,
           bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));
 
-#define INTERWORK_FLAG(abfd)   (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
+#define INTERWORK_FLAG(abfd)   (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK)
 
 /* The linker script knows the section names for placement.
    The entry_names are used to do simple name mangling on the stubs.
@@ -79,22 +78,22 @@ static int elf32_thumb_to_arm_stub
    this.  It is set up so that any shared library function that is
    called before the relocation has been set up calls the dynamic
    linker first.  */
-static const bfd_byte elf32_arm_plt0_entry [PLT_ENTRY_SIZE] =
+static const unsigned long elf32_arm_plt0_entry [PLT_ENTRY_SIZE / 4] =
 {
-  0x04, 0xe0, 0x2d, 0xe5,      /* str   lr, [sp, #-4]!     */
-  0x10, 0xe0, 0x9f, 0xe5,      /* ldr   lr, [pc, #16]      */
-  0x0e, 0xe0, 0x8f, 0xe0,      /* adr   lr, pc, lr         */
-  0x08, 0xf0, 0xbe, 0xe5       /* ldr   pc, [lr, #8]!      */
+  0xe52de004,  /* str   lr, [sp, #-4]!     */
+  0xe59fe010,  /* ldr   lr, [pc, #16]      */
+  0xe08fe00e,  /* add   lr, pc, lr         */
+  0xe5bef008   /* ldr   pc, [lr, #8]!      */
 };
 
 /* Subsequent entries in a procedure linkage table look like
    this.  */
-static const bfd_byte elf32_arm_plt_entry [PLT_ENTRY_SIZE] =
+static const unsigned long elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] =
 {
-  0x04, 0xc0, 0x9f, 0xe5,      /* ldr   ip, [pc, #4]       */
-  0x0c, 0xc0, 0x8f, 0xe0,      /* add   ip, pc, ip         */
-  0x00, 0xf0, 0x9c, 0xe5,      /* ldr   pc, [ip]           */
-  0x00, 0x00, 0x00, 0x00        /* offset to symbol in got  */
+  0xe59fc004,  /* ldr   ip, [pc, #4]       */
+  0xe08fc00c,  /* add   ip, pc, ip         */
+  0xe59cf000,  /* ldr   pc, [ip]           */
+  0x00000000   /* offset to symbol in got  */
 };
 
 /* The ARM linker needs to keep track of the number of relocs that it
@@ -159,7 +158,6 @@ struct elf32_arm_link_hash_table
   int no_pipeline_knowledge;
 };
 
-
 /* Create an entry in an ARM ELF linker hash table.  */
 
 static struct bfd_hash_entry *
@@ -682,7 +680,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
                }
            }
 
-         /* If the relocation is not against a symbol it cannot concern us. */
+         /* If the relocation is not against a symbol it cannot concern us.  */
          h = NULL;
 
          /* We don't care about local symbols.  */
@@ -1021,6 +1019,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
   bfd_signed_vma                signed_addend;
   struct elf32_arm_link_hash_table * globals;
 
+  /* If the start address has been set, then set the EF_ARM_HASENTRY
+     flag.  Setting this more than once is redundant, but the cost is
+     not too high, and it keeps the code simple.
+     
+     The test is done  here, rather than somewhere else, because the
+     start address is only set just before the final link commences.
+
+     Note - if the user deliberately sets a start address of 0, the
+     flag will not be set.  */
+  if (bfd_get_start_address (output_bfd) != 0)
+    elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
+      
   globals = elf32_arm_hash_table (info);
 
   dynobj = elf_hash_table (info)->dynobj;
@@ -1285,7 +1295,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
 
        case R_ARM_REL32:
          value -= (input_section->output_section->vma
-                   + input_section->output_offset);
+                   + input_section->output_offset + rel->r_offset);
          value += addend;
          break;
        }
@@ -1436,6 +1446,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
        lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
 
+#ifndef OLD_ARM_ABI
+       if (r_type == R_ARM_THM_XPC22
+           && ((lower_insn & 0x1800) == 0x0800))
+         /* Remove bit zero of the adjusted offset.  Bit zero can only be
+            set if the upper insn is at a half-word boundary, since the
+            destination address, an ARM instruction, must always be on a
+            word boundary.  The semantics of the BLX (1) instruction, however,
+            are that bit zero in the offset must always be zero, and the
+            corresponding bit one in the target address will be set from bit
+            one of the source address.  */
+         lower_insn &= ~1;
+#endif 
        /* Put the relocated value back in the object file:  */
        bfd_put_16 (input_bfd, upper_insn, hit_data);
        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
@@ -1479,7 +1501,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                                       (bfd_vma) 0);
 
     case R_ARM_GOTPC:
-      /* Use global offset table as symbol value. */
+      /* Use global offset table as symbol value.  */
       BFD_ASSERT (sgot != NULL);
 
       if (sgot == NULL)
@@ -1965,7 +1987,7 @@ elf32_arm_set_private_flags (abfd, flags)
     {
       if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
        {
-         if (flags & EF_INTERWORK)
+         if (flags & EF_ARM_INTERWORK)
            _bfd_error_handler (_("\
 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
                                bfd_get_filename (abfd));
@@ -2006,28 +2028,28 @@ elf32_arm_copy_private_bfd_data (ibfd, obfd)
       && in_flags != out_flags)
     {
       /* Cannot mix APCS26 and APCS32 code.  */
-      if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
+      if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
        return false;
 
       /* Cannot mix float APCS and non-float APCS code.  */
-      if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
+      if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
        return false;
 
       /* If the src and dest have different interworking flags
          then turn off the interworking bit.  */
-      if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
+      if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
        {
-         if (out_flags & EF_INTERWORK)
+         if (out_flags & EF_ARM_INTERWORK)
            _bfd_error_handler (_("\
 Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
                          bfd_get_filename (obfd), bfd_get_filename (ibfd));
 
-         in_flags &= ~EF_INTERWORK;
+         in_flags &= ~EF_ARM_INTERWORK;
        }
 
       /* Likewise for PIC, though don't warn for this case.  */
-      if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
-       in_flags &= ~EF_PIC;
+      if ((in_flags & EF_ARM_PIC) != (out_flags & EF_ARM_PIC))
+       in_flags &= ~EF_ARM_PIC;
     }
 
   elf_elfheader (obfd)->e_flags = in_flags;
@@ -2124,49 +2146,49 @@ Error: %s compiled for EABI version %d, whereas %s is compiled for version %d"),
   /* Not sure what needs to be checked for EABI versions >= 1.  */
   if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
     {
-      if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
+      if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
        {
          _bfd_error_handler (_("\
 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
                        bfd_get_filename (ibfd),
-                       in_flags & EF_APCS_26 ? 26 : 32,
+                       in_flags & EF_ARM_APCS_26 ? 26 : 32,
                        bfd_get_filename (obfd),
-                       out_flags & EF_APCS_26 ? 26 : 32);
+                       out_flags & EF_ARM_APCS_26 ? 26 : 32);
          flags_compatible = false;
        }
 
-      if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
+      if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
        {
          _bfd_error_handler (_("\
 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
                        bfd_get_filename (ibfd),
-                    in_flags & EF_APCS_FLOAT ? _("float") : _("integer"),
+                    in_flags & EF_ARM_APCS_FLOAT ? _("float") : _("integer"),
                        bfd_get_filename (obfd),
-                     out_flags & EF_APCS_26 ? _("float") : _("integer"));
+                     out_flags & EF_ARM_APCS_26 ? _("float") : _("integer"));
          flags_compatible = false;
        }
 
-#ifdef EF_SOFT_FLOAT
-      if ((in_flags & EF_SOFT_FLOAT) != (out_flags & EF_SOFT_FLOAT))
+#ifdef EF_ARM_SOFT_FLOAT
+      if ((in_flags & EF_ARM_SOFT_FLOAT) != (out_flags & EF_ARM_SOFT_FLOAT))
        {
          _bfd_error_handler (_ ("\
 Error: %s uses %s floating point, whereas %s uses %s floating point"),
                              bfd_get_filename (ibfd),
-                             in_flags & EF_SOFT_FLOAT ? _("soft") : _("hard"),
+                             in_flags & EF_ARM_SOFT_FLOAT ? _("soft") : _("hard"),
                              bfd_get_filename (obfd),
-                             out_flags & EF_SOFT_FLOAT ? _("soft") : _("hard"));
+                             out_flags & EF_ARM_SOFT_FLOAT ? _("soft") : _("hard"));
          flags_compatible = false;
        }
 #endif
 
       /* Interworking mismatch is only a warning.  */
-      if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
+      if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
        _bfd_error_handler (_("\
 Warning: %s %s interworking, whereas %s %s"),
-                         bfd_get_filename (ibfd),
-         in_flags & EF_INTERWORK ? _("supports") : _("does not support"),
-                         bfd_get_filename (obfd),
-                   out_flags & EF_INTERWORK ? _("does not") : _("does"));
+                           bfd_get_filename (ibfd),
+                           in_flags & EF_ARM_INTERWORK ? _("supports") : _("does not support"),
+                           bfd_get_filename (obfd),
+                           out_flags & EF_ARM_INTERWORK ? _("does") : _("does not"));
     }
 
   return flags_compatible;
@@ -2200,31 +2222,31 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
       /* The following flag bits are GNU extenstions and not part of the
         official ARM ELF extended ABI.  Hence they are only decoded if
         the EABI version is not set.  */
-      if (flags & EF_INTERWORK)
+      if (flags & EF_ARM_INTERWORK)
        fprintf (file, _(" [interworking enabled]"));
 
-      if (flags & EF_APCS_26)
+      if (flags & EF_ARM_APCS_26)
        fprintf (file, _(" [APCS-26]"));
       else
        fprintf (file, _(" [APCS-32]"));
 
-      if (flags & EF_APCS_FLOAT)
+      if (flags & EF_ARM_APCS_FLOAT)
        fprintf (file, _(" [floats passed in float registers]"));
 
-      if (flags & EF_PIC)
+      if (flags & EF_ARM_PIC)
        fprintf (file, _(" [position independent]"));
 
-      if (flags & EF_NEW_ABI)
+      if (flags & EF_ARM_NEW_ABI)
        fprintf (file, _(" [new ABI]"));
 
-      if (flags & EF_OLD_ABI)
+      if (flags & EF_ARM_OLD_ABI)
        fprintf (file, _(" [old ABI]"));
 
-      if (flags & EF_SOFT_FLOAT)
+      if (flags & EF_ARM_SOFT_FLOAT)
        fprintf (file, _(" [software FP]"));
 
-      flags &= ~(EF_INTERWORK | EF_APCS_26 | EF_APCS_FLOAT | EF_PIC
-                | EF_NEW_ABI | EF_OLD_ABI | EF_SOFT_FLOAT);
+      flags &= ~(EF_ARM_INTERWORK | EF_ARM_APCS_26 | EF_ARM_APCS_FLOAT | EF_ARM_PIC
+                | EF_ARM_NEW_ABI | EF_ARM_OLD_ABI | EF_ARM_SOFT_FLOAT);
       break;
 
     case EF_ARM_EABI_VER1:
@@ -2238,6 +2260,24 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
       flags &= ~ EF_ARM_SYMSARESORTED;
       break;
 
+    case EF_ARM_EABI_VER2:
+      fprintf (file, _(" [Version2 EABI]"));
+
+      if (flags & EF_ARM_SYMSARESORTED)
+       fprintf (file, _(" [sorted symbol table]"));
+      else
+       fprintf (file, _(" [unsorted symbol table]"));
+
+      if (flags & EF_ARM_DYNSYMSUSESEGIDX)
+       fprintf (file, _(" [dynamic symbols use segment index]"));
+
+      if (flags & EF_ARM_MAPSYMSFIRST)
+       fprintf (file, _(" [mapping symbols precede others]"));
+
+      flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX 
+                | EF_ARM_MAPSYMSFIRST);
+      break;
+
     default:
       fprintf (file, _(" <EABI version unrecognised>"));
       break;
@@ -2621,7 +2661,6 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
   return true;
 }
 
-
 /* Find the nearest line to a particular section and offset, for error
    reporting.   This code is a duplicate of the code in elf.c, except
    that it also accepts STT_ARM_TFUNC as a symbol that names a function.  */
@@ -2645,7 +2684,8 @@ elf32_arm_find_nearest_line
 
   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
                                     filename_ptr, functionname_ptr,
-                                    line_ptr, 0))
+                                    line_ptr, 0,
+                                    &elf_tdata (abfd)->dwarf2_find_line_info))
     return true;
 
   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
@@ -3137,9 +3177,12 @@ elf32_arm_finish_dynamic_symbol (output_bfd, info, h, sym)
       got_offset = (plt_index + 3) * 4;
 
       /* Fill in the entry in the procedure linkage table.  */
-      memcpy (splt->contents + h->plt.offset,
-              elf32_arm_plt_entry,
-             PLT_ENTRY_SIZE);
+      bfd_put_32 (output_bfd, elf32_arm_plt_entry[0],
+                 splt->contents + h->plt.offset + 0);
+      bfd_put_32 (output_bfd, elf32_arm_plt_entry[1],
+                 splt->contents + h->plt.offset + 4);
+      bfd_put_32 (output_bfd, elf32_arm_plt_entry[2],
+                 splt->contents + h->plt.offset + 8);
       bfd_put_32 (output_bfd,
                      (sgot->output_section->vma
                       + sgot->output_offset
@@ -3169,6 +3212,13 @@ elf32_arm_finish_dynamic_symbol (output_bfd, info, h, sym)
          /* Mark the symbol as undefined, rather than as defined in
             the .plt section.  Leave the value alone.  */
          sym->st_shndx = SHN_UNDEF;
+         /* If the symbol is weak, we do need to clear the value.
+            Otherwise, the PLT entry would provide a definition for
+            the symbol even if the symbol wasn't defined anywhere,
+            and so the symbol would never be NULL.  */
+         if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
+             == 0)
+           sym->st_value = 0;
        }
     }
 
@@ -3328,7 +3378,12 @@ elf32_arm_finish_dynamic_sections (output_bfd, info)
 
       /* Fill in the first entry in the procedure linkage table.  */
       if (splt->_raw_size > 0)
-       memcpy (splt->contents, elf32_arm_plt0_entry, PLT_ENTRY_SIZE);
+       {
+         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[0], splt->contents +  0);
+         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[1], splt->contents +  4);
+         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[2], splt->contents +  8);
+         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[3], splt->contents + 12);
+       }
 
       /* UnixWare sets the entsize of .plt to 4, although that doesn't
         really seem like the right value.  */
@@ -3366,12 +3421,10 @@ elf32_arm_post_process_headers (abfd, link_info)
   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
 }
 
-
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_MACHINE_CODE               EM_ARM
 #define ELF_MAXPAGESIZE                        0x8000
 
-
 #define bfd_elf32_bfd_copy_private_bfd_data    elf32_arm_copy_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   elf32_arm_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags                elf32_arm_set_private_flags
This page took 0.0426029999999999 seconds and 4 git commands to generate.