Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
Sriraman Tallam
tmsriram@google.com
Thu Mar 3 23:58:00 GMT 2011
More information about the Binutils mailing list
Thu Mar 3 23:58:00 GMT 2011
- Previous message (by thread): PATCH: Support TLS x32 IE->LE transition
- Next message (by thread): Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi,
I am working on a linker plugin to use callgraph edge profiles
generated by GCC to guide function layout in the linker. The compiler
passes the callgraph edge profile values to the linker via special
.note sections, I am working on a GCC patch to do this. The linker
plugin reads the .note sections and constructs an annotated callgraph
with the edge profiles. It then uses the Pettis-Hansen algorithm,
"Profile-guided Code Positioning, PLDI 1990, K. Pettis, and R.C.
Hansen.", to determine the order of functions in the final layout.
In order for my plugin to do the above, I need the interfaces to
read section contents & attributes and reorder them. I have attached a
patch for review that adds these interfaces to the GOLD plugin
infrastructure. I have also made appropriate changes to allow section
ordering from a plugin.
* layout.cc (Layout::Layout): Initialize section_ordering_specified_,
input_section_position_, and input_section_glob_.
(Layout::update_layout_of_sections): New function.
(read_layout_from_file): Add parameter filename and call function
section_ordering_specified.
* layout.h (is_section_ordering_specified): New function.
(section_ordering_specified): New function.
(read_layout_from_file): Add parameter filename.
(update_layout_of_sections): New function.
(section_ordering_specified_): New boolean member.
* main.cc(main): Call load_plugins after layout object is defined.
Call read_layout_from_file when section ordering is specified.
* output.cc (Output_section::add_input_section): Use
function section_ordering_specified to check if section ordering is
needed.
(Output_section::update_section_layout): New function.
(Output_section::sort_attached_input_sections): Check if input section
must be reordered.
* plugin.cc (get_object_handle): New function.
(get_section_count): New function.
(get_section_type): New function.
(get_section_name): New function.
(get_section_contents): New function.
(read_layout_from_file): New function.
(allow_section_ordering): New function.
(Plugin::load): Add the new interfaces to the transfer vector.
(Plugin_manager::load_plugins): New parameter.
* plugin.h (input_objects): New function.
(layout): New function.
* plugin_test.c (get_object_handle): New function pointer.
(get_section_count): New function pointer.
(get_section_type): New function pointer.
(get_section_name): New function pointer.
(get_section_contents): New function pointer.
(read_layout_from_file): New function pointer.
(allow_section_ordering): New function pointer.
(onload): Check if the new interfaces exist.
Thanks,
-Sri.
-------------- next part --------------
Index: plugin-api.h
===================================================================
RCS file: /cvs/src/src/include/plugin-api.h,v
retrieving revision 1.13
diff -u -u -p -r1.13 plugin-api.h
--- plugin-api.h 3 Jan 2011 21:05:50 -0000 1.13
+++ plugin-api.h 3 Mar 2011 22:28:49 -0000
@@ -240,6 +240,58 @@ typedef
enum ld_plugin_status
(*ld_plugin_message) (int level, const char *format, ...);
+/* The linker's interface for retrieving the handle (pointer) to an object. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_get_object_handle) (const char* filename, void** handle);
+
+/* The linker's interface for retrieving the number of sections in an object.
+ The handle parameter can be obtained using the "ld_plugin_get_object_handle"
+ interface. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_get_section_count) (void* handle, unsigned int* count);
+
+/* The linker's interface for retrieving the section type of a specific
+ section in an object. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_get_section_type) (void* handle, unsigned int shndx,
+ unsigned int* type);
+
+/* The linker's interface for retrieving the name of specific section in
+ an object. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_get_section_name) (void* handle, unsigned int shndx,
+ char** section_name_ptr);
+/* The linker's interface for retrieving the contents of a specific section
+ in an object. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_get_section_contents) (void* handle, unsigned int shndx,
+ unsigned char** section_contents,
+ unsigned int* len);
+
+/* The linker's interface for specifying the desired order of sections
+ through a file. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_read_layout_from_file) (const char* filename);
+
+/* The linker's interface for specifying that reordering of sections is
+ desired. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_allow_section_ordering) (void);
+
enum ld_plugin_level
{
LDPL_INFO,
@@ -269,7 +321,14 @@ enum ld_plugin_tag
LDPT_ADD_INPUT_LIBRARY,
LDPT_OUTPUT_NAME,
LDPT_SET_EXTRA_LIBRARY_PATH,
- LDPT_GNU_LD_VERSION
+ LDPT_GNU_LD_VERSION,
+ LDPT_GET_SECTION_COUNT,
+ LDPT_GET_SECTION_TYPE,
+ LDPT_GET_OBJECT_HANDLE,
+ LDPT_GET_SECTION_NAME,
+ LDPT_GET_SECTION_CONTENTS,
+ LDPT_READ_LAYOUT_FROM_FILE,
+ LDPT_ALLOW_SECTION_ORDERING
};
/* The plugin transfer vector. */
@@ -292,6 +351,13 @@ struct ld_plugin_tv
ld_plugin_release_input_file tv_release_input_file;
ld_plugin_add_input_library tv_add_input_library;
ld_plugin_set_extra_library_path tv_set_extra_library_path;
+ ld_plugin_get_object_handle tv_get_object_handle;
+ ld_plugin_get_section_count tv_get_section_count;
+ ld_plugin_get_section_type tv_get_section_type;
+ ld_plugin_get_section_name tv_get_section_name;
+ ld_plugin_get_section_contents tv_get_section_contents;
+ ld_plugin_read_layout_from_file tv_read_layout_from_file;
+ ld_plugin_allow_section_ordering tv_allow_section_ordering;
} tv_u;
};
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.190
diff -u -u -p -r1.190 layout.cc
--- layout.cc 10 Jan 2011 21:57:31 -0000 1.190
+++ layout.cc 3 Mar 2011 22:29:00 -0000
@@ -207,7 +207,11 @@ Layout::Layout(int number_of_input_files
record_output_section_data_from_script_(false),
script_output_section_data_list_(),
segment_states_(NULL),
- relaxation_debug_check_(NULL)
+ relaxation_debug_check_(NULL),
+ section_ordering_specified_(false),
+ input_section_position_(),
+ input_section_glob_()
+
{
// Make space for more than enough segments for a typical file.
// This is just for efficiency--it's OK if we wind up needing more.
@@ -1817,13 +1821,27 @@ Layout::find_section_order_index(const s
return 0;
}
+// Updates the input section order of all output sections.
+
+void
+Layout::update_layout_of_sections()
+{
+ for (Section_list::iterator p = this->section_list_.begin();
+ p != this->section_list_.end();
+ ++p)
+ {
+ if ((*p) == NULL)
+ continue;
+ (*p)->update_section_layout(this);
+ }
+}
+
// Read the sequence of input sections from the file specified with
// --section-ordering-file.
void
-Layout::read_layout_from_file()
+Layout::read_layout_from_file(const char* filename)
{
- const char* filename = parameters->options().section_ordering_file();
std::ifstream in;
std::string line;
@@ -1834,6 +1852,7 @@ Layout::read_layout_from_file()
std::getline(in, line); // this chops off the trailing \n, if any
unsigned int position = 1;
+ this->section_ordering_specified();
while (in)
{
Index: layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.88
diff -u -u -p -r1.88 layout.h
--- layout.h 14 Dec 2010 19:03:30 -0000 1.88
+++ layout.h 3 Mar 2011 22:29:00 -0000
@@ -414,11 +414,23 @@ class Layout
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
+ bool
+ is_section_ordering_specified()
+ { return section_ordering_specified_; }
+
+ void
+ section_ordering_specified()
+ { section_ordering_specified_ = true; }
+
+
unsigned int
find_section_order_index(const std::string&);
+ void
+ read_layout_from_file(const char* filename);
+
void
- read_layout_from_file();
+ update_layout_of_sections();
// Layout an input reloc section when doing a relocatable link. The
// section is RELOC_SHNDX in OBJECT, with data in SHDR.
@@ -1147,6 +1159,7 @@ class Layout
Segment_states* segment_states_;
// A relaxation debug checker. We only create one when in debugging mode.
Relaxation_debug_check* relaxation_debug_check_;
+ bool section_ordering_specified_;
// Hash a pattern to its position in the section ordering file.
Unordered_map<std::string, unsigned int> input_section_position_;
// Vector of glob only patterns in the section_ordering file.
Index: main.cc
===================================================================
RCS file: /cvs/src/src/gold/main.cc,v
retrieving revision 1.42
diff -u -u -p -r1.42 main.cc
--- main.cc 14 Dec 2010 19:03:30 -0000 1.42
+++ main.cc 3 Mar 2011 22:29:00 -0000
@@ -195,10 +195,6 @@ main(int argc, char** argv)
if (parameters->options().relocatable())
command_line.script_options().version_script_info()->clear();
- // Load plugin libraries.
- if (command_line.options().has_plugins())
- command_line.options().plugins()->load_plugins();
-
// The work queue.
Workqueue workqueue(command_line.options());
@@ -231,8 +227,13 @@ main(int argc, char** argv)
if (layout.incremental_inputs() != NULL)
layout.incremental_inputs()->report_command_line(argc, argv);
- if (parameters->options().section_ordering_file())
- layout.read_layout_from_file();
+ // Load plugin libraries.
+ if (command_line.options().has_plugins())
+ command_line.options().plugins()->load_plugins(&layout);
+
+ const char* section_ordering_file = parameters->options().section_ordering_file();
+ if (section_ordering_file)
+ layout.read_layout_from_file(section_ordering_file);
// Get the search path from the -L options.
Dirsearch search_path;
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.140
diff -u -u -p -r1.140 output.cc
--- output.cc 12 Feb 2011 03:19:24 -0000 1.140
+++ output.cc 3 Mar 2011 22:29:00 -0000
@@ -2165,10 +2165,10 @@ Output_section::add_input_section(Layout
|| this->must_sort_attached_input_sections()
|| parameters->options().user_set_Map()
|| parameters->target().may_relax()
- || parameters->options().section_ordering_file())
+ || layout->is_section_ordering_specified())
{
Input_section isecn(object, shndx, input_section_size, addralign);
- if (parameters->options().section_ordering_file())
+ if (layout->is_section_ordering_specified())
{
unsigned int section_order_index =
layout->find_section_order_index(std::string(secname));
@@ -3041,6 +3041,32 @@ Output_section::Input_section_sort_secti
return s1_secn_index < s2_secn_index;
}
+// Updates the ordering of input sections in this output section.
+
+void
+Output_section::update_section_layout(Layout* layout)
+{
+ for (Input_section_list::iterator p = this->input_sections_.begin();
+ p != this->input_sections_.end();
+ ++p)
+ {
+ if ((*p).is_input_section()
+ || (*p).is_relaxed_input_section())
+ {
+ Object* obj = ((*p).is_input_section() ? (*p).relobj()
+ : (*p).relaxed_input_section()->relobj());
+ std::string section_name = obj->section_name((*p).shndx());
+ unsigned int section_order_index =
+ layout->find_section_order_index(std::string(section_name));
+ if (section_order_index != 0)
+ {
+ (*p).set_section_order_index(section_order_index);
+ this->set_input_section_order_specified();
+ }
+ }
+ }
+}
+
// Sort the input sections attached to an output section.
void
@@ -3083,7 +3109,7 @@ Output_section::sort_attached_input_sect
}
else
{
- gold_assert(parameters->options().section_ordering_file());
+ gold_assert(this->input_section_order_specified());
std::sort(sort_list.begin(), sort_list.end(),
Input_section_sort_section_order_index_compare());
}
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.118
diff -u -u -p -r1.118 output.h
--- output.h 23 Dec 2010 19:56:14 -0000 1.118
+++ output.h 3 Mar 2011 22:29:00 -0000
@@ -2564,6 +2564,9 @@ class Output_section : public Output_dat
flags() const
{ return this->flags_; }
+ void
+ update_section_layout(Layout* layout);
+
// Update the output section flags based on input section flags.
void
update_flags_for_input_section(elfcpp::Elf_Xword flags);
Index: plugin.cc
===================================================================
RCS file: /cvs/src/src/gold/plugin.cc,v
retrieving revision 1.43
diff -u -u -p -r1.43 plugin.cc
--- plugin.cc 8 Feb 2011 05:03:19 -0000 1.43
+++ plugin.cc 3 Mar 2011 22:29:00 -0000
@@ -86,6 +86,31 @@ set_extra_library_path(const char *path)
static enum ld_plugin_status
message(int level, const char *format, ...);
+static enum ld_plugin_status
+get_object_handle(const char* filename, void** handle);
+
+static enum ld_plugin_status
+get_section_count(void* handle, unsigned int* count);
+
+static enum ld_plugin_status
+get_section_type(void* handle, unsigned int shndx,
+ unsigned int* type);
+
+static enum ld_plugin_status
+get_section_name(void* handle, unsigned int shndx,
+ char** section_name_ptr);
+
+static enum ld_plugin_status
+get_section_contents(void* handle, unsigned int shndx,
+ unsigned char** section_contents,
+ unsigned int* len);
+
+static enum ld_plugin_status
+read_layout_from_file(const char* filename);
+
+static enum ld_plugin_status
+allow_section_ordering();
+
};
#endif // ENABLE_PLUGINS
@@ -130,7 +155,7 @@ Plugin::load()
sscanf(ver, "%d.%d", &major, &minor);
// Allocate and populate a transfer vector.
- const int tv_fixed_size = 16;
+ const int tv_fixed_size = 23;
int tv_size = this->args_.size() + tv_fixed_size;
ld_plugin_tv* tv = new ld_plugin_tv[tv_size];
@@ -208,6 +233,34 @@ Plugin::load()
tv[i].tv_tag = LDPT_SET_EXTRA_LIBRARY_PATH;
tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path;
+ ++i;
+ tv[i].tv_tag = LDPT_GET_OBJECT_HANDLE;
+ tv[i].tv_u.tv_get_object_handle = get_object_handle;
+
+ ++i;
+ tv[i].tv_tag = LDPT_GET_SECTION_COUNT;
+ tv[i].tv_u.tv_get_section_count = get_section_count;
+
+ ++i;
+ tv[i].tv_tag = LDPT_GET_SECTION_TYPE;
+ tv[i].tv_u.tv_get_section_type = get_section_type;
+
+ ++i;
+ tv[i].tv_tag = LDPT_GET_SECTION_NAME;
+ tv[i].tv_u.tv_get_section_name = get_section_name;
+
+ ++i;
+ tv[i].tv_tag = LDPT_GET_SECTION_CONTENTS;
+ tv[i].tv_u.tv_get_section_contents = get_section_contents;
+
+ ++i;
+ tv[i].tv_tag = LDPT_READ_LAYOUT_FROM_FILE;
+ tv[i].tv_u.tv_read_layout_from_file = read_layout_from_file;
+
+ ++i;
+ tv[i].tv_tag = LDPT_ALLOW_SECTION_ORDERING;
+ tv[i].tv_u.tv_allow_section_ordering = allow_section_ordering;
+
++i;
tv[i].tv_tag = LDPT_NULL;
tv[i].tv_u.tv_val = 0;
@@ -319,8 +372,9 @@ Plugin_manager::~Plugin_manager()
// Load all plugin libraries.
void
-Plugin_manager::load_plugins()
+Plugin_manager::load_plugins(Layout* layout)
{
+ this->layout_ = layout;
for (this->current_ = this->plugins_.begin();
this->current_ != this->plugins_.end();
++this->current_)
@@ -404,7 +458,7 @@ Plugin_manager::all_symbols_read(Workque
this->task_ = task;
this->input_objects_ = input_objects;
this->symtab_ = symtab;
- this->layout_ = layout;
+ gold_assert (this->layout_ == layout);
this->dirpath_ = dirpath;
this->mapfile_ = mapfile;
this->this_blocker_ = NULL;
@@ -1317,6 +1371,146 @@ message(int level, const char* format, .
return LDPS_OK;
}
+// Find the object having the given name.
+// Parameters :
+// FILENAME : The name of the object whose handle needs to be
+// retrieved.
+// HANDLE : Storage for the retrieved handle.
+
+static enum ld_plugin_status
+get_object_handle(const char* filename, void** handle)
+{
+ gold_assert(parameters->options().has_plugins());
+ Input_objects* input_objects =
+ parameters->options().plugins()->input_objects();
+ *handle = NULL;
+ if (input_objects == NULL)
+ {
+ return LDPS_ERR;
+ }
+
+ for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
+ p != input_objects->relobj_end();
+ ++p)
+ {
+ if (strcmp((*p)->name().c_str(), filename) == 0)
+ {
+ *handle = static_cast<void*>(*p);
+ break;
+ }
+ }
+
+ if (*handle == NULL)
+ return LDPS_ERR;
+ return LDPS_OK;
+}
+
+// Get the section count of the object corresponding to the handle.
+// Parameters :
+// HANDLE : This is the Relobj pointer. This can be obtained using
+// "get_object_handle".
+// COUNT : Storage for the retrieved section count.
+
+static enum ld_plugin_status
+get_section_count(void* handle, unsigned int* count)
+{
+ gold_assert(parameters->options().has_plugins()
+ && handle != NULL);
+ Relobj* p = static_cast<Relobj*>(handle);
+ *count = p->shnum();
+ return LDPS_OK;
+}
+
+// Get the type of the specified section in the object corresponding
+// to the handle.
+// Parameters :
+// HANDLE : This is the Relobj pointer. This can be obtained using
+// "get_object_handle".
+// SHNDX : Index of the section in the object.
+// TYPE : Storage for the section type.
+
+static enum ld_plugin_status
+get_section_type(void* handle, unsigned int shndx, unsigned int* type)
+{
+ gold_assert(parameters->options().has_plugins()
+ && handle != NULL);
+ Relobj* p = static_cast<Relobj*>(handle);
+ *type = p->section_type(shndx);
+ return LDPS_OK;
+}
+
+// Get the name of the specified section in the object corresponding
+// to the handle.
+// Parameters :
+// HANDLE : This is the Relobj pointer. This can be obtained using
+// "get_object_handle".
+// SHNDX : Index of the section in the object.
+// SECTION_NAME_PTR : Storage for the section name.
+
+static enum ld_plugin_status
+get_section_name(void* handle, unsigned int shndx, char** section_name_ptr)
+{
+ gold_assert(parameters->options().has_plugins()
+ && handle != NULL);
+ Relobj* p = static_cast<Relobj*>(handle);
+ const char* section_name = p->section_name(shndx).c_str();
+ *section_name_ptr = (char*)malloc(strlen(section_name) + 1);
+ strcpy(*section_name_ptr, section_name);
+ return LDPS_OK;
+}
+
+// Get the contents of the specified section in the object corresponding
+// to the handle.
+// Parameters :
+// HANDLE : This is the Relobj pointer. This can be obtained
+// using "get_object_handle".
+// SHNDX : Index of the section in the object.
+// SECTION_CONTENTS_PTR : Storage for the section contents.
+// LEN : Storage for the section length.
+
+static enum ld_plugin_status
+get_section_contents(void* handle, unsigned int shndx,
+ unsigned char** section_contents_ptr,
+ unsigned int* len)
+{
+ gold_assert(parameters->options().has_plugins()
+ && handle != NULL);
+ Relobj* p = static_cast<Relobj*>(handle);
+ section_size_type plen;
+ const unsigned char* section_contents = p->section_contents(shndx, &plen,
+ false);
+ *section_contents_ptr = (unsigned char*)malloc(plen);
+ memcpy(*section_contents_ptr, section_contents, plen);
+ *len = plen;
+ return LDPS_OK;
+}
+
+// Specify the ordering of sections in the final layout in a file. This
+// does what the linker option --section-ordering-file does.
+// Parameters :
+// FILENAME : The file specifying the order of sections.
+
+static enum ld_plugin_status
+read_layout_from_file(const char* filename)
+{
+ gold_assert(parameters->options().has_plugins());
+ Layout* layout = parameters->options().plugins()->layout();
+ layout->read_layout_from_file(filename);
+ layout->update_layout_of_sections();
+ return LDPS_OK;
+}
+
+// Let the linker know that the sections could be reordered.
+
+static enum ld_plugin_status
+allow_section_ordering()
+{
+ gold_assert(parameters->options().has_plugins());
+ Layout* layout = parameters->options().plugins()->layout();
+ layout->section_ordering_specified();
+ return LDPS_OK;
+}
+
#endif // ENABLE_PLUGINS
// Allocate a Pluginobj object of the appropriate size and endianness.
Index: plugin.h
===================================================================
RCS file: /cvs/src/src/gold/plugin.h,v
retrieving revision 1.16
diff -u -u -p -r1.16 plugin.h
--- plugin.h 24 Jan 2011 21:48:40 -0000 1.16
+++ plugin.h 3 Mar 2011 22:29:00 -0000
@@ -153,7 +153,7 @@ class Plugin_manager
// Load all plugin libraries.
void
- load_plugins();
+ load_plugins(Layout* layout);
// Call the plugin claim-file handlers in turn to see if any claim the file.
Pluginobj*
@@ -262,6 +262,14 @@ class Plugin_manager
in_replacement_phase() const
{ return this->in_replacement_phase_; }
+ Input_objects*
+ input_objects() const
+ { return input_objects_; }
+
+ Layout*
+ layout()
+ { return layout_; }
+
private:
Plugin_manager(const Plugin_manager&);
Plugin_manager& operator=(const Plugin_manager&);
Index: testsuite/plugin_test.c
===================================================================
RCS file: /cvs/src/src/gold/testsuite/plugin_test.c,v
retrieving revision 1.4
diff -u -u -p -r1.4 plugin_test.c
--- testsuite/plugin_test.c 9 Nov 2009 16:11:34 -0000 1.4
+++ testsuite/plugin_test.c 3 Mar 2011 22:29:00 -0000
@@ -60,6 +60,13 @@ static ld_plugin_add_input_file add_inpu
static ld_plugin_message message = NULL;
static ld_plugin_get_input_file get_input_file = NULL;
static ld_plugin_release_input_file release_input_file = NULL;
+static ld_plugin_get_object_handle get_object_handle = NULL;
+static ld_plugin_get_section_count get_section_count = NULL;
+static ld_plugin_get_section_type get_section_type = NULL;
+static ld_plugin_get_section_name get_section_name = NULL;
+static ld_plugin_get_section_contents get_section_contents = NULL;
+static ld_plugin_read_layout_from_file read_layout_from_file = NULL;
+static ld_plugin_allow_section_ordering allow_section_ordering = NULL;
#define MAXOPTS 10
@@ -126,6 +133,27 @@ onload(struct ld_plugin_tv *tv)
case LDPT_RELEASE_INPUT_FILE:
release_input_file = entry->tv_u.tv_release_input_file;
break;
+ case LDPT_GET_OBJECT_HANDLE:
+ get_object_handle = *entry->tv_u.tv_get_object_handle;
+ break;
+ case LDPT_GET_SECTION_COUNT:
+ get_section_count = *entry->tv_u.tv_get_section_count;
+ break;
+ case LDPT_GET_SECTION_TYPE:
+ get_section_type = *entry->tv_u.tv_get_section_type;
+ break;
+ case LDPT_GET_SECTION_NAME:
+ get_section_name = *entry->tv_u.tv_get_section_name;
+ break;
+ case LDPT_GET_SECTION_CONTENTS:
+ get_section_contents = *entry->tv_u.tv_get_section_contents;
+ break;
+ case LDPT_READ_LAYOUT_FROM_FILE:
+ read_layout_from_file = *entry->tv_u.tv_read_layout_from_file;
+ break;
+ case LDPT_ALLOW_SECTION_ORDERING:
+ allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
+ break;
default:
break;
}
@@ -179,6 +207,48 @@ onload(struct ld_plugin_tv *tv)
return LDPS_ERR;
}
+ if (get_object_handle == NULL)
+ {
+ fprintf(stderr, "tv_get_object_handle interface missing\n");
+ return LDPS_ERR;
+ }
+
+ if (get_section_count == NULL)
+ {
+ fprintf(stderr, "tv_get_section_count interface missing\n");
+ return LDPS_ERR;
+ }
+
+ if (get_section_type == NULL)
+ {
+ fprintf(stderr, "tv_get_section_type interface missing\n");
+ return LDPS_ERR;
+ }
+
+ if (get_section_name == NULL)
+ {
+ fprintf(stderr, "tv_get_section_name interface missing\n");
+ return LDPS_ERR;
+ }
+
+ if (get_section_contents == NULL)
+ {
+ fprintf(stderr, "tv_get_section_contents interface missing\n");
+ return LDPS_ERR;
+ }
+
+ if (read_layout_from_file == NULL)
+ {
+ fprintf(stderr, "tv_read_layout_from_file interface missing\n");
+ return LDPS_ERR;
+ }
+
+ if (allow_section_ordering != NULL)
+ {
+ fprintf(stderr, "tv_allow_section_ordering interface missing\n");
+ return LDPS_ERR;
+ }
+
return LDPS_OK;
}
- Previous message (by thread): PATCH: Support TLS x32 IE->LE transition
- Next message (by thread): Plugin interfaces to do Pettis Hansen style code layout in the gold linker.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list