Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Call module for 'compile' command. |
2 | ||
42a4f53d | 3 | Copyright (C) 2014-2019 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 | { | |
35 | /* Boolean to set true upon a call of do_module_cleanup. | |
36 | The pointer may be NULL. */ | |
37 | int *executedp; | |
38 | ||
39 | /* .c file OBJFILE was built from. It needs to be xfree-d. */ | |
40 | char *source_file; | |
41 | ||
5c65b58a JK |
42 | /* Copy from struct compile_module. */ |
43 | enum compile_i_scope_types scope; | |
44 | void *scope_data; | |
45 | ||
36de76f9 JK |
46 | /* Copy from struct compile_module. */ |
47 | struct type *out_value_type; | |
48 | CORE_ADDR out_value_addr; | |
49 | ||
7f361056 JK |
50 | /* Copy from struct compile_module. */ |
51 | struct munmap_list *munmap_list_head; | |
52 | ||
bb2ec1b3 TT |
53 | /* objfile_name of our objfile. */ |
54 | char objfile_name_string[1]; | |
55 | }; | |
56 | ||
57 | /* Cleanup everything after the inferior function dummy frame gets | |
58 | discarded. */ | |
59 | ||
60 | static dummy_frame_dtor_ftype do_module_cleanup; | |
61 | static void | |
5e970501 | 62 | do_module_cleanup (void *arg, int registers_valid) |
bb2ec1b3 | 63 | { |
9a3c8263 | 64 | struct do_module_cleanup *data = (struct do_module_cleanup *) arg; |
bb2ec1b3 TT |
65 | |
66 | if (data->executedp != NULL) | |
36de76f9 JK |
67 | { |
68 | *data->executedp = 1; | |
69 | ||
70 | /* This code cannot be in compile_object_run as OUT_VALUE_TYPE | |
71 | no longer exists there. */ | |
72 | if (data->scope == COMPILE_I_PRINT_ADDRESS_SCOPE | |
73 | || data->scope == COMPILE_I_PRINT_VALUE_SCOPE) | |
74 | { | |
75 | struct value *addr_value; | |
76 | struct type *ptr_type = lookup_pointer_type (data->out_value_type); | |
77 | ||
78 | addr_value = value_from_pointer (ptr_type, data->out_value_addr); | |
79 | ||
80 | /* SCOPE_DATA would be stale unlesse EXECUTEDP != NULL. */ | |
81 | compile_print_value (value_ind (addr_value), data->scope_data); | |
82 | } | |
83 | } | |
bb2ec1b3 | 84 | |
2030c079 | 85 | for (objfile *objfile : current_program_space->objfiles ()) |
bb2ec1b3 TT |
86 | if ((objfile->flags & OBJF_USERLOADED) == 0 |
87 | && (strcmp (objfile_name (objfile), data->objfile_name_string) == 0)) | |
88 | { | |
9e86da07 | 89 | delete objfile; |
bb2ec1b3 TT |
90 | |
91 | /* It may be a bit too pervasive in this dummy_frame dtor callback. */ | |
92 | clear_symtab_users (0); | |
93 | ||
94 | break; | |
95 | } | |
96 | ||
97 | /* Delete the .c file. */ | |
98 | unlink (data->source_file); | |
99 | xfree (data->source_file); | |
100 | ||
c9e0a7e3 | 101 | delete data->munmap_list_head; |
7f361056 | 102 | |
bb2ec1b3 TT |
103 | /* Delete the .o file. */ |
104 | unlink (data->objfile_name_string); | |
105 | xfree (data); | |
106 | } | |
107 | ||
108 | /* Perform inferior call of MODULE. This function may throw an error. | |
109 | This function may leave files referenced by MODULE on disk until | |
110 | the inferior call dummy frame is discarded. This function may throw errors. | |
111 | Thrown errors and left MODULE files are unrelated events. Caller must no | |
112 | longer touch MODULE's memory after this function has been called. */ | |
113 | ||
114 | void | |
115 | compile_object_run (struct compile_module *module) | |
116 | { | |
117 | struct value *func_val; | |
bb2ec1b3 | 118 | struct do_module_cleanup *data; |
bb2ec1b3 TT |
119 | const char *objfile_name_s = objfile_name (module->objfile); |
120 | int dtor_found, executed = 0; | |
83d3415e | 121 | struct symbol *func_sym = module->func_sym; |
bb2ec1b3 | 122 | CORE_ADDR regs_addr = module->regs_addr; |
83d3415e | 123 | struct objfile *objfile = module->objfile; |
bb2ec1b3 | 124 | |
224c3ddb SM |
125 | data = (struct do_module_cleanup *) xmalloc (sizeof (*data) |
126 | + strlen (objfile_name_s)); | |
bb2ec1b3 TT |
127 | data->executedp = &executed; |
128 | data->source_file = xstrdup (module->source_file); | |
129 | strcpy (data->objfile_name_string, objfile_name_s); | |
5c65b58a JK |
130 | data->scope = module->scope; |
131 | data->scope_data = module->scope_data; | |
36de76f9 JK |
132 | data->out_value_type = module->out_value_type; |
133 | data->out_value_addr = module->out_value_addr; | |
7f361056 | 134 | data->munmap_list_head = module->munmap_list_head; |
bb2ec1b3 TT |
135 | |
136 | xfree (module->source_file); | |
137 | xfree (module); | |
83d3415e | 138 | module = NULL; |
bb2ec1b3 | 139 | |
a70b8144 | 140 | try |
bb2ec1b3 | 141 | { |
83d3415e JK |
142 | struct type *func_type = SYMBOL_TYPE (func_sym); |
143 | htab_t copied_types; | |
144 | int current_arg = 0; | |
145 | struct value **vargs; | |
146 | ||
147 | /* OBJFILE may disappear while FUNC_TYPE still will be in use. */ | |
148 | copied_types = create_copied_types_hash (objfile); | |
149 | func_type = copy_type_recursive (objfile, func_type, copied_types); | |
150 | htab_delete (copied_types); | |
151 | ||
152 | gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC); | |
153 | func_val = value_from_pointer (lookup_pointer_type (func_type), | |
2b1ffcfd | 154 | BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func_sym))); |
83d3415e | 155 | |
8d749320 | 156 | vargs = XALLOCAVEC (struct value *, TYPE_NFIELDS (func_type)); |
83d3415e | 157 | if (TYPE_NFIELDS (func_type) >= 1) |
bb2ec1b3 | 158 | { |
83d3415e JK |
159 | gdb_assert (regs_addr != 0); |
160 | vargs[current_arg] = value_from_pointer | |
161 | (TYPE_FIELD_TYPE (func_type, current_arg), regs_addr); | |
162 | ++current_arg; | |
bb2ec1b3 | 163 | } |
36de76f9 JK |
164 | if (TYPE_NFIELDS (func_type) >= 2) |
165 | { | |
166 | gdb_assert (data->out_value_addr != 0); | |
167 | vargs[current_arg] = value_from_pointer | |
168 | (TYPE_FIELD_TYPE (func_type, current_arg), data->out_value_addr); | |
169 | ++current_arg; | |
170 | } | |
83d3415e | 171 | gdb_assert (current_arg == TYPE_NFIELDS (func_type)); |
e71585ff PA |
172 | auto args = gdb::make_array_view (vargs, TYPE_NFIELDS (func_type)); |
173 | call_function_by_hand_dummy (func_val, NULL, args, | |
83d3415e | 174 | do_module_cleanup, data); |
bb2ec1b3 | 175 | } |
230d2906 | 176 | catch (const gdb_exception_error &ex) |
bb2ec1b3 | 177 | { |
7556d4a4 | 178 | /* In the case of DTOR_FOUND or in the case of EXECUTED nothing |
bb2ec1b3 | 179 | needs to be done. */ |
7556d4a4 PA |
180 | dtor_found = find_dummy_frame_dtor (do_module_cleanup, data); |
181 | if (!executed) | |
182 | data->executedp = NULL; | |
bb2ec1b3 TT |
183 | gdb_assert (!(dtor_found && executed)); |
184 | if (!dtor_found && !executed) | |
5e970501 | 185 | do_module_cleanup (data, 0); |
eedc3f4f | 186 | throw; |
bb2ec1b3 | 187 | } |
7556d4a4 PA |
188 | |
189 | dtor_found = find_dummy_frame_dtor (do_module_cleanup, data); | |
190 | gdb_assert (!dtor_found && executed); | |
bb2ec1b3 | 191 | } |