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 
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
simple_object_internal_read(int descriptor,off_t offset,unsigned char * buffer,size_t size,const char ** errmsg,int * err)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
simple_object_internal_write(int descriptor,off_t offset,const unsigned char * buffer,size_t size,const char ** errmsg,int * err)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 *
simple_object_start_read(int descriptor,off_t offset,const char * segment_name,const char ** errmsg,int * err)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 *
simple_object_find_sections(simple_object_read * sobj,int (* pfn)(void *,const char *,off_t,off_t),void * data,int * err)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
find_one_section(void * data,const char * name,off_t offset,off_t length)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
simple_object_find_section(simple_object_read * sobj,const char * name,off_t * offset,off_t * length,const char ** errmsg,int * err)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 *
handle_lto_debug_sections(const char * name,int rename)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 .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 
310 static char *
handle_lto_debug_sections_rename(const char * name)311 handle_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 
318 static char *
handle_lto_debug_sections_norename(const char * name)319 handle_lto_debug_sections_norename (const char *name)
320 {
321   return handle_lto_debug_sections (name, 0);
322 }
323 
324 /* Copy LTO debug sections.  */
325 
326 const char *
simple_object_copy_lto_debug_sections(simple_object_read * sobj,const char * dest,int * err,int rename)327 simple_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 
381 simple_object_attributes *
simple_object_fetch_attributes(simple_object_read * sobj,const char ** errmsg,int * err)382 simple_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 
399 void
simple_object_release_read(simple_object_read * sobj)400 simple_object_release_read (simple_object_read *sobj)
401 {
402   sobj->functions->release_read (sobj->data);
403   XDELETE (sobj);
404 }
405 
406 /* Merge attributes.  */
407 
408 const char *
simple_object_attributes_merge(simple_object_attributes * to,simple_object_attributes * from,int * err)409 simple_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 
423 void
simple_object_release_attributes(simple_object_attributes * attrs)424 simple_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 
432 simple_object_write *
simple_object_start_write(simple_object_attributes * attrs,const char * segment_name,const char ** errmsg,int * err)433 simple_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 
454 simple_object_write_section *
simple_object_write_create_section(simple_object_write * sobj,const char * name,unsigned int align,const char ** errmsg ATTRIBUTE_UNUSED,int * err ATTRIBUTE_UNUSED)455 simple_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 
485 const char *
simple_object_write_add_data(simple_object_write * sobj ATTRIBUTE_UNUSED,simple_object_write_section * section,const void * buffer,size_t size,int copy,int * err ATTRIBUTE_UNUSED)486 simple_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 
526 const char *
simple_object_write_to_file(simple_object_write * sobj,int descriptor,int * err)527 simple_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 
535 void
simple_object_release_write(simple_object_write * sobj)536 simple_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