diff options
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf.c | 4 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/bfdlink.h | 7 | ||||
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/ldlang.c | 36 | ||||
-rw-r--r-- | ld/ldlang.h | 4 | ||||
-rw-r--r-- | ld/ldmain.c | 3 |
8 files changed, 70 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f1d2ed7..0bd6795 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2007-02-21 Nick Clifton <nickc@redhat.com> + + * elf.c (_bfd_elf_map_sections_to_segments): If the + override_segment_assignment callback is defined then call it. + 2007-02-21 Alan Modra <amodra@bigpond.net.au> * elf32-spu.c (spu_elf_size_stubs): Correct order of warning args. @@ -3953,6 +3953,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) new_segment = FALSE; } + /* Allow interested parties a chance to override our decision. */ + if (last_hdr && info->callbacks->override_segment_assignment) + new_segment = info->callbacks->override_segment_assignment (info, abfd, hdr, last_hdr, new_segment); + if (! new_segment) { if ((hdr->flags & SEC_READONLY) == 0) diff --git a/include/ChangeLog b/include/ChangeLog index 6c25355..e5b7dba 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2007-02-21 Nick Clifton <nickc@redhat.com> + + * bfdlink.h (struct bfd_link_callbacks): Add + override_segment_assignment field. + 2007-02-17 Mark Mitchell <mark@codesourcery.com> Nathan Sidwell <nathan@codesourcery.com> Vladimir Prus <vladimir@codesourcery.com diff --git a/include/bfdlink.h b/include/bfdlink.h index 6842243..46e3cf5 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -566,6 +566,13 @@ struct bfd_link_callbacks /* General link info message. */ void (*einfo) (const char *fmt, ...); + /* This callback provides a chance for users of the BFD library to + override its decision about whether to place two adjacent sections + into the same segment. */ + bfd_boolean (*override_segment_assignment) + (struct bfd_link_info *, bfd * abfd, + asection * current_section, asection * previous_section, + bfd_boolean new_segment); }; /* The linker builds link_order structures which tell the code how to diff --git a/ld/ChangeLog b/ld/ChangeLog index cbe0544..7c6506b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2007-02-21 Nick Clifton <nickc@redhat.com> + + * ldlang.c (ldlang_override_segment_assignment): New function. + * ldlang.h (ldlang_override_segment_assignment): Prototype. + * ldmain.c (link_callbacks): Add + ldlang_override_segment_assignment. + 2007-02-20 Alan Modra <amodra@bigpond.net.au> * ldexp.c (fold_name <LOADADDR>): Ensure result is always absolute. diff --git a/ld/ldlang.c b/ld/ldlang.c index 8a69c70..fa597f3 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -4704,6 +4704,42 @@ lang_size_sections_1 return dot; } +/* Callback routine that is used in _bfd_elf_map_sections_to_segments. */ + +bfd_boolean +ldlang_override_segment_assignment (struct bfd_link_info * info ATTRIBUTE_UNUSED, + bfd * abfd ATTRIBUTE_UNUSED, + asection * current_section, + asection * previous_section, + bfd_boolean new_segment) +{ + lang_output_section_statement_type * cur; + lang_output_section_statement_type * prev; + + if (new_segment) + return TRUE; + + /* Paranoia checks. */ + if (current_section == NULL || previous_section == NULL) + return new_segment; + + /* Find the memory regions associated with the two sections. + We call lang_output_section_find() here rather than scanning the list + of output sections looking for a matching section pointer because if + we have a large number of sections a hash lookup is faster. */ + cur = lang_output_section_find (current_section->name); + prev = lang_output_section_find (previous_section->name); + + if (cur == NULL || prev == NULL) + return new_segment; + + /* If the regions are different then force the sections to live in + different segments. See the email thread starting here for the + reasons why this is necessary: + http://sourceware.org/ml/binutils/2007-02/msg00216.html */ + return cur->region != prev->region; +} + void one_lang_size_sections_pass (bfd_boolean *relax, bfd_boolean check_regions) { diff --git a/ld/ldlang.h b/ld/ldlang.h index 0074159..d34ea68 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -623,4 +623,8 @@ extern void add_excluded_libs (const char *); extern bfd_boolean load_symbols (lang_input_statement_type *, lang_statement_list_type *); +extern bfd_boolean +ldlang_override_segment_assignment + (struct bfd_link_info *, bfd *, asection *, asection *, bfd_boolean); + #endif diff --git a/ld/ldmain.c b/ld/ldmain.c index 9e6a0c3..f47758f 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -161,7 +161,8 @@ static struct bfd_link_callbacks link_callbacks = reloc_dangerous, unattached_reloc, notice, - einfo + einfo, + ldlang_override_segment_assignment }; struct bfd_link_info link_info; |