1 /* plugin_section_reorder.c -- Simple plugin to reorder function sections
3 Copyright 2011 Free Software Foundation, Inc.
4 Written by Sriraman Tallam <tmsriram@google.com>.
6 This file is part of gold.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
31 #include "plugin-api.h"
33 static ld_plugin_get_input_section_count get_input_section_count
= NULL
;
34 static ld_plugin_get_input_section_type get_input_section_type
= NULL
;
35 static ld_plugin_get_input_section_name get_input_section_name
= NULL
;
36 static ld_plugin_get_input_section_contents get_input_section_contents
= NULL
;
37 static ld_plugin_update_section_order update_section_order
= NULL
;
38 static ld_plugin_allow_section_ordering allow_section_ordering
= NULL
;
40 enum ld_plugin_status
onload(struct ld_plugin_tv
*tv
);
41 enum ld_plugin_status
claim_file_hook(const struct ld_plugin_input_file
*file
,
43 enum ld_plugin_status
all_symbols_read_hook(void);
45 /* Plugin entry point. */
47 onload(struct ld_plugin_tv
*tv
)
49 struct ld_plugin_tv
*entry
;
50 for (entry
= tv
; entry
->tv_tag
!= LDPT_NULL
; ++entry
)
52 switch (entry
->tv_tag
)
54 case LDPT_REGISTER_CLAIM_FILE_HOOK
:
55 assert((*entry
->tv_u
.tv_register_claim_file
) (claim_file_hook
) == LDPS_OK
);
57 case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK
:
58 assert((*entry
->tv_u
.tv_register_all_symbols_read
) (all_symbols_read_hook
)
61 case LDPT_GET_INPUT_SECTION_COUNT
:
62 get_input_section_count
= *entry
->tv_u
.tv_get_input_section_count
;
64 case LDPT_GET_INPUT_SECTION_TYPE
:
65 get_input_section_type
= *entry
->tv_u
.tv_get_input_section_type
;
67 case LDPT_GET_INPUT_SECTION_NAME
:
68 get_input_section_name
= *entry
->tv_u
.tv_get_input_section_name
;
70 case LDPT_GET_INPUT_SECTION_CONTENTS
:
71 get_input_section_contents
= *entry
->tv_u
.tv_get_input_section_contents
;
73 case LDPT_UPDATE_SECTION_ORDER
:
74 update_section_order
= *entry
->tv_u
.tv_update_section_order
;
76 case LDPT_ALLOW_SECTION_ORDERING
:
77 allow_section_ordering
= *entry
->tv_u
.tv_allow_section_ordering
;
84 if (get_input_section_count
== NULL
85 || get_input_section_type
== NULL
86 || get_input_section_name
== NULL
87 || get_input_section_contents
== NULL
88 || update_section_order
== NULL
89 || allow_section_ordering
== NULL
)
91 fprintf(stderr
, "Some interfaces are missing\n");
98 inline static int is_prefix_of(const char *prefix
, const char *str
)
100 return strncmp(prefix
, str
, strlen (prefix
)) == 0;
103 struct ld_plugin_section section_list
[3];
106 /* This function is called by the linker for every new object it encounters. */
107 enum ld_plugin_status
108 claim_file_hook(const struct ld_plugin_input_file
*file
, int *claimed
)
110 static int is_ordering_specified
= 0;
111 struct ld_plugin_section section
;
112 unsigned int count
= 0;
116 if (is_ordering_specified
== 0)
118 /* Inform the linker to prepare for section reordering. */
119 (*allow_section_ordering
)();
120 is_ordering_specified
= 1;
123 (*get_input_section_count
)(file
->handle
, &count
);
125 for (shndx
= 0; shndx
< count
; ++shndx
)
130 section
.handle
= file
->handle
;
131 section
.shndx
= shndx
;
132 (*get_input_section_name
)(section
, &name
);
134 /* Order is foo() followed by bar() followed by baz() */
135 if (is_prefix_of(".text.", name
))
137 if (strstr(name
, "_Z3foov") != NULL
)
139 else if (strstr(name
, "_Z3barv") != NULL
)
141 else if (strstr(name
, "_Z3bazv") != NULL
)
148 section_list
[position
].handle
= file
->handle
;
149 section_list
[position
].shndx
= shndx
;
156 /* This function is called by the linker after all the symbols have been read.
157 At this stage, it is fine to tell the linker the desired function order. */
159 enum ld_plugin_status
160 all_symbols_read_hook(void)
162 if (num_entries
== 3)
163 update_section_order(section_list
, num_entries
);