]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/rust-object-export.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / rust-object-export.cc
1 /* rust-backend.c -- Rust 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 "rust-system.h"
21 #include "coretypes.h"
22 #include "target.h"
23 #include "tree.h"
24 #include "memmodel.h"
25 #include "tm_p.h"
26 #include "diagnostic.h"
27 #include "simple-object.h"
28 #include "stor-layout.h"
29 #include "intl.h"
30 #include "output.h" /* for assemble_string */
31 #include "common/common-target.h"
32
33 // satisfy intellisense
34 #include "options.h"
35
36 /* The segment name we pass to simple_object_start_read to find Rust
37 export data. */
38
39 #ifndef RUST_EXPORT_SEGMENT_NAME
40 #define RUST_EXPORT_SEGMENT_NAME "__GNU_RUST"
41 #endif
42
43 /* The section name we use when reading and writing export data. */
44
45 #ifndef RUST_EXPORT_SECTION_NAME
46 #define RUST_EXPORT_SECTION_NAME ".rust_export"
47 #endif
48
49 #ifndef TARGET_AIX_OS
50 #define TARGET_AIX_OS 0
51 #endif
52
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
61 /* Return the alignment in bytes of a struct field of type T. */
62
63 unsigned int
64 rust_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 v = ADJUST_FIELD_ALIGN (NULL_TREE, t, v);
77 #endif
78
79 return v / BITS_PER_UNIT;
80 }
81
82 /* This is called by the Rust frontend proper to add data to the
83 section containing Rust export data. */
84
85 void
86 rust_write_export_data (const char *bytes, unsigned int size)
87 {
88 static section *sec;
89
90 if (sec == NULL)
91 {
92 gcc_assert (targetm_common.have_named_sections);
93 sec = get_section (RUST_EXPORT_SECTION_NAME,
94 TARGET_AIX_OS ? SECTION_EXCLUDE : SECTION_DEBUG, NULL);
95 }
96
97 switch_to_section (sec);
98 assemble_string (bytes, size);
99 }
100
101 /* The rust_read_export_data function is called by the Rust frontend
102 proper to read Rust export data from an object file. FD is a file
103 descriptor open for reading. OFFSET is the offset within the file
104 where the object file starts; this will be 0 except when reading an
105 archive. On success this returns NULL and sets *PBUF to a buffer
106 allocated using malloc, of size *PLEN, holding the export data. If
107 the data is not found, this returns NULL and sets *PBUF to NULL and
108 *PLEN to 0. If some error occurs, this returns an error message
109 and sets *PERR to an errno value or 0 if there is no relevant
110 errno. */
111
112 const char *
113 rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
114 int *perr)
115 {
116 simple_object_read *sobj;
117 const char *errmsg;
118 off_t sec_offset;
119 off_t sec_length;
120 int found;
121 char *buf;
122 ssize_t c;
123
124 *pbuf = NULL;
125 *plen = 0;
126
127 sobj = simple_object_start_read (fd, offset, RUST_EXPORT_SEGMENT_NAME,
128 &errmsg, perr);
129 if (sobj == NULL)
130 {
131 /* If we get an error here, just pretend that we didn't find any
132 export data. This is the right thing to do if the error is
133 that the file was not recognized as an object file. This
134 will ignore file I/O errors, but it's not too big a deal
135 because we will wind up giving some other error later. */
136 return NULL;
137 }
138
139 found = simple_object_find_section (sobj, RUST_EXPORT_SECTION_NAME,
140 &sec_offset, &sec_length, &errmsg, perr);
141 simple_object_release_read (sobj);
142 if (!found)
143 return errmsg;
144
145 if (lseek (fd, offset + sec_offset, SEEK_SET) < 0)
146 {
147 *perr = errno;
148 return _ ("lseek failed while reading export data");
149 }
150
151 buf = XNEWVEC (char, sec_length);
152 if (buf == NULL)
153 {
154 *perr = errno;
155 return _ ("memory allocation failed while reading export data");
156 }
157
158 c = read (fd, buf, sec_length);
159 if (c < 0)
160 {
161 *perr = errno;
162 free (buf);
163 return _ ("read failed while reading export data");
164 }
165
166 if (c < sec_length)
167 {
168 free (buf);
169 return _ ("short read while reading export data");
170 }
171
172 *pbuf = buf;
173 *plen = sec_length;
174
175 return NULL;
176 }