1 /* simple-object.c -- simple routines to read and write object files.
2    Copyright (C) 2010-2020 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 #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 
55 static 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 
66 int
67 simple_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 
110 int
111 simple_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 
153 simple_object_read *
154 simple_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 
193 const char *
194 simple_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 
204 struct 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 
218 static int
219 find_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 
236 int
237 simple_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 
262 static char *
263 handle_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 .comment section under the same name if present.  Solaris
297      ld uses them to relax its checking of ELF gABI access rules for
298      COMDAT sections in objects produced by GCC.  */
299   else if (strcmp (name, ".comment") == 0)
300     return strcpy (newname, name);
301   free (newname);
302   return NULL;
303 }
304 
305 /* Wrapper for handle_lto_debug_sections.  */
306 
307 static char *
308 handle_lto_debug_sections_rename (const char *name)
309 {
310   return handle_lto_debug_sections (name, 1);
311 }
312 
313 /* Wrapper for handle_lto_debug_sections.  */
314 
315 static char *
316 handle_lto_debug_sections_norename (const char *name)
317 {
318   return handle_lto_debug_sections (name, 0);
319 }
320 
321 /* Copy LTO debug sections.  */
322 
323 const char *
324 simple_object_copy_lto_debug_sections (simple_object_read *sobj,
325 				       const char *dest, int *err, int rename)
326 {
327   const char *errmsg;
328   simple_object_write *dest_sobj;
329   simple_object_attributes *attrs;
330   int outfd;
331 
332   if (! sobj->functions->copy_lto_debug_sections)
333     {
334       *err = EINVAL;
335       return "simple_object_copy_lto_debug_sections not implemented";
336     }
337 
338   attrs = simple_object_fetch_attributes (sobj, &errmsg, err);
339   if (! attrs)
340     return errmsg;
341   dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err);
342   simple_object_release_attributes (attrs);
343   if (! dest_sobj)
344     return errmsg;
345 
346   errmsg = sobj->functions->copy_lto_debug_sections
347 	 	 (sobj, dest_sobj,
348 		  rename ? handle_lto_debug_sections_rename
349 			 : handle_lto_debug_sections_norename,  err);
350   if (errmsg)
351     {
352       simple_object_release_write (dest_sobj);
353       return errmsg;
354     }
355 
356   outfd = open (dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, 00777);
357   if (outfd == -1)
358     {
359       *err = errno;
360       simple_object_release_write (dest_sobj);
361       return "open failed";
362     }
363 
364   errmsg = simple_object_write_to_file (dest_sobj, outfd, err);
365   close (outfd);
366   if (errmsg)
367     {
368       simple_object_release_write (dest_sobj);
369       return errmsg;
370     }
371 
372   simple_object_release_write (dest_sobj);
373   return NULL;
374 }
375 
376 /* Fetch attributes.  */
377 
378 simple_object_attributes *
379 simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
380 				int *err)
381 {
382   void *data;
383   simple_object_attributes *ret;
384 
385   data = sobj->functions->fetch_attributes (sobj, errmsg, err);
386   if (data == NULL)
387     return NULL;
388   ret = XNEW (simple_object_attributes);
389   ret->functions = sobj->functions;
390   ret->data = data;
391   return ret;
392 }
393 
394 /* Release an simple_object_read.  */
395 
396 void
397 simple_object_release_read (simple_object_read *sobj)
398 {
399   sobj->functions->release_read (sobj->data);
400   XDELETE (sobj);
401 }
402 
403 /* Merge attributes.  */
404 
405 const char *
406 simple_object_attributes_merge (simple_object_attributes *to,
407 				simple_object_attributes *from,
408 				int *err)
409 {
410   if (to->functions != from->functions)
411     {
412       *err = 0;
413       return "different object file format";
414     }
415   return to->functions->attributes_merge (to->data, from->data, err);
416 }
417 
418 /* Release an attributes structure.  */
419 
420 void
421 simple_object_release_attributes (simple_object_attributes *attrs)
422 {
423   attrs->functions->release_attributes (attrs->data);
424   XDELETE (attrs);
425 }
426 
427 /* Start creating an object file.  */
428 
429 simple_object_write *
430 simple_object_start_write (simple_object_attributes *attrs,
431 			   const char *segment_name, const char **errmsg,
432 			   int *err)
433 {
434   void *data;
435   simple_object_write *ret;
436 
437   data = attrs->functions->start_write (attrs->data, errmsg, err);
438   if (data == NULL)
439     return NULL;
440   ret = XNEW (simple_object_write);
441   ret->functions = attrs->functions;
442   ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
443   ret->sections = NULL;
444   ret->last_section = NULL;
445   ret->data = data;
446   return ret;
447 }
448 
449 /* Start creating a section.  */
450 
451 simple_object_write_section *
452 simple_object_write_create_section (simple_object_write *sobj, const char *name,
453 				    unsigned int align,
454 				    const char **errmsg ATTRIBUTE_UNUSED,
455 				    int *err ATTRIBUTE_UNUSED)
456 {
457   simple_object_write_section *ret;
458 
459   ret = XNEW (simple_object_write_section);
460   ret->next = NULL;
461   ret->name = xstrdup (name);
462   ret->align = align;
463   ret->buffers = NULL;
464   ret->last_buffer = NULL;
465 
466   if (sobj->last_section == NULL)
467     {
468       sobj->sections = ret;
469       sobj->last_section = ret;
470     }
471   else
472     {
473       sobj->last_section->next = ret;
474       sobj->last_section = ret;
475     }
476 
477   return ret;
478 }
479 
480 /* Add data to a section.  */
481 
482 const char *
483 simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
484 			      simple_object_write_section *section,
485 			      const void *buffer,
486 			      size_t size, int copy,
487 			      int *err ATTRIBUTE_UNUSED)
488 {
489   struct simple_object_write_section_buffer *wsb;
490 
491   wsb = XNEW (struct simple_object_write_section_buffer);
492   wsb->next = NULL;
493   wsb->size = size;
494 
495   if (!copy)
496     {
497       wsb->buffer = buffer;
498       wsb->free_buffer = NULL;
499     }
500   else
501     {
502       wsb->free_buffer = (void *) XNEWVEC (char, size);
503       memcpy (wsb->free_buffer, buffer, size);
504       wsb->buffer = wsb->free_buffer;
505     }
506 
507   if (section->last_buffer == NULL)
508     {
509       section->buffers = wsb;
510       section->last_buffer = wsb;
511     }
512   else
513     {
514       section->last_buffer->next = wsb;
515       section->last_buffer = wsb;
516     }
517 
518   return NULL;
519 }
520 
521 /* Write the complete object file.  */
522 
523 const char *
524 simple_object_write_to_file (simple_object_write *sobj, int descriptor,
525 			     int *err)
526 {
527   return sobj->functions->write_to_file (sobj, descriptor, err);
528 }
529 
530 /* Release an simple_object_write.  */
531 
532 void
533 simple_object_release_write (simple_object_write *sobj)
534 {
535   simple_object_write_section *section;
536 
537   free (sobj->segment_name);
538 
539   section = sobj->sections;
540   while (section != NULL)
541     {
542       struct simple_object_write_section_buffer *buffer;
543       simple_object_write_section *next_section;
544 
545       buffer = section->buffers;
546       while (buffer != NULL)
547 	{
548 	  struct simple_object_write_section_buffer *next_buffer;
549 
550 	  if (buffer->free_buffer != NULL)
551 	    XDELETEVEC (buffer->free_buffer);
552 	  next_buffer = buffer->next;
553 	  XDELETE (buffer);
554 	  buffer = next_buffer;
555 	}
556 
557       next_section = section->next;
558       free (section->name);
559       XDELETE (section);
560       section = next_section;
561     }
562 
563   sobj->functions->release_write (sobj->data);
564   XDELETE (sobj);
565 }
566