From d324f6d66ba4ddd975973e0a494c5c9c9be532fc Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 9 Apr 2012 16:27:18 +0000 Subject: [PATCH] bfd/ * elf.c (_bfd_elf_map_sections_to_segments): Set INFO->user_phdrs. * elf-nacl.c (nacl_modify_segment_map): Do nothing if INFO->user_phdrs. (nacl_modify_program_headers): Likewise. include/ * bfdlink.h (struct bfd_link_info): Add new member user_phdrs. --- bfd/ChangeLog | 6 ++++++ bfd/elf-nacl.c | 12 +++++++++++- bfd/elf.c | 14 +++++++++----- include/ChangeLog | 4 ++++ include/bfdlink.h | 7 +++++-- 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 56a1121e90..6d1294408a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2012-04-09 Roland McGrath + + * elf.c (_bfd_elf_map_sections_to_segments): Set INFO->user_phdrs. + * elf-nacl.c (nacl_modify_segment_map): Do nothing if INFO->user_phdrs. + (nacl_modify_program_headers): Likewise. + 2012-04-03 Roland McGrath * elf-nacl.c: New file. diff --git a/bfd/elf-nacl.c b/bfd/elf-nacl.c index 3ba7f5582e..842e367d97 100644 --- a/bfd/elf-nacl.c +++ b/bfd/elf-nacl.c @@ -62,13 +62,18 @@ segment_nonexecutable_and_has_contents (struct elf_segment_map *seg) The first non-executable PT_LOAD segment appears first in the file and contains the ELF file header and phdrs. */ bfd_boolean -nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) +nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info) { struct elf_segment_map **m = &elf_tdata (abfd)->segment_map; struct elf_segment_map **first_load = NULL; struct elf_segment_map **last_load = NULL; bfd_boolean moved_headers = FALSE; + if (info != NULL && info->user_phdrs) + /* The linker script used PHDRS explicitly, so don't change what the + user asked for. */ + return TRUE; + while (*m != NULL) { struct elf_segment_map *seg = *m; @@ -141,6 +146,11 @@ nacl_modify_program_headers (bfd *abfd, Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr; Elf_Internal_Phdr *p = phdr; + if (info != NULL && info->user_phdrs) + /* The linker script used PHDRS explicitly, so don't change what the + user asked for. */ + return TRUE; + /* Find the PT_LOAD that contains the headers (should be the first). */ while (*m != NULL) { diff --git a/bfd/elf.c b/bfd/elf.c index df43a6ad4c..7faa8f652c 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -2527,7 +2527,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd, rel_hdr = bfd_zalloc (abfd, amt); reldata->hdr = rel_hdr; - amt = sizeof ".rela" + strlen (asect->name); + amt = sizeof ".rela" + strlen (asect->name); name = (char *) bfd_alloc (abfd, amt); if (name == NULL) return FALSE; @@ -3744,6 +3744,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) bfd_boolean no_user_phdrs; no_user_phdrs = elf_tdata (abfd)->segment_map == NULL; + + if (info != NULL) + info->user_phdrs = !no_user_phdrs; + if (no_user_phdrs && bfd_count_sections (abfd) != 0) { asection *s; @@ -4351,7 +4355,7 @@ assign_file_positions_for_load_sections (bfd *abfd, elf_elfheader (abfd)->e_phoff = 0; elf_elfheader (abfd)->e_phentsize = 0; } - + elf_elfheader (abfd)->e_phnum = alloc; if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1) @@ -5428,7 +5432,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) 1. It is within the address space of the segment -- we use the LMA if that is set for the segment and the VMA otherwise, 2. It is an allocated section or a NOTE section in a PT_NOTE - segment. + segment. 3. There is an output section associated with it, 4. The section has not already been allocated to a previous segment. 5. PT_GNU_STACK segments do not include any sections. @@ -6148,7 +6152,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) if (map->includes_filehdr && lowest_section != NULL) /* We need to keep the space used by the headers fixed. */ map->header_size = lowest_section->vma - segment->p_vaddr; - + if (!map->includes_phdrs && !map->includes_filehdr && map->p_paddr_valid) @@ -9633,7 +9637,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd, if (p->addend != 0) { char buf[30], *a; - + memcpy (names, "+0x", sizeof ("+0x") - 1); names += sizeof ("+0x") - 1; bfd_sprintf_vma (abfd, buf, p->addend); diff --git a/include/ChangeLog b/include/ChangeLog index c5b84b5799..495c0c8910 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2012-04-09 Roland McGrath + + * bfdlink.h (struct bfd_link_info): Add new member user_phdrs. + 2012-03-15 Alan Modra * dis-asm.h (disassemble_init_powerpc): Declare. diff --git a/include/bfdlink.h b/include/bfdlink.h index c79d8f0553..d900b4783f 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -229,7 +229,7 @@ typedef enum {with_flags, without_flags} flag_type; /* A section flag list. */ struct flag_info_list { - flag_type with; + flag_type with; const char *name; bfd_boolean valid; struct flag_info_list *next; @@ -405,6 +405,9 @@ struct bfd_link_info /* TRUE if we should warn alternate ELF machine code. */ unsigned int warn_alternate_em: 1; + /* TRUE if the linker script contained an explicit PHDRS command. */ + unsigned int user_phdrs: 1; + /* Char that may appear as the first char of a symbol, but should be skipped (like symbol_leading_char) when looking up symbols in wrap_hash. Used by PowerPC Linux for 'dot' symbols. */ @@ -674,7 +677,7 @@ struct bfd_link_order } indirect; struct { - /* Size of contents, or zero when contents should be filled by + /* Size of contents, or zero when contents should be filled by the architecture-dependent fill function. A non-zero value allows filling of the output section with an arbitrary repeated pattern. */