* elf-hppa.h (elf_hppa_reloc_final_type): Handle selectors for
[deliverable/binutils-gdb.git] / bfd / elf.c
index b103b95a42b0e0d3cfc85b9bb889e7a6deb8e94a..afde13e8d945f6fcc6d426c914084c6433100cf3 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,6 +1,7 @@
 /* ELF executable support for BFD.
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1478,8 +1479,7 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
 
 /* This is a hook for the ELF emulation code in the generic linker to
    tell the backend linker what file name to use for the DT_NEEDED
-   entry for a dynamic object.  The generic linker passes name as an
-   empty string to indicate that no DT_NEEDED entry should be made.  */
+   entry for a dynamic object.  */
 
 void
 bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
@@ -1490,11 +1490,11 @@ bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
 }
 
 void
-bfd_elf_set_dt_needed_soname (bfd *abfd, const char *name)
+bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class)
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && bfd_get_format (abfd) == bfd_object)
-    elf_dt_soname (abfd) = name;
+    elf_dyn_lib_class (abfd) = lib_class;
 }
 
 /* Get the list of DT_NEEDED entries for a link.  This is a hook for
@@ -3359,7 +3359,9 @@ map_sections_to_segments (bfd *abfd)
        {
          if ((hdr->flags & SEC_READONLY) == 0)
            writable = TRUE;
-         last_hdr = hdr;
+         /* Ignore .tbss section for segment layout purposes.  */
+         if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
+           last_hdr = hdr;
          continue;
        }
 
@@ -3571,6 +3573,35 @@ elf_sort_sections (const void *arg1, const void *arg2)
   return sec1->target_index - sec2->target_index;
 }
 
+/* Ian Lance Taylor writes:
+
+   We shouldn't be using % with a negative signed number.  That's just
+   not good.  We have to make sure either that the number is not
+   negative, or that the number has an unsigned type.  When the types
+   are all the same size they wind up as unsigned.  When file_ptr is a
+   larger signed type, the arithmetic winds up as signed long long,
+   which is wrong.
+
+   What we're trying to say here is something like ``increase OFF by
+   the least amount that will cause it to be equal to the VMA modulo
+   the page size.''  */
+/* In other words, something like:
+
+   vma_offset = m->sections[0]->vma % bed->maxpagesize;
+   off_offset = off % bed->maxpagesize;
+   if (vma_offset < off_offset)
+     adjustment = vma_offset + bed->maxpagesize - off_offset;
+   else
+     adjustment = vma_offset - off_offset;
+     
+   which can can be collapsed into the expression below.  */
+
+static file_ptr
+vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
+{
+  return ((vma - off) % maxpagesize);
+}
+
 /* Assign file positions to the sections based on the mapping from
    sections to segments.  This function also sets up some fields in
    the file header, and writes out the program headers.  */
@@ -3698,7 +3729,8 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
          && (m->sections[0]->flags & SEC_ALLOC) != 0)
        {
          if ((abfd->flags & D_PAGED) != 0)
-           off += (m->sections[0]->vma - off) % bed->maxpagesize;
+           off += vma_page_aligned_bias (m->sections[0]->vma, off,
+                                         bed->maxpagesize);
          else
            {
              bfd_size_type align;
@@ -3713,7 +3745,8 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
                    align = secalign;
                }
 
-             off += (m->sections[0]->vma - off) % (1 << align);
+             off += vma_page_aligned_bias (m->sections[0]->vma, off,
+                                           1 << align);
            }
        }
 
@@ -3875,9 +3908,11 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
                     not have the SEC_LOAD case just above, and then
                     this was necessary, but now I'm not sure.  */
                  if ((abfd->flags & D_PAGED) != 0)
-                   adjust = (sec->vma - voff) % bed->maxpagesize;
+                   adjust = vma_page_aligned_bias (sec->vma, voff,
+                                                   bed->maxpagesize);
                  else
-                   adjust = (sec->vma - voff) % align;
+                   adjust = vma_page_aligned_bias (sec->vma, voff,
+                                                   align);
                }
              else
                adjust = 0;
@@ -4211,9 +4246,11 @@ assign_file_positions_except_relocs (bfd *abfd,
                 ? "*unknown*"
                 : hdr->bfd_section->name)));
              if ((abfd->flags & D_PAGED) != 0)
-               off += (hdr->sh_addr - off) % bed->maxpagesize;
+               off += vma_page_aligned_bias (hdr->sh_addr, off,
+                                             bed->maxpagesize);
              else
-               off += (hdr->sh_addr - off) % hdr->sh_addralign;
+               off += vma_page_aligned_bias (hdr->sh_addr, off,
+                                             hdr->sh_addralign);
              off = _bfd_elf_assign_file_position_for_section (hdr, off,
                                                               FALSE);
            }
@@ -4625,8 +4662,9 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
        2. It is an allocated segment,
        3. There is an output section associated with it,
        4. The section has not already been allocated to a previous segment.
-       5. PT_TLS segment includes only SHF_TLS sections.
-       6. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.  */
+       5. PT_GNU_STACK segments do not include any sections.
+       6. PT_TLS segment includes only SHF_TLS sections.
+       7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.  */
 #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)              \
   ((((segment->p_paddr                                                 \
       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)       \
@@ -4634,6 +4672,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
      && (section->flags & SEC_ALLOC) != 0)                             \
     || IS_COREFILE_NOTE (segment, section))                            \
    && section->output_section != NULL                                  \
+   && segment->p_type != PT_GNU_STACK                                  \
    && (segment->p_type != PT_TLS                                       \
        || (section->flags & SEC_THREAD_LOCAL))                         \
    && (segment->p_type == PT_LOAD                                      \
@@ -5259,6 +5298,7 @@ swap_out_syms (bfd *abfd,
   char *outbound_shndx;
   int idx;
   bfd_size_type amt;
+  bfd_boolean name_local_sections;
 
   if (!elf_map_symbols (abfd))
     return FALSE;
@@ -5324,6 +5364,10 @@ swap_out_syms (bfd *abfd,
       outbound_shndx += sizeof (Elf_External_Sym_Shndx);
   }
 
+  name_local_sections
+    = (bed->elf_backend_name_local_section_symbols
+       && bed->elf_backend_name_local_section_symbols (abfd));
+
   syms = bfd_get_outsymbols (abfd);
   for (idx = 0; idx < symcount; idx++)
     {
@@ -5333,7 +5377,8 @@ swap_out_syms (bfd *abfd,
       flagword flags = syms[idx]->flags;
       int type;
 
-      if ((flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
+      if (!name_local_sections
+         && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
        {
          /* Local section symbols have no name.  */
          sym.st_name = 0;
This page took 0.025279 seconds and 4 git commands to generate.