Bug 594 - ld refuses to put data into PT_NOTE segment
Summary: ld refuses to put data into PT_NOTE segment
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.15
: P2 normal
Target Milestone: ---
Assignee: Ben Elliston
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-11-30 20:27 UTC by Paul Koning
Modified: 2006-04-27 06:19 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Koning 2004-11-30 20:27:55 UTC
I want to put data into a PT_NOTE segment without also putting it into the
program segment.  If I do put it into the program (PT_LOAD) segment, all is
well.  If I try to avoid that, by supplying data in a section that's marked as
not allocatable, I get contradictory results:

notedata.S:

	.section	notedata
	.byte	0
	.byte	1
	.byte	42

script:

PHDRS
{
  note PT_NOTE ;
  prog PT_LOAD ;
}

SECTIONS
{
  notedata :
  {
	notedata.o (notedata)
  } :note /*:prog*/
  .text 0x10000 :
  {
	*(.data .text .bss .reginfo)
  } :prog
}

Test run:

pkoning@plato1 src]$ gcc -c notedata.S
[pkoning@plato1 src]$ ld -o test2 -T test.ld notedata.o
[pkoning@plato1 src]$ objdump -p test2

test2:     file format elf32-i386

Program Header:
    NOTE off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**0
         filesz 0x00000000 memsz 0x00000003 flags r--
    LOAD off    0x00001000 vaddr 0x00010000 paddr 0x00010000 align 2**12
         filesz 0x00000000 memsz 0x00000000 flags r-x

[pkoning@plato1 src]$ objdump -h test2

test2:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 notedata      00000003  00000000  00000000  00001000  2**0
                  CONTENTS, READONLY
  1 .text         00000000  00010000  00010000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

No link warnings this time.  And the "notedata" section has a
"contents" attribute but not "alloc".

Now the filesz is zero, though the memsz reflects the size I wanted.
That's actually the reverse of what I expected to see -- given that
ALLOC and LOAD aren't set, I wouldn't have expected a memsize.

The above example is done with the stock ld from NetBSD 1.6 (which is version
2.11) but I see the identical failure with mips targeted tools version 2.14 and
2.15.
      paul
Comment 1 Ben Elliston 2004-12-06 06:11:47 UTC
Reproduced on NetBSD 1.6 with CVS binutils.
Comment 2 Ben Elliston 2004-12-07 03:44:20 UTC
Reproduced on other architectures.
Comment 3 Nick Clifton 2005-02-07 17:54:42 UTC
Subject: Re:  ld refuses to put data into PT_NOTE segment

Hi Paul,

   Please could you try out the attached small patch and see if this 
fixed things for you.

Cheers
   Nick



Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.264
diff -c -3 -p -r1.264 elf.c
*** bfd/elf.c	6 Feb 2005 23:21:44 -0000	1.264
--- bfd/elf.c	7 Feb 2005 17:53:16 -0000
*************** assign_file_positions_for_segments (bfd 
*** 4163,4168 ****
--- 4163,4169 ----
  		  /* The section VMA must equal the file position
  		     modulo the page size.  */
  		  bfd_size_type page = align;
+ 
  		  if ((abfd->flags & D_PAGED) != 0)
  		    page = bed->maxpagesize;
  		  adjust = vma_page_aligned_bias (sec->vma,
*************** assign_file_positions_for_segments (bfd 
*** 4222,4227 ****
--- 4223,4234 ----
  		  p->p_filesz += sec->size;
  		  p->p_memsz += sec->size;
  		}
+ 	      /* PR ld/594:  Sections in note segments which are not loaded
+ 		 contribute to the file size but not the in-memory size.  */
+ 	      else if (p->p_type == PT_NOTE
+ 		  && (flags & SEC_HAS_CONTENTS) != 0)
+ 		p->p_filesz += sec->size;
+ 
  	      /* .tbss is special.  It doesn't contribute to p_memsz of
  		 normal segments.  */
  	      else if ((flags & SEC_THREAD_LOCAL) == 0
Comment 4 Paul Koning 2005-07-08 16:31:59 UTC
Apologies for the very slow response -- I missed the note in my mail and just
spotted it.

It looks like the patch mostly cures things.  In particular, filesz and memsz
are now correct.  But it does not correctly fill in the file offset in the
program headers:

[pkoning@plato1 src]$ mipsel-netbsdelf-objdump -hp a.out

a.out:     file format elf32-littlemips

Program Header:
    NOTE off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**0
         filesz 0x00000003 memsz 0x00000000 flags r--
    LOAD off    0x00001000 vaddr 0x00010000 paddr 0x00010000 align 2**12
         filesz 0x00000018 memsz 0x00000018 flags r-x
private flags = 1002: [abi=O32] [mips1] [not 32bitmode]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 notedata      00000003  00000000  00000000  00001018  2**0
                  CONTENTS, READONLY
  1 .text         00000018  00010000  00010000  00001000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .pdr          00000000  00000000  00000000  0000101c  2**2
                  CONTENTS, READONLY

The section headers show "notedata" at offset 0x1018, and hexdump confirms that
this is correct.  But the program header offset for the NOTE is 0; instead it
should also be 0x1018.
Comment 5 Ben Elliston 2006-04-27 06:19:17 UTC
Fixed by:

2006-04-21  Alan Modra  <amodra@bigpond.net.au>

        * elf.c (assign_file_positions_except_relocs): Move code setting
        file position of non-loaded sections..
        (assign_file_positions_for_segments): ..to here.