tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

PT_PHDR is useful without PT_INTERP change broke building memtest86+



Hi,

This change affected building sysutils/memtest86+.

/current/obj/tooldir.NetBSD-8.99.34-amd64/bin/x86_64--netbsd-ld --no-dynamic-linker -shared -Bsymbolic -T memtest_shared.lds -o memtest_shared head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o config.o cpuid.o linuxbios.o pci.o memsize.o spd.o error.o dmi.o controller.o smp.o vmem.o random.o
/current/obj/tooldir.NetBSD-8.99.34-amd64/bin/x86_64--netbsd-ld: memtest_shared: not enough room for program headers, try linking with -N
/current/obj/tooldir.NetBSD-8.99.34-amd64/bin/x86_64--netbsd-ld: final link failed: bad value

It uses this ldscript:

OUTPUT_FORMAT("elf32-i386");
OUTPUT_ARCH(i386);

ENTRY(startup_32); 
SECTIONS {
	. = 0;
	.text : {
		_start = .;
		*(.text)
		*(.text.*)
		*(.plt)
		_etext = . ;
	} = 0x9090
	.rodata : {
		*(.rodata)
		*(.rodata.*)
	}
	.dynsym     : { *(.dynsym) }
	.dynstr     : { *(.dynstr) }
	.hash       : { *(.hash) }
	.gnu.hash   : { *(.gnu.hash) }
	.dynamic    : { *(.dynamic) }

	.rel.text    : { *(.rel.text   .rel.text.*) }
	.rel.rodata  : { *(.rel.rodata .rel.rodata.*) }
	.rel.data    : { *(.rel.data   .rel.data.*) }
	.rel.got     : { *(.rel.got    .rel.got.*) }
	.rel.plt     : { *(.rel.plt    .rel.plt.*) }

	. = ALIGN(4);
	.data : {
		 _data = .; 
		*(.data) 
		*(.data.*) 
	}
	.got : {
		*(.got.plt)
		*(.got)
		_edata = . ;
	}
	. = ALIGN(4);
	.bss : { 
		_bss = .;
		*(.dynbss)
		*(.bss) 
		*(.bss.*) 
		*(COMMON) 
		/* _end must be at least 256 byte aligned */
		. = ALIGN(256); 
		_end = .;
	}
	/DISCARD/ : { *(*) }	
}

Before:
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x200000 0x00000000 0x00000000 0x2afb0 0x70400 RWE 0x200000
  DYNAMIC        0x21e8ec 0x0001e8ec 0x0001e8ec 0x00080 0x00080 RW  0x4


