===================================================================
@@ -33,9 +33,13 @@ along with this program; see the file COPYING3. I
This plugin dumps the final layout order of the functions in a file
called "final_layout.txt". To change the output file, pass the new
- file name with --plugin-opt. To dump to stderr instead, just pass
- stderr to --plugin-opt. */
+ file name with --plugin-opt,file=<name>. To dump to stderr instead,
+ just pass stderr as the file name.
+ This plugin also allows placing all functions found cold in a separate
+ segment. This can be enabled with the linker option:
+ --plugin-opt,split_segment=yes. */
+
#if HAVE_STDINT_H
#include <stdint.h>
#endif
@@ -89,9 +93,10 @@ static int is_api_exist = 0;
/* The plugin does nothing when no-op is 1. */
static int no_op = 0;
-/* The plugin does not create a new segment for unlikely code if
- no_segment is set. */
-static int no_segment = 0;
+/* The plugin creates a new segment for unlikely code if split_segment
+ is set. This can be set with the linker option:
+ "--plugin-opt,split_segment=yes". */
+static int split_segment = 0;
/* Copies new output file name out_file */
void get_filename (const char *name)
@@ -110,7 +115,7 @@ process_option (const char *name)
{
const char *option_group = "group=";
const char *option_file = "file=";
- const char *option_segment = "segment=";
+ const char *option_segment = "split_segment=";
/* Check if option is "group=" */
if (strncmp (name, option_group, strlen (option_group)) == 0)
@@ -129,13 +134,14 @@ process_option (const char *name)
return;
}
- /* Check if options is "segment=none" */
+ /* Check if options is "split_segment=[yes|no]" */
if (strncmp (name, option_segment, strlen (option_segment)) == 0)
{
- if (strcmp (name + strlen (option_segment), "none") == 0)
- no_segment = 1;
- else
- no_segment = 0;
+ const char *option_val = name + strlen (option_segment);
+ if (strcmp (option_val, "no") == 0)
+ split_segment = 0;
+ else if (strcmp (option_val, "yes") == 0)
+ split_segment = 1;
return;
}
@@ -244,7 +250,10 @@ claim_file_hook (const struct ld_plugin_input_file
{
/* Inform the linker to prepare for section reordering. */
(*allow_section_ordering) ();
- (*allow_unique_segment_for_sections) ();
+ /* Inform the linker to allow certain sections to be placed in
+ a separate segment. */
+ if (split_segment == 1)
+ (*allow_unique_segment_for_sections) ();
is_ordering_specified = 1;
}
@@ -335,15 +344,29 @@ all_symbols_read_hook (void)
if (out_file != NULL
&& strcmp (out_file, "stderr") != 0)
fclose (fp);
- /* Pass the new order of functions to the linker. */
- update_section_order (section_list, unlikely_segment_start);
- assert (num_entries >= unlikely_segment_end);
- update_section_order (section_list, num_entries - unlikely_segment_end);
- /* Map all unlikely code into a new segment. */
- if (no_segment == 0)
- unique_segment_for_sections (".text.unlikely_executed", 0, 0x1000,
- section_list + unlikely_segment_start,
- unlikely_segment_end - unlikely_segment_start);
+
+ if (split_segment == 1)
+ {
+ /* Pass the new order of functions to the linker. */
+ /* Fix the order of all sections upto the beginning of the
+ unlikely section. */
+ update_section_order (section_list, unlikely_segment_start);
+ assert (num_entries >= unlikely_segment_end);
+ /* Fix the order of all sections after the end of the unlikely
+ section. */
+ update_section_order (section_list, num_entries - unlikely_segment_end);
+ /* Map all unlikely code into a new segment. */
+ unique_segment_for_sections (
+ ".text.unlikely_executed", 0, 0x1000,
+ section_list + unlikely_segment_start,
+ unlikely_segment_end - unlikely_segment_start);
+ }
+ else
+ {
+ /* Pass the new order of functions to the linker. */
+ update_section_order (section_list, num_entries);
+ }
+
cleanup ();
return LDPS_OK;
}