[AArch64] Support RAS extension for ARMv8 onwards.
[deliverable/binutils-gdb.git] / bfd / elflink.c
index 991efacfe1c96b25ad0e12cf376d2f91b7e30261..37638b2f2c88134ace1abe4bf0ce30f835623dae 100644 (file)
@@ -3245,12 +3245,26 @@ elf_add_dt_needed_tag (bfd *abfd,
   return 0;
 }
 
+/* Return true if SONAME is on the needed list between NEEDED and STOP
+   (or the end of list if STOP is NULL), and needed by a library that
+   will be loaded.  */
+
 static bfd_boolean
-on_needed_list (const char *soname, struct bfd_link_needed_list *needed)
-{
-  for (; needed != NULL; needed = needed->next)
-    if ((elf_dyn_lib_class (needed->by) & DYN_AS_NEEDED) == 0
-       && strcmp (soname, needed->name) == 0)
+on_needed_list (const char *soname,
+               struct bfd_link_needed_list *needed,
+               struct bfd_link_needed_list *stop)
+{
+  struct bfd_link_needed_list *look;
+  for (look = needed; look != stop; look = look->next)
+    if (strcmp (soname, look->name) == 0
+       && ((elf_dyn_lib_class (look->by) & DYN_AS_NEEDED) == 0
+           /* If needed by a library that itself is not directly
+              needed, recursively check whether that library is
+              indirectly needed.  Since we add DT_NEEDED entries to
+              the end of the list, library dependencies appear after
+              the library.  Therefore search prior to the current
+              LOOK, preventing possible infinite recursion.  */
+           || on_needed_list (elf_dt_name (look->by), needed, look)))
       return TRUE;
 
   return FALSE;
@@ -4569,7 +4583,7 @@ error_free_dyn:
                    goto error_free_vers;
                }
            }
-         else if (dynsym && h->dynindx != -1)
+         else if (h->dynindx != -1)
            /* If the symbol already has a dynamic index, but
               visibility says it should not be visible, turn it into
               a local symbol.  */