After, with this patch to the ldscript:
 SECTIONS {
-	. = 0;
+	. = 0x100;


Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00000034 0x00000034 0x00060 0x00060 R   0x4
  LOAD           0x000000 0x00000000 0x00000000 0x2afb0 0x70400 RWE 0x200000
  DYNAMIC        0x01e9ec 0x0001e9ec 0x0001e9ec 0x00080 0x00080 RW  0x4

Do you think that memtest86+ is wrong or is this a problem?


On Fri, Jul 13, 2018 at 07:54:14PM +0000, Joerg Sonnenberger wrote:
> Module Name:	src
> Committed By:	joerg
> Date:		Fri Jul 13 19:54:14 UTC 2018
> 
> Modified Files:
> 	src/external/gpl3/binutils.old/dist/bfd: elf.c
> 	src/external/gpl3/binutils/dist/bfd: elf.c
> 
> Log Message:
> Reapply with fixed condition:
> PT_PHDR is useful without PT_INTERP, i.e. for static PIE. It removes the
> need for platform-specific computations of _DYNAMIC and friends.
> 
> 
> To generate a diff of this commit:
> cvs rdiff -u -r1.7 -r1.8 src/external/gpl3/binutils.old/dist/bfd/elf.c
> cvs rdiff -u -r1.11 -r1.12 src/external/gpl3/binutils/dist/bfd/elf.c
> 
> Please note that diffs are not public domain; they are subject to the
> copyright notices on the relevant files.
> 

> Modified files:
> 
> Index: src/external/gpl3/binutils.old/dist/bfd/elf.c
> diff -u src/external/gpl3/binutils.old/dist/bfd/elf.c:1.7 src/external/gpl3/binutils.old/dist/bfd/elf.c:1.8
> --- src/external/gpl3/binutils.old/dist/bfd/elf.c:1.7	Fri Jul 13 10:49:17 2018
> +++ src/external/gpl3/binutils.old/dist/bfd/elf.c	Fri Jul 13 19:54:14 2018
> @@ -4159,7 +4159,7 @@ static bfd_size_type
>  get_program_header_size (bfd *abfd, struct bfd_link_info *info)
>  {
>    size_t segs;
> -  asection *s;
> +  asection *s, *s2;
>    const struct elf_backend_data *bed;
>  
>    /* Assume we will need exactly two PT_LOAD segments: one for text
> @@ -4167,21 +4167,28 @@ get_program_header_size (bfd *abfd, stru
>    segs = 2;
>  
>    s = bfd_get_section_by_name (abfd, ".interp");
> +  s2 = bfd_get_section_by_name (abfd, ".dynamic");
>    if (s != NULL && (s->flags & SEC_LOAD) != 0)
>      {
> -      /* If we have a loadable interpreter section, we need a
> -	 PT_INTERP segment.  In this case, assume we also need a
> -	 PT_PHDR segment, although that may not be true for all
> -	 targets.  */
> -      segs += 2;
> +      ++segs;
>      }
>  
> -  if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
> +  if (s2 != NULL && (s2->flags & SEC_LOAD) != 0)
>      {
>        /* We need a PT_DYNAMIC segment.  */
>        ++segs;
>      }
>  
> +  if ((s != NULL && (s->flags & SEC_LOAD) != 0) ||
> +      (s2 != NULL && (s2->flags & SEC_LOAD) != 0))
> +    {
> +      /*
> +       * If either a PT_INTERP or PT_DYNAMIC segment is created,
> +       * also create a PT_PHDR segment.
> +       */
> +      ++segs;
> +    }
> +
>    if (info != NULL && info->relro)
>      {
>        /* We need a PT_GNU_RELRO segment.  */
> @@ -4447,7 +4454,13 @@ _bfd_elf_map_sections_to_segments (bfd *
>  	 the program headers and a PT_INTERP segment for the .interp
>  	 section.  */
>        s = bfd_get_section_by_name (abfd, ".interp");
> -      if (s != NULL && (s->flags & SEC_LOAD) != 0)
> +      if (s != NULL && (s->flags & SEC_LOAD) == 0)
> +	s = NULL;
> +      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
> +      if (dynsec != NULL && (dynsec->flags & SEC_LOAD) == 0)
> +	dynsec = NULL;
> +
> +      if (s != NULL || dynsec != NULL)
>  	{
>  	  amt = sizeof (struct elf_segment_map);
>  	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
> @@ -4462,7 +4475,10 @@ _bfd_elf_map_sections_to_segments (bfd *
>  
>  	  *pm = m;
>  	  pm = &m->next;
> +	}
>  
> +      if (s != NULL)
> +	{
>  	  amt = sizeof (struct elf_segment_map);
>  	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
>  	  if (m == NULL)
> @@ -4489,10 +4505,6 @@ _bfd_elf_map_sections_to_segments (bfd *
>        if (maxpagesize == 0)
>  	maxpagesize = 1;
>        writable = FALSE;
> -      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
> -      if (dynsec != NULL
> -	  && (dynsec->flags & SEC_LOAD) == 0)
> -	dynsec = NULL;
>  
>        /* Deal with -Ttext or something similar such that the first section
>  	 is not adjacent to the program headers.  This is an
> 
> Index: src/external/gpl3/binutils/dist/bfd/elf.c
> diff -u src/external/gpl3/binutils/dist/bfd/elf.c:1.11 src/external/gpl3/binutils/dist/bfd/elf.c:1.12
> --- src/external/gpl3/binutils/dist/bfd/elf.c:1.11	Fri Jul 13 10:49:17 2018
> +++ src/external/gpl3/binutils/dist/bfd/elf.c	Fri Jul 13 19:54:13 2018
> @@ -4301,7 +4301,7 @@ static bfd_size_type
>  get_program_header_size (bfd *abfd, struct bfd_link_info *info)
>  {
>    size_t segs;
> -  asection *s;
> +  asection *s, *s2;
>    const struct elf_backend_data *bed;
>  
>    /* Assume we will need exactly two PT_LOAD segments: one for text
> @@ -4309,21 +4309,28 @@ get_program_header_size (bfd *abfd, stru
>    segs = 2;
>  
>    s = bfd_get_section_by_name (abfd, ".interp");
> +  s2 = bfd_get_section_by_name (abfd, ".dynamic");
>    if (s != NULL && (s->flags & SEC_LOAD) != 0)
>      {
> -      /* If we have a loadable interpreter section, we need a
> -	 PT_INTERP segment.  In this case, assume we also need a
> -	 PT_PHDR segment, although that may not be true for all
> -	 targets.  */
> -      segs += 2;
> +      ++segs;
>      }
>  
> -  if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
> +  if (s2 != NULL && (s2->flags & SEC_LOAD) != 0)
>      {
>        /* We need a PT_DYNAMIC segment.  */
>        ++segs;
>      }
>  
> +  if ((s != NULL && (s->flags & SEC_LOAD) != 0) ||
> +      (s2 != NULL && (s2->flags & SEC_LOAD) != 0))
> +    {
> +      /*
> +       * If either a PT_INTERP or PT_DYNAMIC segment is created,
> +       * also create a PT_PHDR segment.
> +       */
> +      ++segs;
> +    }
> +
>    if (info != NULL && info->relro)
>      {
>        /* We need a PT_GNU_RELRO segment.  */
> @@ -4619,7 +4626,13 @@ _bfd_elf_map_sections_to_segments (bfd *
>  	 the program headers and a PT_INTERP segment for the .interp
>  	 section.  */
>        s = bfd_get_section_by_name (abfd, ".interp");
> -      if (s != NULL && (s->flags & SEC_LOAD) != 0)
> +      if (s != NULL && (s->flags & SEC_LOAD) == 0)
> +	s = NULL;
> +      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
> +      if (dynsec != NULL && (dynsec->flags & SEC_LOAD) == 0)
> +	dynsec = NULL;
> +
> +      if (s != NULL || dynsec != NULL)
>  	{
>  	  amt = sizeof (struct elf_segment_map);
>  	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
> @@ -4633,7 +4646,10 @@ _bfd_elf_map_sections_to_segments (bfd *
>  	  linker_created_pt_phdr_segment = TRUE;
>  	  *pm = m;
>  	  pm = &m->next;
> +	}
>  
> +      if (s != NULL)
> +	{
>  	  amt = sizeof (struct elf_segment_map);
>  	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
>  	  if (m == NULL)
> @@ -4661,10 +4677,6 @@ _bfd_elf_map_sections_to_segments (bfd *
>  	maxpagesize = 1;
>        writable = FALSE;
>        executable = FALSE;
> -      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
> -      if (dynsec != NULL
> -	  && (dynsec->flags & SEC_LOAD) == 0)
> -	dynsec = NULL;
>  
>        /* Deal with -Ttext or something similar such that the first section
>  	 is not adjacent to the program headers.  This is an
> 



Home | Main Index | Thread Index | Old Index