]>
Commit | Line | Data |
---|---|---|
637bd3af | 1 | /* go-backend.c -- Go frontend interface to gcc backend. |
fbd26352 | 2 | Copyright (C) 2010-2019 Free Software Foundation, Inc. |
637bd3af | 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" | |
4cba6f60 | 23 | #include "target.h" |
24 | #include "tree.h" | |
ad7b10a2 | 25 | #include "memmodel.h" |
4cba6f60 | 26 | #include "tm_p.h" |
27 | #include "diagnostic.h" | |
612cc2ea | 28 | #include "simple-object.h" |
9ed99284 | 29 | #include "stor-layout.h" |
612cc2ea | 30 | #include "intl.h" |
dff12c10 | 31 | #include "output.h" /* for assemble_string */ |
218e3e4e | 32 | #include "common/common-target.h" |
03118c21 | 33 | #include "go-c.h" |
637bd3af | 34 | |
612cc2ea | 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 | ||
647ec977 | 48 | #ifndef TARGET_AIX |
49 | #define TARGET_AIX 0 | |
50 | #endif | |
51 | ||
637bd3af | 52 | /* This file holds all the cases where the Go frontend needs |
53 | information from gcc's backend. */ | |
54 | ||
56368084 | 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 | ||
637bd3af | 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 | |
700a9760 | 78 | v = ADJUST_FIELD_ALIGN (NULL_TREE, t, v); |
637bd3af | 79 | #endif |
80 | ||
81 | return v / BITS_PER_UNIT; | |
82 | } | |
83 | ||
60fd3d88 | 84 | /* This is called by the Go frontend proper if the unsafe package was |
f4d3c071 | 85 | imported. When that happens we cannot do type-based alias |
60fd3d88 | 86 | analysis. */ |
87 | ||
88 | void | |
89 | go_imported_unsafe (void) | |
90 | { | |
91 | flag_strict_aliasing = false; | |
92 | ||
60fd3d88 | 93 | /* Let the backend know that the options have changed. */ |
94 | targetm.override_options_after_change (); | |
95 | } | |
f3231e7d | 96 | |
97 | /* This is called by the Go frontend proper to add data to the | |
612cc2ea | 98 | section containing Go export data. */ |
f3231e7d | 99 | |
100 | void | |
101 | go_write_export_data (const char *bytes, unsigned int size) | |
102 | { | |
103 | static section* sec; | |
104 | ||
105 | if (sec == NULL) | |
106 | { | |
218e3e4e | 107 | gcc_assert (targetm_common.have_named_sections); |
647ec977 | 108 | sec = get_section (GO_EXPORT_SECTION_NAME, |
109 | TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG, | |
110 | NULL); | |
f3231e7d | 111 | } |
112 | ||
113 | switch_to_section (sec); | |
114 | assemble_string (bytes, size); | |
115 | } | |
612cc2ea | 116 | |
117 | /* The go_read_export_data function is called by the Go frontend | |
118 | proper to read Go export data from an object file. FD is a file | |
119 | descriptor open for reading. OFFSET is the offset within the file | |
120 | where the object file starts; this will be 0 except when reading an | |
121 | archive. On success this returns NULL and sets *PBUF to a buffer | |
122 | allocated using malloc, of size *PLEN, holding the export data. If | |
123 | the data is not found, this returns NULL and sets *PBUF to NULL and | |
124 | *PLEN to 0. If some error occurs, this returns an error message | |
125 | and sets *PERR to an errno value or 0 if there is no relevant | |
126 | errno. */ | |
127 | ||
128 | const char * | |
129 | go_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen, | |
130 | int *perr) | |
131 | { | |
132 | simple_object_read *sobj; | |
133 | const char *errmsg; | |
134 | off_t sec_offset; | |
135 | off_t sec_length; | |
136 | int found; | |
137 | char *buf; | |
138 | ssize_t c; | |
139 | ||
140 | *pbuf = NULL; | |
141 | *plen = 0; | |
142 | ||
143 | sobj = simple_object_start_read (fd, offset, GO_EXPORT_SEGMENT_NAME, | |
144 | &errmsg, perr); | |
145 | if (sobj == NULL) | |
146 | { | |
147 | /* If we get an error here, just pretend that we didn't find any | |
148 | export data. This is the right thing to do if the error is | |
149 | that the file was not recognized as an object file. This | |
150 | will ignore file I/O errors, but it's not too big a deal | |
151 | because we will wind up giving some other error later. */ | |
152 | return NULL; | |
153 | } | |
154 | ||
155 | found = simple_object_find_section (sobj, GO_EXPORT_SECTION_NAME, | |
156 | &sec_offset, &sec_length, | |
157 | &errmsg, perr); | |
158 | simple_object_release_read (sobj); | |
159 | if (!found) | |
160 | return errmsg; | |
161 | ||
162 | if (lseek (fd, offset + sec_offset, SEEK_SET) < 0) | |
163 | { | |
164 | *perr = errno; | |
165 | return _("lseek failed while reading export data"); | |
166 | } | |
167 | ||
168 | buf = XNEWVEC (char, sec_length); | |
169 | if (buf == NULL) | |
170 | { | |
171 | *perr = errno; | |
172 | return _("memory allocation failed while reading export data"); | |
173 | } | |
174 | ||
175 | c = read (fd, buf, sec_length); | |
176 | if (c < 0) | |
177 | { | |
178 | *perr = errno; | |
179 | free (buf); | |
180 | return _("read failed while reading export data"); | |
181 | } | |
182 | ||
183 | if (c < sec_length) | |
184 | { | |
185 | free (buf); | |
186 | return _("short read while reading export data"); | |
187 | } | |
188 | ||
189 | *pbuf = buf; | |
190 | *plen = sec_length; | |
191 | ||
192 | return NULL; | |
193 | } |