* elflink.h (elf_link_sort_cmp1): Sort RELATIVE relocs first, not
authorJakub Jelinek <jakub@redhat.com>
Fri, 24 Aug 2001 11:17:30 +0000 (11:17 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 24 Aug 2001 11:17:30 +0000 (11:17 +0000)
last.
(elf_link_sort_relocs): Adjust accordingly.

* elf64-alpha.c (struct alpha_elf_link_hash_entry): Add reltext flag.
(elf64_alpha_check_relocs): Set it if section this reloc is against
is read-only.  Set DF_TEXTREL if a RELATIVE reloc is needed against
read-only section.
(elf64_alpha_calc_dynrel_sizes): Set DF_TEXTREL flag if relocation
is is against read-only section.
(elf64_alpha_size_dynamic_sections): Use DF_TEXTREL flag, don't
check section names.
(elf64_alpha_reloc_type_class): New.
(elf_backend_reloc_type_class): Define.

bfd/ChangeLog
bfd/elf64-alpha.c
bfd/elflink.h

index 166ca49a374bec8d32ad7a61b2c621ebd68af02a..70ef3cfbee748aaddf3ac90d1ac403f23b43d8ba 100644 (file)
@@ -1,3 +1,20 @@
+2001-08-24  Jakub Jelinek  <jakub@redhat.com>
+
+       * elflink.h (elf_link_sort_cmp1): Sort RELATIVE relocs first, not
+       last.
+       (elf_link_sort_relocs): Adjust accordingly.
+
+       * elf64-alpha.c (struct alpha_elf_link_hash_entry): Add reltext flag.
+       (elf64_alpha_check_relocs): Set it if section this reloc is against
+       is read-only.  Set DF_TEXTREL if a RELATIVE reloc is needed against
+       read-only section.
+       (elf64_alpha_calc_dynrel_sizes): Set DF_TEXTREL flag if relocation
+       is is against read-only section.
+       (elf64_alpha_size_dynamic_sections): Use DF_TEXTREL flag, don't
+       check section names.
+       (elf64_alpha_reloc_type_class): New.
+       (elf_backend_reloc_type_class): Define.
+
 2001-08-24  Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
 
        * linker.c (_bfd_generic_link_add_archive_symbols): Replace alloca()
@@ -40,7 +57,7 @@
 
        * aoutf1.h (sunos_write_object_contents): Silence compile time
        warning.
-        * libaout.h (N_SET_DYNAMIC): Silence compile time warning.
+       * libaout.h (N_SET_DYNAMIC): Silence compile time warning.
 
        * bout.c: Add missing function prototypes.  Fix formatting.
        * coff-z8k.c: Add missing function prototypes.  Fix formatting.
        * elfxx-target.h (elf_backend_sprintf_vma): Initialise if not
        already defined.
        (elf_backend_fprintf_vma): Initialise if not already defined.
-        (struct elf_backend_data): Initialise the
+       (struct elf_backend_data): Initialise the
        elf_backend_sprintf_vma and elf_backend_fprintf_vma fields.
 
 2001-08-10  Andreas Jaeger  <aj@suse.de>
index 73a085ff7cd3b9816b39039e6547116d061ba73b..567fcefed539150c6251828b0b59593d8f91ef2c 100644 (file)
@@ -133,6 +133,8 @@ static boolean elf64_alpha_merge_ind_symbols
   PARAMS((struct alpha_elf_link_hash_entry *, PTR));
 static Elf_Internal_Rela * elf64_alpha_find_reloc_at_ofs
   PARAMS ((Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_vma, int));
+static enum elf_reloc_type_class elf64_alpha_reloc_type_class
+  PARAMS ((int));
 \f
 struct alpha_elf_link_hash_entry
 {
@@ -182,7 +184,10 @@ struct alpha_elf_link_hash_entry
     asection *srel;
 
     /* what kind of relocation? */
-    unsigned long rtype;
+    unsigned int rtype;
+
+    /* is this against read-only section? */
+    unsigned int reltext : 1;
 
     /* how many did we find?  */
     unsigned long count;
@@ -2627,6 +2632,7 @@ elf64_alpha_check_relocs (abfd, info, sec, relocs)
                  rent->srel = sreloc;
                  rent->rtype = r_type;
                  rent->count = 1;
+                 rent->reltext = (sec->flags & SEC_READONLY) != 0;
 
                  rent->next = h->reloc_entries;
                  h->reloc_entries = rent;
@@ -2639,6 +2645,8 @@ elf64_alpha_check_relocs (abfd, info, sec, relocs)
              /* If this is a shared library, and the section is to be
                 loaded into memory, we need a RELATIVE reloc.  */
              sreloc->_raw_size += sizeof (Elf64_External_Rela);
+             if (sec->flags & SEC_READONLY)
+               info->flags |= DF_TEXTREL;
            }
          break;
        }
