This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC PATCH] avoid intermingling executable and nonexecutable sections in a segment


Here is a potentially real patch to accomplish what I asked about.
This is generic to SEPARATE_CODE=yes, which feels like the right thing.

The way this goes about injecting the hook is a kludge modelled on
what ld/plugin.c:plugin_load_plugins does (end of that function).
The choice of the after_open hook as the place to do this is pretty
arbitrary--just someplace before map_segments gets called.

This feels obviously quite hacky.  But IMHO some kludgery to get a variant
override_segment_assignment hook installed is better than hairy
segment-splitting code in the modify_segment_map hook.

What do people think about this change?


Thanks,
Roland


ld/
2012-11-20  Roland McGrath  <mcgrathr@google.com>

	* emultempl/elf32.em [$SEPARATE_CODE = yes]
	(elf_separate_code_override_segment_assignment): New function.
	(gld${EMULATION_NAME}_after_open) [$SEPARATE_CODE = yes]:
	Install that as link_info.callbacks->override_segment_assignment,
	preserving the original callbacks.

--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -884,6 +884,30 @@ gld${EMULATION_NAME}_check_needed
(lang_input_statement_type *s)

 EOF

+if test x"$SEPARATE_CODE" = xyes; then
+fragment <<EOF
+
+static const struct bfd_link_callbacks *orig_callbacks;
+static struct bfd_link_callbacks elf_separate_code_callbacks;
+
+/* We must never comingle code and non-code sections in one segment.  */
+static bfd_boolean
+elf_separate_code_override_segment_assignment (struct bfd_link_info *info,
+                                               bfd *abfd,
+                                               asection *current_section,
+                                               asection *previous_section,
+                                               bfd_boolean new_segment)
+{
+  if ((current_section->flags ^ previous_section->flags) & SEC_CODE)
+    return TRUE;
+  return (*orig_callbacks->override_segment_assignment) (info, abfd,
+                                                         current_section,
+                                                         previous_section,
+                                                         new_segment);
+}
+EOF
+fi
+
 if test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then
 fragment <<EOF

@@ -1062,6 +1086,18 @@ gld${EMULATION_NAME}_after_open (void)

   after_open_default ();

+EOF
+if [ "x${SEPARATE_CODE}" = xyes ] ; then
+fragment <<EOF
+  orig_callbacks = link_info.callbacks;
+  elf_separate_code_callbacks = *orig_callbacks;
+  elf_separate_code_callbacks.override_segment_assignment
+    = elf_separate_code_override_segment_assignment;
+  link_info.callbacks = &elf_separate_code_callbacks;
+
+EOF
+fi
+fragment <<EOF
   htab = elf_hash_table (&link_info);
   if (!is_elf_hash_table (htab))
     return;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]