Commit | Line | Data |
---|---|---|
bb2ec1b3 TT |
1 | /* Call module for 'compile' command. |
2 | ||
32d0add0 | 3 | Copyright (C) 2014-2015 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" | |
27 | ||
28 | /* Helper for do_module_cleanup. */ | |
29 | ||
30 | struct do_module_cleanup | |
31 | { | |
32 | /* Boolean to set true upon a call of do_module_cleanup. | |
33 | The pointer may be NULL. */ | |
34 | int *executedp; | |
35 | ||
36 | /* .c file OBJFILE was built from. It needs to be xfree-d. */ | |
37 | char *source_file; | |
38 | ||
39 | /* objfile_name of our objfile. */ | |
40 | char objfile_name_string[1]; | |
41 | }; | |
42 | ||
43 | /* Cleanup everything after the inferior function dummy frame gets | |
44 | discarded. */ | |
45 | ||
46 | static dummy_frame_dtor_ftype do_module_cleanup; | |
47 | static void | |
48 | do_module_cleanup (void *arg) | |
49 | { | |
50 | struct do_module_cleanup *data = arg; | |
51 | struct objfile *objfile; | |
52 | ||
53 | if (data->executedp != NULL) | |
54 | *data->executedp = 1; | |
55 | ||
56 | ALL_OBJFILES (objfile) | |
57 | if ((objfile->flags & OBJF_USERLOADED) == 0 | |
58 | && (strcmp (objfile_name (objfile), data->objfile_name_string) == 0)) | |
59 | { | |
60 | free_objfile (objfile); | |
61 | ||
62 | /* It may be a bit too pervasive in this dummy_frame dtor callback. */ | |
63 | clear_symtab_users (0); | |
64 | ||
65 | break; | |
66 | } | |
67 | ||
68 | /* Delete the .c file. */ | |
69 | unlink (data->source_file); | |
70 | xfree (data->source_file); | |
71 | ||
72 | /* Delete the .o file. */ | |
73 | unlink (data->objfile_name_string); | |
74 | xfree (data); | |
75 | } | |
76 | ||
77 | /* Perform inferior call of MODULE. This function may throw an error. | |
78 | This function may leave files referenced by MODULE on disk until | |
79 | the inferior call dummy frame is discarded. This function may throw errors. | |
80 | Thrown errors and left MODULE files are unrelated events. Caller must no | |
81 | longer touch MODULE's memory after this function has been called. */ | |
82 | ||
83 | void | |
84 | compile_object_run (struct compile_module *module) | |
85 | { | |
86 | struct value *func_val; | |
87 | struct frame_id dummy_id; | |
88 | struct cleanup *cleanups; | |
89 | struct do_module_cleanup *data; | |
bb2ec1b3 TT |
90 | const char *objfile_name_s = objfile_name (module->objfile); |
91 | int dtor_found, executed = 0; | |
92 | CORE_ADDR func_addr = module->func_addr; | |
93 | CORE_ADDR regs_addr = module->regs_addr; | |
94 | ||
95 | data = xmalloc (sizeof (*data) + strlen (objfile_name_s)); | |
96 | data->executedp = &executed; | |
97 | data->source_file = xstrdup (module->source_file); | |
98 | strcpy (data->objfile_name_string, objfile_name_s); | |
99 | ||
100 | xfree (module->source_file); | |
101 | xfree (module); | |
102 | ||
492d29ea | 103 | TRY |
bb2ec1b3 TT |
104 | { |
105 | func_val = value_from_pointer | |
106 | (builtin_type (target_gdbarch ())->builtin_func_ptr, | |
107 | func_addr); | |
108 | ||
109 | if (regs_addr == 0) | |
110 | call_function_by_hand_dummy (func_val, 0, NULL, | |
111 | do_module_cleanup, data); | |
112 | else | |
113 | { | |
114 | struct value *arg_val; | |
115 | ||
116 | arg_val = value_from_pointer | |
117 | (builtin_type (target_gdbarch ())->builtin_func_ptr, | |
118 | regs_addr); | |
119 | call_function_by_hand_dummy (func_val, 1, &arg_val, | |
120 | do_module_cleanup, data); | |
121 | } | |
122 | } | |
492d29ea | 123 | CATCH (ex, RETURN_MASK_ERROR) |
bb2ec1b3 | 124 | { |
7556d4a4 | 125 | /* In the case of DTOR_FOUND or in the case of EXECUTED nothing |
bb2ec1b3 | 126 | needs to be done. */ |
7556d4a4 PA |
127 | dtor_found = find_dummy_frame_dtor (do_module_cleanup, data); |
128 | if (!executed) | |
129 | data->executedp = NULL; | |
bb2ec1b3 TT |
130 | gdb_assert (!(dtor_found && executed)); |
131 | if (!dtor_found && !executed) | |
132 | do_module_cleanup (data); | |
133 | throw_exception (ex); | |
134 | } | |
492d29ea | 135 | END_CATCH |
7556d4a4 PA |
136 | |
137 | dtor_found = find_dummy_frame_dtor (do_module_cleanup, data); | |
138 | gdb_assert (!dtor_found && executed); | |
bb2ec1b3 | 139 | } |