[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: BUG: bfd/elf allows only 2 PT_LOAD phdrs
From: |
Bhavesh P. Davda |
Subject: |
Re: BUG: bfd/elf allows only 2 PT_LOAD phdrs |
Date: |
Tue, 10 Dec 2002 10:55:45 -0700 |
Hi Nick,
Attached are the following files:
1. test.c, the source code for an example for requiring 3 PT_LOAD
segments
2. ld_map, the linker script used to append to the default linker script
3. Makefile, to build test.c
I am also attaching a alternative patch to bfd/elf.c, since
address@hidden, the binutils maintainer for RedHat refused to apply my
original patch. His concern was valid: the original patch would grow the
program headers for all elf binaries, whether or not you needed 2 or
more PT_LOAD segments.
The new patch only creates additional PT_LOAD segments and grows the
program header if it needs to, i.e. going through the output sections,
it encounters a case that requires a new PT_LOAD segment be created. The
above example shows one such case...
Thanks
- Bhavesh
Nick Clifton wrote:
>
> Hi Bhavesh,
>
> > IMHO, the following is too restrictive in bfd/elf.c:
>
> > /* Assume we will need exactly two PT_LOAD segments: one for text
> > and one for data. */
> > segs = 2;
>
> > I tried allowing 3 PT_LOAD segments, and it works for both the normal 2
> > PT_LOAD segments case and the 3 PT_LOAD segments case.
> >
> > The final ELF executable produced with this change was identical to that
> > produced without this change for the normal case.
>
> Do you have a small test case which needs 3 PT_LOAD segments, which
> we could incorporate into the linker testsuite ?
>
> Cheers
> Nick
int cda_data[4096] __attribute__ ((section(".cda")));
int main()
{
cda_data[0] = 0;
cda_data[500] = 500;
while (1) ;
return 0;
}
SECTIONS {
.cda_bss 0x10000000 : {
*(.cda)
}
}
all: test
test.o: test.c
gcc -g3 -O0 -c test.c
test: test.o
/usr/bin/ld --dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o
/usr/lib/crti.o /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/crtbegin.o
-L/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2 test.o ld_map -lgcc -lc -lgcc
/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/crtend.o /usr/lib/crtn.o
diff -Naur orig/src/bfd/elf.c new/src/bfd/elf.c
--- orig/src/bfd/elf.c Sat Nov 30 01:39:37 2002
+++ new/src/bfd/elf.c Fri Dec 6 19:11:30 2002
@@ -3639,20 +3639,13 @@
return TRUE;
/* If we already counted the number of program segments, make sure
- that we allocated enough space. This happens when SIZEOF_HEADERS
+ that we allocate enough space. This happens when SIZEOF_HEADERS
is used in a linker script. */
alloc = elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr;
- if (alloc != 0 && count > alloc)
+ if ((alloc != 0 && count > alloc) || (alloc == 0))
{
- ((*_bfd_error_handler)
- (_("%s: Not enough room for program headers (allocated %u, need %u)"),
- bfd_get_filename (abfd), alloc, count));
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ alloc = count;
}
-
- if (alloc == 0)
- alloc = count;
amt = alloc * sizeof (Elf_Internal_Phdr);
phdrs = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);