Enable generation of GNU stack notes on Linux
[official-gcc.git] / libcc1 / context.cc
blob3263c167ff2e489f0841f418e144ac2fb043ce42
1 /* Generic plugin context
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include <cc1plugin-config.h>
22 #undef PACKAGE_NAME
23 #undef PACKAGE_STRING
24 #undef PACKAGE_TARNAME
25 #undef PACKAGE_VERSION
27 #include "../gcc/config.h"
29 #undef PACKAGE_NAME
30 #undef PACKAGE_STRING
31 #undef PACKAGE_TARNAME
32 #undef PACKAGE_VERSION
34 #include "gcc-plugin.h"
35 #include "system.h"
36 #include "coretypes.h"
37 #include "stringpool.h"
38 #include "hash-set.h"
39 #include "diagnostic.h"
40 #include "langhooks.h"
41 #include "langhooks-def.h"
43 #include "gcc-interface.h"
45 #include "context.hh"
46 #include "marshall.hh"
50 #ifdef __GNUC__
51 #pragma GCC visibility push(default)
52 #endif
53 int plugin_is_GPL_compatible;
54 #ifdef __GNUC__
55 #pragma GCC visibility pop
56 #endif
58 cc1_plugin::plugin_context *cc1_plugin::current_context;
62 // This is put into the lang hooks when the plugin starts.
64 static void
65 plugin_print_error_function (diagnostic_context *context, const char *file,
66 diagnostic_info *diagnostic)
68 if (current_function_decl != NULL_TREE
69 && DECL_NAME (current_function_decl) != NULL_TREE
70 && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
71 GCC_FE_WRAPPER_FUNCTION) == 0)
72 return;
73 lhd_print_error_function (context, file, diagnostic);
78 location_t
79 cc1_plugin::plugin_context::get_location_t (const char *filename,
80 unsigned int line_number)
82 if (filename == NULL)
83 return UNKNOWN_LOCATION;
85 filename = intern_filename (filename);
86 linemap_add (line_table, LC_ENTER, false, filename, line_number);
87 location_t loc = linemap_line_start (line_table, line_number, 0);
88 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
89 return loc;
92 // Add a file name to FILE_NAMES and return the canonical copy.
93 const char *
94 cc1_plugin::plugin_context::intern_filename (const char *filename)
96 const char **slot = file_names.find_slot (filename, INSERT);
97 if (*slot == NULL)
99 /* The file name must live as long as the line map, which
100 effectively means as long as this compilation. So, we copy
101 the string here but never free it. */
102 *slot = xstrdup (filename);
104 return *slot;
107 void
108 cc1_plugin::plugin_context::mark ()
110 for (const auto &item : address_map)
112 ggc_mark (item->decl);
113 ggc_mark (item->address);
116 for (const auto &item : preserved)
117 ggc_mark (&item);
122 // Perform GC marking.
124 static void
125 gc_mark (void *, void *)
127 if (cc1_plugin::current_context != NULL)
128 cc1_plugin::current_context->mark ();
131 void
132 cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info,
133 unsigned int version)
135 long fd = -1;
136 for (int i = 0; i < plugin_info->argc; ++i)
138 if (strcmp (plugin_info->argv[i].key, "fd") == 0)
140 char *tail;
141 errno = 0;
142 fd = strtol (plugin_info->argv[i].value, &tail, 0);
143 if (*tail != '\0' || errno != 0)
144 fatal_error (input_location,
145 "%s: invalid file descriptor argument to plugin",
146 plugin_info->base_name);
147 break;
150 if (fd == -1)
151 fatal_error (input_location,
152 "%s: required plugin argument %<fd%> is missing",
153 plugin_info->base_name);
155 current_context = new plugin_context (fd);
157 // Handshake.
158 cc1_plugin::protocol_int h_version;
159 if (!current_context->require ('H')
160 || ! ::cc1_plugin::unmarshall (current_context, &h_version))
161 fatal_error (input_location,
162 "%s: handshake failed", plugin_info->base_name);
163 if (h_version != version)
164 fatal_error (input_location,
165 "%s: unknown version in handshake", plugin_info->base_name);
167 register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
168 gc_mark, NULL);
170 lang_hooks.print_error_function = plugin_print_error_function;