1 /* simple-object.c -- simple routines to read and write object files.
2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Google.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 51 Franklin Street - Fifth Floor,
18 Boston, MA 02110-1301, USA. */
21 #include "libiberty.h"
22 #include "simple-object.h"
39 #ifdef HAVE_INTTYPES_H
47 #include "simple-object-common.h"
49 /* The known object file formats. */
51 static const struct simple_object_functions
* const format_functions
[] =
53 &simple_object_elf_functions
,
54 &simple_object_mach_o_functions
,
55 &simple_object_coff_functions
,
56 &simple_object_xcoff_functions
59 /* Read data from a file using the simple_object error reporting
63 simple_object_internal_read (int descriptor
, off_t offset
,
64 unsigned char *buffer
, size_t size
,
65 const char **errmsg
, int *err
)
67 if (lseek (descriptor
, offset
, SEEK_SET
) < 0)
76 ssize_t got
= read (descriptor
, buffer
, size
);
84 else if (errno
!= EINTR
)
95 *errmsg
= "file too short";
103 /* Write data to a file using the simple_object error reporting
107 simple_object_internal_write (int descriptor
, off_t offset
,
108 const unsigned char *buffer
, size_t size
,
109 const char **errmsg
, int *err
)
111 if (lseek (descriptor
, offset
, SEEK_SET
) < 0)
120 ssize_t wrote
= write (descriptor
, buffer
, size
);
128 else if (errno
!= EINTR
)
139 *errmsg
= "short write";
150 simple_object_start_read (int descriptor
, off_t offset
,
151 const char *segment_name
, const char **errmsg
,
154 unsigned char header
[SIMPLE_OBJECT_MATCH_HEADER_LEN
];
157 if (!simple_object_internal_read (descriptor
, offset
, header
,
158 SIMPLE_OBJECT_MATCH_HEADER_LEN
,
162 len
= sizeof (format_functions
) / sizeof (format_functions
[0]);
163 for (i
= 0; i
< len
; ++i
)
167 data
= format_functions
[i
]->match (header
, descriptor
, offset
,
168 segment_name
, errmsg
, err
);
171 simple_object_read
*ret
;
173 ret
= XNEW (simple_object_read
);
174 ret
->descriptor
= descriptor
;
175 ret
->offset
= offset
;
176 ret
->functions
= format_functions
[i
];
182 *errmsg
= "file not recognized";
187 /* Find all sections. */
190 simple_object_find_sections (simple_object_read
*sobj
,
191 int (*pfn
) (void *, const char *, off_t
, off_t
),
195 return sobj
->functions
->find_sections (sobj
, pfn
, data
, err
);
198 /* Internal data passed to find_one_section. */
200 struct find_one_section_data
202 /* The section we are looking for. */
204 /* Where to store the section offset. */
206 /* Where to store the section length. */
208 /* Set if the name is found. */
212 /* Internal function passed to find_sections. */
215 find_one_section (void *data
, const char *name
, off_t offset
, off_t length
)
217 struct find_one_section_data
*fosd
= (struct find_one_section_data
*) data
;
219 if (strcmp (name
, fosd
->name
) != 0)
222 *fosd
->offset
= offset
;
223 *fosd
->length
= length
;
226 /* Stop iteration. */
230 /* Find a section. */
233 simple_object_find_section (simple_object_read
*sobj
, const char *name
,
234 off_t
*offset
, off_t
*length
,
235 const char **errmsg
, int *err
)
237 struct find_one_section_data fosd
;
240 fosd
.offset
= offset
;
241 fosd
.length
= length
;
244 *errmsg
= simple_object_find_sections (sobj
, find_one_section
,
245 (void *) &fosd
, err
);
253 /* Callback to identify and rename LTO debug sections by name.
254 Returns 1 if NAME is a LTO debug section, 0 if not. */
257 handle_lto_debug_sections (const char *name
)
259 char *newname
= XCNEWVEC (char, strlen (name
) + 1);
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). */
265 /* Also include corresponding reloc sections. */
266 if (strncmp (name
, ".rela", sizeof (".rela") - 1) == 0)
268 strncpy (newname
, name
, sizeof (".rela") - 1);
269 name
+= sizeof (".rela") - 1;
271 else if (strncmp (name
, ".rel", sizeof (".rel") - 1) == 0)
273 strncpy (newname
, name
, sizeof (".rel") - 1);
274 name
+= sizeof (".rel") - 1;
276 /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
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);
284 /* Copy over .note.GNU-stack section under the same name if present. */
285 else if (strcmp (name
, ".note.GNU-stack") == 0)
286 return strcpy (newname
, name
);
290 /* Copy LTO debug sections. */
293 simple_object_copy_lto_debug_sections (simple_object_read
*sobj
,
294 const char *dest
, int *err
)
297 simple_object_write
*dest_sobj
;
298 simple_object_attributes
*attrs
;
301 if (! sobj
->functions
->copy_lto_debug_sections
)
304 return "simple_object_copy_lto_debug_sections not implemented";
307 attrs
= simple_object_fetch_attributes (sobj
, &errmsg
, err
);
310 dest_sobj
= simple_object_start_write (attrs
, NULL
, &errmsg
, err
);
311 simple_object_release_attributes (attrs
);
315 errmsg
= sobj
->functions
->copy_lto_debug_sections (sobj
, dest_sobj
,
316 handle_lto_debug_sections
,
320 simple_object_release_write (dest_sobj
);
324 outfd
= creat (dest
, 00777);
328 simple_object_release_write (dest_sobj
);
329 return "open failed";
332 errmsg
= simple_object_write_to_file (dest_sobj
, outfd
, err
);
336 simple_object_release_write (dest_sobj
);
340 simple_object_release_write (dest_sobj
);
344 /* Fetch attributes. */
346 simple_object_attributes
*
347 simple_object_fetch_attributes (simple_object_read
*sobj
, const char **errmsg
,
351 simple_object_attributes
*ret
;
353 data
= sobj
->functions
->fetch_attributes (sobj
, errmsg
, err
);
356 ret
= XNEW (simple_object_attributes
);
357 ret
->functions
= sobj
->functions
;
362 /* Release an simple_object_read. */
365 simple_object_release_read (simple_object_read
*sobj
)
367 sobj
->functions
->release_read (sobj
->data
);
371 /* Merge attributes. */
374 simple_object_attributes_merge (simple_object_attributes
*to
,
375 simple_object_attributes
*from
,
378 if (to
->functions
!= from
->functions
)
381 return "different object file format";
383 return to
->functions
->attributes_merge (to
->data
, from
->data
, err
);
386 /* Release an attributes structure. */
389 simple_object_release_attributes (simple_object_attributes
*attrs
)
391 attrs
->functions
->release_attributes (attrs
->data
);
395 /* Start creating an object file. */
397 simple_object_write
*
398 simple_object_start_write (simple_object_attributes
*attrs
,
399 const char *segment_name
, const char **errmsg
,
403 simple_object_write
*ret
;
405 data
= attrs
->functions
->start_write (attrs
->data
, errmsg
, err
);
408 ret
= XNEW (simple_object_write
);
409 ret
->functions
= attrs
->functions
;
410 ret
->segment_name
= segment_name
? xstrdup (segment_name
) : NULL
;
411 ret
->sections
= NULL
;
412 ret
->last_section
= NULL
;
417 /* Start creating a section. */
419 simple_object_write_section
*
420 simple_object_write_create_section (simple_object_write
*sobj
, const char *name
,
422 const char **errmsg ATTRIBUTE_UNUSED
,
423 int *err ATTRIBUTE_UNUSED
)
425 simple_object_write_section
*ret
;
427 ret
= XNEW (simple_object_write_section
);
429 ret
->name
= xstrdup (name
);
432 ret
->last_buffer
= NULL
;
434 if (sobj
->last_section
== NULL
)
436 sobj
->sections
= ret
;
437 sobj
->last_section
= ret
;
441 sobj
->last_section
->next
= ret
;
442 sobj
->last_section
= ret
;
448 /* Add data to a section. */
451 simple_object_write_add_data (simple_object_write
*sobj ATTRIBUTE_UNUSED
,
452 simple_object_write_section
*section
,
454 size_t size
, int copy
,
455 int *err ATTRIBUTE_UNUSED
)
457 struct simple_object_write_section_buffer
*wsb
;
459 wsb
= XNEW (struct simple_object_write_section_buffer
);
465 wsb
->buffer
= buffer
;
466 wsb
->free_buffer
= NULL
;
470 wsb
->free_buffer
= (void *) XNEWVEC (char, size
);
471 memcpy (wsb
->free_buffer
, buffer
, size
);
472 wsb
->buffer
= wsb
->free_buffer
;
475 if (section
->last_buffer
== NULL
)
477 section
->buffers
= wsb
;
478 section
->last_buffer
= wsb
;
482 section
->last_buffer
->next
= wsb
;
483 section
->last_buffer
= wsb
;
489 /* Write the complete object file. */
492 simple_object_write_to_file (simple_object_write
*sobj
, int descriptor
,
495 return sobj
->functions
->write_to_file (sobj
, descriptor
, err
);
498 /* Release an simple_object_write. */
501 simple_object_release_write (simple_object_write
*sobj
)
503 simple_object_write_section
*section
;
505 free (sobj
->segment_name
);
507 section
= sobj
->sections
;
508 while (section
!= NULL
)
510 struct simple_object_write_section_buffer
*buffer
;
511 simple_object_write_section
*next_section
;
513 buffer
= section
->buffers
;
514 while (buffer
!= NULL
)
516 struct simple_object_write_section_buffer
*next_buffer
;
518 if (buffer
->free_buffer
!= NULL
)
519 XDELETEVEC (buffer
->free_buffer
);
520 next_buffer
= buffer
->next
;
522 buffer
= next_buffer
;
525 next_section
= section
->next
;
526 free (section
->name
);
528 section
= next_section
;
531 sobj
->functions
->release_write (sobj
->data
);