@@ -4593,7 +4607,8 @@ error_free_dyn:
                       || (old_bfd->flags & BFD_PLUGIN) == 0))
                  || (h->ref_dynamic_nonweak
                      && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0
-                     && !on_needed_list (elf_dt_name (abfd), htab->needed))))
+                     && !on_needed_list (elf_dt_name (abfd),
+                                         htab->needed, NULL))))
            {
              int ret;
              const char *soname = elf_dt_name (abfd);
@@ -7751,10 +7766,15 @@ resolve_symbol (const char *name,
   return FALSE;
 }
 
+/* Looks up NAME in SECTIONS.  If found sets RESULT to NAME's address (in
+   bytes) and returns TRUE, otherwise returns FALSE.  Accepts pseudo-section
+   names like "foo.end" which is the end address of section "foo".  */
+   
 static bfd_boolean
 resolve_section (const char *name,
                 asection *sections,
-                bfd_vma *result)
+                bfd_vma *result,
+                bfd * abfd)
 {
   asection *curr;
   unsigned int len;
@@ -7767,6 +7787,7 @@ resolve_section (const char *name,
       }
 
   /* Hmm. still haven't found it. try pseudo-section names.  */
+  /* FIXME: This could be coded more efficiently...  */
   for (curr = sections; curr; curr = curr->next)
     {
       len = strlen (curr->name);
@@ -7777,7 +7798,7 @@ resolve_section (const char *name,
        {
          if (strncmp (".end", name + len, 4) == 0)
            {
-             *result = curr->vma + curr->size;
+             *result = curr->vma + curr->size / bfd_octets_per_byte (abfd);
              return TRUE;
            }
 
@@ -7859,7 +7880,7 @@ eval_symbol (bfd_vma *result,
 
       if (symbol_is_section)
        {
-         if (!resolve_section (symbuf, flinfo->output_bfd->sections, result)
+         if (!resolve_section (symbuf, flinfo->output_bfd->sections, result, input_bfd)
              && !resolve_symbol (symbuf, input_bfd, flinfo, result,
                                  isymbuf, locsymcount))
            {
@@ -7872,7 +7893,7 @@ eval_symbol (bfd_vma *result,
          if (!resolve_symbol (symbuf, input_bfd, flinfo, result,
                               isymbuf, locsymcount)
              && !resolve_section (symbuf, flinfo->output_bfd->sections,
-                                  result))
+                                  result, input_bfd))
            {
              undefined_reference ("symbol", symbuf);
              return FALSE;
@@ -8096,8 +8117,8 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd,
   else
     shift = (8 * wordsz) - (start + len);
 
-  /* FIXME: octets_per_byte.  */
-  x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset);
+  x = get_value (wordsz, chunksz, input_bfd,
+                contents + rel->r_offset * bfd_octets_per_byte (input_bfd));
 
 #ifdef DEBUG
   printf ("Doing complex reloc: "
@@ -8129,8 +8150,8 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd,
          (unsigned long) relocation, (unsigned long) (mask << shift),
          (unsigned long) ((relocation & mask) << shift), (unsigned long) x);
 #endif
-  /* FIXME: octets_per_byte.  */
-  put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset);
+  put_value (wordsz, chunksz, input_bfd, x,
+            contents + rel->r_offset * bfd_octets_per_byte (input_bfd));
   return r;
 }
 
@@ -10535,11 +10556,13 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
          break;
        default:
          {
-           /* FIXME: octets_per_byte.  */
            if (! (o->flags & SEC_EXCLUDE))
              {
                file_ptr offset = (file_ptr) o->output_offset;
                bfd_size_type todo = o->size;
+
+               offset *= bfd_octets_per_byte (output_bfd);
+
                if ((o->flags & SEC_ELF_REVERSE_COPY))
                  {
                    /* Reverse-copy input section to output.  */
@@ -10703,8 +10726,11 @@ elf_reloc_link_order (bfd *output_bfd,
            }
          break;
        }
+
       ok = bfd_set_section_contents (output_bfd, output_section, buf,
-                                    link_order->offset, size);
+                                    link_order->offset
+                                    * bfd_octets_per_byte (output_bfd),
+                                    size);
       free (buf);
       if (! ok)
        return FALSE;
@@ -10886,9 +10912,8 @@ elf_fixup_link_order (bfd *abfd, asection *o)
     {
       s = sections[n]->u.indirect.section;
       offset &= ~(bfd_vma) 0 << s->alignment_power;
-      s->output_offset = offset;
+      s->output_offset = offset / bfd_octets_per_byte (abfd);
       sections[n]->offset = offset;
-      /* FIXME: octets_per_byte.  */
       offset += sections[n]->size;
     }
 
@@ -11680,7 +11705,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
       /* sh_name was set in prep_headers.  */
       symstrtab_hdr->sh_type = SHT_STRTAB;
-      symstrtab_hdr->sh_flags = 0;
+      symstrtab_hdr->sh_flags = bed->elf_strtab_flags;
       symstrtab_hdr->sh_addr = 0;
       symstrtab_hdr->sh_size = _bfd_elf_strtab_size (flinfo.symstrtab);
       symstrtab_hdr->sh_entsize = 0;
@@ -11948,10 +11973,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
            continue;
          if (strcmp (o->name, ".dynstr") != 0)
            {
-             /* FIXME: octets_per_byte.  */
              if (! bfd_set_section_contents (abfd, o->output_section,
                                              o->contents,
-                                             (file_ptr) o->output_offset,
+                                             (file_ptr) o->output_offset
+                                             * bfd_octets_per_byte (abfd),
                                              o->size))
                goto error_return;
            }
This page took 0.030044 seconds and 4 git commands to generate.