]>
Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Load module for 'compile' command. |
2 | ||
213516ef | 3 | Copyright (C) 2014-2023 Free Software Foundation, Inc. |
bb2ec1b3 TT |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
21 | #include "compile-object-load.h" | |
22 | #include "compile-internal.h" | |
23 | #include "command.h" | |
24 | #include "objfiles.h" | |
25 | #include "gdbcore.h" | |
26 | #include "readline/tilde.h" | |
27 | #include "bfdlink.h" | |
28 | #include "gdbcmd.h" | |
29 | #include "regcache.h" | |
30 | #include "inferior.h" | |
00431a78 | 31 | #include "gdbthread.h" |
bb2ec1b3 | 32 | #include "compile.h" |
36de76f9 | 33 | #include "block.h" |
bb2ec1b3 | 34 | #include "arch-utils.h" |
325fac50 | 35 | #include <algorithm> |
bb2ec1b3 | 36 | |
c9e0a7e3 TT |
37 | /* Add inferior mmap memory range ADDR..ADDR+SIZE (exclusive) to the |
38 | list. */ | |
7f361056 JK |
39 | |
40 | void | |
c9e0a7e3 | 41 | munmap_list::add (CORE_ADDR addr, CORE_ADDR size) |
7f361056 | 42 | { |
c9e0a7e3 TT |
43 | struct munmap_item item = { addr, size }; |
44 | items.push_back (item); | |
7f361056 JK |
45 | } |
46 | ||
c9e0a7e3 | 47 | /* Destroy an munmap_list. */ |
7f361056 | 48 | |
c9e0a7e3 | 49 | munmap_list::~munmap_list () |
7f361056 | 50 | { |
c9e0a7e3 | 51 | for (auto &item : items) |
40f03055 | 52 | { |
a70b8144 | 53 | try |
40f03055 TT |
54 | { |
55 | gdbarch_infcall_munmap (target_gdbarch (), item.addr, item.size); | |
56 | } | |
230d2906 | 57 | catch (const gdb_exception_error &ex) |
40f03055 TT |
58 | { |
59 | /* There's not much the user can do, so just ignore | |
60 | this. */ | |
61 | } | |
40f03055 | 62 | } |
7f361056 JK |
63 | } |
64 | ||
92677124 TT |
65 | /* A data structure that is used to lay out sections of our objfile in |
66 | inferior memory. */ | |
bb2ec1b3 TT |
67 | |
68 | struct setup_sections_data | |
69 | { | |
92677124 TT |
70 | explicit setup_sections_data (bfd *abfd) |
71 | : m_bfd (abfd), | |
72 | m_last_section_first (abfd->sections) | |
73 | { | |
74 | } | |
75 | ||
76 | /* Place all ABFD sections next to each other obeying all | |
77 | constraints. */ | |
78 | void setup_one_section (asection *sect); | |
79 | ||
80 | /* List of inferior mmap ranges where setup_sections should add its | |
81 | next range. */ | |
82 | struct munmap_list munmap_list; | |
83 | ||
84 | private: | |
85 | ||
86 | /* The BFD. */ | |
87 | bfd *m_bfd; | |
88 | ||
bb2ec1b3 | 89 | /* Size of all recent sections with matching LAST_PROT. */ |
92677124 | 90 | CORE_ADDR m_last_size = 0; |
bb2ec1b3 TT |
91 | |
92 | /* First section matching LAST_PROT. */ | |
92677124 | 93 | asection *m_last_section_first; |
bb2ec1b3 TT |
94 | |
95 | /* Memory protection like the prot parameter of gdbarch_infcall_mmap. */ | |
92677124 | 96 | unsigned m_last_prot = -1; |
bb2ec1b3 TT |
97 | |
98 | /* Maximum of alignments of all sections matching LAST_PROT. | |
99 | This value is always at least 1. This value is always a power of 2. */ | |
92677124 | 100 | CORE_ADDR m_last_max_alignment = -1; |
7f361056 | 101 | |
bb2ec1b3 TT |
102 | }; |
103 | ||
92677124 | 104 | /* See setup_sections_data. */ |
bb2ec1b3 | 105 | |
92677124 TT |
106 | void |
107 | setup_sections_data::setup_one_section (asection *sect) | |
bb2ec1b3 | 108 | { |
bb2ec1b3 TT |
109 | CORE_ADDR alignment; |
110 | unsigned prot; | |
111 | ||
112 | if (sect != NULL) | |
113 | { | |
114 | /* It is required by later bfd_get_relocated_section_contents. */ | |
115 | if (sect->output_section == NULL) | |
116 | sect->output_section = sect; | |
117 | ||
fd361982 | 118 | if ((bfd_section_flags (sect) & SEC_ALLOC) == 0) |
bb2ec1b3 TT |
119 | return; |
120 | ||
bb2b33b9 | 121 | /* Make the memory always readable. */ |
bb2ec1b3 | 122 | prot = GDB_MMAP_PROT_READ; |
fd361982 | 123 | if ((bfd_section_flags (sect) & SEC_READONLY) == 0) |
bb2ec1b3 | 124 | prot |= GDB_MMAP_PROT_WRITE; |
fd361982 | 125 | if ((bfd_section_flags (sect) & SEC_CODE) != 0) |
bb2ec1b3 TT |
126 | prot |= GDB_MMAP_PROT_EXEC; |
127 | ||
128 | if (compile_debug) | |
6cb06a8c TT |
129 | gdb_printf (gdb_stdlog, |
130 | "module \"%s\" section \"%s\" size %s prot %u\n", | |
131 | bfd_get_filename (m_bfd), | |
132 | bfd_section_name (sect), | |
133 | paddress (target_gdbarch (), | |
134 | bfd_section_size (sect)), | |
135 | prot); | |
bb2ec1b3 TT |
136 | } |
137 | else | |
138 | prot = -1; | |
139 | ||
140 | if (sect == NULL | |
92677124 | 141 | || (m_last_prot != prot && bfd_section_size (sect) != 0)) |
bb2ec1b3 TT |
142 | { |
143 | CORE_ADDR addr; | |
144 | asection *sect_iter; | |
145 | ||
92677124 | 146 | if (m_last_size != 0) |
bb2ec1b3 | 147 | { |
92677124 TT |
148 | addr = gdbarch_infcall_mmap (target_gdbarch (), m_last_size, |
149 | m_last_prot); | |
150 | munmap_list.add (addr, m_last_size); | |
bb2ec1b3 | 151 | if (compile_debug) |
6cb06a8c TT |
152 | gdb_printf (gdb_stdlog, |
153 | "allocated %s bytes at %s prot %u\n", | |
154 | paddress (target_gdbarch (), m_last_size), | |
155 | paddress (target_gdbarch (), addr), | |
156 | m_last_prot); | |
bb2ec1b3 TT |
157 | } |
158 | else | |
159 | addr = 0; | |
160 | ||
92677124 | 161 | if ((addr & (m_last_max_alignment - 1)) != 0) |
bb2ec1b3 TT |
162 | error (_("Inferior compiled module address %s " |
163 | "is not aligned to BFD required %s."), | |
164 | paddress (target_gdbarch (), addr), | |
92677124 | 165 | paddress (target_gdbarch (), m_last_max_alignment)); |
bb2ec1b3 | 166 | |
92677124 | 167 | for (sect_iter = m_last_section_first; sect_iter != sect; |
bb2ec1b3 | 168 | sect_iter = sect_iter->next) |
fd361982 AM |
169 | if ((bfd_section_flags (sect_iter) & SEC_ALLOC) != 0) |
170 | bfd_set_section_vma (sect_iter, addr + bfd_section_vma (sect_iter)); | |
bb2ec1b3 | 171 | |
92677124 TT |
172 | m_last_size = 0; |
173 | m_last_section_first = sect; | |
174 | m_last_prot = prot; | |
175 | m_last_max_alignment = 1; | |
bb2ec1b3 TT |
176 | } |
177 | ||
178 | if (sect == NULL) | |
179 | return; | |
180 | ||
fd361982 | 181 | alignment = ((CORE_ADDR) 1) << bfd_section_alignment (sect); |
92677124 | 182 | m_last_max_alignment = std::max (m_last_max_alignment, alignment); |
bb2ec1b3 | 183 | |
92677124 | 184 | m_last_size = (m_last_size + alignment - 1) & -alignment; |
bb2ec1b3 | 185 | |
92677124 | 186 | bfd_set_section_vma (sect, m_last_size); |
bb2ec1b3 | 187 | |
92677124 TT |
188 | m_last_size += bfd_section_size (sect); |
189 | m_last_size = (m_last_size + alignment - 1) & -alignment; | |
bb2ec1b3 TT |
190 | } |
191 | ||
192 | /* Helper for link_callbacks callbacks vector. */ | |
193 | ||
1a72702b | 194 | static void |
bb2ec1b3 TT |
195 | link_callbacks_multiple_definition (struct bfd_link_info *link_info, |
196 | struct bfd_link_hash_entry *h, bfd *nbfd, | |
197 | asection *nsec, bfd_vma nval) | |
198 | { | |
199 | bfd *abfd = link_info->input_bfds; | |
200 | ||
201 | if (link_info->allow_multiple_definition) | |
1a72702b | 202 | return; |
8e8347b8 | 203 | warning (_("Compiled module \"%s\": multiple symbol definitions: %s"), |
bb2ec1b3 | 204 | bfd_get_filename (abfd), h->root.string); |
bb2ec1b3 TT |
205 | } |
206 | ||
207 | /* Helper for link_callbacks callbacks vector. */ | |
208 | ||
1a72702b | 209 | static void |
bb2ec1b3 | 210 | link_callbacks_warning (struct bfd_link_info *link_info, const char *xwarning, |
dda83cd7 | 211 | const char *symbol, bfd *abfd, asection *section, |
bb2ec1b3 TT |
212 | bfd_vma address) |
213 | { | |
8e8347b8 | 214 | warning (_("Compiled module \"%s\" section \"%s\": warning: %s"), |
fd361982 | 215 | bfd_get_filename (abfd), bfd_section_name (section), |
bb2ec1b3 | 216 | xwarning); |
bb2ec1b3 TT |
217 | } |
218 | ||
219 | /* Helper for link_callbacks callbacks vector. */ | |
220 | ||
1a72702b | 221 | static void |
bb2ec1b3 TT |
222 | link_callbacks_undefined_symbol (struct bfd_link_info *link_info, |
223 | const char *name, bfd *abfd, asection *section, | |
224 | bfd_vma address, bfd_boolean is_fatal) | |
225 | { | |
226 | warning (_("Cannot resolve relocation to \"%s\" " | |
227 | "from compiled module \"%s\" section \"%s\"."), | |
fd361982 | 228 | name, bfd_get_filename (abfd), bfd_section_name (section)); |
bb2ec1b3 TT |
229 | } |
230 | ||
231 | /* Helper for link_callbacks callbacks vector. */ | |
232 | ||
1a72702b | 233 | static void |
bb2ec1b3 TT |
234 | link_callbacks_reloc_overflow (struct bfd_link_info *link_info, |
235 | struct bfd_link_hash_entry *entry, | |
236 | const char *name, const char *reloc_name, | |
237 | bfd_vma addend, bfd *abfd, asection *section, | |
238 | bfd_vma address) | |
239 | { | |
bb2ec1b3 TT |
240 | } |
241 | ||
242 | /* Helper for link_callbacks callbacks vector. */ | |
243 | ||
1a72702b | 244 | static void |
bb2ec1b3 TT |
245 | link_callbacks_reloc_dangerous (struct bfd_link_info *link_info, |
246 | const char *message, bfd *abfd, | |
247 | asection *section, bfd_vma address) | |
248 | { | |
249 | warning (_("Compiled module \"%s\" section \"%s\": dangerous " | |
250 | "relocation: %s\n"), | |
fd361982 | 251 | bfd_get_filename (abfd), bfd_section_name (section), |
bb2ec1b3 | 252 | message); |
bb2ec1b3 TT |
253 | } |
254 | ||
255 | /* Helper for link_callbacks callbacks vector. */ | |
256 | ||
1a72702b | 257 | static void |
bb2ec1b3 TT |
258 | link_callbacks_unattached_reloc (struct bfd_link_info *link_info, |
259 | const char *name, bfd *abfd, asection *section, | |
260 | bfd_vma address) | |
261 | { | |
262 | warning (_("Compiled module \"%s\" section \"%s\": unattached " | |
263 | "relocation: %s\n"), | |
fd361982 | 264 | bfd_get_filename (abfd), bfd_section_name (section), |
bb2ec1b3 | 265 | name); |
bb2ec1b3 TT |
266 | } |
267 | ||
268 | /* Helper for link_callbacks callbacks vector. */ | |
269 | ||
77b64a49 PA |
270 | static void link_callbacks_einfo (const char *fmt, ...) |
271 | ATTRIBUTE_PRINTF (1, 2); | |
272 | ||
bb2ec1b3 TT |
273 | static void |
274 | link_callbacks_einfo (const char *fmt, ...) | |
275 | { | |
bb2ec1b3 | 276 | va_list ap; |
bb2ec1b3 TT |
277 | |
278 | va_start (ap, fmt); | |
20dcd8ca | 279 | std::string str = string_vprintf (fmt, ap); |
bb2ec1b3 | 280 | va_end (ap); |
bb2ec1b3 | 281 | |
20dcd8ca | 282 | warning (_("Compile module: warning: %s"), str.c_str ()); |
bb2ec1b3 TT |
283 | } |
284 | ||
285 | /* Helper for bfd_get_relocated_section_contents. | |
286 | Only these symbols are set by bfd_simple_get_relocated_section_contents | |
287 | but bfd/ seems to use even the NULL ones without checking them first. */ | |
288 | ||
289 | static const struct bfd_link_callbacks link_callbacks = | |
290 | { | |
291 | NULL, /* add_archive_element */ | |
292 | link_callbacks_multiple_definition, /* multiple_definition */ | |
293 | NULL, /* multiple_common */ | |
294 | NULL, /* add_to_set */ | |
295 | NULL, /* constructor */ | |
296 | link_callbacks_warning, /* warning */ | |
297 | link_callbacks_undefined_symbol, /* undefined_symbol */ | |
298 | link_callbacks_reloc_overflow, /* reloc_overflow */ | |
299 | link_callbacks_reloc_dangerous, /* reloc_dangerous */ | |
300 | link_callbacks_unattached_reloc, /* unattached_reloc */ | |
301 | NULL, /* notice */ | |
302 | link_callbacks_einfo, /* einfo */ | |
303 | NULL, /* info */ | |
304 | NULL, /* minfo */ | |
305 | NULL, /* override_segment_assignment */ | |
306 | }; | |
307 | ||
308 | struct link_hash_table_cleanup_data | |
309 | { | |
40f03055 TT |
310 | explicit link_hash_table_cleanup_data (bfd *abfd_) |
311 | : abfd (abfd_), | |
312 | link_next (abfd->link.next) | |
313 | { | |
314 | } | |
bb2ec1b3 | 315 | |
40f03055 TT |
316 | ~link_hash_table_cleanup_data () |
317 | { | |
318 | if (abfd->is_linker_output) | |
319 | (*abfd->link.hash->hash_table_free) (abfd); | |
320 | abfd->link.next = link_next; | |
321 | } | |
bb2ec1b3 | 322 | |
40f03055 | 323 | DISABLE_COPY_AND_ASSIGN (link_hash_table_cleanup_data); |
bb2ec1b3 | 324 | |
40f03055 TT |
325 | private: |
326 | ||
327 | bfd *abfd; | |
328 | bfd *link_next; | |
329 | }; | |
bb2ec1b3 TT |
330 | |
331 | /* Relocate and store into inferior memory each section SECT of ABFD. */ | |
332 | ||
333 | static void | |
334 | copy_sections (bfd *abfd, asection *sect, void *data) | |
335 | { | |
9a3c8263 | 336 | asymbol **symbol_table = (asymbol **) data; |
40f03055 | 337 | bfd_byte *sect_data_got; |
bb2ec1b3 TT |
338 | struct bfd_link_info link_info; |
339 | struct bfd_link_order link_order; | |
340 | CORE_ADDR inferior_addr; | |
bb2ec1b3 | 341 | |
fd361982 | 342 | if ((bfd_section_flags (sect) & (SEC_ALLOC | SEC_LOAD)) |
bb2ec1b3 TT |
343 | != (SEC_ALLOC | SEC_LOAD)) |
344 | return; | |
345 | ||
fd361982 | 346 | if (bfd_section_size (sect) == 0) |
bb2ec1b3 TT |
347 | return; |
348 | ||
349 | /* Mostly a copy of bfd_simple_get_relocated_section_contents which GDB | |
350 | cannot use as it does not report relocations to undefined symbols. */ | |
351 | memset (&link_info, 0, sizeof (link_info)); | |
352 | link_info.output_bfd = abfd; | |
353 | link_info.input_bfds = abfd; | |
354 | link_info.input_bfds_tail = &abfd->link.next; | |
355 | ||
40f03055 | 356 | struct link_hash_table_cleanup_data cleanup_data (abfd); |
bb2ec1b3 TT |
357 | |
358 | abfd->link.next = NULL; | |
359 | link_info.hash = bfd_link_hash_table_create (abfd); | |
360 | ||
bb2ec1b3 TT |
361 | link_info.callbacks = &link_callbacks; |
362 | ||
363 | memset (&link_order, 0, sizeof (link_order)); | |
364 | link_order.next = NULL; | |
365 | link_order.type = bfd_indirect_link_order; | |
366 | link_order.offset = 0; | |
fd361982 | 367 | link_order.size = bfd_section_size (sect); |
bb2ec1b3 TT |
368 | link_order.u.indirect.section = sect; |
369 | ||
40f03055 | 370 | gdb::unique_xmalloc_ptr<gdb_byte> sect_data |
fd361982 | 371 | ((bfd_byte *) xmalloc (bfd_section_size (sect))); |
bb2ec1b3 TT |
372 | |
373 | sect_data_got = bfd_get_relocated_section_contents (abfd, &link_info, | |
40f03055 TT |
374 | &link_order, |
375 | sect_data.get (), | |
bb2ec1b3 TT |
376 | FALSE, symbol_table); |
377 | ||
378 | if (sect_data_got == NULL) | |
379 | error (_("Cannot map compiled module \"%s\" section \"%s\": %s"), | |
fd361982 | 380 | bfd_get_filename (abfd), bfd_section_name (sect), |
bb2ec1b3 | 381 | bfd_errmsg (bfd_get_error ())); |
40f03055 | 382 | gdb_assert (sect_data_got == sect_data.get ()); |
bb2ec1b3 | 383 | |
fd361982 | 384 | inferior_addr = bfd_section_vma (sect); |
40f03055 | 385 | if (0 != target_write_memory (inferior_addr, sect_data.get (), |
fd361982 | 386 | bfd_section_size (sect))) |
bb2ec1b3 TT |
387 | error (_("Cannot write compiled module \"%s\" section \"%s\" " |
388 | "to inferior memory range %s-%s."), | |
fd361982 | 389 | bfd_get_filename (abfd), bfd_section_name (sect), |
bb2ec1b3 TT |
390 | paddress (target_gdbarch (), inferior_addr), |
391 | paddress (target_gdbarch (), | |
fd361982 | 392 | inferior_addr + bfd_section_size (sect))); |
bb2ec1b3 TT |
393 | } |
394 | ||
36de76f9 JK |
395 | /* Fetch the type of COMPILE_I_EXPR_PTR_TYPE and COMPILE_I_EXPR_VAL |
396 | symbols in OBJFILE so we can calculate how much memory to allocate | |
397 | for the out parameter. This avoids needing a malloc in the generated | |
398 | code. Throw an error if anything fails. | |
399 | GDB first tries to compile the code with COMPILE_I_PRINT_ADDRESS_SCOPE. | |
400 | If it finds user tries to print an array type this function returns | |
401 | NULL. Caller will then regenerate the code with | |
402 | COMPILE_I_PRINT_VALUE_SCOPE, recompiles it again and finally runs it. | |
403 | This is because __auto_type array-to-pointer type conversion of | |
404 | COMPILE_I_EXPR_VAL which gets detected by COMPILE_I_EXPR_PTR_TYPE | |
405 | preserving the array type. */ | |
406 | ||
407 | static struct type * | |
408 | get_out_value_type (struct symbol *func_sym, struct objfile *objfile, | |
409 | enum compile_i_scope_types scope) | |
410 | { | |
d976bace JK |
411 | struct symbol *gdb_ptr_type_sym; |
412 | /* Initialize it just to avoid a GCC false warning. */ | |
413 | struct symbol *gdb_val_sym = NULL; | |
4d18dfad | 414 | struct type *gdb_ptr_type, *gdb_type_from_ptr, *gdb_type, *retval; |
d976bace JK |
415 | /* Initialize it just to avoid a GCC false warning. */ |
416 | const struct block *block = NULL; | |
36de76f9 JK |
417 | const struct blockvector *bv; |
418 | int nblocks = 0; | |
419 | int block_loop = 0; | |
420 | ||
bcfe6157 TT |
421 | lookup_name_info func_matcher (GCC_FE_WRAPPER_FUNCTION, |
422 | symbol_name_match_type::SEARCH_NAME); | |
423 | ||
4206d69e | 424 | bv = func_sym->symtab ()->compunit ()->blockvector (); |
63d609de | 425 | nblocks = bv->num_blocks (); |
36de76f9 JK |
426 | |
427 | gdb_ptr_type_sym = NULL; | |
428 | for (block_loop = 0; block_loop < nblocks; block_loop++) | |
429 | { | |
d976bace | 430 | struct symbol *function = NULL; |
36de76f9 JK |
431 | const struct block *function_block; |
432 | ||
63d609de | 433 | block = bv->block (block_loop); |
6c00f721 | 434 | if (block->function () != NULL) |
36de76f9 | 435 | continue; |
de63c46b PA |
436 | gdb_val_sym = block_lookup_symbol (block, |
437 | COMPILE_I_EXPR_VAL, | |
438 | symbol_name_match_type::SEARCH_NAME, | |
439 | VAR_DOMAIN); | |
36de76f9 JK |
440 | if (gdb_val_sym == NULL) |
441 | continue; | |
442 | ||
443 | function_block = block; | |
63d609de SM |
444 | while (function_block != bv->static_block () |
445 | && function_block != bv->global_block ()) | |
36de76f9 | 446 | { |
f135fe72 | 447 | function_block = function_block->superblock (); |
6c00f721 | 448 | function = function_block->function (); |
36de76f9 JK |
449 | if (function != NULL) |
450 | break; | |
451 | } | |
452 | if (function != NULL | |
63d609de | 453 | && function_block->superblock () == bv->static_block () |
bcfe6157 | 454 | && symbol_matches_search_name (function, func_matcher)) |
36de76f9 JK |
455 | break; |
456 | } | |
457 | if (block_loop == nblocks) | |
33aa3c10 | 458 | error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_VAL); |
36de76f9 | 459 | |
5f9c5a63 | 460 | gdb_type = gdb_val_sym->type (); |
f168693b | 461 | gdb_type = check_typedef (gdb_type); |
36de76f9 JK |
462 | |
463 | gdb_ptr_type_sym = block_lookup_symbol (block, COMPILE_I_EXPR_PTR_TYPE, | |
de63c46b | 464 | symbol_name_match_type::SEARCH_NAME, |
36de76f9 JK |
465 | VAR_DOMAIN); |
466 | if (gdb_ptr_type_sym == NULL) | |
467 | error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE); | |
5f9c5a63 | 468 | gdb_ptr_type = gdb_ptr_type_sym->type (); |
f168693b | 469 | gdb_ptr_type = check_typedef (gdb_ptr_type); |
78134374 | 470 | if (gdb_ptr_type->code () != TYPE_CODE_PTR) |
36de76f9 | 471 | error (_("Type of \"%s\" is not a pointer"), COMPILE_I_EXPR_PTR_TYPE); |
27710edb | 472 | gdb_type_from_ptr = check_typedef (gdb_ptr_type->target_type ()); |
36de76f9 JK |
473 | |
474 | if (types_deeply_equal (gdb_type, gdb_type_from_ptr)) | |
475 | { | |
476 | if (scope != COMPILE_I_PRINT_ADDRESS_SCOPE) | |
477 | error (_("Expected address scope in compiled module \"%s\"."), | |
478 | objfile_name (objfile)); | |
479 | return gdb_type; | |
480 | } | |
481 | ||
78134374 | 482 | if (gdb_type->code () != TYPE_CODE_PTR) |
36de76f9 JK |
483 | error (_("Invalid type code %d of symbol \"%s\" " |
484 | "in compiled module \"%s\"."), | |
78134374 | 485 | gdb_type_from_ptr->code (), COMPILE_I_EXPR_VAL, |
36de76f9 JK |
486 | objfile_name (objfile)); |
487 | ||
4d18dfad | 488 | retval = gdb_type_from_ptr; |
78134374 | 489 | switch (gdb_type_from_ptr->code ()) |
36de76f9 JK |
490 | { |
491 | case TYPE_CODE_ARRAY: | |
27710edb | 492 | gdb_type_from_ptr = gdb_type_from_ptr->target_type (); |
36de76f9 JK |
493 | break; |
494 | case TYPE_CODE_FUNC: | |
495 | break; | |
496 | default: | |
497 | error (_("Invalid type code %d of symbol \"%s\" " | |
498 | "in compiled module \"%s\"."), | |
78134374 | 499 | gdb_type_from_ptr->code (), COMPILE_I_EXPR_PTR_TYPE, |
36de76f9 JK |
500 | objfile_name (objfile)); |
501 | } | |
502 | if (!types_deeply_equal (gdb_type_from_ptr, | |
27710edb | 503 | gdb_type->target_type ())) |
36de76f9 JK |
504 | error (_("Referenced types do not match for symbols \"%s\" and \"%s\" " |
505 | "in compiled module \"%s\"."), | |
506 | COMPILE_I_EXPR_PTR_TYPE, COMPILE_I_EXPR_VAL, | |
507 | objfile_name (objfile)); | |
508 | if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE) | |
509 | return NULL; | |
4d18dfad | 510 | return retval; |
36de76f9 JK |
511 | } |
512 | ||
83d3415e JK |
513 | /* Fetch the type of first parameter of FUNC_SYM. |
514 | Return NULL if FUNC_SYM has no parameters. Throw an error otherwise. */ | |
bb2ec1b3 TT |
515 | |
516 | static struct type * | |
83d3415e | 517 | get_regs_type (struct symbol *func_sym, struct objfile *objfile) |
bb2ec1b3 | 518 | { |
5f9c5a63 | 519 | struct type *func_type = func_sym->type (); |
83d3415e | 520 | struct type *regsp_type, *regs_type; |
bb2ec1b3 TT |
521 | |
522 | /* No register parameter present. */ | |
1f704f76 | 523 | if (func_type->num_fields () == 0) |
bb2ec1b3 TT |
524 | return NULL; |
525 | ||
940da03e | 526 | regsp_type = check_typedef (func_type->field (0).type ()); |
78134374 | 527 | if (regsp_type->code () != TYPE_CODE_PTR) |
bb2ec1b3 TT |
528 | error (_("Invalid type code %d of first parameter of function \"%s\" " |
529 | "in compiled module \"%s\"."), | |
78134374 | 530 | regsp_type->code (), GCC_FE_WRAPPER_FUNCTION, |
bb2ec1b3 TT |
531 | objfile_name (objfile)); |
532 | ||
27710edb | 533 | regs_type = check_typedef (regsp_type->target_type ()); |
78134374 | 534 | if (regs_type->code () != TYPE_CODE_STRUCT) |
bb2ec1b3 TT |
535 | error (_("Invalid type code %d of dereferenced first parameter " |
536 | "of function \"%s\" in compiled module \"%s\"."), | |
78134374 | 537 | regs_type->code (), GCC_FE_WRAPPER_FUNCTION, |
bb2ec1b3 TT |
538 | objfile_name (objfile)); |
539 | ||
540 | return regs_type; | |
541 | } | |
542 | ||
543 | /* Store all inferior registers required by REGS_TYPE to inferior memory | |
544 | starting at inferior address REGS_BASE. */ | |
545 | ||
546 | static void | |
547 | store_regs (struct type *regs_type, CORE_ADDR regs_base) | |
548 | { | |
549 | struct gdbarch *gdbarch = target_gdbarch (); | |
bb2ec1b3 TT |
550 | int fieldno; |
551 | ||
1f704f76 | 552 | for (fieldno = 0; fieldno < regs_type->num_fields (); fieldno++) |
bb2ec1b3 | 553 | { |
33d16dd9 | 554 | const char *reg_name = regs_type->field (fieldno).name (); |
b610c045 | 555 | ULONGEST reg_bitpos = regs_type->field (fieldno).loc_bitpos (); |
bb2ec1b3 TT |
556 | ULONGEST reg_bitsize = TYPE_FIELD_BITSIZE (regs_type, fieldno); |
557 | ULONGEST reg_offset; | |
940da03e SM |
558 | struct type *reg_type |
559 | = check_typedef (regs_type->field (fieldno).type ()); | |
df86565b | 560 | ULONGEST reg_size = reg_type->length (); |
bb2ec1b3 TT |
561 | int regnum; |
562 | struct value *regval; | |
563 | CORE_ADDR inferior_addr; | |
564 | ||
565 | if (strcmp (reg_name, COMPILE_I_SIMPLE_REGISTER_DUMMY) == 0) | |
566 | continue; | |
567 | ||
568 | if ((reg_bitpos % 8) != 0 || reg_bitsize != 0) | |
569 | error (_("Invalid register \"%s\" position %s bits or size %s bits"), | |
570 | reg_name, pulongest (reg_bitpos), pulongest (reg_bitsize)); | |
571 | reg_offset = reg_bitpos / 8; | |
572 | ||
78134374 SM |
573 | if (reg_type->code () != TYPE_CODE_INT |
574 | && reg_type->code () != TYPE_CODE_PTR) | |
bb2ec1b3 | 575 | error (_("Invalid register \"%s\" type code %d"), reg_name, |
78134374 | 576 | reg_type->code ()); |
bb2ec1b3 TT |
577 | |
578 | regnum = compile_register_name_demangle (gdbarch, reg_name); | |
579 | ||
580 | regval = value_from_register (reg_type, regnum, get_current_frame ()); | |
581 | if (value_optimized_out (regval)) | |
582 | error (_("Register \"%s\" is optimized out."), reg_name); | |
583 | if (!value_entirely_available (regval)) | |
584 | error (_("Register \"%s\" is not available."), reg_name); | |
585 | ||
586 | inferior_addr = regs_base + reg_offset; | |
50888e42 SM |
587 | if (0 != target_write_memory (inferior_addr, |
588 | value_contents (regval).data (), | |
bb2ec1b3 TT |
589 | reg_size)) |
590 | error (_("Cannot write register \"%s\" to inferior memory at %s."), | |
591 | reg_name, paddress (gdbarch, inferior_addr)); | |
592 | } | |
593 | } | |
594 | ||
aaee65ae PA |
595 | /* Load the object file specified in FILE_NAMES into inferior memory. |
596 | Throw an error otherwise. Caller must fully dispose the return | |
597 | value by calling compile_object_run. Returns NULL only for | |
598 | COMPILE_I_PRINT_ADDRESS_SCOPE when COMPILE_I_PRINT_VALUE_SCOPE | |
599 | should have been used instead. */ | |
bb2ec1b3 | 600 | |
e947a848 | 601 | compile_module_up |
aaee65ae | 602 | compile_object_load (const compile_file_names &file_names, |
5c65b58a | 603 | enum compile_i_scope_types scope, void *scope_data) |
bb2ec1b3 | 604 | { |
798a7429 | 605 | CORE_ADDR regs_addr, out_value_addr = 0; |
83d3415e JK |
606 | struct symbol *func_sym; |
607 | struct type *func_type; | |
bb2ec1b3 TT |
608 | struct bound_minimal_symbol bmsym; |
609 | long storage_needed; | |
610 | asymbol **symbol_table, **symp; | |
611 | long number_of_symbols, missing_symbols; | |
36de76f9 | 612 | struct type *regs_type, *out_value_type = NULL; |
ee0c3293 | 613 | char **matching; |
bb2ec1b3 | 614 | struct objfile *objfile; |
83d3415e JK |
615 | int expect_parameters; |
616 | struct type *expect_return_type; | |
bb2ec1b3 | 617 | |
ee0c3293 TT |
618 | gdb::unique_xmalloc_ptr<char> filename |
619 | (tilde_expand (file_names.object_file ())); | |
bb2ec1b3 | 620 | |
ad80db5b | 621 | gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename.get (), gnutarget)); |
bb2ec1b3 TT |
622 | if (abfd == NULL) |
623 | error (_("\"%s\": could not open as compiled module: %s"), | |
dda83cd7 | 624 | filename.get (), bfd_errmsg (bfd_get_error ())); |
bb2ec1b3 | 625 | |
192b62ce | 626 | if (!bfd_check_format_matches (abfd.get (), bfd_object, &matching)) |
bb2ec1b3 | 627 | error (_("\"%s\": not in loadable format: %s"), |
803c08d0 TT |
628 | filename.get (), |
629 | gdb_bfd_errmsg (bfd_get_error (), matching).c_str ()); | |
bb2ec1b3 | 630 | |
192b62ce | 631 | if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0) |
ee0c3293 | 632 | error (_("\"%s\": not in object format."), filename.get ()); |
bb2ec1b3 | 633 | |
92677124 TT |
634 | struct setup_sections_data setup_sections_data (abfd.get ()); |
635 | for (asection *sect = abfd->sections; sect != nullptr; sect = sect->next) | |
636 | setup_sections_data.setup_one_section (sect); | |
637 | setup_sections_data.setup_one_section (nullptr); | |
bb2ec1b3 | 638 | |
192b62ce | 639 | storage_needed = bfd_get_symtab_upper_bound (abfd.get ()); |
bb2ec1b3 TT |
640 | if (storage_needed < 0) |
641 | error (_("Cannot read symbols of compiled module \"%s\": %s"), | |
c9e0a7e3 | 642 | filename.get (), bfd_errmsg (bfd_get_error ())); |
bb2ec1b3 TT |
643 | |
644 | /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in | |
645 | "Reading symbols from ..." message for automatically generated file. */ | |
98badbfd | 646 | objfile_up objfile_holder (symbol_file_add_from_bfd (abfd, |
268e4f09 TT |
647 | filename.get (), |
648 | 0, NULL, 0, NULL)); | |
ed2b3126 | 649 | objfile = objfile_holder.get (); |
bb2ec1b3 | 650 | |
83d3415e | 651 | func_sym = lookup_global_symbol_from_objfile (objfile, |
442853af | 652 | GLOBAL_BLOCK, |
83d3415e | 653 | GCC_FE_WRAPPER_FUNCTION, |
d12307c1 | 654 | VAR_DOMAIN).symbol; |
83d3415e JK |
655 | if (func_sym == NULL) |
656 | error (_("Cannot find function \"%s\" in compiled module \"%s\"."), | |
657 | GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); | |
5f9c5a63 | 658 | func_type = func_sym->type (); |
78134374 | 659 | if (func_type->code () != TYPE_CODE_FUNC) |
83d3415e JK |
660 | error (_("Invalid type code %d of function \"%s\" in compiled " |
661 | "module \"%s\"."), | |
78134374 | 662 | func_type->code (), GCC_FE_WRAPPER_FUNCTION, |
83d3415e JK |
663 | objfile_name (objfile)); |
664 | ||
665 | switch (scope) | |
666 | { | |
667 | case COMPILE_I_SIMPLE_SCOPE: | |
668 | expect_parameters = 1; | |
669 | expect_return_type = builtin_type (target_gdbarch ())->builtin_void; | |
670 | break; | |
671 | case COMPILE_I_RAW_SCOPE: | |
672 | expect_parameters = 0; | |
673 | expect_return_type = builtin_type (target_gdbarch ())->builtin_void; | |
674 | break; | |
36de76f9 JK |
675 | case COMPILE_I_PRINT_ADDRESS_SCOPE: |
676 | case COMPILE_I_PRINT_VALUE_SCOPE: | |
677 | expect_parameters = 2; | |
678 | expect_return_type = builtin_type (target_gdbarch ())->builtin_void; | |
679 | break; | |
83d3415e | 680 | default: |
f34652de | 681 | internal_error (_("invalid scope %d"), scope); |
83d3415e | 682 | } |
1f704f76 | 683 | if (func_type->num_fields () != expect_parameters) |
83d3415e JK |
684 | error (_("Invalid %d parameters of function \"%s\" in compiled " |
685 | "module \"%s\"."), | |
1f704f76 | 686 | func_type->num_fields (), GCC_FE_WRAPPER_FUNCTION, |
83d3415e | 687 | objfile_name (objfile)); |
27710edb | 688 | if (!types_deeply_equal (expect_return_type, func_type->target_type ())) |
83d3415e | 689 | error (_("Invalid return type of function \"%s\" in compiled " |
c9e0a7e3 TT |
690 | "module \"%s\"."), |
691 | GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); | |
bb2ec1b3 TT |
692 | |
693 | /* The memory may be later needed | |
694 | by bfd_generic_get_relocated_section_contents | |
695 | called from default_symfile_relocate. */ | |
224c3ddb SM |
696 | symbol_table = (asymbol **) obstack_alloc (&objfile->objfile_obstack, |
697 | storage_needed); | |
192b62ce | 698 | number_of_symbols = bfd_canonicalize_symtab (abfd.get (), symbol_table); |
bb2ec1b3 TT |
699 | if (number_of_symbols < 0) |
700 | error (_("Cannot parse symbols of compiled module \"%s\": %s"), | |
c9e0a7e3 | 701 | filename.get (), bfd_errmsg (bfd_get_error ())); |
bb2ec1b3 TT |
702 | |
703 | missing_symbols = 0; | |
704 | for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++) | |
705 | { | |
706 | asymbol *sym = *symp; | |
707 | ||
708 | if (sym->flags != 0) | |
709 | continue; | |
bb2ec1b3 TT |
710 | sym->flags = BSF_GLOBAL; |
711 | sym->section = bfd_abs_section_ptr; | |
712 | if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0) | |
713 | { | |
b0fd6b30 | 714 | if (compile_debug) |
6cb06a8c TT |
715 | gdb_printf (gdb_stdlog, |
716 | "ELF symbol \"%s\" relocated to zero\n", | |
717 | sym->name); | |
b0fd6b30 JK |
718 | |
719 | /* It seems to be a GCC bug, with -mcmodel=large there should be no | |
720 | need for _GLOBAL_OFFSET_TABLE_. Together with -fPIE the data | |
721 | remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero. */ | |
bb2ec1b3 TT |
722 | sym->value = 0; |
723 | continue; | |
724 | } | |
bad23de3 WS |
725 | if (strcmp (sym->name, ".TOC.") == 0) |
726 | { | |
727 | /* Handle the .TOC. symbol as the linker would do. Set the .TOC. | |
728 | sections value to 0x8000 (see bfd/elf64-ppc.c TOC_BASE_OFF); | |
729 | point the symbol section at the ".toc" section; | |
730 | and pass the toc->vma value into bfd_set_gp_value(). | |
731 | If the .toc section is not found, use the first section | |
732 | with the SEC_ALLOC flag set. In the unlikely case that | |
733 | we still do not have a section identified, fall back to using | |
734 | the "*ABS*" section. */ | |
735 | asection *toc_fallback = bfd_get_section_by_name(abfd.get(), ".toc"); | |
736 | if (toc_fallback == NULL) | |
737 | { | |
738 | for (asection *tsect = abfd->sections; tsect != nullptr; | |
739 | tsect = tsect->next) | |
740 | { | |
741 | if (bfd_section_flags (tsect) & SEC_ALLOC) | |
742 | { | |
743 | toc_fallback = tsect; | |
744 | break; | |
745 | } | |
746 | } | |
747 | } | |
748 | ||
749 | if (toc_fallback == NULL) | |
750 | /* If we've gotten here, we have not found a section usable | |
751 | as a backup for the .toc section. In this case, use the | |
752 | absolute (*ABS*) section. */ | |
753 | toc_fallback = bfd_abs_section_ptr; | |
754 | ||
755 | sym->section = toc_fallback; | |
756 | sym->value = 0x8000; | |
757 | bfd_set_gp_value(abfd.get(), toc_fallback->vma); | |
758 | if (compile_debug) | |
6cb06a8c TT |
759 | gdb_printf (gdb_stdlog, |
760 | "Connectiong ELF symbol \"%s\" to the .toc section (%s)\n", | |
761 | sym->name, | |
762 | paddress (target_gdbarch (), sym->value)); | |
bad23de3 WS |
763 | continue; |
764 | } | |
765 | ||
bb2ec1b3 TT |
766 | bmsym = lookup_minimal_symbol (sym->name, NULL, NULL); |
767 | switch (bmsym.minsym == NULL | |
60f62e2b | 768 | ? mst_unknown : bmsym.minsym->type ()) |
bb2ec1b3 TT |
769 | { |
770 | case mst_text: | |
078a0207 KS |
771 | case mst_bss: |
772 | case mst_data: | |
4aeddc50 | 773 | sym->value = bmsym.value_address (); |
b0fd6b30 | 774 | if (compile_debug) |
6cb06a8c TT |
775 | gdb_printf (gdb_stdlog, |
776 | "ELF mst_text symbol \"%s\" relocated to %s\n", | |
777 | sym->name, | |
778 | paddress (target_gdbarch (), sym->value)); | |
bb2ec1b3 | 779 | break; |
e26efa40 JK |
780 | case mst_text_gnu_ifunc: |
781 | sym->value = gnu_ifunc_resolve_addr (target_gdbarch (), | |
4aeddc50 | 782 | bmsym.value_address ()); |
b0fd6b30 | 783 | if (compile_debug) |
6cb06a8c TT |
784 | gdb_printf (gdb_stdlog, |
785 | "ELF mst_text_gnu_ifunc symbol \"%s\" " | |
786 | "relocated to %s\n", | |
787 | sym->name, | |
788 | paddress (target_gdbarch (), sym->value)); | |
e26efa40 | 789 | break; |
bb2ec1b3 TT |
790 | default: |
791 | warning (_("Could not find symbol \"%s\" " | |
792 | "for compiled module \"%s\"."), | |
ee0c3293 | 793 | sym->name, filename.get ()); |
bb2ec1b3 TT |
794 | missing_symbols++; |
795 | } | |
796 | } | |
797 | if (missing_symbols) | |
798 | error (_("%ld symbols were missing, cannot continue."), missing_symbols); | |
799 | ||
192b62ce | 800 | bfd_map_over_sections (abfd.get (), copy_sections, symbol_table); |
bb2ec1b3 | 801 | |
83d3415e | 802 | regs_type = get_regs_type (func_sym, objfile); |
bb2ec1b3 TT |
803 | if (regs_type == NULL) |
804 | regs_addr = 0; | |
805 | else | |
806 | { | |
807 | /* Use read-only non-executable memory protection. */ | |
808 | regs_addr = gdbarch_infcall_mmap (target_gdbarch (), | |
df86565b | 809 | regs_type->length (), |
bb2ec1b3 TT |
810 | GDB_MMAP_PROT_READ); |
811 | gdb_assert (regs_addr != 0); | |
df86565b | 812 | setup_sections_data.munmap_list.add (regs_addr, regs_type->length ()); |
b6de3f96 | 813 | if (compile_debug) |
6cb06a8c TT |
814 | gdb_printf (gdb_stdlog, |
815 | "allocated %s bytes at %s for registers\n", | |
816 | paddress (target_gdbarch (), | |
df86565b | 817 | regs_type->length ()), |
6cb06a8c | 818 | paddress (target_gdbarch (), regs_addr)); |
bb2ec1b3 TT |
819 | store_regs (regs_type, regs_addr); |
820 | } | |
821 | ||
36de76f9 JK |
822 | if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE |
823 | || scope == COMPILE_I_PRINT_VALUE_SCOPE) | |
824 | { | |
825 | out_value_type = get_out_value_type (func_sym, objfile, scope); | |
826 | if (out_value_type == NULL) | |
c9e0a7e3 | 827 | return NULL; |
36de76f9 JK |
828 | check_typedef (out_value_type); |
829 | out_value_addr = gdbarch_infcall_mmap (target_gdbarch (), | |
df86565b | 830 | out_value_type->length (), |
36de76f9 JK |
831 | (GDB_MMAP_PROT_READ |
832 | | GDB_MMAP_PROT_WRITE)); | |
833 | gdb_assert (out_value_addr != 0); | |
92677124 | 834 | setup_sections_data.munmap_list.add (out_value_addr, |
df86565b | 835 | out_value_type->length ()); |
36de76f9 | 836 | if (compile_debug) |
6cb06a8c TT |
837 | gdb_printf (gdb_stdlog, |
838 | "allocated %s bytes at %s for printed value\n", | |
839 | paddress (target_gdbarch (), | |
df86565b | 840 | out_value_type->length ()), |
6cb06a8c | 841 | paddress (target_gdbarch (), out_value_addr)); |
36de76f9 JK |
842 | } |
843 | ||
e947a848 | 844 | compile_module_up retval (new struct compile_module); |
ed2b3126 | 845 | retval->objfile = objfile_holder.release (); |
92677124 | 846 | retval->source_file = file_names.source_file (); |
83d3415e | 847 | retval->func_sym = func_sym; |
bb2ec1b3 | 848 | retval->regs_addr = regs_addr; |
5c65b58a JK |
849 | retval->scope = scope; |
850 | retval->scope_data = scope_data; | |
36de76f9 JK |
851 | retval->out_value_type = out_value_type; |
852 | retval->out_value_addr = out_value_addr; | |
92677124 | 853 | retval->munmap_list = std::move (setup_sections_data.munmap_list); |
7f361056 | 854 | |
bb2ec1b3 TT |
855 | return retval; |
856 | } |