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 }
539