@@ -3181,6 +3189,8 @@ elf64_alpha_calc_dynrel_sizes (h, info)
          {
            relent->srel->_raw_size +=
              sizeof (Elf64_External_Rela) * relent->count;
+           if (relent->reltext)
+             info->flags |= DT_TEXTREL;
          }
 
       dynobj = elf_hash_table(info)->dynobj;
@@ -3214,7 +3224,6 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
 {
   bfd *dynobj;
   asection *s;
-  boolean reltext;
   boolean relplt;
 
   dynobj = elf_hash_table(info)->dynobj;
@@ -3263,7 +3272,6 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */
-  reltext = false;
   relplt = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
@@ -3293,19 +3301,6 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
 
          if (!strip)
            {
-             const char *outname;
-             asection *target;
-
-             /* If this relocation section applies to a read only
-                section, then we probably need a DT_TEXTREL entry.  */
-             outname = bfd_get_section_name (output_bfd,
-                                             s->output_section);
-             target = bfd_get_section_by_name (output_bfd, outname + 5);
-             if (target != NULL
-                 && (target->flags & SEC_READONLY) != 0
-                 && (target->flags & SEC_ALLOC) != 0)
-               reltext = true;
-
              if (strcmp(name, ".rela.plt") == 0)
                relplt = true;
 
@@ -3361,11 +3356,10 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
                                            sizeof (Elf64_External_Rela)))
        return false;
 
-      if (reltext)
+      if (info->flags & DF_TEXTREL)
        {
          if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
            return false;
-         info->flags |= DF_TEXTREL;
        }
     }
 
@@ -4650,6 +4644,23 @@ elf64_alpha_final_link (abfd, info)
 
   return true;
 }
+
+static enum elf_reloc_type_class
+elf64_alpha_reloc_type_class (type)
+     int type;
+{
+  switch (type)
+    {
+    case R_ALPHA_RELATIVE:
+      return reloc_class_relative;
+    case R_ALPHA_JMP_SLOT:
+      return reloc_class_plt;
+    case R_ALPHA_COPY:
+      return reloc_class_copy;
+    default:
+      return reloc_class_normal;
+    }
+}
 \f
 /* ECOFF swapping routines.  These are used when dealing with the
    .mdebug section, which is in the ECOFF debugging format.  Copied
@@ -4777,6 +4788,8 @@ const struct elf_size_info alpha_elf_size_info =
   elf64_alpha_finish_dynamic_sections
 #define bfd_elf64_bfd_final_link \
   elf64_alpha_final_link
+#define elf_backend_reloc_type_class \
+  elf64_alpha_reloc_type_class
 
 #define elf_backend_ecoff_debug_swap \
   &elf64_alpha_ecoff_debug_swap
index 4428767a0ea7a33524b56d66c28b46e8a49ac2eb..8af57e824ee4a68f61e049d46d3dac979526b0a6 100644 (file)
@@ -4300,9 +4300,9 @@ elf_link_sort_cmp1 (A, B)
   relativeb = b->type == reloc_class_relative;
 
   if (relativea < relativeb)
-    return -1;
-  if (relativea > relativeb)
     return 1;
+  if (relativea > relativeb)
+    return -1;
   if (ELF_R_SYM (a->u.rel.r_info) < ELF_R_SYM (b->u.rel.r_info))
     return -1;
   if (ELF_R_SYM (a->u.rel.r_info) > ELF_R_SYM (b->u.rel.r_info))
@@ -4429,14 +4429,15 @@ elf_link_sort_relocs (abfd, info, psec)
       }
 
   qsort (rela, count, sizeof (*rela), elf_link_sort_cmp1);
-  for (i = 0, j = 0; i < count && rela[i].type != reloc_class_relative; i++)
+  for (ret = 0; ret < count && rela[ret].type == reloc_class_relative; ret++)
+    ;
+  for (i = ret, j = ret; i < count; i++)
     {
       if (ELF_R_SYM (rela[i].u.rel.r_info) != ELF_R_SYM (rela[j].u.rel.r_info))
        j = i;
       rela[i].offset = rela[j].u.rel.r_offset;
     }
-  ret = count - i;
-  qsort (rela, i, sizeof (*rela), elf_link_sort_cmp2);
+  qsort (rela + ret, count - ret, sizeof (*rela), elf_link_sort_cmp2);
   
   for (o = dynobj->sections; o != NULL; o = o->next)
     if ((o->flags & (SEC_HAS_CONTENTS|SEC_LINKER_CREATED))