Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Call module for 'compile' command. |
2 | ||
88b9d363 | 3 | Copyright (C) 2014-2022 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-run.h" | |
22 | #include "value.h" | |
23 | #include "infcall.h" | |
24 | #include "objfiles.h" | |
25 | #include "compile-internal.h" | |
26 | #include "dummy-frame.h" | |
83d3415e | 27 | #include "block.h" |
36de76f9 JK |
28 | #include "valprint.h" |
29 | #include "compile.h" | |
bb2ec1b3 TT |
30 | |
31 | /* Helper for do_module_cleanup. */ | |
32 | ||
33 | struct do_module_cleanup | |
34 | { | |
e616f60a TT |
35 | do_module_cleanup (int *ptr, compile_module_up &&mod) |
36 | : executedp (ptr), | |
37 | module (std::move (mod)) | |
38 | { | |
39 | } | |
0dbf6ee6 | 40 | |
0dbf6ee6 TT |
41 | DISABLE_COPY_AND_ASSIGN (do_module_cleanup); |
42 | ||
bb2ec1b3 TT |
43 | /* Boolean to set true upon a call of do_module_cleanup. |
44 | The pointer may be NULL. */ | |
45 | int *executedp; | |
46 | ||
e616f60a TT |
47 | /* The compile module. */ |
48 | compile_module_up module; | |
bb2ec1b3 TT |
49 | }; |
50 | ||
51 | /* Cleanup everything after the inferior function dummy frame gets | |
52 | discarded. */ | |
53 | ||
54 | static dummy_frame_dtor_ftype do_module_cleanup; | |
55 | static void | |
5e970501 | 56 | do_module_cleanup (void *arg, int registers_valid) |
bb2ec1b3 | 57 | { |
9a3c8263 | 58 | struct do_module_cleanup *data = (struct do_module_cleanup *) arg; |
bb2ec1b3 TT |
59 | |
60 | if (data->executedp != NULL) | |
36de76f9 JK |
61 | { |
62 | *data->executedp = 1; | |
63 | ||
64 | /* This code cannot be in compile_object_run as OUT_VALUE_TYPE | |
65 | no longer exists there. */ | |
e616f60a TT |
66 | if (data->module->scope == COMPILE_I_PRINT_ADDRESS_SCOPE |
67 | || data->module->scope == COMPILE_I_PRINT_VALUE_SCOPE) | |
36de76f9 JK |
68 | { |
69 | struct value *addr_value; | |
e616f60a TT |
70 | struct type *ptr_type |
71 | = lookup_pointer_type (data->module->out_value_type); | |
36de76f9 | 72 | |
e616f60a TT |
73 | addr_value = value_from_pointer (ptr_type, |
74 | data->module->out_value_addr); | |
36de76f9 | 75 | |
30baf67b | 76 | /* SCOPE_DATA would be stale unless EXECUTEDP != NULL. */ |
e616f60a TT |
77 | compile_print_value (value_ind (addr_value), |
78 | data->module->scope_data); | |
36de76f9 JK |
79 | } |
80 | } | |
bb2ec1b3 | 81 | |
e616f60a TT |
82 | /* We have to make a copy of the name so that we can unlink the |
83 | underlying file -- removing the objfile will cause the name to be | |
84 | freed, so we can't simply keep a reference to it. */ | |
85 | std::string objfile_name_s = objfile_name (data->module->objfile); | |
2030c079 | 86 | for (objfile *objfile : current_program_space->objfiles ()) |
bb2ec1b3 | 87 | if ((objfile->flags & OBJF_USERLOADED) == 0 |
e616f60a | 88 | && objfile_name_s == objfile_name (objfile)) |
bb2ec1b3 | 89 | { |
268e4f09 | 90 | objfile->unlink (); |
bb2ec1b3 TT |
91 | |
92 | /* It may be a bit too pervasive in this dummy_frame dtor callback. */ | |
93 | clear_symtab_users (0); | |
94 | ||
95 | break; | |
96 | } | |
97 | ||
98 | /* Delete the .c file. */ | |
92677124 | 99 | unlink (data->module->source_file.c_str ()); |
7f361056 | 100 | |
bb2ec1b3 | 101 | /* Delete the .o file. */ |
e616f60a | 102 | unlink (objfile_name_s.c_str ()); |
0dbf6ee6 TT |
103 | |
104 | delete data; | |
bb2ec1b3 TT |
105 | } |
106 | ||
0295dde6 AB |
107 | /* Create a copy of FUNC_TYPE that is independent of OBJFILE. */ |
108 | ||
109 | static type * | |
110 | create_copied_type_recursive (objfile *objfile, type *func_type) | |
111 | { | |
112 | htab_up copied_types = create_copied_types_hash (objfile); | |
113 | func_type = copy_type_recursive (objfile, func_type, copied_types.get ()); | |
114 | return func_type; | |
115 | } | |
116 | ||
bb2ec1b3 TT |
117 | /* Perform inferior call of MODULE. This function may throw an error. |
118 | This function may leave files referenced by MODULE on disk until | |
119 | the inferior call dummy frame is discarded. This function may throw errors. | |
120 | Thrown errors and left MODULE files are unrelated events. Caller must no | |
121 | longer touch MODULE's memory after this function has been called. */ | |
122 | ||
123 | void | |
e947a848 | 124 | compile_object_run (compile_module_up &&module) |
bb2ec1b3 TT |
125 | { |
126 | struct value *func_val; | |
bb2ec1b3 | 127 | struct do_module_cleanup *data; |
bb2ec1b3 | 128 | int dtor_found, executed = 0; |
83d3415e | 129 | struct symbol *func_sym = module->func_sym; |
bb2ec1b3 | 130 | CORE_ADDR regs_addr = module->regs_addr; |
83d3415e | 131 | struct objfile *objfile = module->objfile; |
bb2ec1b3 | 132 | |
e616f60a | 133 | data = new struct do_module_cleanup (&executed, std::move (module)); |
bb2ec1b3 | 134 | |
a70b8144 | 135 | try |
bb2ec1b3 | 136 | { |
83d3415e | 137 | struct type *func_type = SYMBOL_TYPE (func_sym); |
83d3415e JK |
138 | int current_arg = 0; |
139 | struct value **vargs; | |
140 | ||
0295dde6 AB |
141 | /* OBJFILE may disappear while FUNC_TYPE is still in use as a |
142 | result of the call to DO_MODULE_CLEANUP below, so we need a copy | |
143 | that does not depend on the objfile in anyway. */ | |
144 | func_type = create_copied_type_recursive (objfile, func_type); | |
83d3415e | 145 | |
78134374 | 146 | gdb_assert (func_type->code () == TYPE_CODE_FUNC); |
83d3415e | 147 | func_val = value_from_pointer (lookup_pointer_type (func_type), |
2b1ffcfd | 148 | BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func_sym))); |
83d3415e | 149 | |
1f704f76 SM |
150 | vargs = XALLOCAVEC (struct value *, func_type->num_fields ()); |
151 | if (func_type->num_fields () >= 1) | |
bb2ec1b3 | 152 | { |
83d3415e JK |
153 | gdb_assert (regs_addr != 0); |
154 | vargs[current_arg] = value_from_pointer | |
940da03e | 155 | (func_type->field (current_arg).type (), regs_addr); |
83d3415e | 156 | ++current_arg; |
bb2ec1b3 | 157 | } |
1f704f76 | 158 | if (func_type->num_fields () >= 2) |
36de76f9 | 159 | { |
e616f60a | 160 | gdb_assert (data->module->out_value_addr != 0); |
36de76f9 | 161 | vargs[current_arg] = value_from_pointer |
e616f60a TT |
162 | (func_type->field (current_arg).type (), |
163 | data->module->out_value_addr); | |
36de76f9 JK |
164 | ++current_arg; |
165 | } | |
1f704f76 SM |
166 | gdb_assert (current_arg == func_type->num_fields ()); |
167 | auto args = gdb::make_array_view (vargs, func_type->num_fields ()); | |
e71585ff | 168 | call_function_by_hand_dummy (func_val, NULL, args, |
83d3415e | 169 | do_module_cleanup, data); |
bb2ec1b3 | 170 | } |
230d2906 | 171 | catch (const gdb_exception_error &ex) |
bb2ec1b3 | 172 | { |
7556d4a4 | 173 | /* In the case of DTOR_FOUND or in the case of EXECUTED nothing |
bb2ec1b3 | 174 | needs to be done. */ |
7556d4a4 PA |
175 | dtor_found = find_dummy_frame_dtor (do_module_cleanup, data); |
176 | if (!executed) | |
177 | data->executedp = NULL; | |
bb2ec1b3 TT |
178 | gdb_assert (!(dtor_found && executed)); |
179 | if (!dtor_found && !executed) | |
5e970501 | 180 | do_module_cleanup (data, 0); |
eedc3f4f | 181 | throw; |
bb2ec1b3 | 182 | } |
7556d4a4 PA |
183 | |
184 | dtor_found = find_dummy_frame_dtor (do_module_cleanup, data); | |
185 | gdb_assert (!dtor_found && executed); | |
bb2ec1b3 | 186 | } |