Updated Malay translation for the bfd sub-directory
[binutils-gdb.git] / gold / testsuite / plugin_new_section_layout.c
blob2b83f35bfdf8f8161bb7ea879f6e1294ec487c8d
1 /* plugin_new_section_layout.c -- Simple plugin to reorder function sections in
2 plugin-generated objects
4 Copyright (C) 2017-2025 Free Software Foundation, Inc.
5 Written by Stephen Crane <sjc@immunant.com>.
7 This file is part of gold.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 /* This plugin tests the new_input API of the linker plugin interface that
25 * allows plugins to modify section layout and assign sections to segments for
26 * sections in plugin-generated object files. It assumes that another plugin is
27 * also in use which will add new files. In practice a plugin is likely to
28 * generate new input files itself in all_symbols_read and want to
29 * reorder/assign sections for these files in the new_input_hook callback. */
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <assert.h>
39 #include "plugin-api.h"
40 #include "elf/common.h"
42 static ld_plugin_get_input_section_count get_input_section_count = NULL;
43 static ld_plugin_get_input_section_type get_input_section_type = NULL;
44 static ld_plugin_get_input_section_name get_input_section_name = NULL;
45 static ld_plugin_update_section_order update_section_order = NULL;
46 static ld_plugin_allow_section_ordering allow_section_ordering = NULL;
47 static ld_plugin_allow_unique_segment_for_sections
48 allow_unique_segment_for_sections = NULL;
49 static ld_plugin_unique_segment_for_sections unique_segment_for_sections = NULL;
51 enum ld_plugin_status onload(struct ld_plugin_tv *tv);
52 enum ld_plugin_status new_input_hook(const struct ld_plugin_input_file *file);
54 /* Plugin entry point. */
55 enum ld_plugin_status
56 onload(struct ld_plugin_tv *tv)
58 struct ld_plugin_tv *entry;
59 for (entry = tv; entry->tv_tag != LDPT_NULL; ++entry)
61 switch (entry->tv_tag)
63 case LDPT_GET_INPUT_SECTION_COUNT:
64 get_input_section_count = *entry->tv_u.tv_get_input_section_count;
65 break;
66 case LDPT_GET_INPUT_SECTION_TYPE:
67 get_input_section_type = *entry->tv_u.tv_get_input_section_type;
68 break;
69 case LDPT_GET_INPUT_SECTION_NAME:
70 get_input_section_name = *entry->tv_u.tv_get_input_section_name;
71 break;
72 case LDPT_UPDATE_SECTION_ORDER:
73 update_section_order = *entry->tv_u.tv_update_section_order;
74 break;
75 case LDPT_ALLOW_SECTION_ORDERING:
76 allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
77 break;
78 case LDPT_ALLOW_UNIQUE_SEGMENT_FOR_SECTIONS:
79 allow_unique_segment_for_sections
80 = *entry->tv_u.tv_allow_unique_segment_for_sections;
81 break;
82 case LDPT_UNIQUE_SEGMENT_FOR_SECTIONS:
83 unique_segment_for_sections
84 = *entry->tv_u.tv_unique_segment_for_sections;
85 break;
86 case LDPT_REGISTER_NEW_INPUT_HOOK:
87 assert((*entry->tv_u.tv_register_new_input) (new_input_hook)
88 == LDPS_OK);
89 break;
90 default:
91 break;
95 if (get_input_section_count == NULL
96 || get_input_section_type == NULL
97 || get_input_section_name == NULL
98 || update_section_order == NULL
99 || allow_section_ordering == NULL
100 || allow_unique_segment_for_sections == NULL
101 || unique_segment_for_sections == NULL)
103 fprintf(stderr, "Some interfaces are missing\n");
104 return LDPS_ERR;
107 /* Inform the linker to prepare for section reordering. */
108 (*allow_section_ordering)();
109 /* Inform the linker to prepare to map some sections to unique
110 segments. */
111 (*allow_unique_segment_for_sections)();
113 return LDPS_OK;
116 inline static int is_prefix_of(const char *prefix, const char *str)
118 return strncmp(prefix, str, strlen (prefix)) == 0;
121 /* This function is called by the linker when new files are added by a plugin.
122 We can now tell the linker the desired function order since we have a file
123 handle for the newly added file. */
125 enum ld_plugin_status
126 new_input_hook(const struct ld_plugin_input_file *file)
128 struct ld_plugin_section section_list[3];
129 int num_entries = 0;
130 unsigned int count;
132 if (get_input_section_count(file->handle, &count) != LDPS_OK)
133 return LDPS_ERR;
135 unsigned int i;
136 for (i = 0; i < count; ++i)
138 struct ld_plugin_section section;
139 unsigned int type = 0;
140 char *name = NULL;
141 int position = 3;
143 section.handle = file->handle;
144 section.shndx = i;
146 if (get_input_section_type(section, &type) != LDPS_OK)
147 return LDPS_ERR;
148 if (type != SHT_PROGBITS)
149 continue;
151 if (get_input_section_name(section, &name))
152 return LDPS_ERR;
154 /* As in plugin_section_order.c, order is foo() followed by bar()
155 followed by baz() */
156 if (is_prefix_of(".text.", name))
158 if (strstr(name, "_Z3foov") != NULL)
159 position = 0;
160 else if (strstr(name, "_Z3barv") != NULL)
161 position = 1;
162 else if (strstr(name, "_Z3bazv") != NULL)
163 position = 2;
164 else
165 position = 3;
167 if (position < 3)
169 section_list[position] = section;
170 num_entries++;
174 if (num_entries != 3)
175 return LDPS_ERR;
177 update_section_order(section_list, num_entries);
178 unique_segment_for_sections (".text.plugin_created_unique", 0, 0x1000,
179 section_list, num_entries);
181 return LDPS_OK;