diff -Nru binutils-2.19/debian/changelog binutils-2.19/debian/changelog --- binutils-2.19/debian/changelog 2008-12-12 14:05:50.000000000 +0000 +++ binutils-2.19/debian/changelog 2008-12-12 14:06:06.000000000 +0000 @@ -1,3 +1,10 @@ +binutils (2.19-0ubuntu4) jaunty; urgency=low + + * debian/patches/213-PT_GNU_RELRO.dpatch: + - Handle PT_GNU_RELRO properly (LP: #254790). + + -- Luca Falavigna Fri, 12 Dec 2008 14:00:17 +0000 + binutils (2.19-0ubuntu3) jaunty; urgency=low * debian/patches/129_scale-DW_CFA_advance_loc.dpatch: Scale diff -Nru binutils-2.19/debian/patches/00list binutils-2.19/debian/patches/00list --- binutils-2.19/debian/patches/00list 2008-12-12 14:05:50.000000000 +0000 +++ binutils-2.19/debian/patches/00list 2008-12-12 14:06:06.000000000 +0000 @@ -22,3 +22,4 @@ 210-hjl-binutils-signed 211-hjl-binutils-weakdef 212-hjl-bfd-64k +213-PT_GNU_RELRO diff -Nru binutils-2.19/debian/patches/213-PT_GNU_RELRO.dpatch binutils-2.19/debian/patches/213-PT_GNU_RELRO.dpatch --- binutils-2.19/debian/patches/213-PT_GNU_RELRO.dpatch 1970-01-01 00:00:00.000000000 +0000 +++ binutils-2.19/debian/patches/213-PT_GNU_RELRO.dpatch 2008-12-12 14:06:06.000000000 +0000 @@ -0,0 +1,170 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 213-PT_GNU_RELRO.dpatch by Luca Falavigna +## DP: Handle PT_GNU_RELRO properly. + +@DPATCH@ +diff -urNad binutils-2.19~/bfd/elf.c binutils-2.19/bfd/elf.c +--- binutils-2.19~/bfd/elf.c 2008-12-12 13:55:17.000000000 +0000 ++++ binutils-2.19/bfd/elf.c 2008-12-12 13:57:16.000000000 +0000 +@@ -4613,7 +4613,61 @@ + m != NULL; + m = m->next, p++) + { +- if (m->count != 0) ++ if (p->p_type == PT_GNU_RELRO) ++ { ++ const Elf_Internal_Phdr *lp; ++ ++ BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); ++ ++ if (link_info != NULL) ++ { ++ /* During linking the range of the RELRO segment is passed ++ in link_info. */ ++ for (lp = phdrs; lp < phdrs + count; ++lp) ++ { ++ if (lp->p_type == PT_LOAD ++ && lp->p_vaddr >= link_info->relro_start ++ && lp->p_vaddr < link_info->relro_end ++ && lp->p_vaddr + lp->p_filesz >= link_info->relro_end) ++ break; ++ } ++ } ++ else ++ { ++ /* Otherwise we are copying an executable or shared ++ library, but we need to use the same linker logic. */ ++ for (lp = phdrs; lp < phdrs + count; ++lp) ++ { ++ if (lp->p_type == PT_LOAD ++ && lp->p_paddr == p->p_paddr) ++ break; ++ } ++ } ++ ++ if (lp < phdrs + count) ++ { ++ p->p_vaddr = lp->p_vaddr; ++ p->p_paddr = lp->p_paddr; ++ p->p_offset = lp->p_offset; ++ if (link_info != NULL) ++ p->p_filesz = link_info->relro_end - lp->p_vaddr; ++ else if (m->p_size_valid) ++ p->p_filesz = m->p_size; ++ else ++ abort (); ++ p->p_memsz = p->p_filesz; ++ p->p_align = 1; ++ p->p_flags = (lp->p_flags & ~PF_W); ++ } ++ else if (link_info != NULL) ++ { ++ memset (p, 0, sizeof *p); ++ p->p_type = PT_NULL; ++ } ++ else ++ abort (); ++ } ++ else if (m->count != 0) + { + if (p->p_type != PT_LOAD + && (p->p_type != PT_NOTE +@@ -4629,87 +4683,20 @@ + p->p_filesz = sect->filepos - m->sections[0]->filepos; + if (hdr->sh_type != SHT_NOBITS) + p->p_filesz += hdr->sh_size; +- +- 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) +- { +- /* We should use p_size if it is valid since it +- may contain the first few bytes of the next +- SEC_ALLOC section. */ +- if (m->p_size_valid) +- p->p_filesz = m->p_size; +- else +- abort (); +- 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; ++ p->p_offset = m->sections[0]->filepos; + } + } +- else ++ else if (m->includes_filehdr) + { +- if (m->includes_filehdr) +- { +- p->p_vaddr = filehdr_vaddr; +- if (! m->p_paddr_valid) +- p->p_paddr = filehdr_paddr; +- } +- else if (m->includes_phdrs) +- { +- p->p_vaddr = phdrs_vaddr; +- if (! m->p_paddr_valid) +- p->p_paddr = phdrs_paddr; +- } +- else if (p->p_type == PT_GNU_RELRO) +- { +- Elf_Internal_Phdr *lp; +- +- for (lp = phdrs; lp < phdrs + count; ++lp) +- { +- if (lp->p_type == PT_LOAD +- && lp->p_vaddr <= link_info->relro_end +- && lp->p_vaddr >= link_info->relro_start +- && (lp->p_vaddr + lp->p_filesz +- >= link_info->relro_end)) +- break; +- } +- +- if (lp < phdrs + count +- && link_info->relro_end > lp->p_vaddr) +- { +- p->p_vaddr = lp->p_vaddr; +- p->p_paddr = lp->p_paddr; +- p->p_offset = lp->p_offset; +- p->p_filesz = link_info->relro_end - lp->p_vaddr; +- p->p_memsz = p->p_filesz; +- p->p_align = 1; +- p->p_flags = (lp->p_flags & ~PF_W); +- } +- else +- { +- memset (p, 0, sizeof *p); +- p->p_type = PT_NULL; +- } +- } ++ p->p_vaddr = filehdr_vaddr; ++ if (! m->p_paddr_valid) ++ p->p_paddr = filehdr_paddr; ++ } ++ else if (m->includes_phdrs) ++ { ++ p->p_vaddr = phdrs_vaddr; ++ if (! m->p_paddr_valid) ++ p->p_paddr = phdrs_paddr; + } + } +