]> oss.titaniummirror.com Git - msp430-binutils.git/blobdiff - debian/patches/204-hjl-binutils-tls-relro.dpatch
Import 2.18.1~cvs20080103-0tinyos1 from old svn repo.
[msp430-binutils.git] / debian / patches / 204-hjl-binutils-tls-relro.dpatch
diff --git a/debian/patches/204-hjl-binutils-tls-relro.dpatch b/debian/patches/204-hjl-binutils-tls-relro.dpatch
new file mode 100755 (executable)
index 0000000..9ab4ab6
--- /dev/null
@@ -0,0 +1,587 @@
+#!/bin/sh -e
+## 204-hjl-binutils-tls-relro.dpatch
+##
+## DP: Description: PR binutils/3281; objcopy changes PT_GNU_RELRO when there is PT_TLS
+## DP: Author: H.J. Lu  <hongjiu.lu@intel.com>
+## DP: Upstream status: hjl 2.17.50.0.18
+## DP: Original patch: binutils-tls-relro-14.patch
+
+if [ $# -ne 1 ]; then
+    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+       -patch) patch $patch_opts -p1 < $0;;
+       -unpatch) patch $patch_opts -p1 -R < $0;;
+        *)
+                echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+                exit 1;;
+esac
+
+exit 0
+
+bfd/
+
+2007-01-23  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/3281
+       * elf-bfd.h (elf_obj_tdata): Remove relro.
+
+       * elf.c (get_program_header_size): Check info->relro instead
+       of elf_tdata (abfd)->relro.
+       (_bfd_elf_map_sections_to_segments): Likewise.
+       (assign_file_positions_for_load_sections): Don't set
+       PT_GNU_RELRO segment alignment here.
+       (assign_file_positions_for_non_load_sections): Properly set up
+       PT_GNU_RELRO segment for copying executable/shared library.
+       (elf_section_status): New enum.
+       (rewrite_elf_program_header): Add elf_section_status. Remove
+       PT_GNU_RELRO segment if a section is modified.
+       (copy_private_bfd_data): Updated rewrite_elf_program_header
+       call.
+
+include/elf/
+
+2006-10-20  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/3281
+       * internal.h (ELF_IS_SECTION_IN_SEGMENT): Allow SHF_TLS
+       sections in PT_GNU_RELRO segments.
+
+ld/
+
+2006-10-20  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/3281
+       * ldexp.h (ldexp_control): Add relro, relro_start_stat and
+       relro_end_stat.
+
+       * ldexp.c (fold_binary): Set expld.dataseg.relro to
+       exp_dataseg_relro_start or exp_dataseg_relro_end when
+       seeing DATA_SEGMENT_ALIGN or DATA_SEGMENT_RELRO_END,
+       respectively.
+
+       * ldlang.c (lang_size_sections_1): Properly set
+       expld.dataseg.relro_start_stat and
+       expld.dataseg.relro_end_stat.
+       (find_relro_section_callback): New function.
+       (lang_find_relro_sections_1): Likewise.
+       (lang_find_relro_sections): Likewise.
+       (lang_process): Call lang_find_relro_sections for
+       non-relocatable link.
+
+ld/testsuite/
+
+2006-10-20  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/3281
+       * ld-elf/binutils.exp: Update "-z relro" tests to use relro.s.
+       Add "-z relro" tests with TLS for objcopy.
+
+       * ld-elf/relro.s: New file.
+
+@DPATCH@
+diff -urNad binutils-2.18~cvs20070812~/bfd/elf-bfd.h binutils-2.18~cvs20070812/bfd/elf-bfd.h
+--- binutils-2.18~cvs20070812~/bfd/elf-bfd.h   2007-08-04 18:31:00.000000000 +0200
++++ binutils-2.18~cvs20070812/bfd/elf-bfd.h    2007-08-12 13:31:23.000000000 +0200
+@@ -1428,9 +1428,6 @@
+   /* Segment flags for the PT_GNU_STACK segment.  */
+   unsigned int stack_flags;
+-  /* Should the PT_GNU_RELRO segment be emitted?  */
+-  bfd_boolean relro;
+-
+   /* Symbol version definitions in external objects.  */
+   Elf_Internal_Verdef *verdef;
+diff -urNad binutils-2.18~cvs20070812~/bfd/elf.c binutils-2.18~cvs20070812/bfd/elf.c
+--- binutils-2.18~cvs20070812~/bfd/elf.c       2007-08-07 02:06:14.000000000 +0200
++++ binutils-2.18~cvs20070812/bfd/elf.c        2007-08-12 13:31:23.000000000 +0200
+@@ -3321,7 +3321,7 @@
+       /* We need a PT_DYNAMIC segment.  */
+       ++segs;
+-      if (elf_tdata (abfd)->relro)
++      if (info->relro)
+       {
+         /* We need a PT_GNU_RELRO segment only when there is a
+            PT_DYNAMIC segment.  */
+@@ -3848,7 +3848,7 @@
+         pm = &m->next;
+       }
+-      if (dynsec != NULL && elf_tdata (abfd)->relro)
++      if (dynsec != NULL && info->relro)
+       {
+         /* We make a PT_GNU_RELRO segment only when there is a
+            PT_DYNAMIC segment.  */
+@@ -4323,12 +4323,10 @@
+                   p->p_memsz += this_hdr->sh_size;
+               }
+-            if (p->p_type == PT_GNU_RELRO)
+-              p->p_align = 1;
+-            else if (align > p->p_align
+-                     && !m->p_align_valid
+-                     && (p->p_type != PT_LOAD
+-                         || (abfd->flags & D_PAGED) == 0))
++            if (align > p->p_align
++                && !m->p_align_valid
++                && (p->p_type != PT_LOAD
++                    || (abfd->flags & D_PAGED) == 0))
+               p->p_align = align;
+           }
+@@ -4477,18 +4475,53 @@
+       if (m->count != 0)
+       {
+         if (p->p_type != PT_LOAD
+-            && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core))
++            && (p->p_type != PT_NOTE
++                || bfd_get_format (abfd) != bfd_core))
+           {
+             Elf_Internal_Shdr *hdr;
++            asection *sect;
++
+             BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
+-            hdr = &elf_section_data (m->sections[m->count - 1])->this_hdr;
+-            p->p_filesz = (m->sections[m->count - 1]->filepos
+-                           - m->sections[0]->filepos);
++            sect = m->sections[m->count - 1];
++            hdr = &elf_section_data (sect)->this_hdr;
++            p->p_filesz = sect->filepos - m->sections[0]->filepos;
+             if (hdr->sh_type != SHT_NOBITS)
+               p->p_filesz += hdr->sh_size;
+-            p->p_offset = m->sections[0]->filepos;
++            if (p->p_type == PT_GNU_RELRO)
++              {
++                /* When we get here, we are copying executable
++                   or shared library. But we need to use the same
++                   linker logic.  */
++                Elf_Internal_Phdr *lp;
++
++                for (lp = phdrs; lp < phdrs + count; ++lp)
++                  {
++                    if (lp->p_type == PT_LOAD
++                        && lp->p_paddr == p->p_paddr)
++                      break;
++                  }
++        
++                if (lp < phdrs + count)
++                  {
++                    /* The end of PT_GNU_RELRO segment is the next
++                       SEC_ALLOC section after it if it exists.  */
++                    if (sect->next != NULL
++                        && (sect->next->flags & SEC_ALLOC) != 0)
++                      p->p_filesz = sect->next->lma - lp->p_vaddr;
++                    else
++                      p->p_filesz += p->p_vaddr - lp->p_vaddr;
++                    p->p_vaddr = lp->p_vaddr;
++                    p->p_offset = lp->p_offset;
++                    p->p_memsz = p->p_filesz;
++                    p->p_align = 1;
++                  }
++                else
++                  abort ();
++              }
++            else
++              p->p_offset = m->sections[0]->filepos;
+           }
+       }
+       else
+@@ -4923,8 +4956,17 @@
+ /* Rewrite program header information.  */
++enum elf_section_status
++{
++  unknown,
++  added,
++  removed,
++  modified
++};
++
+ static bfd_boolean
+-rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
++rewrite_elf_program_header (bfd *ibfd, bfd *obfd,
++                          enum elf_section_status status)
+ {
+   Elf_Internal_Ehdr *iehdr;
+   struct elf_segment_map *map;
+@@ -5077,7 +5119,14 @@
+           }
+       if (segment->p_type != PT_LOAD)
+-      continue;
++      {
++        /* If a section is added or mofied, remove PT_GNU_RELRO
++           segment.  */
++        if (status != removed &&
++            segment->p_type == PT_GNU_RELRO)
++          segment->p_type = PT_NULL;
++        continue;
++      }
+       /* Determine if this segment overlaps any previous segments.  */
+       for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2 ++)
+@@ -5657,6 +5706,12 @@
+ static bfd_boolean
+ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+ {
++  enum elf_section_status status;
++  Elf_Internal_Phdr *segment;
++  asection *section, *osec;
++  unsigned int i, num_segments;
++  Elf_Internal_Shdr *this_hdr;
++
+   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+     return TRUE;
+@@ -5664,16 +5719,13 @@
+   if (elf_tdata (ibfd)->phdr == NULL)
+     return TRUE;
++  status = unknown;
+   if (ibfd->xvec == obfd->xvec)
+     {
+-      /* Check to see if any sections in the input BFD
+-       covered by ELF program header have changed.  */
+-      Elf_Internal_Phdr *segment;
+-      asection *section, *osec;
+-      unsigned int i, num_segments;
+-      Elf_Internal_Shdr *this_hdr;
++      /* Check to see if any sections in the input BFD covered by ELF
++       program header have changed.
+-      /* Initialize the segment mark field.  */
++       Initialize the segment mark field.  */
+       for (section = obfd->sections; section != NULL;
+          section = section->next)
+       section->segment_mark = FALSE;
+@@ -5725,7 +5777,10 @@
+          section = section->next)
+       {
+         if (section->segment_mark == FALSE)
+-          goto rewrite;
++          { 
++            status = added;
++            goto rewrite;
++          }
+         else
+           section->segment_mark = FALSE;
+       }
+@@ -5734,7 +5789,42 @@
+     }
+ rewrite:
+-  return rewrite_elf_program_header (ibfd, obfd);
++  if (status == unknown)
++    {
++      /* We need to find out how we are changed.  */
++      num_segments = elf_elfheader (ibfd)->e_phnum;
++      for (i = 0, segment = elf_tdata (ibfd)->phdr;
++         i < num_segments;
++         i++, segment++)
++      {
++        for (section = ibfd->sections;
++             section != NULL; section = section->next)
++          {
++            osec = section->output_section;
++
++            /* Check if this section is covered by the segment.  */
++            this_hdr = &(elf_section_data(section)->this_hdr);
++            if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
++              {
++                if (osec == NULL)
++                  status = removed;
++                else if (section->flags != osec->flags
++                         || section->lma != osec->lma
++                         || section->vma != osec->vma
++                         || section->size != osec->size
++                         || section->rawsize != osec->rawsize
++                         || section->alignment_power != osec->alignment_power)
++                  {
++                    /* Stop if a section is modified.  */
++                    status = modified;
++                    break;
++                  }
++              }
++          }
++      }
++    }
++  BFD_ASSERT (status != unknown);
++  return rewrite_elf_program_header (ibfd, obfd, status);
+ }
+ /* Initialize private output section information from input section.  */
+diff -urNad binutils-2.18~cvs20070812~/bfd/elflink.c binutils-2.18~cvs20070812/bfd/elflink.c
+--- binutils-2.18~cvs20070812~/bfd/elflink.c   2007-08-12 13:30:46.000000000 +0200
++++ binutils-2.18~cvs20070812/bfd/elflink.c    2007-08-12 13:31:23.000000000 +0200
+@@ -5364,7 +5364,6 @@
+     return TRUE;
+   bed = get_elf_backend_data (output_bfd);
+-  elf_tdata (output_bfd)->relro = info->relro;
+   if (info->execstack)
+     elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
+   else if (info->noexecstack)
+diff -urNad binutils-2.18~cvs20070812~/include/elf/internal.h binutils-2.18~cvs20070812/include/elf/internal.h
+--- binutils-2.18~cvs20070812~/include/elf/internal.h  2007-05-02 15:44:36.000000000 +0200
++++ binutils-2.18~cvs20070812/include/elf/internal.h   2007-08-12 13:31:23.000000000 +0200
+@@ -266,11 +266,12 @@
+      || segment->p_type == PT_TLS) ? sec_hdr->sh_size : 0)
+ /* Decide if the given sec_hdr is in the given segment.  PT_TLS segment
+-   contains only SHF_TLS sections.  Only PT_LOAD and PT_TLS segments
+-   can contain SHF_TLS sections.  */
++   contains only SHF_TLS sections.  Only PT_LOAD, PT_GNU_RELRO and
++   and PT_TLS segments can contain SHF_TLS sections.  */
+ #define ELF_IS_SECTION_IN_SEGMENT(sec_hdr, segment)                   \
+   (((((sec_hdr->sh_flags & SHF_TLS) != 0)                             \
+      && (segment->p_type == PT_TLS                                    \
++       || segment->p_type == PT_GNU_RELRO                             \
+        || segment->p_type == PT_LOAD))                                \
+     || ((sec_hdr->sh_flags & SHF_TLS) == 0                            \
+       && segment->p_type != PT_TLS))                                  \
+diff -urNad binutils-2.18~cvs20070812~/ld/ldexp.c binutils-2.18~cvs20070812/ld/ldexp.c
+--- binutils-2.18~cvs20070812~/ld/ldexp.c      2007-07-06 16:09:41.000000000 +0200
++++ binutils-2.18~cvs20070812/ld/ldexp.c       2007-08-12 13:31:23.000000000 +0200
+@@ -390,6 +390,7 @@
+             break;
+           case DATA_SEGMENT_ALIGN:
++            expld.dataseg.relro = exp_dataseg_relro_start;
+             if (expld.phase != lang_first_phase_enum
+                 && expld.section == bfd_abs_section_ptr
+                 && (expld.dataseg.phase == exp_dataseg_none
+@@ -425,6 +426,7 @@
+             break;
+           case DATA_SEGMENT_RELRO_END:
++            expld.dataseg.relro = exp_dataseg_relro_end;
+             if (expld.phase != lang_first_phase_enum
+                 && (expld.dataseg.phase == exp_dataseg_align_seen
+                     || expld.dataseg.phase == exp_dataseg_adjust
+diff -urNad binutils-2.18~cvs20070812~/ld/ldexp.h binutils-2.18~cvs20070812/ld/ldexp.h
+--- binutils-2.18~cvs20070812~/ld/ldexp.h      2007-07-06 16:09:41.000000000 +0200
++++ binutils-2.18~cvs20070812/ld/ldexp.h       2007-08-12 13:31:23.000000000 +0200
+@@ -98,6 +98,8 @@
+   lang_final_phase_enum
+ } lang_phase_type;
++union lang_statement_union;
++
+ struct ldexp_control {
+   /* Modify expression evaluation depending on this.  */
+   lang_phase_type phase;
+@@ -125,6 +127,15 @@
+     } phase;
+     bfd_vma base, min_base, relro_end, end, pagesize, maxpagesize;
++
++    enum {
++      exp_dataseg_relro_none,
++      exp_dataseg_relro_start,
++      exp_dataseg_relro_end,
++    } relro;
++
++    union lang_statement_union *relro_start_stat;
++    union lang_statement_union *relro_end_stat;
+   } dataseg;
+ };
+diff -urNad binutils-2.18~cvs20070812~/ld/ldlang.c binutils-2.18~cvs20070812/ld/ldlang.c
+--- binutils-2.18~cvs20070812~/ld/ldlang.c     2007-07-29 14:33:37.000000000 +0200
++++ binutils-2.18~cvs20070812/ld/ldlang.c      2007-08-12 13:31:23.000000000 +0200
+@@ -4631,10 +4631,32 @@
+           bfd_vma newdot = dot;
+           etree_type *tree = s->assignment_statement.exp;
++          expld.dataseg.relro = exp_dataseg_relro_none;
++
+           exp_fold_tree (tree,
+                          output_section_statement->bfd_section,
+                          &newdot);
++          if (expld.dataseg.relro == exp_dataseg_relro_start)
++            {
++              if (!expld.dataseg.relro_start_stat)
++                expld.dataseg.relro_start_stat = s;
++              else
++                {
++                  ASSERT (expld.dataseg.relro_start_stat == s);
++                }
++            }
++          else if (expld.dataseg.relro == exp_dataseg_relro_end)
++            {
++              if (!expld.dataseg.relro_end_stat)
++                expld.dataseg.relro_end_stat = s;
++              else
++                {
++                  ASSERT (expld.dataseg.relro_end_stat == s);
++                }
++            }
++          expld.dataseg.relro = exp_dataseg_relro_none;
++
+           /* This symbol is relative to this section.  */
+           if ((tree->type.node_class == etree_provided
+                || tree->type.node_class == etree_assign)
+@@ -5660,6 +5682,81 @@
+     bfd_gc_sections (output_bfd, &link_info);
+ }
++/* Worker for lang_find_relro_sections_1.  */
++
++static void
++find_relro_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED,
++                           struct wildcard_list *sec ATTRIBUTE_UNUSED,
++                           asection *section,
++                           lang_input_statement_type *file ATTRIBUTE_UNUSED,
++                           void *data)
++{
++  /* Discarded, excluded and ignored sections effectively have zero
++     size.  */
++  if (section->output_section != NULL
++      && section->output_section->owner == output_bfd
++      && (section->output_section->flags & SEC_EXCLUDE) == 0
++      && !IGNORE_SECTION (section)
++      && section->size != 0)
++    {
++      bfd_boolean *has_relro_section = (bfd_boolean *) data;
++      *has_relro_section = TRUE;
++    }
++}
++
++/* Iterate over sections for relro sections.  */
++
++static void
++lang_find_relro_sections_1 (lang_statement_union_type *s,
++                          bfd_boolean *has_relro_section)
++{
++  if (*has_relro_section)
++    return;
++
++  for (; s != NULL; s = s->header.next)
++    {
++      if (s == expld.dataseg.relro_end_stat)
++      break;
++
++      switch (s->header.type)
++      {
++      case lang_wild_statement_enum:
++        walk_wild (&s->wild_statement,
++                   find_relro_section_callback,
++                   has_relro_section);
++        break;
++      case lang_constructors_statement_enum:
++        lang_find_relro_sections_1 (constructor_list.head,
++                                    has_relro_section);
++        break;
++      case lang_output_section_statement_enum:
++        lang_find_relro_sections_1 (s->output_section_statement.children.head,
++                                    has_relro_section);
++        break;
++      case lang_group_statement_enum:
++        lang_find_relro_sections_1 (s->group_statement.children.head,
++                                    has_relro_section);
++        break;
++      default:
++        break;
++      }
++    }
++}
++
++static void
++lang_find_relro_sections (void)
++{
++  bfd_boolean has_relro_section = FALSE;
++
++  /* Check all sections in the link script.  */
++
++  lang_find_relro_sections_1 (expld.dataseg.relro_start_stat,
++                            &has_relro_section);
++
++  if (!has_relro_section)
++    link_info.relro = FALSE;
++}
++
+ /* Relax all sections until bfd_relax_section gives up.  */
+ static void
+@@ -5787,6 +5884,10 @@
+      section positions, since they will affect SIZEOF_HEADERS.  */
+   lang_record_phdrs ();
++  /* Check relro sections.  */
++  if (link_info.relro && ! link_info.relocatable)
++    lang_find_relro_sections ();
++
+   /* Size up the sections.  */
+   lang_size_sections (NULL, !command_line.relax);
+diff -urNad binutils-2.18~cvs20070812~/ld/testsuite/ld-elf/binutils.exp binutils-2.18~cvs20070812/ld/testsuite/ld-elf/binutils.exp
+--- binutils-2.18~cvs20070812~/ld/testsuite/ld-elf/binutils.exp        2007-07-06 16:09:43.000000000 +0200
++++ binutils-2.18~cvs20070812/ld/testsuite/ld-elf/binutils.exp 2007-08-12 13:31:23.000000000 +0200
+@@ -104,24 +104,33 @@
+ binutils_test objcopy "" maxpage1
+ binutils_test objcopy "-shared" maxpage1
+-binutils_test strip "-z relro" maxpage1
+-binutils_test strip "-z relro -shared" maxpage1
+-binutils_test objcopy "-z relro" maxpage1
+-binutils_test objcopy "-z relro -shared" maxpage1
++binutils_test strip "-z relro" relro
++binutils_test strip "-z relro -shared" relro
++binutils_test objcopy "-z relro" relro
++binutils_test objcopy "-z relro -shared" relro
+ binutils_test objcopy "" tbss1
++binutils_test objcopy "-z relro" tbss1
+ binutils_test objcopy "-shared" tbss1
++binutils_test objcopy "-shared -z relro" tbss1
+ binutils_test objcopy "-z max-page-size=0x100000" tbss1
+ binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tbss1
+ binutils_test objcopy "" tdata1
++binutils_test objcopy "-z relro" tdata1
+ binutils_test objcopy "-shared" tdata1
++binutils_test objcopy "-shared -z relro" tdata1
+ binutils_test objcopy "-z max-page-size=0x100000" tdata1
+ binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tdata1
+ binutils_test objcopy "" tbss2
++binutils_test objcopy "-z relro" tbss2
+ binutils_test objcopy "-shared" tbss2
++binutils_test objcopy "-shared -z relro" tbss2
+ binutils_test objcopy "-z max-page-size=0x100000" tbss2
+ binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tbss2
+-binutils_test objcopy "-z max-page-size=0x100000" tdata2
++
+ binutils_test objcopy "" tdata2
++binutils_test objcopy "-z relro" tdata2
+ binutils_test objcopy "-shared" tdata2
++binutils_test objcopy "-shared -z relro" tdata2
++binutils_test objcopy "-z max-page-size=0x100000" tdata2
+ binutils_test objcopy "-z max-page-size=0x100000 -z common-page-size=0x1000" tdata2
+diff -urNad binutils-2.18~cvs20070812~/ld/testsuite/ld-elf/relro.s binutils-2.18~cvs20070812/ld/testsuite/ld-elf/relro.s
+--- binutils-2.18~cvs20070812~/ld/testsuite/ld-elf/relro.s     1970-01-01 01:00:00.000000000 +0100
++++ binutils-2.18~cvs20070812/ld/testsuite/ld-elf/relro.s      2007-08-12 13:31:23.000000000 +0200
+@@ -0,0 +1,14 @@
++      .globl main
++      .globl start
++      .globl _start
++      .globl __start
++      .text
++main:
++start:
++_start:
++__start:
++      .long   0
++      .data
++      .long   0
++      .section .data.rel.ro,"aw",%progbits
++      .long   0