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 #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 1 if NAME is a LTO debug section, 0 if not. */
259
260 static char *
handle_lto_debug_sections(const char * name)261 handle_lto_debug_sections (const char *name)
262 {
263 char *newname = XCNEWVEC (char, strlen (name) + 1);
264
265 /* ??? So we can't use .gnu.lto_ prefixed sections as the assembler
266 complains about bogus section flags. Which means we need to arrange
267 for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make
268 fat lto object tooling work for the fat part). */
269 /* Also include corresponding reloc sections. */
270 if (strncmp (name, ".rela", sizeof (".rela") - 1) == 0)
271 {
272 strncpy (newname, name, sizeof (".rela") - 1);
273 name += sizeof (".rela") - 1;
274 }
275 else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0)
276 {
277 strncpy (newname, name, sizeof (".rel") - 1);
278 name += sizeof (".rel") - 1;
279 }
280 /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
281 sections. */
282 /* Copy LTO debug sections and rename them to their non-LTO name. */
283 if (strncmp (name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0)
284 return strcat (newname, name + sizeof (".gnu.debuglto_") - 1);
285 else if (strncmp (name, ".gnu.lto_.debug_",
286 sizeof (".gnu.lto_.debug_") -1) == 0)
287 return strcat (newname, name + sizeof (".gnu.lto_") - 1);
288 /* Copy over .note.GNU-stack section under the same name if present. */
289 else if (strcmp (name, ".note.GNU-stack") == 0)
290 return strcpy (newname, name);
291 /* Copy over .comment section under the same name if present. Solaris
292 ld uses them to relax its checking of ELF gABI access rules for
293 COMDAT sections in objects produced by GCC. */
294 else if (strcmp (name, ".comment") == 0)
295 return strcpy (newname, name);
296 return NULL;
297 }
298
299 /* Copy LTO debug sections. */
300
301 const char *
simple_object_copy_lto_debug_sections(simple_object_read * sobj,const char * dest,int * err)302 simple_object_copy_lto_debug_sections (simple_object_read *sobj,
303 const char *dest, int *err)
304 {
305 const char *errmsg;
306 simple_object_write *dest_sobj;
307 simple_object_attributes *attrs;
308 int outfd;
309
310 if (! sobj->functions->copy_lto_debug_sections)
311 {
312 *err = EINVAL;
313 return "simple_object_copy_lto_debug_sections not implemented";
314 }
315
316 attrs = simple_object_fetch_attributes (sobj, &errmsg, err);
317 if (! attrs)
318 return errmsg;
319 dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err);
320 simple_object_release_attributes (attrs);
321 if (! dest_sobj)
322 return errmsg;
323
324 errmsg = sobj->functions->copy_lto_debug_sections (sobj, dest_sobj,
325 handle_lto_debug_sections,
326 err);
327 if (errmsg)
328 {
329 simple_object_release_write (dest_sobj);
330 return errmsg;
331 }
332
333 outfd = open (dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, 00777);
334 if (outfd == -1)
335 {
336 *err = errno;
337 simple_object_release_write (dest_sobj);
338 return "open failed";
339 }
340
341 errmsg = simple_object_write_to_file (dest_sobj, outfd, err);
342 close (outfd);
343 if (errmsg)
344 {
345 simple_object_release_write (dest_sobj);
346 return errmsg;
347 }
348
349 simple_object_release_write (dest_sobj);
350 return NULL;
351 }
352
353 /* Fetch attributes. */
354
355 simple_object_attributes *
simple_object_fetch_attributes(simple_object_read * sobj,const char ** errmsg,int * err)356 simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
357 int *err)
358 {
359 void *data;
360 simple_object_attributes *ret;
361
362 data = sobj->functions->fetch_attributes (sobj, errmsg, err);
363 if (data == NULL)
364 return NULL;
365 ret = XNEW (simple_object_attributes);
366 ret->functions = sobj->functions;
367 ret->data = data;
368 return ret;
369 }
370
371 /* Release an simple_object_read. */
372
373 void
simple_object_release_read(simple_object_read * sobj)374 simple_object_release_read (simple_object_read *sobj)
375 {
376 sobj->functions->release_read (sobj->data);
377 XDELETE (sobj);
378 }
379
380 /* Merge attributes. */
381
382 const char *
simple_object_attributes_merge(simple_object_attributes * to,simple_object_attributes * from,int * err)383 simple_object_attributes_merge (simple_object_attributes *to,
384 simple_object_attributes *from,
385 int *err)
386 {
387 if (to->functions != from->functions)
388 {
389 *err = 0;
390 return "different object file format";
391 }
392 return to->functions->attributes_merge (to->data, from->data, err);
393 }
394
395 /* Release an attributes structure. */
396
397 void
simple_object_release_attributes(simple_object_attributes * attrs)398 simple_object_release_attributes (simple_object_attributes *attrs)
399 {
400 attrs->functions->release_attributes (attrs->data);
401 XDELETE (attrs);
402 }
403
404 /* Start creating an object file. */
405
406 simple_object_write *
simple_object_start_write(simple_object_attributes * attrs,const char * segment_name,const char ** errmsg,int * err)407 simple_object_start_write (simple_object_attributes *attrs,
408 const char *segment_name, const char **errmsg,
409 int *err)
410 {
411 void *data;
412 simple_object_write *ret;
413
414 data = attrs->functions->start_write (attrs->data, errmsg, err);
415 if (data == NULL)
416 return NULL;
417 ret = XNEW (simple_object_write);
418 ret->functions = attrs->functions;
419 ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
420 ret->sections = NULL;
421 ret->last_section = NULL;
422 ret->data = data;
423 return ret;
424 }
425
426 /* Start creating a section. */
427
428 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)429 simple_object_write_create_section (simple_object_write *sobj, const char *name,
430 unsigned int align,
431 const char **errmsg ATTRIBUTE_UNUSED,
432 int *err ATTRIBUTE_UNUSED)
433 {
434 simple_object_write_section *ret;
435
436 ret = XNEW (simple_object_write_section);
437 ret->next = NULL;
438 ret->name = xstrdup (name);
439 ret->align = align;
440 ret->buffers = NULL;
441 ret->last_buffer = NULL;
442
443 if (sobj->last_section == NULL)
444 {
445 sobj->sections = ret;
446 sobj->last_section = ret;
447 }
448 else
449 {
450 sobj->last_section->next = ret;
451 sobj->last_section = ret;
452 }
453
454 return ret;
455 }
456
457 /* Add data to a section. */
458
459 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)460 simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
461 simple_object_write_section *section,
462 const void *buffer,
463 size_t size, int copy,
464 int *err ATTRIBUTE_UNUSED)
465 {
466 struct simple_object_write_section_buffer *wsb;
467
468 wsb = XNEW (struct simple_object_write_section_buffer);
469 wsb->next = NULL;
470 wsb->size = size;
471
472 if (!copy)
473 {
474 wsb->buffer = buffer;
475 wsb->free_buffer = NULL;
476 }
477 else
478 {
479 wsb->free_buffer = (void *) XNEWVEC (char, size);
480 memcpy (wsb->free_buffer, buffer, size);
481 wsb->buffer = wsb->free_buffer;
482 }
483
484 if (section->last_buffer == NULL)
485 {
486 section->buffers = wsb;
487 section->last_buffer = wsb;
488 }
489 else
490 {
491 section->last_buffer->next = wsb;
492 section->last_buffer = wsb;
493 }
494
495 return NULL;
496 }
497
498 /* Write the complete object file. */
499
500 const char *
simple_object_write_to_file(simple_object_write * sobj,int descriptor,int * err)501 simple_object_write_to_file (simple_object_write *sobj, int descriptor,
502 int *err)
503 {
504 return sobj->functions->write_to_file (sobj, descriptor, err);
505 }
506
507 /* Release an simple_object_write. */
508
509 void
simple_object_release_write(simple_object_write * sobj)510 simple_object_release_write (simple_object_write *sobj)
511 {
512 simple_object_write_section *section;
513
514 free (sobj->segment_name);
515
516 section = sobj->sections;
517 while (section != NULL)
518 {
519 struct simple_object_write_section_buffer *buffer;
520 simple_object_write_section *next_section;
521
522 buffer = section->buffers;
523 while (buffer != NULL)
524 {
525 struct simple_object_write_section_buffer *next_buffer;
526
527 if (buffer->free_buffer != NULL)
528 XDELETEVEC (buffer->free_buffer);
529 next_buffer = buffer->next;
530 XDELETE (buffer);
531 buffer = next_buffer;
532 }
533
534 next_section = section->next;
535 free (section->name);
536 XDELETE (section);
537 section = next_section;
538 }
539
540 sobj->functions->release_write (sobj->data);
541 XDELETE (sobj);
542 }
543