Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
+static inline hashval_t +edge_hash_function (unsigned int id1, unsigned int id2) +{ + /* If the number of functions is less than 1000, this gives a unique value + for every function id combination. */ + const int MULTIPLIER = 1000; + return id1* MULTIPLIER + id2; Change to id1 16 | id2 + if (edge_map == NULL) + { + edge_map = htab_create (25, edge_map_htab_hash_descriptor, + edge_map_htab_eq_descriptor , NULL); Use a larger size and don't hardcode the value. + if (function_map == NULL) + { + function_map = htab_create (25, function_map_htab_hash_descriptor, + function_map_htab_eq_descriptor , NULL); Use a larger size and don't hardcode the value. + caller_node = get_function_node (caller); + /* Real nodes are nodes that correspond to .text sections found. These will + definitely be sorted. */ + set_as_real_node (caller_node); This is redundant as set_node_type sets the type correctly. + if (*slot == NULL) + { + reset_functions (edge, new_node, kept_node); + *slot = edge; + add_edge_to_node (new_node, edge); edge will still be in old_node's edge_list +static void set_node_type (Node *n) +{ + void **slot; + char *name = n-name; + slot = htab_find_slot_with_hash (section_map, name, htab_hash_string (name), + INSERT); Use htab_find_with_hash or pass NOINSERT. + /* Allocate section_map. */ + if (section_map == NULL) + { + section_map = htab_create (10, section_map_htab_hash_descriptor, + section_map_htab_eq_descriptor , NULL); With -ffunction-sections, this should be roughly equal to size of function_map. +static void +write_out_node (FILE *fp, char *name, + void **handles, unsigned int *shndx, int position) +{ + void **slot; + slot = htab_find_slot_with_hash (section_map, name, htab_hash_string (name), + INSERT); Use htab_find_with_hash or pass NOINSERT. Index: function_reordering_plugin/function_reordering_plugin.c === --- function_reordering_plugin/function_reordering_plugin.c (revision 0) +++ function_reordering_plugin/function_reordering_plugin.c (revision 0) + parse_callgraph_section_contents (section_contents, (unsigned int)length); +} + else if (name != NULL) +free (name); name should be freed in the body of then and else-if as well. -Easwaran On Mon, Sep 26, 2011 at 5:22 PM, Sriraman Tallam tmsri...@google.com wrote: *Resending as plain text* I am attaching a patch of the updated files. This patch was meant for the google gcc-4_6 branch. Sorry for not mentioning this upfront in my original mail. Thanks, -Sri. On Mon, Sep 26, 2011 at 9:53 AM, Sriraman Tallam tmsri...@google.com wrote: On Mon, Sep 26, 2011 at 9:22 AM, Nathan Froyd nfr...@mozilla.com wrote: On 9/23/2011 6:03 PM, Sriraman Tallam wrote: This patch adds a new linker plugin to re-order functions. This is great stuff. We were experimenting with using the coverage files to generate an ordering for --section-ordering-file, but this might be even better, will have to experiment with it. A couple of comments on the code itself: Index: function_reordering_plugin/callgraph.h +inline static Edge_list * +make_edge_list (Edge *e) +{ + Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list)); If you are going to use libiberty via hashtab.h, you might as well make use of the *ALLOC family of macros to make this and other allocations a little neater. +/*Represents an edge in the call graph. */ +struct __edge__ I think the usual convention is to call this edge_d or something similar, avoiding the profusion of underscores. +void +map_section_name_to_index (char *section_name, void *handle, int shndx) +{ + void **slot; + char *function_name; + + if (is_prefix_of (.text.hot., section_name)) + function_name = section_name + 10 /* strlen (.text.hot.) */; + else if (is_prefix_of (.text.unlikely., section_name)) + function_name = section_name + 15 /* strlen (.text.unlikely.) */; + else if (is_prefix_of (.text.cold., section_name)) + function_name = section_name + 11 /* strlen (.text.cold.) */; + else if (is_prefix_of (.text.startup., section_name)) + function_name = section_name + 14 /* strlen (.text.startup.) */; + else + function_name = section_name + 6 /*strlen (.text.) */; You don't handle plain .text; this is assuming -ffunction-sections, right? Can this limitation be easily removed? You need to compile with -ffunction-sections or the individual sections cannot be re-ordered. That is why I assumed a .text.* prefix before every function section. Did you have something else in mind? Thanks for your other comments. I will make those changes. -Sri. I think it is customary to put the comment after the semicolon. Might just be easier to
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
Made all the changes. Attaching new patch of updated files. On Tue, Sep 27, 2011 at 11:26 AM, Easwaran Raman era...@google.com wrote: +static inline hashval_t +edge_hash_function (unsigned int id1, unsigned int id2) +{ + /* If the number of functions is less than 1000, this gives a unique value + for every function id combination. */ + const int MULTIPLIER = 1000; + return id1* MULTIPLIER + id2; Change to id1 16 | id2 + if (edge_map == NULL) + { + edge_map = htab_create (25, edge_map_htab_hash_descriptor, + edge_map_htab_eq_descriptor , NULL); Use a larger size and don't hardcode the value. + if (function_map == NULL) + { + function_map = htab_create (25, function_map_htab_hash_descriptor, + function_map_htab_eq_descriptor , NULL); Use a larger size and don't hardcode the value. + caller_node = get_function_node (caller); + /* Real nodes are nodes that correspond to .text sections found. These will + definitely be sorted. */ + set_as_real_node (caller_node); This is redundant as set_node_type sets the type correctly. + if (*slot == NULL) + { + reset_functions (edge, new_node, kept_node); + *slot = edge; + add_edge_to_node (new_node, edge); edge will still be in old_node's edge_list I do not have to explicitly delete this as the merged node's edge_list will never be traversed except when cleaning up. +static void set_node_type (Node *n) +{ + void **slot; + char *name = n-name; + slot = htab_find_slot_with_hash (section_map, name, htab_hash_string (name), + INSERT); Use htab_find_with_hash or pass NOINSERT. + /* Allocate section_map. */ + if (section_map == NULL) + { + section_map = htab_create (10, section_map_htab_hash_descriptor, + section_map_htab_eq_descriptor , NULL); With -ffunction-sections, this should be roughly equal to size of function_map. +static void +write_out_node (FILE *fp, char *name, + void **handles, unsigned int *shndx, int position) +{ + void **slot; + slot = htab_find_slot_with_hash (section_map, name, htab_hash_string (name), + INSERT); Use htab_find_with_hash or pass NOINSERT. Index: function_reordering_plugin/function_reordering_plugin.c === --- function_reordering_plugin/function_reordering_plugin.c (revision 0) +++ function_reordering_plugin/function_reordering_plugin.c (revision 0) + parse_callgraph_section_contents (section_contents, (unsigned int)length); + } + else if (name != NULL) + free (name); name should be freed in the body of then and else-if as well. -Easwaran On Mon, Sep 26, 2011 at 5:22 PM, Sriraman Tallam tmsri...@google.com wrote: *Resending as plain text* I am attaching a patch of the updated files. This patch was meant for the google gcc-4_6 branch. Sorry for not mentioning this upfront in my original mail. Thanks, -Sri. On Mon, Sep 26, 2011 at 9:53 AM, Sriraman Tallam tmsri...@google.com wrote: On Mon, Sep 26, 2011 at 9:22 AM, Nathan Froyd nfr...@mozilla.com wrote: On 9/23/2011 6:03 PM, Sriraman Tallam wrote: This patch adds a new linker plugin to re-order functions. This is great stuff. We were experimenting with using the coverage files to generate an ordering for --section-ordering-file, but this might be even better, will have to experiment with it. A couple of comments on the code itself: Index: function_reordering_plugin/callgraph.h +inline static Edge_list * +make_edge_list (Edge *e) +{ + Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list)); If you are going to use libiberty via hashtab.h, you might as well make use of the *ALLOC family of macros to make this and other allocations a little neater. +/*Represents an edge in the call graph. */ +struct __edge__ I think the usual convention is to call this edge_d or something similar, avoiding the profusion of underscores. +void +map_section_name_to_index (char *section_name, void *handle, int shndx) +{ + void **slot; + char *function_name; + + if (is_prefix_of (.text.hot., section_name)) + function_name = section_name + 10 /* strlen (.text.hot.) */; + else if (is_prefix_of (.text.unlikely., section_name)) + function_name = section_name + 15 /* strlen (.text.unlikely.) */; + else if (is_prefix_of (.text.cold., section_name)) + function_name = section_name + 11 /* strlen (.text.cold.) */; + else if (is_prefix_of (.text.startup., section_name)) + function_name = section_name + 14 /* strlen (.text.startup.) */; + else + function_name = section_name + 6 /*strlen (.text.) */; You don't handle plain .text; this is assuming -ffunction-sections, right? Can
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
OK for google/gcc-4_6 and google/main branches. -Easwaran On Tue, Sep 27, 2011 at 4:07 PM, Sriraman Tallam tmsri...@google.com wrote: Made all the changes. Attaching new patch of updated files. On Tue, Sep 27, 2011 at 11:26 AM, Easwaran Raman era...@google.com wrote: +static inline hashval_t +edge_hash_function (unsigned int id1, unsigned int id2) +{ + /* If the number of functions is less than 1000, this gives a unique value + for every function id combination. */ + const int MULTIPLIER = 1000; + return id1* MULTIPLIER + id2; Change to id1 16 | id2 + if (edge_map == NULL) + { + edge_map = htab_create (25, edge_map_htab_hash_descriptor, + edge_map_htab_eq_descriptor , NULL); Use a larger size and don't hardcode the value. + if (function_map == NULL) + { + function_map = htab_create (25, function_map_htab_hash_descriptor, + function_map_htab_eq_descriptor , NULL); Use a larger size and don't hardcode the value. + caller_node = get_function_node (caller); + /* Real nodes are nodes that correspond to .text sections found. These will + definitely be sorted. */ + set_as_real_node (caller_node); This is redundant as set_node_type sets the type correctly. + if (*slot == NULL) + { + reset_functions (edge, new_node, kept_node); + *slot = edge; + add_edge_to_node (new_node, edge); edge will still be in old_node's edge_list I do not have to explicitly delete this as the merged node's edge_list will never be traversed except when cleaning up. +static void set_node_type (Node *n) +{ + void **slot; + char *name = n-name; + slot = htab_find_slot_with_hash (section_map, name, htab_hash_string (name), + INSERT); Use htab_find_with_hash or pass NOINSERT. + /* Allocate section_map. */ + if (section_map == NULL) + { + section_map = htab_create (10, section_map_htab_hash_descriptor, + section_map_htab_eq_descriptor , NULL); With -ffunction-sections, this should be roughly equal to size of function_map. +static void +write_out_node (FILE *fp, char *name, + void **handles, unsigned int *shndx, int position) +{ + void **slot; + slot = htab_find_slot_with_hash (section_map, name, htab_hash_string (name), + INSERT); Use htab_find_with_hash or pass NOINSERT. Index: function_reordering_plugin/function_reordering_plugin.c === --- function_reordering_plugin/function_reordering_plugin.c (revision 0) +++ function_reordering_plugin/function_reordering_plugin.c (revision 0) + parse_callgraph_section_contents (section_contents, (unsigned int)length); + } + else if (name != NULL) + free (name); name should be freed in the body of then and else-if as well. -Easwaran On Mon, Sep 26, 2011 at 5:22 PM, Sriraman Tallam tmsri...@google.com wrote: *Resending as plain text* I am attaching a patch of the updated files. This patch was meant for the google gcc-4_6 branch. Sorry for not mentioning this upfront in my original mail. Thanks, -Sri. On Mon, Sep 26, 2011 at 9:53 AM, Sriraman Tallam tmsri...@google.com wrote: On Mon, Sep 26, 2011 at 9:22 AM, Nathan Froyd nfr...@mozilla.com wrote: On 9/23/2011 6:03 PM, Sriraman Tallam wrote: This patch adds a new linker plugin to re-order functions. This is great stuff. We were experimenting with using the coverage files to generate an ordering for --section-ordering-file, but this might be even better, will have to experiment with it. A couple of comments on the code itself: Index: function_reordering_plugin/callgraph.h +inline static Edge_list * +make_edge_list (Edge *e) +{ + Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list)); If you are going to use libiberty via hashtab.h, you might as well make use of the *ALLOC family of macros to make this and other allocations a little neater. +/*Represents an edge in the call graph. */ +struct __edge__ I think the usual convention is to call this edge_d or something similar, avoiding the profusion of underscores. +void +map_section_name_to_index (char *section_name, void *handle, int shndx) +{ + void **slot; + char *function_name; + + if (is_prefix_of (.text.hot., section_name)) + function_name = section_name + 10 /* strlen (.text.hot.) */; + else if (is_prefix_of (.text.unlikely., section_name)) + function_name = section_name + 15 /* strlen (.text.unlikely.) */; + else if (is_prefix_of (.text.cold., section_name)) + function_name = section_name + 11 /* strlen (.text.cold.) */;
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
On 9/23/2011 6:03 PM, Sriraman Tallam wrote: This patch adds a new linker plugin to re-order functions. This is great stuff. We were experimenting with using the coverage files to generate an ordering for --section-ordering-file, but this might be even better, will have to experiment with it. A couple of comments on the code itself: Index: function_reordering_plugin/callgraph.h +inline static Edge_list * +make_edge_list (Edge *e) +{ + Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list)); If you are going to use libiberty via hashtab.h, you might as well make use of the *ALLOC family of macros to make this and other allocations a little neater. +/*Represents an edge in the call graph. */ +struct __edge__ I think the usual convention is to call this edge_d or something similar, avoiding the profusion of underscores. +void +map_section_name_to_index (char *section_name, void *handle, int shndx) +{ + void **slot; + char *function_name; + + if (is_prefix_of (.text.hot., section_name)) +function_name = section_name + 10 /* strlen (.text.hot.) */; + else if (is_prefix_of (.text.unlikely., section_name)) +function_name = section_name + 15 /* strlen (.text.unlikely.) */; + else if (is_prefix_of (.text.cold., section_name)) +function_name = section_name + 11 /* strlen (.text.cold.) */; + else if (is_prefix_of (.text.startup., section_name)) +function_name = section_name + 14 /* strlen (.text.startup.) */; + else +function_name = section_name + 6 /*strlen (.text.) */; You don't handle plain .text; this is assuming -ffunction-sections, right? Can this limitation be easily removed? I think it is customary to put the comment after the semicolon. Might just be easier to say something like: const char *sections[] = { .text.hot, ... } char *function_name = NULL; for (i = 0; i ARRAY_SIZE (sections); i++) if (is_prefix_of (sections[i], section_name)) { function_name = section_name + strlen (sections[i]); break; } if (!function_name) function_name = section_name + 6; /* strlen (.text.) */ I guess that's not much shorter. +void +cleanup () +{ + Node *node; + Edge *edge; + + /* Free all nodes and edge_lists. */ + for (node = node_chain; node != NULL; ) +{ + Node *next_node = node-next; + Edge_list *it; + for (it = node-edge_list; it != NULL; ) +{ + Edge_list *next_it = it-next; + free (it); + it = next_it; +} Write a free_edge_list function, since you do this once here and twice below. -Nathan
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
*Resending as plain text* I am attaching a patch of the updated files. This patch was meant for the google gcc-4_6 branch. Sorry for not mentioning this upfront in my original mail. Thanks, -Sri. On Mon, Sep 26, 2011 at 9:53 AM, Sriraman Tallam tmsri...@google.com wrote: On Mon, Sep 26, 2011 at 9:22 AM, Nathan Froyd nfr...@mozilla.com wrote: On 9/23/2011 6:03 PM, Sriraman Tallam wrote: This patch adds a new linker plugin to re-order functions. This is great stuff. We were experimenting with using the coverage files to generate an ordering for --section-ordering-file, but this might be even better, will have to experiment with it. A couple of comments on the code itself: Index: function_reordering_plugin/callgraph.h +inline static Edge_list * +make_edge_list (Edge *e) +{ + Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list)); If you are going to use libiberty via hashtab.h, you might as well make use of the *ALLOC family of macros to make this and other allocations a little neater. +/*Represents an edge in the call graph. */ +struct __edge__ I think the usual convention is to call this edge_d or something similar, avoiding the profusion of underscores. +void +map_section_name_to_index (char *section_name, void *handle, int shndx) +{ + void **slot; + char *function_name; + + if (is_prefix_of (.text.hot., section_name)) + function_name = section_name + 10 /* strlen (.text.hot.) */; + else if (is_prefix_of (.text.unlikely., section_name)) + function_name = section_name + 15 /* strlen (.text.unlikely.) */; + else if (is_prefix_of (.text.cold., section_name)) + function_name = section_name + 11 /* strlen (.text.cold.) */; + else if (is_prefix_of (.text.startup., section_name)) + function_name = section_name + 14 /* strlen (.text.startup.) */; + else + function_name = section_name + 6 /*strlen (.text.) */; You don't handle plain .text; this is assuming -ffunction-sections, right? Can this limitation be easily removed? You need to compile with -ffunction-sections or the individual sections cannot be re-ordered. That is why I assumed a .text.* prefix before every function section. Did you have something else in mind? Thanks for your other comments. I will make those changes. -Sri. I think it is customary to put the comment after the semicolon. Might just be easier to say something like: const char *sections[] = { .text.hot, ... } char *function_name = NULL; for (i = 0; i ARRAY_SIZE (sections); i++) if (is_prefix_of (sections[i], section_name)) { function_name = section_name + strlen (sections[i]); break; } if (!function_name) function_name = section_name + 6; /* strlen (.text.) */ I guess that's not much shorter. +void +cleanup () +{ + Node *node; + Edge *edge; + + /* Free all nodes and edge_lists. */ + for (node = node_chain; node != NULL; ) + { + Node *next_node = node-next; + Edge_list *it; + for (it = node-edge_list; it != NULL; ) + { + Edge_list *next_it = it-next; + free (it); + it = next_it; + } Write a free_edge_list function, since you do this once here and twice below. -Nathan Index: function_reordering_plugin/function_reordering_plugin.c === --- function_reordering_plugin/function_reordering_plugin.c (revision 0) +++ function_reordering_plugin/function_reordering_plugin.c (revision 0) @@ -0,0 +1,246 @@ +/* Function re-ordering plugin for gold. + Copyright (C) 2011 Free Software Foundation, Inc. + Contributed by Sriraman Tallam (tmsri...@google.com). + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +http://www.gnu.org/licenses/. */ + +/* This plugin should be invoked only when callgraph edge profile + information is available in the object files generated using the + compiler flag -fcallgraph-profiles-sections. The callgraph edge + profiles are stored in special sections marked .gnu.callgraph.* + + This plugin reads the callgraph sections and constructs an annotated + callgraph. It then repeatedly groups sections that are connected by + hot edges and passes the new function layout to the linker. The + layout is based on the procedure reordering
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
Re: [google] Linker plugin to do function reordering... Is there a particularly good reason for why you guys slip `[google]' into all of your `Subject:' lines? I was under the impresions that this list is for work on GCC. Consider putting something germane in the brackets instead.
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
On 11-09-24 09:37 , Michael Witten wrote: Re: [google] Linker plugin to do function reordering... Is there a particularly good reason for why you guys slip `[google]' into all of your `Subject:' lines? Yes, labels in brackets tend to be markers for branches, version numbers, specific modules. In this case, they're used to indicate patches to one of the google branches (http://gcc.gnu.org/svn.html, http://gcc.gnu.org/ml/gcc/2011-01/msg00246.html). Diego.
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
I think you may be trolling, but I'll give you the benefit of the doubt since you seem to be lacking some background. On Sat, Sep 24, 2011 at 15:19, Michael Witten mfwit...@gmail.com wrote: Why is gnu.gcc.org hosting work that is specific to some company's build system? We've long allowed different companies hold branches on gcc.gnu.org. From one of the links I posted in my previous response: http://gcc.gnu.org/svn.html#distrobranches Why is it necessary to announce a patch [series] for this branch when it is intended that such a patch [series] make it to the trunk? Shouldn't an employee of your company submit a `trunk'-worthy patch [series] for review as would anyone else? Yes, and you will see several patches from google.com addresses that are not labeled [google]. Those are meant for trunk or devel branches. It is true that if a patch is meant for trunk, it should not have a branch tag. I expect slipups like that to occur from time to time. Thanks for pointing it out. I wonder what `issue5124041' means. Is that a reference that only has meaning for employees of your company? No. This is Rietveld, an open source code review system. I suggested using it for code reviews a while ago and contributed a script to facilitate using it with GCC. See http://gcc.gnu.org/wiki/rietveld Diego.
Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
On Sep 24, 2011, at 12:19 PM, Michael Witten wrote: Why is gnu.gcc.org hosting work that is specific to some company's build system? This list isn't for this topic. If you want, please, really, go play in gnu.misc.discuss. This list is for technical patches and the technical review of such. If your email isn't of that nature, then it is off-topic for this list. Thanks. Why is gnu.gcc.org hosting such a pointless branch? Is it just that the technical inadequacies of SVN made it easier for your multi-billion-dollar company to host its essentially private work in GNU's repository? This isn't GNU's repository, this is GCC's repository.
[google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)
This patch adds a new linker plugin to re-order functions. The plugin constructs an annotated callgraph with edge profile information and then repeatedly groups sections that are connected by hot edges and passes the new function layout to the linker. The grouping is done similar to the Pettis Hansen procedure ordering scheme. I had earlier reverted a patch for a plugin that was written in C++. I have re-written the same plugin in C. How to use the plugin: During Profile use build stage of Feedback-directed builds, use the flags: -fcallgraph-profiles-sections -Wl,--plugin,path_to_plugin/libfunction_reordering_plugin.so The first flag generates special .gnu.callgraph.text sections which contain the callgraph profiles that are read by the plugin and an new function layout is generated. The ordering of sections is dumped in file final_layout.txt along with the callgraph edge profile information. The plugin itself is implemented in the three files: function_ordering_plugin.c, callgraph.c, and callgraph.h. The file include/plugin-api.h has changes which has already been submitted to trunk. The rest is related to Makefiles and configure scripts to build and install the plugin. I have not attached any of the auto-generated files. Index: configure.ac === --- configure.ac(revision 178891) +++ configure.ac(working copy) @@ -1738,6 +1738,8 @@ ACX_ELF_TARGET_IFELSE([# ELF platforms build the lto-plugin always. build_lto_plugin=yes + # Allow ELF platforms to build the function_reordering_plugin always. + build_function_reordering_plugin=yes ],[if test x$default_enable_lto = xyes ; then case $target in *-apple-darwin9 | *-cygwin* | *-mingw*) ;; @@ -1865,6 +1867,11 @@ extra_host_libiberty_configure_flags=--enable-shared fi fi + if test ${build_function_reordering_plugin} = yes ; then +configdirs=$configdirs function_reordering_plugin +extra_host_libiberty_configure_flags=--enable-shared + fi + AC_SUBST(extra_host_libiberty_configure_flags) missing_languages=`echo ,$enable_languages, | sed -e s/,all,/,/ -e s/,c,/,/ ` Index: include/plugin-api.h === --- include/plugin-api.h(revision 178891) +++ include/plugin-api.h(working copy) @@ -93,6 +93,14 @@ int resolution; }; +/* An object's section. */ + +struct ld_plugin_section +{ + const void* handle; + unsigned int shndx; +}; + /* Whether the symbol is a definition, reference, or common, weak or not. */ enum ld_plugin_symbol_kind @@ -203,6 +211,10 @@ (*ld_plugin_get_input_file) (const void *handle, struct ld_plugin_input_file *file); +typedef +enum ld_plugin_status +(*ld_plugin_get_view) (const void *handle, const void **viewp); + /* The linker's interface for releasing the input file. */ typedef @@ -240,6 +252,65 @@ enum ld_plugin_status (*ld_plugin_message) (int level, const char *format, ...); +/* The linker's interface for retrieving the number of sections in an object. + The handle is obtained in the claim_file handler. This interface should + only be invoked in the claim_file handler. This function sets *COUNT to + the number of sections in the object. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_count) (const void* handle, unsigned int *count); + +/* The linker's interface for retrieving the section type of a specific + section in an object. This interface should only be invoked in the + claim_file handler. This function sets *TYPE to an ELF SHT_xxx value. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_type) (const struct ld_plugin_section section, + unsigned int *type); + +/* The linker's interface for retrieving the name of a specific section in + an object. This interface should only be invoked in the claim_file handler. + This function sets *SECTION_NAME_PTR to a null-terminated buffer allocated + by malloc. The plugin must free *SECTION_NAME_PTR. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_name) (const struct ld_plugin_section section, + char **section_name_ptr); + +/* The linker's interface for retrieving the contents of a specific section + in an object. This interface should only be invoked in the claim_file + handler. This function sets *SECTION_CONTENTS to point to a buffer that is + valid until clam_file handler returns. It sets *LEN to the size of the + buffer. */ + +typedef +enum ld_plugin_status +(*ld_plugin_get_input_section_contents) (const struct ld_plugin_section section, + const unsigned char **section_contents, + size_t* len); + +/* The linker's interface for specifying the desired order of sections. + The