summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf.c4
-rw-r--r--include/ChangeLog5
-rw-r--r--include/bfdlink.h7
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/ldlang.c36
-rw-r--r--ld/ldlang.h4
-rw-r--r--ld/ldmain.c3
8 files changed, 70 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f1d2ed7452..0bd6795229 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.
diff --git a/bfd/elf.c b/bfd/elf.c
index 460502c2e4..95f34010ac 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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 6c25355f30..e5b7dba324 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 6842243d09..46e3cf5c54 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 cbe0544979..7c6506b04e 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 8a69c7028d..fa597f3c05 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 0074159fc9..d34ea6894d 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 9e6a0c393d..f47758ffed 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;