1 /* C/C++ language support for compilation.
3 Copyright (C) 2014-2020 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
21 #include "compile-internal.h"
22 #include "compile-c.h"
23 #include "compile-cplus.h"
27 #include "macroscope.h"
29 #include "gdbsupport/function-view.h"
30 #include "gdbsupport/gdb-dlfcn.h"
31 #include "gdbsupport/preprocessor.h"
34 /* See compile-internal.h. */
37 c_get_mode_for_size (int size
)
39 const char *mode
= NULL
;
56 internal_error (__FILE__
, __LINE__
, _("Invalid GCC mode size %d."), size
);
62 /* See compile-internal.h. */
65 c_get_range_decl_name (const struct dynamic_prop
*prop
)
67 return string_printf ("__gdb_prop_%s", host_address_to_string (prop
));
72 /* Load the plug-in library FE_LIBCC and return the initialization function
75 template <typename FUNCTYPE
>
77 load_libcompile (const char *fe_libcc
, const char *fe_context
)
81 /* gdb_dlopen will call error () on an error, so no need to check
83 gdb_dlhandle_up handle
= gdb_dlopen (fe_libcc
);
84 func
= (FUNCTYPE
*) gdb_dlsym (handle
, fe_context
);
87 error (_("could not find symbol %s in library %s"), fe_context
, fe_libcc
);
89 /* Leave the library open. */
94 /* Return the compile instance associated with the current context.
95 This function calls the symbol returned from the load_libcompile
96 function. FE_LIBCC is the library to load. BASE_VERSION is the
97 base compile plug-in version we support. API_VERSION is the
98 API version supported. */
100 template <typename INSTTYPE
, typename FUNCTYPE
, typename CTXTYPE
,
101 typename BASE_VERSION_TYPE
, typename API_VERSION_TYPE
>
103 get_compile_context (const char *fe_libcc
, const char *fe_context
,
104 BASE_VERSION_TYPE base_version
,
105 API_VERSION_TYPE api_version
)
107 static FUNCTYPE
*func
;
108 static CTXTYPE
*context
;
112 func
= load_libcompile
<FUNCTYPE
> (fe_libcc
, fe_context
);
113 gdb_assert (func
!= NULL
);
116 context
= (*func
) (base_version
, api_version
);
118 error (_("The loaded version of GCC does not support the required version "
121 return new INSTTYPE (context
);
124 /* A C-language implementation of get_compile_context. */
127 c_get_compile_context ()
129 return get_compile_context
130 <compile_c_instance
, gcc_c_fe_context_function
, gcc_c_context
,
131 gcc_base_api_version
, gcc_c_api_version
>
132 (STRINGIFY (GCC_C_FE_LIBCC
), STRINGIFY (GCC_C_FE_CONTEXT
),
133 GCC_FE_VERSION_0
, GCC_C_FE_VERSION_0
);
136 /* A C++-language implementation of get_compile_context. */
139 cplus_get_compile_context ()
141 return get_compile_context
142 <compile_cplus_instance
, gcc_cp_fe_context_function
, gcc_cp_context
,
143 gcc_base_api_version
, gcc_cp_api_version
>
144 (STRINGIFY (GCC_CP_FE_LIBCC
), STRINGIFY (GCC_CP_FE_CONTEXT
),
145 GCC_FE_VERSION_0
, GCC_CP_FE_VERSION_0
);
150 /* Write one macro definition. */
153 print_one_macro (const char *name
, const struct macro_definition
*macro
,
154 struct macro_source_file
*source
, int line
,
157 /* Don't print command-line defines. They will be supplied another
162 /* None of -Wno-builtin-macro-redefined, #undef first
163 or plain #define of the same value would avoid a warning. */
164 fprintf_filtered (file
, "#ifndef %s\n# define %s", name
, name
);
166 if (macro
->kind
== macro_function_like
)
170 fputs_filtered ("(", file
);
171 for (i
= 0; i
< macro
->argc
; i
++)
173 fputs_filtered (macro
->argv
[i
], file
);
174 if (i
+ 1 < macro
->argc
)
175 fputs_filtered (", ", file
);
177 fputs_filtered (")", file
);
180 fprintf_filtered (file
, " %s\n#endif\n", macro
->replacement
);
183 /* Write macro definitions at PC to FILE. */
186 write_macro_definitions (const struct block
*block
, CORE_ADDR pc
,
187 struct ui_file
*file
)
189 gdb::unique_xmalloc_ptr
<struct macro_scope
> scope
;
192 scope
= sal_macro_scope (find_pc_line (pc
, 0));
194 scope
= default_macro_scope ();
196 scope
= user_macro_scope ();
198 if (scope
!= NULL
&& scope
->file
!= NULL
&& scope
->file
->table
!= NULL
)
200 macro_for_each_in_scope (scope
->file
, scope
->line
,
201 [&] (const char *name
,
202 const macro_definition
*macro
,
203 macro_source_file
*source
,
206 print_one_macro (name
, macro
, source
, line
, file
);
211 /* Generate a structure holding all the registers used by the function
215 generate_register_struct (struct ui_file
*stream
, struct gdbarch
*gdbarch
,
216 const unsigned char *registers_used
)
221 fputs_unfiltered ("struct " COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
" {\n",
224 if (registers_used
!= NULL
)
225 for (i
= 0; i
< gdbarch_num_regs (gdbarch
); ++i
)
227 if (registers_used
[i
])
229 struct type
*regtype
= check_typedef (register_type (gdbarch
, i
));
230 std::string regname
= compile_register_name_mangled (gdbarch
, i
);
234 /* You might think we could use type_print here. However,
235 target descriptions often use types with names like
236 "int64_t", which may not be defined in the inferior
237 (and in any case would not be looked up due to the
238 #pragma business). So, we take a much simpler
239 approach: for pointer- or integer-typed registers, emit
240 the field in the most direct way; and for other
241 register types (typically flags or vectors), emit a
242 maximally-aligned array of the correct size. */
244 fputs_unfiltered (" ", stream
);
245 switch (TYPE_CODE (regtype
))
248 fprintf_filtered (stream
, "__gdb_uintptr %s",
255 = c_get_mode_for_size (TYPE_LENGTH (regtype
));
259 if (TYPE_UNSIGNED (regtype
))
260 fputs_unfiltered ("unsigned ", stream
);
261 fprintf_unfiltered (stream
,
263 " __attribute__ ((__mode__(__%s__)))",
273 fprintf_unfiltered (stream
,
274 " unsigned char %s[%s]"
275 " __attribute__((__aligned__("
276 "__BIGGEST_ALIGNMENT__)))",
278 pulongest (TYPE_LENGTH (regtype
)));
280 fputs_unfiltered (";\n", stream
);
285 fputs_unfiltered (" char " COMPILE_I_SIMPLE_REGISTER_DUMMY
";\n",
288 fputs_unfiltered ("};\n\n", stream
);
291 /* C-language policy to emit a push user expression pragma into BUF. */
293 struct c_push_user_expression
295 void push_user_expression (struct ui_file
*buf
)
297 fputs_unfiltered ("#pragma GCC user_expression\n", buf
);
301 /* C-language policy to emit a pop user expression pragma into BUF.
302 For C, this is a nop. */
304 struct pop_user_expression_nop
306 void pop_user_expression (struct ui_file
*buf
)
312 /* C-language policy to construct a code header for a block of code.
313 Takes a scope TYPE argument which selects the correct header to
316 struct c_add_code_header
318 void add_code_header (enum compile_i_scope_types type
, struct ui_file
*buf
)
322 case COMPILE_I_SIMPLE_SCOPE
:
323 fputs_unfiltered ("void "
324 GCC_FE_WRAPPER_FUNCTION
326 COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
328 COMPILE_I_SIMPLE_REGISTER_ARG_NAME
333 case COMPILE_I_PRINT_ADDRESS_SCOPE
:
334 case COMPILE_I_PRINT_VALUE_SCOPE
:
335 /* <string.h> is needed for a memcpy call below. */
336 fputs_unfiltered ("#include <string.h>\n"
338 GCC_FE_WRAPPER_FUNCTION
340 COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
342 COMPILE_I_SIMPLE_REGISTER_ARG_NAME
344 COMPILE_I_PRINT_OUT_ARG_TYPE
346 COMPILE_I_PRINT_OUT_ARG
351 case COMPILE_I_RAW_SCOPE
:
355 gdb_assert_not_reached (_("Unknown compiler scope reached."));
360 /* C-language policy to construct a code footer for a block of code.
361 Takes a scope TYPE which selects the correct footer to insert into BUF. */
363 struct c_add_code_footer
365 void add_code_footer (enum compile_i_scope_types type
, struct ui_file
*buf
)
369 case COMPILE_I_SIMPLE_SCOPE
:
370 case COMPILE_I_PRINT_ADDRESS_SCOPE
:
371 case COMPILE_I_PRINT_VALUE_SCOPE
:
372 fputs_unfiltered ("}\n", buf
);
375 case COMPILE_I_RAW_SCOPE
:
379 gdb_assert_not_reached (_("Unknown compiler scope reached."));
384 /* C-language policy to emit the user code snippet INPUT into BUF based on the
389 void add_input (enum compile_i_scope_types type
, const char *input
,
394 case COMPILE_I_PRINT_ADDRESS_SCOPE
:
395 case COMPILE_I_PRINT_VALUE_SCOPE
:
396 fprintf_unfiltered (buf
,
397 "__auto_type " COMPILE_I_EXPR_VAL
" = %s;\n"
398 "typeof (%s) *" COMPILE_I_EXPR_PTR_TYPE
";\n"
399 "memcpy (" COMPILE_I_PRINT_OUT_ARG
", %s"
400 COMPILE_I_EXPR_VAL
",\n"
401 "sizeof (*" COMPILE_I_EXPR_PTR_TYPE
"));\n"
403 (type
== COMPILE_I_PRINT_ADDRESS_SCOPE
408 fputs_unfiltered (input
, buf
);
411 fputs_unfiltered ("\n", buf
);
415 /* C++-language policy to emit a push user expression pragma into
418 struct cplus_push_user_expression
420 void push_user_expression (struct ui_file
*buf
)
422 fputs_unfiltered ("#pragma GCC push_user_expression\n", buf
);
426 /* C++-language policy to emit a pop user expression pragma into BUF. */
428 struct cplus_pop_user_expression
430 void pop_user_expression (struct ui_file
*buf
)
432 fputs_unfiltered ("#pragma GCC pop_user_expression\n", buf
);
436 /* C++-language policy to construct a code header for a block of code.
437 Takes a scope TYPE argument which selects the correct header to
440 struct cplus_add_code_header
442 void add_code_header (enum compile_i_scope_types type
, struct ui_file
*buf
)
446 case COMPILE_I_SIMPLE_SCOPE
:
447 fputs_unfiltered ("void "
448 GCC_FE_WRAPPER_FUNCTION
450 COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
452 COMPILE_I_SIMPLE_REGISTER_ARG_NAME
457 case COMPILE_I_PRINT_ADDRESS_SCOPE
:
458 case COMPILE_I_PRINT_VALUE_SCOPE
:
460 "#include <cstring>\n"
461 "#include <bits/move.h>\n"
463 GCC_FE_WRAPPER_FUNCTION
465 COMPILE_I_SIMPLE_REGISTER_STRUCT_TAG
467 COMPILE_I_SIMPLE_REGISTER_ARG_NAME
469 COMPILE_I_PRINT_OUT_ARG_TYPE
471 COMPILE_I_PRINT_OUT_ARG
476 case COMPILE_I_RAW_SCOPE
:
480 gdb_assert_not_reached (_("Unknown compiler scope reached."));
485 /* C++-language policy to emit the user code snippet INPUT into BUF based on
488 struct cplus_add_input
490 void add_input (enum compile_i_scope_types type
, const char *input
,
495 case COMPILE_I_PRINT_VALUE_SCOPE
:
496 case COMPILE_I_PRINT_ADDRESS_SCOPE
:
499 /* "auto" strips ref- and cv- qualifiers, so we need to also strip
500 those from COMPILE_I_EXPR_PTR_TYPE. */
501 "auto " COMPILE_I_EXPR_VAL
" = %s;\n"
503 "std::add_pointer<std::remove_cv<decltype (%s)>::type>::type "
505 "__gdb_expr_ptr " COMPILE_I_EXPR_PTR_TYPE
";\n"
506 "std::memcpy (" COMPILE_I_PRINT_OUT_ARG
", %s ("
507 COMPILE_I_EXPR_VAL
"),\n"
508 "\tsizeof (*" COMPILE_I_EXPR_PTR_TYPE
"));\n"
510 (type
== COMPILE_I_PRINT_ADDRESS_SCOPE
511 ? "__builtin_addressof" : ""));
515 fputs_unfiltered (input
, buf
);
518 fputs_unfiltered ("\n", buf
);
522 /* A host class representing a compile program.
524 CompileInstanceType is the type of the compile_instance for the
527 PushUserExpressionPolicy and PopUserExpressionPolicy are used to
528 push and pop user expression pragmas to the compile plug-in.
530 AddCodeHeaderPolicy and AddCodeFooterPolicy are used to add the appropriate
531 code header and footer, respectively.
533 AddInputPolicy adds the actual user code. */
535 template <class CompileInstanceType
, class PushUserExpressionPolicy
,
536 class PopUserExpressionPolicy
, class AddCodeHeaderPolicy
,
537 class AddCodeFooterPolicy
, class AddInputPolicy
>
538 class compile_program
539 : private PushUserExpressionPolicy
, private PopUserExpressionPolicy
,
540 private AddCodeHeaderPolicy
, private AddCodeFooterPolicy
,
541 private AddInputPolicy
545 /* Construct a compile_program using the compiler instance INST
546 using the architecture given by GDBARCH. */
547 compile_program (CompileInstanceType
*inst
, struct gdbarch
*gdbarch
)
548 : m_instance (inst
), m_arch (gdbarch
)
552 /* Take the source code provided by the user with the 'compile'
553 command and compute the additional wrapping, macro, variable and
554 register operations needed. INPUT is the source code derived from
555 the 'compile' command, EXPR_BLOCK denotes the block relevant contextually
556 to the inferior when the expression was created, and EXPR_PC
557 indicates the value of $PC.
559 Returns the text of the program to compile. */
560 std::string
compute (const char *input
, const struct block
*expr_block
,
563 string_file var_stream
;
566 /* Do not generate local variable information for "raw"
567 compilations. In this case we aren't emitting our own function
568 and the user's code may only refer to globals. */
569 if (m_instance
->scope () != COMPILE_I_RAW_SCOPE
)
571 /* Generate the code to compute variable locations, but do it
572 before generating the function header, so we can define the
573 register struct before the function body. This requires a
575 gdb::unique_xmalloc_ptr
<unsigned char> registers_used
576 = generate_c_for_variable_locations (m_instance
, &var_stream
, m_arch
,
577 expr_block
, expr_pc
);
579 buf
.puts ("typedef unsigned int"
580 " __attribute__ ((__mode__(__pointer__)))"
581 " __gdb_uintptr;\n");
582 buf
.puts ("typedef int"
583 " __attribute__ ((__mode__(__pointer__)))"
586 /* Iterate all log2 sizes in bytes supported by c_get_mode_for_size. */
587 for (int i
= 0; i
< 4; ++i
)
589 const char *mode
= c_get_mode_for_size (1 << i
);
591 gdb_assert (mode
!= NULL
);
592 buf
.printf ("typedef int"
593 " __attribute__ ((__mode__(__%s__)))"
598 generate_register_struct (&buf
, m_arch
, registers_used
.get ());
601 AddCodeHeaderPolicy::add_code_header (m_instance
->scope (), &buf
);
603 if (m_instance
->scope () == COMPILE_I_SIMPLE_SCOPE
604 || m_instance
->scope () == COMPILE_I_PRINT_ADDRESS_SCOPE
605 || m_instance
->scope () == COMPILE_I_PRINT_VALUE_SCOPE
)
607 buf
.write (var_stream
.c_str (), var_stream
.size ());
608 PushUserExpressionPolicy::push_user_expression (&buf
);
611 write_macro_definitions (expr_block
, expr_pc
, &buf
);
613 /* The user expression has to be in its own scope, so that "extern"
614 works properly. Otherwise gcc thinks that the "extern"
615 declaration is in the same scope as the declaration provided by
617 if (m_instance
->scope () != COMPILE_I_RAW_SCOPE
)
620 buf
.puts ("#line 1 \"gdb command line\"\n");
622 AddInputPolicy::add_input (m_instance
->scope (), input
, &buf
);
624 /* For larger user expressions the automatic semicolons may be
626 if (strchr (input
, '\n') == NULL
)
629 if (m_instance
->scope () != COMPILE_I_RAW_SCOPE
)
632 if (m_instance
->scope () == COMPILE_I_SIMPLE_SCOPE
633 || m_instance
->scope () == COMPILE_I_PRINT_ADDRESS_SCOPE
634 || m_instance
->scope () == COMPILE_I_PRINT_VALUE_SCOPE
)
635 PopUserExpressionPolicy::pop_user_expression (&buf
);
637 AddCodeFooterPolicy::add_code_footer (m_instance
->scope (), &buf
);
638 return buf
.string ();
643 /* The compile instance to be used for compilation and
645 CompileInstanceType
*m_instance
;
647 /* The architecture to be used. */
648 struct gdbarch
*m_arch
;
651 /* The types used for C and C++ program computations. */
653 typedef compile_program
<compile_c_instance
,
654 c_push_user_expression
, pop_user_expression_nop
,
655 c_add_code_header
, c_add_code_footer
,
656 c_add_input
> c_compile_program
;
658 typedef compile_program
<compile_cplus_instance
,
659 cplus_push_user_expression
, cplus_pop_user_expression
,
660 cplus_add_code_header
, c_add_code_footer
,
661 cplus_add_input
> cplus_compile_program
;
663 /* The la_compute_program method for C. */
666 c_compute_program (compile_instance
*inst
,
668 struct gdbarch
*gdbarch
,
669 const struct block
*expr_block
,
672 compile_c_instance
*c_inst
= static_cast<compile_c_instance
*> (inst
);
673 c_compile_program
program (c_inst
, gdbarch
);
675 return program
.compute (input
, expr_block
, expr_pc
);
678 /* The la_compute_program method for C++. */
681 cplus_compute_program (compile_instance
*inst
,
683 struct gdbarch
*gdbarch
,
684 const struct block
*expr_block
,
687 compile_cplus_instance
*cplus_inst
688 = static_cast<compile_cplus_instance
*> (inst
);
689 cplus_compile_program
program (cplus_inst
, gdbarch
);
691 return program
.compute (input
, expr_block
, expr_pc
);