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