Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / libiberty / simple-object.c
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.
4
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
8 later version.
9
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.
14
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.  */
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 #include "simple-object-common.h"
48
49 /* The known object file formats.  */
50
51 static const struct simple_object_functions * const format_functions[] =
52 {
53   &simple_object_elf_functions,
54   &simple_object_mach_o_functions,
55   &simple_object_coff_functions,
56   &simple_object_xcoff_functions
57 };
58
59 /* Read data from a file using the simple_object error reporting
60    conventions.  */
61
62 int
63 simple_object_internal_read (int descriptor, off_t offset,
64                              unsigned char *buffer, size_t size,
65                              const char **errmsg, int *err)
66 {
67   if (lseek (descriptor, offset, SEEK_SET) < 0)
68     {
69       *errmsg = "lseek";
70       *err = errno;
71       return 0;
72     }
73
74   do
75     {
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         }
90     }
91   while (size > 0);
92
93   if (size > 0)
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
106 int
107 simple_object_internal_write (int descriptor, off_t offset,
108                               const unsigned char *buffer, size_t size,
109                               const char **errmsg, int *err)
110 {
111   if (lseek (descriptor, offset, SEEK_SET) < 0)
112     {
113       *errmsg = "lseek";
114       *err = errno;
115       return 0;
116     }
117
118   do
119     {
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         }
134     }
135   while (size > 0);
136
137   if (size > 0)
138     {
139       *errmsg = "short write";
140       *err = 0;
141       return 0;
142     }
143
144   return 1;
145 }
146
147 /* Open for read.  */
148
149 simple_object_read *
150 simple_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
189 const char *
190 simple_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
200 struct 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
214 static int
215 find_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
232 int
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)
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
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
256 static char *
257 handle_lto_debug_sections (const char *name)
258 {
259   char *newname = XCNEWVEC (char, strlen (name) + 1);
260
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)
267     {
268       strncpy (newname, name, sizeof (".rela") - 1);
269       name += sizeof (".rela") - 1;
270     }
271   else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0)
272     {
273       strncpy (newname, name, sizeof (".rel") - 1);
274       name += sizeof (".rel") - 1;
275     }
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);
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);
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;
293 }
294
295 /* Copy LTO debug sections.  */
296
297 const char *
298 simple_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
349 /* Fetch attributes.  */
350
351 simple_object_attributes *
352 simple_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
369 void
370 simple_object_release_read (simple_object_read *sobj)
371 {
372   sobj->functions->release_read (sobj->data);
373   XDELETE (sobj);
374 }
375
376 /* Merge attributes.  */
377
378 const char *
379 simple_object_attributes_merge (simple_object_attributes *to,
380                                 simple_object_attributes *from,
381                                 int *err)
382 {
383   if (to->functions != from->functions)
384     {
385       *err = 0;
386       return "different object file format";
387     }
388   return to->functions->attributes_merge (to->data, from->data, err);
389 }
390
391 /* Release an attributes structure.  */
392
393 void
394 simple_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
402 simple_object_write *
403 simple_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;
415   ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
416   ret->sections = NULL;
417   ret->last_section = NULL;
418   ret->data = data;
419   return ret;
420 }
421
422 /* Start creating a section.  */
423
424 simple_object_write_section *
425 simple_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
455 const char *
456 simple_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
496 const char *
497 simple_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
505 void
506 simple_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 }