daily update
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
index 8d3d5d7e53ee5d36e86abb916272bdcbd3a38a71..2fc555083f2a72c4f8f1e88550ba068d2db777d8 100644 (file)
@@ -215,10 +215,6 @@ static bfd_boolean elfNN_ia64_add_symbol_hook
   PARAMS ((bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym,
           const char **namep, flagword *flagsp, asection **secp,
           bfd_vma *valp));
-static int elfNN_ia64_additional_program_headers
-  PARAMS ((bfd *abfd));
-static bfd_boolean elfNN_ia64_modify_segment_map
-  PARAMS ((bfd *, struct bfd_link_info *));
 static bfd_boolean elfNN_ia64_is_local_label_name
   PARAMS ((bfd *abfd, const char *name));
 static bfd_boolean elfNN_ia64_dynamic_symbol_p
@@ -863,6 +859,12 @@ elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
   bfd_putl64 (t0, hit_addr);
   bfd_putl64 (t1, hit_addr + 8);
 }
+
+/* Rename some of the generic section flags to better document how they
+   are used here.  */
+#define skip_relax_pass_0 need_finalize_relax
+#define skip_relax_pass_1 has_gp_reloc
+
 \f
 /* These functions do relaxation for IA-64 ELF.  */
 
@@ -891,6 +893,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
   bfd_boolean changed_contents = FALSE;
   bfd_boolean changed_relocs = FALSE;
   bfd_boolean changed_got = FALSE;
+  bfd_boolean skip_relax_pass_0 = TRUE;
+  bfd_boolean skip_relax_pass_1 = TRUE;
   bfd_vma gp = 0;
 
   /* Assume we're not going to change any sizes, and we'll only need
@@ -902,11 +906,11 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
     return FALSE;
 
   /* Nothing to do if there are no relocations or there is no need for
-     the relax finalize pass.  */
+     the current pass.  */
   if ((sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
-      || (!link_info->need_relax_finalize
-         && sec->need_finalize_relax == 0))
+      || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
+      || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
     return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -947,20 +951,19 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
        case R_IA64_PCREL21BI:
        case R_IA64_PCREL21M:
        case R_IA64_PCREL21F:
-         /* In the finalize pass, all br relaxations are done. We can
-            skip it. */
-         if (!link_info->need_relax_finalize)
+         /* In pass 1, all br relaxations are done. We can skip it. */
+         if (link_info->relax_pass == 1)
            continue;
+         skip_relax_pass_0 = FALSE;
          is_branch = TRUE;
          break;
 
        case R_IA64_PCREL60B:
-         /* We can't optimize brl to br before the finalize pass since
-            br relaxations will increase the code size. Defer it to
-            the finalize pass.  */
-         if (link_info->need_relax_finalize)
+         /* We can't optimize brl to br in pass 0 since br relaxations
+            will increase the code size. Defer it to pass 1.  */
+         if (link_info->relax_pass == 0)
            {
-             sec->need_finalize_relax = 1;
+             skip_relax_pass_1 = FALSE;
              continue;
            }
          is_branch = TRUE;
@@ -968,12 +971,11 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
 
        case R_IA64_LTOFF22X:
        case R_IA64_LDXMOV:
-         /* We can't relax ldx/mov before the finalize pass since
-            br relaxations will increase the code size. Defer it to
-            the finalize pass.  */
-         if (link_info->need_relax_finalize)
+         /* We can't relax ldx/mov in pass 0 since br relaxations will
+            increase the code size. Defer it to pass 1.  */
+         if (link_info->relax_pass == 0)
            {
-             sec->need_finalize_relax = 1;
+             skip_relax_pass_1 = FALSE;
              continue;
            }
          is_branch = FALSE;
@@ -1363,8 +1365,12 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
        }
     }
 
-  if (!link_info->need_relax_finalize)
-    sec->need_finalize_relax = 0;
+  if (link_info->relax_pass == 0)
+    {
+      /* Pass 0 is only needed to relax br.  */
+      sec->skip_relax_pass_0 = skip_relax_pass_0;
+      sec->skip_relax_pass_1 = skip_relax_pass_1;
+    }
 
   *again = changed_contents || changed_relocs;
   return TRUE;
