2006-12-19 Nathan Sidwell * elf.c (bfd_elf_mkobject): Default program_header_size to zero. (_bfd_elf_map_sections_to_segments): Adjust default program_header_size value. Don't shrink the program header size. (assign_file_positions_for_load_sections): Adjust for default program_header_size value. Assert we've got enough room. (_bfd_elf_sizeof_headers): Always recalculate the header size. Never shrink it. * ld/testsuite/ld-elf/header.d: New. * ld/testsuite/ld-elf/header.t: New. * ld/testsuite/ld-elf/header.s: New. Index: bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.369 diff -c -3 -p -r1.369 elf.c *** bfd/elf.c 19 Dec 2006 08:49:38 -0000 1.369 --- bfd/elf.c 19 Dec 2006 15:32:08 -0000 *************** bfd_elf_mkobject (bfd *abfd) *** 231,237 **** return FALSE; } ! elf_tdata (abfd)->program_header_size = (bfd_size_type) -1; return TRUE; } --- 231,237 ---- return FALSE; } ! elf_tdata (abfd)->program_header_size = 0; return TRUE; } *************** _bfd_elf_map_sections_to_segments (bfd * *** 3894,3900 **** { bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; ! if (phdr_size == (bfd_size_type) -1) phdr_size = get_program_header_size (abfd, info); if ((abfd->flags & D_PAGED) == 0 || sections[0]->lma < phdr_size --- 3894,3900 ---- { bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; ! if (!phdr_size) phdr_size = get_program_header_size (abfd, info); if ((abfd->flags & D_PAGED) == 0 || sections[0]->lma < phdr_size *************** _bfd_elf_map_sections_to_segments (bfd * *** 4145,4151 **** for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) ++count; ! elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr; return TRUE; --- 4145,4152 ---- for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) ++count; ! if (elf_tdata (abfd)->program_header_size < count * bed->s->sizeof_phdr) ! elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr; return TRUE; *************** assign_file_positions_for_load_sections *** 4271,4281 **** elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr; elf_elfheader (abfd)->e_phnum = alloc; ! if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1) elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr; else BFD_ASSERT (elf_tdata (abfd)->program_header_size ! == alloc * bed->s->sizeof_phdr); if (alloc == 0) { --- 4272,4282 ---- elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr; elf_elfheader (abfd)->e_phnum = alloc; ! if (!elf_tdata (abfd)->program_header_size) elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr; else BFD_ASSERT (elf_tdata (abfd)->program_header_size ! >= alloc * bed->s->sizeof_phdr); if (alloc == 0) { *************** _bfd_elf_sizeof_headers (bfd *abfd, stru *** 7193,7213 **** if (!info->relocatable) { ! bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; ! if (phdr_size == (bfd_size_type) -1) ! { ! struct elf_segment_map *m; ! phdr_size = 0; ! for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) ! phdr_size += bed->s->sizeof_phdr; ! if (phdr_size == 0) ! phdr_size = get_program_header_size (abfd, info); ! } ! ! elf_tdata (abfd)->program_header_size = phdr_size; ret += phdr_size; } --- 7194,7216 ---- if (!info->relocatable) { ! bfd_size_type phdr_size = 0; ! struct elf_segment_map *m; ! for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) ! phdr_size += bed->s->sizeof_phdr; ! if (phdr_size == 0) ! phdr_size = get_program_header_size (abfd, info); ! /* Avoid shrinking program header size. Shrinking can lead to ! instability when a section's placement becomes aligned on a ! page boundary with N segments, requiring N+1 segments. And ! with N+1 segments it no longer is aligned. */ ! if (elf_tdata (abfd)->program_header_size > phdr_size) ! phdr_size = elf_tdata (abfd)->program_header_size; ! else ! elf_tdata (abfd)->program_header_size = phdr_size; ret += phdr_size; } Index: ld/testsuite/ld-elf/header.d =================================================================== RCS file: ld/testsuite/ld-elf/header.d diff -N ld/testsuite/ld-elf/header.d *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-elf/header.d 19 Dec 2006 15:32:08 -0000 *************** *** 0 **** --- 1,12 ---- + # ld: -T header.t -z max-page-size=0x10000 + # objdump: -hpw + + #... + Program Header: + LOAD off 0x0*0000000 vaddr 0x0*0010000 paddr 0x0*0010000 align 2..16 + filesz 0x0*0010024 memsz 0x0*0010024 flags rwx + + Sections: + Idx Name Size VMA LMA File off Algn Flags + 0 .text 0*000ffac 0*0010074 0*0010074 0*0000074 2... CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .data 0*0000004 0*0020020 0*0020020 0*0010020 2... CONTENTS, ALLOC, LOAD, DATA Index: ld/testsuite/ld-elf/header.s =================================================================== RCS file: ld/testsuite/ld-elf/header.s diff -N ld/testsuite/ld-elf/header.s *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-elf/header.s 19 Dec 2006 15:32:08 -0000 *************** *** 0 **** --- 1,8 ---- + .text + .globl main + main: + .rept 0x4000 - 0x15 + .long 0xfedcba98 + .endr + .data + .long 0x76543210 Index: ld/testsuite/ld-elf/header.t =================================================================== RCS file: ld/testsuite/ld-elf/header.t diff -N ld/testsuite/ld-elf/header.t *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-elf/header.t 19 Dec 2006 15:32:08 -0000 *************** *** 0 **** --- 1,8 ---- + ENTRY(main) + + SECTIONS + { + . = 0x10000 + SIZEOF_HEADERS; + .text : { *(.text) } + .data : { *(.data) } + }