Branch data Line data Source code
1 : : /* go-backend.cc -- Go frontend interface to gcc backend.
2 : : Copyright (C) 2010-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
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.
10 : :
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.
15 : :
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/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "target.h"
24 : : #include "tree.h"
25 : : #include "memmodel.h"
26 : : #include "tm_p.h"
27 : : #include "diagnostic.h"
28 : : #include "simple-object.h"
29 : : #include "stor-layout.h"
30 : : #include "intl.h"
31 : : #include "output.h" /* for assemble_string */
32 : : #include "common/common-target.h"
33 : : #include "go-c.h"
34 : :
35 : : /* The segment name we pass to simple_object_start_read to find Go
36 : : export data. */
37 : :
38 : : #ifndef GO_EXPORT_SEGMENT_NAME
39 : : #define GO_EXPORT_SEGMENT_NAME "__GNU_GO"
40 : : #endif
41 : :
42 : : /* The section name we use when reading and writing export data. */
43 : :
44 : : #ifndef GO_EXPORT_SECTION_NAME
45 : : #define GO_EXPORT_SECTION_NAME ".go_export"
46 : : #endif
47 : :
48 : : #ifndef TARGET_AIX_OS
49 : : #define TARGET_AIX_OS 0
50 : : #endif
51 : :
52 : : /* This file holds all the cases where the Go frontend needs
53 : : information from gcc's backend. */
54 : :
55 : : /* Return whether or not GCC has reported any errors. */
56 : :
57 : : bool
58 : 92795 : saw_errors (void)
59 : : {
60 : 92795 : return errorcount != 0 || sorrycount != 0;
61 : : }
62 : :
63 : : /* Return the alignment in bytes of a struct field of type T. */
64 : :
65 : : unsigned int
66 : 1186291 : go_field_alignment (tree t)
67 : : {
68 : 1186291 : unsigned int v;
69 : :
70 : 1186291 : v = TYPE_ALIGN (t);
71 : :
72 : : #ifdef BIGGEST_FIELD_ALIGNMENT
73 : : if (v > BIGGEST_FIELD_ALIGNMENT)
74 : : v = BIGGEST_FIELD_ALIGNMENT;
75 : : #endif
76 : :
77 : : #ifdef ADJUST_FIELD_ALIGN
78 : 1186291 : v = ADJUST_FIELD_ALIGN (NULL_TREE, t, v);
79 : : #endif
80 : :
81 : 1186291 : return v / BITS_PER_UNIT;
82 : : }
83 : :
84 : : /* This is called by the Go frontend proper if the unsafe package was
85 : : imported. When that happens we cannot do type-based alias
86 : : analysis. */
87 : :
88 : : void
89 : 3623 : go_imported_unsafe (void)
90 : : {
91 : 3623 : flag_strict_aliasing = false;
92 : 3623 : TREE_OPTIMIZATION (optimization_default_node)->x_flag_strict_aliasing = false;
93 : :
94 : : /* Let the backend know that the options have changed. */
95 : 3623 : targetm.override_options_after_change ();
96 : 3623 : }
97 : :
98 : : /* This is called by the Go frontend proper to add data to the
99 : : section containing Go export data. */
100 : :
101 : : void
102 : 7156276 : go_write_export_data (const char *bytes, unsigned int size)
103 : : {
104 : 7156276 : static section* sec;
105 : :
106 : 7156276 : if (sec == NULL)
107 : : {
108 : 4252 : gcc_assert (targetm_common.have_named_sections);
109 : 4252 : sec = get_section (GO_EXPORT_SECTION_NAME,
110 : : TARGET_AIX_OS ? SECTION_EXCLUDE : SECTION_DEBUG,
111 : : NULL);
112 : : }
113 : :
114 : 7156276 : switch_to_section (sec);
115 : 7156276 : assemble_string (bytes, size);
116 : 7156276 : }
117 : :
118 : : /* The go_read_export_data function is called by the Go frontend
119 : : proper to read Go export data from an object file. FD is a file
120 : : descriptor open for reading. OFFSET is the offset within the file
121 : : where the object file starts; this will be 0 except when reading an
122 : : archive. On success this returns NULL and sets *PBUF to a buffer
123 : : allocated using malloc, of size *PLEN, holding the export data. If
124 : : the data is not found, this returns NULL and sets *PBUF to NULL and
125 : : *PLEN to 0. If some error occurs, this returns an error message
126 : : and sets *PERR to an errno value or 0 if there is no relevant
127 : : errno. */
128 : :
129 : : const char *
130 : 23332 : go_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
131 : : int *perr)
132 : : {
133 : 23332 : simple_object_read *sobj;
134 : 23332 : const char *errmsg;
135 : 23332 : off_t sec_offset;
136 : 23332 : off_t sec_length;
137 : 23332 : int found;
138 : 23332 : char *buf;
139 : 23332 : ssize_t c;
140 : :
141 : 23332 : *pbuf = NULL;
142 : 23332 : *plen = 0;
143 : :
144 : 23332 : sobj = simple_object_start_read (fd, offset, GO_EXPORT_SEGMENT_NAME,
145 : : &errmsg, perr);
146 : 23332 : if (sobj == NULL)
147 : : {
148 : : /* If we get an error here, just pretend that we didn't find any
149 : : export data. This is the right thing to do if the error is
150 : : that the file was not recognized as an object file. This
151 : : will ignore file I/O errors, but it's not too big a deal
152 : : because we will wind up giving some other error later. */
153 : : return NULL;
154 : : }
155 : :
156 : 22610 : found = simple_object_find_section (sobj, GO_EXPORT_SECTION_NAME,
157 : : &sec_offset, &sec_length,
158 : : &errmsg, perr);
159 : 22610 : simple_object_release_read (sobj);
160 : 22610 : if (!found)
161 : 802 : return errmsg;
162 : :
163 : 21808 : if (lseek (fd, offset + sec_offset, SEEK_SET) < 0)
164 : : {
165 : 0 : *perr = errno;
166 : 0 : return _("lseek failed while reading export data");
167 : : }
168 : :
169 : 21808 : buf = XNEWVEC (char, sec_length);
170 : 21808 : if (buf == NULL)
171 : : {
172 : : *perr = errno;
173 : : return _("memory allocation failed while reading export data");
174 : : }
175 : :
176 : 21808 : c = read (fd, buf, sec_length);
177 : 21808 : if (c < 0)
178 : : {
179 : 0 : *perr = errno;
180 : 0 : free (buf);
181 : 0 : return _("read failed while reading export data");
182 : : }
183 : :
184 : 21808 : if (c < sec_length)
185 : : {
186 : 0 : free (buf);
187 : 0 : return _("short read while reading export data");
188 : : }
189 : :
190 : 21808 : *pbuf = buf;
191 : 21808 : *plen = sec_length;
192 : :
193 : 21808 : return NULL;
194 : : }
|