111
|
1 /* go-backend.c -- Go frontend interface to gcc backend.
|
145
|
2 Copyright (C) 2010-2020 Free Software Foundation, Inc.
|
111
|
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
|
|
49 #define TARGET_AIX 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 saw_errors (void)
|
|
59 {
|
|
60 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 go_field_alignment (tree t)
|
|
67 {
|
|
68 unsigned int v;
|
|
69
|
|
70 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 v = ADJUST_FIELD_ALIGN (NULL_TREE, t, v);
|
|
79 #endif
|
|
80
|
|
81 return v / BITS_PER_UNIT;
|
|
82 }
|
|
83
|
|
84 /* This is called by the Go frontend proper if the unsafe package was
|
145
|
85 imported. When that happens we cannot do type-based alias
|
111
|
86 analysis. */
|
|
87
|
|
88 void
|
|
89 go_imported_unsafe (void)
|
|
90 {
|
|
91 flag_strict_aliasing = false;
|
145
|
92 TREE_OPTIMIZATION (optimization_default_node)->x_flag_strict_aliasing = false;
|
111
|
93
|
|
94 /* Let the backend know that the options have changed. */
|
|
95 targetm.override_options_after_change ();
|
|
96 }
|
|
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 go_write_export_data (const char *bytes, unsigned int size)
|
|
103 {
|
|
104 static section* sec;
|
|
105
|
|
106 if (sec == NULL)
|
|
107 {
|
|
108 gcc_assert (targetm_common.have_named_sections);
|
|
109 sec = get_section (GO_EXPORT_SECTION_NAME,
|
|
110 TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG,
|
|
111 NULL);
|
|
112 }
|
|
113
|
|
114 switch_to_section (sec);
|
|
115 assemble_string (bytes, size);
|
|
116 }
|
|
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 go_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
|
|
131 int *perr)
|
|
132 {
|
|
133 simple_object_read *sobj;
|
|
134 const char *errmsg;
|
|
135 off_t sec_offset;
|
|
136 off_t sec_length;
|
|
137 int found;
|
|
138 char *buf;
|
|
139 ssize_t c;
|
|
140
|
|
141 *pbuf = NULL;
|
|
142 *plen = 0;
|
|
143
|
|
144 sobj = simple_object_start_read (fd, offset, GO_EXPORT_SEGMENT_NAME,
|
|
145 &errmsg, perr);
|
|
146 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 found = simple_object_find_section (sobj, GO_EXPORT_SECTION_NAME,
|
|
157 &sec_offset, &sec_length,
|
|
158 &errmsg, perr);
|
|
159 simple_object_release_read (sobj);
|
|
160 if (!found)
|
|
161 return errmsg;
|
|
162
|
|
163 if (lseek (fd, offset + sec_offset, SEEK_SET) < 0)
|
|
164 {
|
|
165 *perr = errno;
|
|
166 return _("lseek failed while reading export data");
|
|
167 }
|
|
168
|
|
169 buf = XNEWVEC (char, sec_length);
|
|
170 if (buf == NULL)
|
|
171 {
|
|
172 *perr = errno;
|
|
173 return _("memory allocation failed while reading export data");
|
|
174 }
|
|
175
|
|
176 c = read (fd, buf, sec_length);
|
|
177 if (c < 0)
|
|
178 {
|
|
179 *perr = errno;
|
|
180 free (buf);
|
|
181 return _("read failed while reading export data");
|
|
182 }
|
|
183
|
|
184 if (c < sec_length)
|
|
185 {
|
|
186 free (buf);
|
|
187 return _("short read while reading export data");
|
|
188 }
|
|
189
|
|
190 *pbuf = buf;
|
|
191 *plen = sec_length;
|
|
192
|
|
193 return NULL;
|
|
194 }
|