ldelfgen.c revision 1.1.1.1.2.2 1 1.1.1.1.2.2 martin /* Emulation code used by all ELF targets.
2 1.1.1.1.2.2 martin Copyright (C) 1991-2020 Free Software Foundation, Inc.
3 1.1.1.1.2.2 martin
4 1.1.1.1.2.2 martin This file is part of the GNU Binutils.
5 1.1.1.1.2.2 martin
6 1.1.1.1.2.2 martin This program is free software; you can redistribute it and/or modify
7 1.1.1.1.2.2 martin it under the terms of the GNU General Public License as published by
8 1.1.1.1.2.2 martin the Free Software Foundation; either version 3 of the License, or
9 1.1.1.1.2.2 martin (at your option) any later version.
10 1.1.1.1.2.2 martin
11 1.1.1.1.2.2 martin This program is distributed in the hope that it will be useful,
12 1.1.1.1.2.2 martin but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1.1.1.2.2 martin MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1.1.1.2.2 martin GNU General Public License for more details.
15 1.1.1.1.2.2 martin
16 1.1.1.1.2.2 martin You should have received a copy of the GNU General Public License
17 1.1.1.1.2.2 martin along with this program; if not, write to the Free Software
18 1.1.1.1.2.2 martin Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1.1.1.2.2 martin MA 02110-1301, USA. */
20 1.1.1.1.2.2 martin
21 1.1.1.1.2.2 martin #include "sysdep.h"
22 1.1.1.1.2.2 martin #include "bfd.h"
23 1.1.1.1.2.2 martin #include "bfdlink.h"
24 1.1.1.1.2.2 martin #include "ctf-api.h"
25 1.1.1.1.2.2 martin #include "ld.h"
26 1.1.1.1.2.2 martin #include "ldmain.h"
27 1.1.1.1.2.2 martin #include "ldmisc.h"
28 1.1.1.1.2.2 martin #include "ldexp.h"
29 1.1.1.1.2.2 martin #include "ldlang.h"
30 1.1.1.1.2.2 martin #include "elf-bfd.h"
31 1.1.1.1.2.2 martin #include "ldelfgen.h"
32 1.1.1.1.2.2 martin
33 1.1.1.1.2.2 martin void
34 1.1.1.1.2.2 martin ldelf_map_segments (bfd_boolean need_layout)
35 1.1.1.1.2.2 martin {
36 1.1.1.1.2.2 martin int tries = 10;
37 1.1.1.1.2.2 martin
38 1.1.1.1.2.2 martin do
39 1.1.1.1.2.2 martin {
40 1.1.1.1.2.2 martin lang_relax_sections (need_layout);
41 1.1.1.1.2.2 martin need_layout = FALSE;
42 1.1.1.1.2.2 martin
43 1.1.1.1.2.2 martin if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour
44 1.1.1.1.2.2 martin && !bfd_link_relocatable (&link_info))
45 1.1.1.1.2.2 martin {
46 1.1.1.1.2.2 martin bfd_size_type phdr_size;
47 1.1.1.1.2.2 martin
48 1.1.1.1.2.2 martin phdr_size = elf_program_header_size (link_info.output_bfd);
49 1.1.1.1.2.2 martin /* If we don't have user supplied phdrs, throw away any
50 1.1.1.1.2.2 martin previous linker generated program headers. */
51 1.1.1.1.2.2 martin if (lang_phdr_list == NULL)
52 1.1.1.1.2.2 martin elf_seg_map (link_info.output_bfd) = NULL;
53 1.1.1.1.2.2 martin if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
54 1.1.1.1.2.2 martin &link_info))
55 1.1.1.1.2.2 martin einfo (_("%F%P: map sections to segments failed: %E\n"));
56 1.1.1.1.2.2 martin
57 1.1.1.1.2.2 martin if (phdr_size != elf_program_header_size (link_info.output_bfd))
58 1.1.1.1.2.2 martin {
59 1.1.1.1.2.2 martin if (tries > 6)
60 1.1.1.1.2.2 martin /* The first few times we allow any change to
61 1.1.1.1.2.2 martin phdr_size . */
62 1.1.1.1.2.2 martin need_layout = TRUE;
63 1.1.1.1.2.2 martin else if (phdr_size
64 1.1.1.1.2.2 martin < elf_program_header_size (link_info.output_bfd))
65 1.1.1.1.2.2 martin /* After that we only allow the size to grow. */
66 1.1.1.1.2.2 martin need_layout = TRUE;
67 1.1.1.1.2.2 martin else
68 1.1.1.1.2.2 martin elf_program_header_size (link_info.output_bfd) = phdr_size;
69 1.1.1.1.2.2 martin }
70 1.1.1.1.2.2 martin }
71 1.1.1.1.2.2 martin }
72 1.1.1.1.2.2 martin while (need_layout && --tries);
73 1.1.1.1.2.2 martin
74 1.1.1.1.2.2 martin if (tries == 0)
75 1.1.1.1.2.2 martin einfo (_("%F%P: looping in map_segments"));
76 1.1.1.1.2.2 martin }
77 1.1.1.1.2.2 martin
78 1.1.1.1.2.2 martin /* We want to emit CTF early if and only if we are not targetting ELF with this
79 1.1.1.1.2.2 martin invocation. */
80 1.1.1.1.2.2 martin
81 1.1.1.1.2.2 martin int
82 1.1.1.1.2.2 martin ldelf_emit_ctf_early (void)
83 1.1.1.1.2.2 martin {
84 1.1.1.1.2.2 martin if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
85 1.1.1.1.2.2 martin return 0;
86 1.1.1.1.2.2 martin return 1;
87 1.1.1.1.2.2 martin }
88 1.1.1.1.2.2 martin
89 1.1.1.1.2.2 martin /* Callbacks used to map from bfd types to libctf types, under libctf's
90 1.1.1.1.2.2 martin control. */
91 1.1.1.1.2.2 martin
92 1.1.1.1.2.2 martin struct ctf_strsym_iter_cb_arg
93 1.1.1.1.2.2 martin {
94 1.1.1.1.2.2 martin struct elf_sym_strtab *syms;
95 1.1.1.1.2.2 martin bfd_size_type symcount;
96 1.1.1.1.2.2 martin struct elf_strtab_hash *symstrtab;
97 1.1.1.1.2.2 martin size_t next_i;
98 1.1.1.1.2.2 martin size_t next_idx;
99 1.1.1.1.2.2 martin };
100 1.1.1.1.2.2 martin
101 1.1.1.1.2.2 martin /* Return strings from the strtab to libctf, one by one. Returns NULL when
102 1.1.1.1.2.2 martin iteration is complete. */
103 1.1.1.1.2.2 martin
104 1.1.1.1.2.2 martin static const char *
105 1.1.1.1.2.2 martin ldelf_ctf_strtab_iter_cb (uint32_t *offset, void *arg_)
106 1.1.1.1.2.2 martin {
107 1.1.1.1.2.2 martin bfd_size_type off;
108 1.1.1.1.2.2 martin const char *ret;
109 1.1.1.1.2.2 martin
110 1.1.1.1.2.2 martin struct ctf_strsym_iter_cb_arg *arg =
111 1.1.1.1.2.2 martin (struct ctf_strsym_iter_cb_arg *) arg_;
112 1.1.1.1.2.2 martin
113 1.1.1.1.2.2 martin /* There is no zeroth string. */
114 1.1.1.1.2.2 martin if (arg->next_i == 0)
115 1.1.1.1.2.2 martin arg->next_i = 1;
116 1.1.1.1.2.2 martin
117 1.1.1.1.2.2 martin if (arg->next_i >= _bfd_elf_strtab_len (arg->symstrtab))
118 1.1.1.1.2.2 martin {
119 1.1.1.1.2.2 martin arg->next_i = 0;
120 1.1.1.1.2.2 martin return NULL;
121 1.1.1.1.2.2 martin }
122 1.1.1.1.2.2 martin
123 1.1.1.1.2.2 martin ret = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i++, &off);
124 1.1.1.1.2.2 martin *offset = off;
125 1.1.1.1.2.2 martin
126 1.1.1.1.2.2 martin /* If we've overflowed, we cannot share any further strings: the CTF
127 1.1.1.1.2.2 martin format cannot encode strings with such high offsets. */
128 1.1.1.1.2.2 martin if (*offset != off)
129 1.1.1.1.2.2 martin return NULL;
130 1.1.1.1.2.2 martin
131 1.1.1.1.2.2 martin return ret;
132 1.1.1.1.2.2 martin }
133 1.1.1.1.2.2 martin
134 1.1.1.1.2.2 martin /* Return symbols from the symbol table to libctf, one by one. We assume (and
135 1.1.1.1.2.2 martin assert) that the symbols in the elf_link_hash_table are in strictly ascending
136 1.1.1.1.2.2 martin order, and that none will be added in between existing ones. Returns NULL
137 1.1.1.1.2.2 martin when iteration is complete. */
138 1.1.1.1.2.2 martin
139 1.1.1.1.2.2 martin static struct ctf_link_sym *
140 1.1.1.1.2.2 martin ldelf_ctf_symbols_iter_cb (struct ctf_link_sym *dest,
141 1.1.1.1.2.2 martin void *arg_)
142 1.1.1.1.2.2 martin {
143 1.1.1.1.2.2 martin struct ctf_strsym_iter_cb_arg *arg =
144 1.1.1.1.2.2 martin (struct ctf_strsym_iter_cb_arg *) arg_;
145 1.1.1.1.2.2 martin
146 1.1.1.1.2.2 martin if (arg->next_i > arg->symcount)
147 1.1.1.1.2.2 martin {
148 1.1.1.1.2.2 martin arg->next_i = 0;
149 1.1.1.1.2.2 martin arg->next_idx = 0;
150 1.1.1.1.2.2 martin return NULL;
151 1.1.1.1.2.2 martin }
152 1.1.1.1.2.2 martin
153 1.1.1.1.2.2 martin ASSERT (arg->syms[arg->next_i].dest_index == arg->next_idx);
154 1.1.1.1.2.2 martin dest->st_name = _bfd_elf_strtab_str (arg->symstrtab, arg->next_i, NULL);
155 1.1.1.1.2.2 martin dest->st_shndx = arg->syms[arg->next_i].sym.st_shndx;
156 1.1.1.1.2.2 martin dest->st_type = ELF_ST_TYPE (arg->syms[arg->next_i].sym.st_info);
157 1.1.1.1.2.2 martin dest->st_value = arg->syms[arg->next_i].sym.st_value;
158 1.1.1.1.2.2 martin arg->next_i++;
159 1.1.1.1.2.2 martin return dest;
160 1.1.1.1.2.2 martin }
161 1.1.1.1.2.2 martin
162 1.1.1.1.2.2 martin void
163 1.1.1.1.2.2 martin ldelf_examine_strtab_for_ctf
164 1.1.1.1.2.2 martin (struct ctf_file *ctf_output, struct elf_sym_strtab *syms,
165 1.1.1.1.2.2 martin bfd_size_type symcount, struct elf_strtab_hash *symstrtab)
166 1.1.1.1.2.2 martin {
167 1.1.1.1.2.2 martin struct ctf_strsym_iter_cb_arg args = { syms, symcount, symstrtab,
168 1.1.1.1.2.2 martin 0, 0 };
169 1.1.1.1.2.2 martin if (!ctf_output)
170 1.1.1.1.2.2 martin return;
171 1.1.1.1.2.2 martin
172 1.1.1.1.2.2 martin if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
173 1.1.1.1.2.2 martin && !bfd_link_relocatable (&link_info))
174 1.1.1.1.2.2 martin {
175 1.1.1.1.2.2 martin if (ctf_link_add_strtab (ctf_output, ldelf_ctf_strtab_iter_cb,
176 1.1.1.1.2.2 martin &args) < 0)
177 1.1.1.1.2.2 martin einfo (_("%F%P: warning: CTF strtab association failed; strings will "
178 1.1.1.1.2.2 martin "not be shared: %s\n"),
179 1.1.1.1.2.2 martin ctf_errmsg (ctf_errno (ctf_output)));
180 1.1.1.1.2.2 martin
181 1.1.1.1.2.2 martin if (ctf_link_shuffle_syms (ctf_output, ldelf_ctf_symbols_iter_cb,
182 1.1.1.1.2.2 martin &args) < 0)
183 1.1.1.1.2.2 martin einfo (_("%F%P: warning: CTF symbol shuffling failed; slight space "
184 1.1.1.1.2.2 martin "cost: %s\n"), ctf_errmsg (ctf_errno (ctf_output)));
185 1.1.1.1.2.2 martin }
186 1.1.1.1.2.2 martin }
187