1 /* LTO routines to use object files.
2 Copyright (C) 2010-2024 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Google.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "diagnostic-core.h"
27 #include "lto-section-names.h"
28 #include "simple-object.h"
30 /* An LTO file wrapped around an simple_object. */
32 struct lto_simple_object
34 /* The base information. */
37 /* The system file descriptor. */
40 /* The simple_object if we are reading the file. */
41 simple_object_read
*sobj_r
;
43 /* The simple_object if we are writing the file. */
44 simple_object_write
*sobj_w
;
46 /* The currently active section. */
47 simple_object_write_section
*section
;
50 /* Saved simple_object attributes. FIXME: Once set, this is never
53 static simple_object_attributes
*saved_attributes
;
55 /* Initialize FILE, an LTO file object for FILENAME. */
58 lto_file_init (lto_file
*file
, const char *filename
, off_t offset
)
60 file
->filename
= filename
;
61 file
->offset
= offset
;
64 /* Open the file FILENAME. It WRITABLE is true, the file is opened
65 for write and, if necessary, created. Otherwise, the file is
66 opened for reading. Returns the opened file. */
69 lto_obj_file_open (const char *filename
, bool writable
)
76 struct lto_simple_object
*lo
;
80 offset_p
= strrchr (filename
, '@');
82 && offset_p
!= filename
83 && sscanf (offset_p
, "@%li%n", &loffset
, &consumed
) >= 1
84 && strlen (offset_p
) == (unsigned int) consumed
)
86 fname
= XNEWVEC (char, offset_p
- filename
+ 1);
87 memcpy (fname
, filename
, offset_p
- filename
);
88 fname
[offset_p
- filename
] = '\0';
89 offset
= (off_t
) loffset
;
93 fname
= xstrdup (filename
);
97 lo
= XCNEW (struct lto_simple_object
);
98 lto_file_init ((lto_file
*) lo
, fname
, offset
);
100 lo
->fd
= open (fname
,
102 ? O_WRONLY
| O_CREAT
| O_BINARY
103 : O_RDONLY
| O_BINARY
),
106 fatal_error (input_location
, "open %s failed: %s", fname
, xstrerror (errno
));
110 simple_object_attributes
*attrs
;
112 lo
->sobj_r
= simple_object_start_read (lo
->fd
, offset
, LTO_SEGMENT_NAME
,
114 if (lo
->sobj_r
== NULL
)
117 attrs
= simple_object_fetch_attributes (lo
->sobj_r
, &errmsg
, &err
);
121 if (saved_attributes
== NULL
)
122 saved_attributes
= attrs
;
125 errmsg
= simple_object_attributes_merge (saved_attributes
, attrs
,
136 gcc_assert (saved_attributes
!= NULL
);
137 lo
->sobj_w
= simple_object_start_write (saved_attributes
,
140 if (lo
->sobj_w
== NULL
)
148 error ("%s: %s", fname
, errmsg
);
150 error ("%s: %s: %s", fname
, errmsg
, xstrerror (err
));
153 lto_obj_file_close ((lto_file
*) lo
);
159 /* Close FILE. If FILE was opened for writing, it is written out
163 lto_obj_file_close (lto_file
*file
)
165 struct lto_simple_object
*lo
= (struct lto_simple_object
*) file
;
167 if (lo
->sobj_r
!= NULL
)
168 simple_object_release_read (lo
->sobj_r
);
169 else if (lo
->sobj_w
!= NULL
)
174 gcc_assert (lo
->base
.offset
== 0);
176 errmsg
= simple_object_write_to_file (lo
->sobj_w
, lo
->fd
, &err
);
180 fatal_error (input_location
, "%s", errmsg
);
182 fatal_error (input_location
, "%s: %s", errmsg
, xstrerror (err
));
185 simple_object_release_write (lo
->sobj_w
);
190 if (close (lo
->fd
) < 0)
191 fatal_error (input_location
, "close: %s", xstrerror (errno
));
195 /* This is passed to lto_obj_add_section. */
197 struct lto_obj_add_section_data
199 /* The hash table of sections. */
200 htab_t section_hash_table
;
201 /* The offset of this file. */
203 /* List in linker order */
204 struct lto_section_list
*list
;
207 /* This is called for each section in the file. */
210 lto_obj_add_section (void *data
, const char *name
, off_t offset
,
213 struct lto_obj_add_section_data
*loasd
=
214 (struct lto_obj_add_section_data
*) data
;
215 htab_t section_hash_table
= (htab_t
) loasd
->section_hash_table
;
217 struct lto_section_slot s_slot
;
219 struct lto_section_list
*list
= loasd
->list
;
221 if (strncmp (name
, section_name_prefix
, strlen (section_name_prefix
)))
224 new_name
= xstrdup (name
);
225 s_slot
.name
= new_name
;
226 slot
= htab_find_slot (section_hash_table
, &s_slot
, INSERT
);
229 struct lto_section_slot
*new_slot
= XCNEW (struct lto_section_slot
);
231 new_slot
->name
= new_name
;
232 new_slot
->start
= loasd
->base_offset
+ offset
;
233 new_slot
->len
= length
;
239 list
->first
= new_slot
;
241 list
->last
->next
= new_slot
;
242 list
->last
= new_slot
;
247 error ("two or more sections for %s", new_name
);
254 /* Build a hash table whose key is the section name and whose data is
255 the start and size of each section in the .o file. */
258 lto_obj_build_section_table (lto_file
*lto_file
, struct lto_section_list
*list
)
260 struct lto_simple_object
*lo
= (struct lto_simple_object
*) lto_file
;
261 htab_t section_hash_table
;
262 struct lto_obj_add_section_data loasd
;
266 section_hash_table
= lto_obj_create_section_hash_table ();
268 gcc_assert (lo
->sobj_r
!= NULL
&& lo
->sobj_w
== NULL
);
269 loasd
.section_hash_table
= section_hash_table
;
270 loasd
.base_offset
= lo
->base
.offset
;
272 errmsg
= simple_object_find_sections (lo
->sobj_r
, lto_obj_add_section
,
277 error ("%s", errmsg
);
279 error ("%s: %s", errmsg
, xstrerror (err
));
280 htab_delete (section_hash_table
);
284 return section_hash_table
;
287 /* The current output file. */
289 static lto_file
*current_out_file
;
291 /* Set the current output file. Return the old one. */
294 lto_set_current_out_file (lto_file
*file
)
298 old_file
= current_out_file
;
299 current_out_file
= file
;
303 /* Return the current output file. */
306 lto_get_current_out_file (void)
308 return current_out_file
;
311 /* Begin writing a new section named NAME in the current output
315 lto_obj_begin_section (const char *name
)
317 struct lto_simple_object
*lo
;
322 lo
= (struct lto_simple_object
*) current_out_file
;
323 gcc_assert (lo
!= NULL
324 && lo
->sobj_r
== NULL
325 && lo
->sobj_w
!= NULL
326 && lo
->section
== NULL
);
328 align
= ceil_log2 (POINTER_SIZE_UNITS
);
329 lo
->section
= simple_object_write_create_section (lo
->sobj_w
, name
, align
,
331 if (lo
->section
== NULL
)
334 fatal_error (input_location
, "%s", errmsg
);
336 fatal_error (input_location
, "%s: %s", errmsg
, xstrerror (errno
));
340 /* Add data to a section. BLOCK is a pointer to memory containing
344 lto_obj_append_data (const void *data
, size_t len
, void *)
346 struct lto_simple_object
*lo
;
350 lo
= (struct lto_simple_object
*) current_out_file
;
351 gcc_assert (lo
!= NULL
&& lo
->section
!= NULL
);
353 errmsg
= simple_object_write_add_data (lo
->sobj_w
, lo
->section
, data
, len
,
358 fatal_error (input_location
, "%s", errmsg
);
360 fatal_error (input_location
, "%s: %s", errmsg
, xstrerror (errno
));
364 /* Stop writing to the current output section. */
367 lto_obj_end_section (void)
369 struct lto_simple_object
*lo
;
371 lo
= (struct lto_simple_object
*) current_out_file
;
372 gcc_assert (lo
!= NULL
&& lo
->section
!= NULL
);