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