@@ -1380,6 +1386,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
     free (internal_relocs);
   return FALSE;
 }
+#undef skip_relax_pass_0
+#undef skip_relax_pass_1
 
 static void
 elfNN_ia64_relax_ldxmov (contents, off)
@@ -1416,22 +1424,15 @@ elfNN_ia64_relax_ldxmov (contents, off)
 /* Return TRUE if NAME is an unwind table section name.  */
 
 static inline bfd_boolean
-is_unwind_section_name (abfd, name)
-       bfd *abfd;
-       const char *name;
+is_unwind_section_name (bfd *abfd, const char *name)
 {
-  size_t len1, len2, len3;
-
   if (elfNN_ia64_hpux_vec (abfd->xvec)
       && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
     return FALSE;
 
-  len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
-  len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
-  len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
-  return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
-          && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
-         || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
+  return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
+          && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
+         || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
 }
 
 /* Handle an IA-64 specific section when reading an object file.  This
@@ -1625,8 +1626,8 @@ elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
 /* Return the number of additional phdrs we will need.  */
 
 static int
-elfNN_ia64_additional_program_headers (abfd)
-     bfd *abfd;
+elfNN_ia64_additional_program_headers (bfd *abfd,
+                                      struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   asection *s;
   int ret = 0;
@@ -1645,9 +1646,8 @@ elfNN_ia64_additional_program_headers (abfd)
 }
 
 static bfd_boolean
-elfNN_ia64_modify_segment_map (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+elfNN_ia64_modify_segment_map (bfd *abfd,
+                              struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   struct elf_segment_map *m, **pm;
   Elf_Internal_Shdr *hdr;
@@ -1730,17 +1730,30 @@ elfNN_ia64_modify_segment_map (abfd, info)
        }
     }
 
-  /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
-     the input sections for each output section in the segment and testing
-     for SHF_IA_64_NORECOV on each.  */
-  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+  return TRUE;
+}
+
+/* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
+   the input sections for each output section in the segment and testing
+   for SHF_IA_64_NORECOV on each.  */
+
+static bfd_boolean
+elfNN_ia64_modify_program_headers (bfd *abfd,
+                                  struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  struct elf_obj_tdata *tdata = elf_tdata (abfd);
+  struct elf_segment_map *m;
+  Elf_Internal_Phdr *p;
+
+  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
     if (m->p_type == PT_LOAD)
       {
        int i;
        for (i = m->count - 1; i >= 0; --i)
          {
            struct bfd_link_order *order = m->sections[i]->map_head.link_order;
-           while (order)
+
+           while (order != NULL)
              {
                if (order->type == bfd_indirect_link_order)
                  {
@@ -1748,7 +1761,7 @@ elfNN_ia64_modify_segment_map (abfd, info)
                    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
                    if (flags & SHF_IA_64_NORECOV)
                      {
-                       m->p_flags |= PF_IA_64_NORECOV;
+                       p->p_flags |= PF_IA_64_NORECOV;
                        goto found;
                      }
                  }
@@ -2196,7 +2209,7 @@ addend_compare (const void *xp, const void *yp)
   const struct elfNN_ia64_dyn_sym_info *y
     = (const struct elfNN_ia64_dyn_sym_info *) yp;
 
-  return x->addend - y->addend;
+  return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
 }
 
 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates.  */
@@ -2601,10 +2614,10 @@ get_reloc_section (abfd, ia64_info, sec, create)
   if (srel_name == NULL)
     return NULL;
 
-  BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
+  BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
               && strcmp (bfd_get_section_name (abfd, sec),
                          srel_name+5) == 0)
-             || (strncmp (srel_name, ".rel", 4) == 0
+             || (CONST_STRNEQ (srel_name, ".rel")
                  && strcmp (bfd_get_section_name (abfd, sec),
                             srel_name+4) == 0));
 
@@ -2721,7 +2734,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
         have yet been processed.  Do something with what we know, as
         this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-                             && (!info->symbolic
+                             && (!SYMBOLIC_BIND (info, h)
                                  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
                             || !h->def_regular
                             || h->root.type == bfd_link_hash_defweak));
@@ -2893,7 +2906,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
         have yet been processed.  Do something with what we know, as
         this may help reduce memory usage and processing time later.  */
       maybe_dynamic = (h && ((!info->executable
-                             && (!info->symbolic
+                             && (!SYMBOLIC_BIND (info, h)
                                  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
                             || !h->def_regular
                             || h->root.type == bfd_link_hash_defweak));
@@ -3682,7 +3695,7 @@ elfNN_ia64_size_dynamic_sections (output_bfd, info)
 
          if (strcmp (name, ".got.plt") == 0)
            strip = FALSE;
-         else if (strncmp (name, ".rel", 4) == 0)
+         else if (CONST_STRNEQ (name, ".rel"))
            {
              if (!strip)
                {
@@ -4346,7 +4359,7 @@ elfNN_ia64_choose_gp (abfd, info)
        continue;
 
       lo = os->vma;
-      hi = os->vma + os->size;
+      hi = os->vma + (os->rawsize ? os->rawsize : os->size);
       if (hi < lo)
        hi = (bfd_vma) -1;
 
@@ -4738,6 +4751,12 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_IA64_LTV32LSB:
        case R_IA64_LTV64MSB:
        case R_IA64_LTV64LSB:
+         /* r_symndx will be zero only for relocs against symbols
+            from removed linkonce sections, or sections discarded by
+            a linker script.  */
+         if (r_symndx == 0)
+           value = 0;
+
          r = elfNN_ia64_install_value (hit_addr, value, r_type);
          break;
 
@@ -5549,9 +5568,9 @@ elfNN_ia64_reloc_type_class (rela)
 
 static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
 {
-  { ".sbss",  5, -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
-  { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
-  { NULL,        0, 0, 0,            0 }
+  { STRING_COMMA_LEN (".sbss"),  -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+  { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+  { NULL,                    0,   0, 0,            0 }
 };
 
 static bfd_boolean
@@ -5578,7 +5597,7 @@ elfNN_ia64_object_p (bfd *abfd)
       if (elf_sec_group (sec) == NULL
          && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
              == (SEC_LINK_ONCE | SEC_CODE))
-         && strncmp (sec->name, ".gnu.linkonce.t.", 16) == 0)
+         && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
        {
          name = sec->name + 16;
 
@@ -5705,6 +5724,7 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
 #define ELF_MACHINE_ALT1               1999    /* EAS2.3 */
 #define ELF_MACHINE_ALT2               1998    /* EAS2.2 */
 #define ELF_MAXPAGESIZE                        0x10000 /* 64KB */
+#define ELF_COMMONPAGESIZE             0x4000  /* 16KB */
 
 #define elf_backend_section_from_shdr \
        elfNN_ia64_section_from_shdr
@@ -5720,6 +5740,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
        elfNN_ia64_additional_program_headers
 #define elf_backend_modify_segment_map \
        elfNN_ia64_modify_segment_map
+#define elf_backend_modify_program_headers \
+       elfNN_ia64_modify_program_headers
 #define elf_info_to_howto \
        elfNN_ia64_info_to_howto
 
@@ -5746,6 +5768,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
        elfNN_ia64_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
        elfNN_ia64_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_relocate_section \
        elfNN_ia64_relocate_section
 #define elf_backend_finish_dynamic_symbol \
@@ -5811,7 +5835,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
 #define elf_backend_want_p_paddr_set_to_zero 1
 
 #undef  ELF_MAXPAGESIZE
-#define ELF_MAXPAGESIZE                 0x1000  /* 1K */
+#define ELF_MAXPAGESIZE                 0x1000  /* 4K */
+#undef ELF_COMMONPAGESIZE
 
 #undef  elfNN_bed
 #define elfNN_bed elfNN_ia64_hpux_bed
This page took 0.027983 seconds and 4 git commands to generate.