simple-object.c revision 1.1.1.7
1/* simple-object.c -- simple routines to read and write object files.
2   Copyright (C) 2010-2019 Free Software Foundation, Inc.
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>
25#include <fcntl.h>
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#ifndef O_BINARY
48#define O_BINARY 0
49#endif
50
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,
59  &simple_object_coff_functions,
60  &simple_object_xcoff_functions
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{
71  if (lseek (descriptor, offset, SEEK_SET) < 0)
72    {
73      *errmsg = "lseek";
74      *err = errno;
75      return 0;
76    }
77
78  do
79    {
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	}
94    }
95  while (size > 0);
96
97  if (size > 0)
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{
115  if (lseek (descriptor, offset, SEEK_SET) < 0)
116    {
117      *errmsg = "lseek";
118      *err = errno;
119      return 0;
120    }
121
122  do
123    {
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	}
138    }
139  while (size > 0);
140
141  if (size > 0)
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
257/* Callback to identify and rename LTO debug sections by name.
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.  */
261
262static char *
263handle_lto_debug_sections (const char *name, int rename)
264{
265  char *newname = rename ? XCNEWVEC (char, strlen (name) + 1)
266	  	         : xstrdup (name);
267
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).  */
272  /* Also include corresponding reloc sections.  */
273  if (strncmp (name, ".rela", sizeof (".rela") - 1) == 0)
274    {
275      if (rename)
276        strncpy (newname, name, sizeof (".rela") - 1);
277      name += sizeof (".rela") - 1;
278    }
279  else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0)
280    {
281      if (rename)
282        strncpy (newname, name, sizeof (".rel") - 1);
283      name += sizeof (".rel") - 1;
284    }
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)
289    return rename ? strcat (newname, name + sizeof (".gnu.debuglto_") - 1) : newname;
290  else if (strncmp (name, ".gnu.lto_.debug_",
291		    sizeof (".gnu.lto_.debug_") -1) == 0)
292    return rename ? strcat (newname, name + sizeof (".gnu.lto_") - 1) : newname;
293  /* Copy over .note.GNU-stack section under the same name if present.  */
294  else if (strcmp (name, ".note.GNU-stack") == 0)
295    return strcpy (newname, name);
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);
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);
304  free (newname);
305  return NULL;
306}
307
308/* Wrapper for handle_lto_debug_sections.  */
309
310static char *
311handle_lto_debug_sections_rename (const char *name)
312{
313  return handle_lto_debug_sections (name, 1);
314}
315
316/* Wrapper for handle_lto_debug_sections.  */
317
318static char *
319handle_lto_debug_sections_norename (const char *name)
320{
321  return handle_lto_debug_sections (name, 0);
322}
323
324/* Copy LTO debug sections.  */
325
326const char *
327simple_object_copy_lto_debug_sections (simple_object_read *sobj,
328				       const char *dest, int *err, int rename)
329{
330  const char *errmsg;
331  simple_object_write *dest_sobj;
332  simple_object_attributes *attrs;
333  int outfd;
334
335  if (! sobj->functions->copy_lto_debug_sections)
336    {
337      *err = EINVAL;
338      return "simple_object_copy_lto_debug_sections not implemented";
339    }
340
341  attrs = simple_object_fetch_attributes (sobj, &errmsg, err);
342  if (! attrs)
343    return errmsg;
344  dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err);
345  simple_object_release_attributes (attrs);
346  if (! dest_sobj)
347    return errmsg;
348
349  errmsg = sobj->functions->copy_lto_debug_sections
350	 	 (sobj, dest_sobj,
351		  rename ? handle_lto_debug_sections_rename
352			 : handle_lto_debug_sections_norename,  err);
353  if (errmsg)
354    {
355      simple_object_release_write (dest_sobj);
356      return errmsg;
357    }
358
359  outfd = open (dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, 00777);
360  if (outfd == -1)
361    {
362      *err = errno;
363      simple_object_release_write (dest_sobj);
364      return "open failed";
365    }
366
367  errmsg = simple_object_write_to_file (dest_sobj, outfd, err);
368  close (outfd);
369  if (errmsg)
370    {
371      simple_object_release_write (dest_sobj);
372      return errmsg;
373    }
374
375  simple_object_release_write (dest_sobj);
376  return NULL;
377}
378
379/* Fetch attributes.  */
380
381simple_object_attributes *
382simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
383				int *err)
384{
385  void *data;
386  simple_object_attributes *ret;
387
388  data = sobj->functions->fetch_attributes (sobj, errmsg, err);
389  if (data == NULL)
390    return NULL;
391  ret = XNEW (simple_object_attributes);
392  ret->functions = sobj->functions;
393  ret->data = data;
394  return ret;
395}
396
397/* Release an simple_object_read.  */
398
399void
400simple_object_release_read (simple_object_read *sobj)
401{
402  sobj->functions->release_read (sobj->data);
403  XDELETE (sobj);
404}
405
406/* Merge attributes.  */
407
408const char *
409simple_object_attributes_merge (simple_object_attributes *to,
410				simple_object_attributes *from,
411				int *err)
412{
413  if (to->functions != from->functions)
414    {
415      *err = 0;
416      return "different object file format";
417    }
418  return to->functions->attributes_merge (to->data, from->data, err);
419}
420
421/* Release an attributes structure.  */
422
423void
424simple_object_release_attributes (simple_object_attributes *attrs)
425{
426  attrs->functions->release_attributes (attrs->data);
427  XDELETE (attrs);
428}
429
430/* Start creating an object file.  */
431
432simple_object_write *
433simple_object_start_write (simple_object_attributes *attrs,
434			   const char *segment_name, const char **errmsg,
435			   int *err)
436{
437  void *data;
438  simple_object_write *ret;
439
440  data = attrs->functions->start_write (attrs->data, errmsg, err);
441  if (data == NULL)
442    return NULL;
443  ret = XNEW (simple_object_write);
444  ret->functions = attrs->functions;
445  ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
446  ret->sections = NULL;
447  ret->last_section = NULL;
448  ret->data = data;
449  return ret;
450}
451
452/* Start creating a section.  */
453
454simple_object_write_section *
455simple_object_write_create_section (simple_object_write *sobj, const char *name,
456				    unsigned int align,
457				    const char **errmsg ATTRIBUTE_UNUSED,
458				    int *err ATTRIBUTE_UNUSED)
459{
460  simple_object_write_section *ret;
461
462  ret = XNEW (simple_object_write_section);
463  ret->next = NULL;
464  ret->name = xstrdup (name);
465  ret->align = align;
466  ret->buffers = NULL;
467  ret->last_buffer = NULL;
468
469  if (sobj->last_section == NULL)
470    {
471      sobj->sections = ret;
472      sobj->last_section = ret;
473    }
474  else
475    {
476      sobj->last_section->next = ret;
477      sobj->last_section = ret;
478    }
479
480  return ret;
481}
482
483/* Add data to a section.  */
484
485const char *
486simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
487			      simple_object_write_section *section,
488			      const void *buffer,
489			      size_t size, int copy,
490			      int *err ATTRIBUTE_UNUSED)
491{
492  struct simple_object_write_section_buffer *wsb;
493
494  wsb = XNEW (struct simple_object_write_section_buffer);
495  wsb->next = NULL;
496  wsb->size = size;
497
498  if (!copy)
499    {
500      wsb->buffer = buffer;
501      wsb->free_buffer = NULL;
502    }
503  else
504    {
505      wsb->free_buffer = (void *) XNEWVEC (char, size);
506      memcpy (wsb->free_buffer, buffer, size);
507      wsb->buffer = wsb->free_buffer;
508    }
509
510  if (section->last_buffer == NULL)
511    {
512      section->buffers = wsb;
513      section->last_buffer = wsb;
514    }
515  else
516    {
517      section->last_buffer->next = wsb;
518      section->last_buffer = wsb;
519    }
520
521  return NULL;
522}
523
524/* Write the complete object file.  */
525
526const char *
527simple_object_write_to_file (simple_object_write *sobj, int descriptor,
528			     int *err)
529{
530  return sobj->functions->write_to_file (sobj, descriptor, err);
531}
532
533/* Release an simple_object_write.  */
534
535void
536simple_object_release_write (simple_object_write *sobj)
537{
538  simple_object_write_section *section;
539
540  free (sobj->segment_name);
541
542  section = sobj->sections;
543  while (section != NULL)
544    {
545      struct simple_object_write_section_buffer *buffer;
546      simple_object_write_section *next_section;
547
548      buffer = section->buffers;
549      while (buffer != NULL)
550	{
551	  struct simple_object_write_section_buffer *next_buffer;
552
553	  if (buffer->free_buffer != NULL)
554	    XDELETEVEC (buffer->free_buffer);
555	  next_buffer = buffer->next;
556	  XDELETE (buffer);
557	  buffer = next_buffer;
558	}
559
560      next_section = section->next;
561      free (section->name);
562      XDELETE (section);
563      section = next_section;
564    }
565
566  sobj->functions->release_write (sobj->data);
567  XDELETE (sobj);
568}
569