config: Sync with GCC
[deliverable/binutils-gdb.git] / libiberty / simple-object.c
CommitLineData
ffa54e5c 1/* simple-object.c -- simple routines to read and write object files.
2a8ae714 2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
ffa54e5c
DD
3 Written by Ian Lance Taylor, Google.
4
5This program is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option) any
8later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 51 Franklin Street - Fifth Floor,
18Boston, MA 02110-1301, USA. */
19
20#include "config.h"
21#include "libiberty.h"
22#include "simple-object.h"
23
24#include <errno.h>
f8ad2513 25#include <fcntl.h>
ffa54e5c
DD
26
27#ifdef HAVE_STDLIB_H
28#include <stdlib.h>
29#endif
30
31#ifdef HAVE_STDINT_H
32#include <stdint.h>
33#endif
34
35#ifdef HAVE_STRING_H
36#include <string.h>
37#endif
38
39#ifdef HAVE_INTTYPES_H
40#include <inttypes.h>
41#endif
42
43#ifndef SEEK_SET
44#define SEEK_SET 0
45#endif
46
47#include "simple-object-common.h"
48
49/* The known object file formats. */
50
51static const struct simple_object_functions * const format_functions[] =
52{
53 &simple_object_elf_functions,
54 &simple_object_mach_o_functions,
07a8e9f0
DD
55 &simple_object_coff_functions,
56 &simple_object_xcoff_functions
ffa54e5c
DD
57};
58
59/* Read data from a file using the simple_object error reporting
60 conventions. */
61
62int
63simple_object_internal_read (int descriptor, off_t offset,
64 unsigned char *buffer, size_t size,
65 const char **errmsg, int *err)
66{
ffa54e5c
DD
67 if (lseek (descriptor, offset, SEEK_SET) < 0)
68 {
69 *errmsg = "lseek";
70 *err = errno;
71 return 0;
72 }
73
81ad11e3 74 do
ffa54e5c 75 {
81ad11e3 76 ssize_t got = read (descriptor, buffer, size);
77 if (got == 0)
78 break;
79 else if (got > 0)
80 {
81 buffer += got;
82 size -= got;
83 }
84 else if (errno != EINTR)
85 {
86 *errmsg = "read";
87 *err = errno;
88 return 0;
89 }
ffa54e5c 90 }
81ad11e3 91 while (size > 0);
ffa54e5c 92
81ad11e3 93 if (size > 0)
ffa54e5c
DD
94 {
95 *errmsg = "file too short";
96 *err = 0;
97 return 0;
98 }
99
100 return 1;
101}
102
103/* Write data to a file using the simple_object error reporting
104 conventions. */
105
106int
107simple_object_internal_write (int descriptor, off_t offset,
108 const unsigned char *buffer, size_t size,
109 const char **errmsg, int *err)
110{
ffa54e5c
DD
111 if (lseek (descriptor, offset, SEEK_SET) < 0)
112 {
113 *errmsg = "lseek";
114 *err = errno;
115 return 0;
116 }
117
c3c3c691 118 do
ffa54e5c 119 {
c3c3c691 120 ssize_t wrote = write (descriptor, buffer, size);
121 if (wrote == 0)
122 break;
123 else if (wrote > 0)
124 {
125 buffer += wrote;
126 size -= wrote;
127 }
128 else if (errno != EINTR)
129 {
130 *errmsg = "write";
131 *err = errno;
132 return 0;
133 }
ffa54e5c 134 }
c3c3c691 135 while (size > 0);
ffa54e5c 136
c3c3c691 137 if (size > 0)
ffa54e5c
DD
138 {
139 *errmsg = "short write";
140 *err = 0;
141 return 0;
142 }
143
144 return 1;
145}
146
147/* Open for read. */
148
149simple_object_read *
150simple_object_start_read (int descriptor, off_t offset,
151 const char *segment_name, const char **errmsg,
152 int *err)
153{
154 unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
155 size_t len, i;
156
157 if (!simple_object_internal_read (descriptor, offset, header,
158 SIMPLE_OBJECT_MATCH_HEADER_LEN,
159 errmsg, err))
160 return NULL;
161
162 len = sizeof (format_functions) / sizeof (format_functions[0]);
163 for (i = 0; i < len; ++i)
164 {
165 void *data;
166
167 data = format_functions[i]->match (header, descriptor, offset,
168 segment_name, errmsg, err);
169 if (data != NULL)
170 {
171 simple_object_read *ret;
172
173 ret = XNEW (simple_object_read);
174 ret->descriptor = descriptor;
175 ret->offset = offset;
176 ret->functions = format_functions[i];
177 ret->data = data;
178 return ret;
179 }
180 }
181
182 *errmsg = "file not recognized";
183 *err = 0;
184 return NULL;
185}
186
187/* Find all sections. */
188
189const char *
190simple_object_find_sections (simple_object_read *sobj,
191 int (*pfn) (void *, const char *, off_t, off_t),
192 void *data,
193 int *err)
194{
195 return sobj->functions->find_sections (sobj, pfn, data, err);
196}
197
198/* Internal data passed to find_one_section. */
199
200struct find_one_section_data
201{
202 /* The section we are looking for. */
203 const char *name;
204 /* Where to store the section offset. */
205 off_t *offset;
206 /* Where to store the section length. */
207 off_t *length;
208 /* Set if the name is found. */
209 int found;
210};
211
212/* Internal function passed to find_sections. */
213
214static int
215find_one_section (void *data, const char *name, off_t offset, off_t length)
216{
217 struct find_one_section_data *fosd = (struct find_one_section_data *) data;
218
219 if (strcmp (name, fosd->name) != 0)
220 return 1;
221
222 *fosd->offset = offset;
223 *fosd->length = length;
224 fosd->found = 1;
225
226 /* Stop iteration. */
227 return 0;
228}
229
230/* Find a section. */
231
232int
233simple_object_find_section (simple_object_read *sobj, const char *name,
234 off_t *offset, off_t *length,
235 const char **errmsg, int *err)
236{
237 struct find_one_section_data fosd;
238
239 fosd.name = name;
240 fosd.offset = offset;
241 fosd.length = length;
242 fosd.found = 0;
243
244 *errmsg = simple_object_find_sections (sobj, find_one_section,
245 (void *) &fosd, err);
246 if (*errmsg != NULL)
247 return 0;
248 if (!fosd.found)
249 return 0;
250 return 1;
251}
252
f8ad2513
NC
253/* Callback to identify and rename LTO debug sections by name.
254 Returns 1 if NAME is a LTO debug section, 0 if not. */
255
e9301e76
NC
256static char *
257handle_lto_debug_sections (const char *name)
f8ad2513 258{
e9301e76
NC
259 char *newname = XCNEWVEC (char, strlen (name) + 1);
260
f8ad2513
NC
261 /* ??? So we can't use .gnu.lto_ prefixed sections as the assembler
262 complains about bogus section flags. Which means we need to arrange
263 for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make
264 fat lto object tooling work for the fat part). */
e9301e76
NC
265 /* Also include corresponding reloc sections. */
266 if (strncmp (name, ".rela", sizeof (".rela") - 1) == 0)
f8ad2513 267 {
e9301e76
NC
268 strncpy (newname, name, sizeof (".rela") - 1);
269 name += sizeof (".rela") - 1;
f8ad2513 270 }
e9301e76 271 else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0)
f8ad2513 272 {
e9301e76
NC
273 strncpy (newname, name, sizeof (".rel") - 1);
274 name += sizeof (".rel") - 1;
f8ad2513 275 }
e9301e76
NC
276 /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
277 sections. */
278 /* Copy LTO debug sections and rename them to their non-LTO name. */
279 if (strncmp (name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0)
280 return strcat (newname, name + sizeof (".gnu.debuglto_") - 1);
281 else if (strncmp (name, ".gnu.lto_.debug_",
282 sizeof (".gnu.lto_.debug_") -1) == 0)
283 return strcat (newname, name + sizeof (".gnu.lto_") - 1);
2a8ae714 284 /* Copy over .note.GNU-stack section under the same name if present. */
e9301e76
NC
285 else if (strcmp (name, ".note.GNU-stack") == 0)
286 return strcpy (newname, name);
287 /* Copy over .comment section under the same name if present. Solaris
288 ld uses them to relax its checking of ELF gABI access rules for
289 COMDAT sections in objects produced by GCC. */
290 else if (strcmp (name, ".comment") == 0)
291 return strcpy (newname, name);
292 return NULL;
f8ad2513
NC
293}
294
295/* Copy LTO debug sections. */
296
297const char *
298simple_object_copy_lto_debug_sections (simple_object_read *sobj,
299 const char *dest, int *err)
300{
301 const char *errmsg;
302 simple_object_write *dest_sobj;
303 simple_object_attributes *attrs;
304 int outfd;
305
306 if (! sobj->functions->copy_lto_debug_sections)
307 {
308 *err = EINVAL;
309 return "simple_object_copy_lto_debug_sections not implemented";
310 }
311
312 attrs = simple_object_fetch_attributes (sobj, &errmsg, err);
313 if (! attrs)
314 return errmsg;
315 dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err);
316 simple_object_release_attributes (attrs);
317 if (! dest_sobj)
318 return errmsg;
319
320 errmsg = sobj->functions->copy_lto_debug_sections (sobj, dest_sobj,
321 handle_lto_debug_sections,
322 err);
323 if (errmsg)
324 {
325 simple_object_release_write (dest_sobj);
326 return errmsg;
327 }
328
329 outfd = creat (dest, 00777);
330 if (outfd == -1)
331 {
332 *err = errno;
333 simple_object_release_write (dest_sobj);
334 return "open failed";
335 }
336
337 errmsg = simple_object_write_to_file (dest_sobj, outfd, err);
338 close (outfd);
339 if (errmsg)
340 {
341 simple_object_release_write (dest_sobj);
342 return errmsg;
343 }
344
345 simple_object_release_write (dest_sobj);
346 return NULL;
347}
348
ffa54e5c
DD
349/* Fetch attributes. */
350
351simple_object_attributes *
352simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
353 int *err)
354{
355 void *data;
356 simple_object_attributes *ret;
357
358 data = sobj->functions->fetch_attributes (sobj, errmsg, err);
359 if (data == NULL)
360 return NULL;
361 ret = XNEW (simple_object_attributes);
362 ret->functions = sobj->functions;
363 ret->data = data;
364 return ret;
365}
366
367/* Release an simple_object_read. */
368
369void
370simple_object_release_read (simple_object_read *sobj)
371{
372 sobj->functions->release_read (sobj->data);
373 XDELETE (sobj);
374}
375
f9e6589d 376/* Merge attributes. */
ffa54e5c
DD
377
378const char *
f9e6589d
DD
379simple_object_attributes_merge (simple_object_attributes *to,
380 simple_object_attributes *from,
381 int *err)
ffa54e5c 382{
f9e6589d 383 if (to->functions != from->functions)
ffa54e5c
DD
384 {
385 *err = 0;
386 return "different object file format";
387 }
f9e6589d 388 return to->functions->attributes_merge (to->data, from->data, err);
ffa54e5c
DD
389}
390
391/* Release an attributes structure. */
392
393void
394simple_object_release_attributes (simple_object_attributes *attrs)
395{
396 attrs->functions->release_attributes (attrs->data);
397 XDELETE (attrs);
398}
399
400/* Start creating an object file. */
401
402simple_object_write *
403simple_object_start_write (simple_object_attributes *attrs,
404 const char *segment_name, const char **errmsg,
405 int *err)
406{
407 void *data;
408 simple_object_write *ret;
409
410 data = attrs->functions->start_write (attrs->data, errmsg, err);
411 if (data == NULL)
412 return NULL;
413 ret = XNEW (simple_object_write);
414 ret->functions = attrs->functions;
f8ad2513 415 ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
ffa54e5c
DD
416 ret->sections = NULL;
417 ret->last_section = NULL;
418 ret->data = data;
419 return ret;
420}
421
422/* Start creating a section. */
423
424simple_object_write_section *
425simple_object_write_create_section (simple_object_write *sobj, const char *name,
426 unsigned int align,
427 const char **errmsg ATTRIBUTE_UNUSED,
428 int *err ATTRIBUTE_UNUSED)
429{
430 simple_object_write_section *ret;
431
432 ret = XNEW (simple_object_write_section);
433 ret->next = NULL;
434 ret->name = xstrdup (name);
435 ret->align = align;
436 ret->buffers = NULL;
437 ret->last_buffer = NULL;
438
439 if (sobj->last_section == NULL)
440 {
441 sobj->sections = ret;
442 sobj->last_section = ret;
443 }
444 else
445 {
446 sobj->last_section->next = ret;
447 sobj->last_section = ret;
448 }
449
450 return ret;
451}
452
453/* Add data to a section. */
454
455const char *
456simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
457 simple_object_write_section *section,
458 const void *buffer,
459 size_t size, int copy,
460 int *err ATTRIBUTE_UNUSED)
461{
462 struct simple_object_write_section_buffer *wsb;
463
464 wsb = XNEW (struct simple_object_write_section_buffer);
465 wsb->next = NULL;
466 wsb->size = size;
467
468 if (!copy)
469 {
470 wsb->buffer = buffer;
471 wsb->free_buffer = NULL;
472 }
473 else
474 {
475 wsb->free_buffer = (void *) XNEWVEC (char, size);
476 memcpy (wsb->free_buffer, buffer, size);
477 wsb->buffer = wsb->free_buffer;
478 }
479
480 if (section->last_buffer == NULL)
481 {
482 section->buffers = wsb;
483 section->last_buffer = wsb;
484 }
485 else
486 {
487 section->last_buffer->next = wsb;
488 section->last_buffer = wsb;
489 }
490
491 return NULL;
492}
493
494/* Write the complete object file. */
495
496const char *
497simple_object_write_to_file (simple_object_write *sobj, int descriptor,
498 int *err)
499{
500 return sobj->functions->write_to_file (sobj, descriptor, err);
501}
502
503/* Release an simple_object_write. */
504
505void
506simple_object_release_write (simple_object_write *sobj)
507{
508 simple_object_write_section *section;
509
510 free (sobj->segment_name);
511
512 section = sobj->sections;
513 while (section != NULL)
514 {
515 struct simple_object_write_section_buffer *buffer;
516 simple_object_write_section *next_section;
517
518 buffer = section->buffers;
519 while (buffer != NULL)
520 {
521 struct simple_object_write_section_buffer *next_buffer;
522
523 if (buffer->free_buffer != NULL)
524 XDELETEVEC (buffer->free_buffer);
525 next_buffer = buffer->next;
526 XDELETE (buffer);
527 buffer = next_buffer;
528 }
529
530 next_section = section->next;
531 free (section->name);
532 XDELETE (section);
533 section = next_section;
534 }
535
536 sobj->functions->release_write (sobj->data);
537 XDELETE (sobj);
538}
This page took 0.440575 seconds and 4 git commands to generate.