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