comparison libiberty/simple-object.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents 561a7518be6b
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* simple-object.c -- simple routines to read and write object files. 1 /* simple-object.c -- simple routines to read and write object files.
2 Copyright 2010 Free Software Foundation, Inc. 2 Copyright (C) 2010-2017 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Google. 3 Written by Ian Lance Taylor, Google.
4 4
5 This program is free software; you can redistribute it and/or modify it 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 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 7 Free Software Foundation; either version 2, or (at your option) any
20 #include "config.h" 20 #include "config.h"
21 #include "libiberty.h" 21 #include "libiberty.h"
22 #include "simple-object.h" 22 #include "simple-object.h"
23 23
24 #include <errno.h> 24 #include <errno.h>
25 #include <fcntl.h>
25 26
26 #ifdef HAVE_STDLIB_H 27 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h> 28 #include <stdlib.h>
28 #endif 29 #endif
29 30
49 50
50 static const struct simple_object_functions * const format_functions[] = 51 static const struct simple_object_functions * const format_functions[] =
51 { 52 {
52 &simple_object_elf_functions, 53 &simple_object_elf_functions,
53 &simple_object_mach_o_functions, 54 &simple_object_mach_o_functions,
54 &simple_object_coff_functions 55 &simple_object_coff_functions,
56 &simple_object_xcoff_functions
55 }; 57 };
56 58
57 /* Read data from a file using the simple_object error reporting 59 /* Read data from a file using the simple_object error reporting
58 conventions. */ 60 conventions. */
59 61
60 int 62 int
61 simple_object_internal_read (int descriptor, off_t offset, 63 simple_object_internal_read (int descriptor, off_t offset,
62 unsigned char *buffer, size_t size, 64 unsigned char *buffer, size_t size,
63 const char **errmsg, int *err) 65 const char **errmsg, int *err)
64 { 66 {
65 ssize_t got;
66
67 if (lseek (descriptor, offset, SEEK_SET) < 0) 67 if (lseek (descriptor, offset, SEEK_SET) < 0)
68 { 68 {
69 *errmsg = "lseek"; 69 *errmsg = "lseek";
70 *err = errno; 70 *err = errno;
71 return 0; 71 return 0;
72 } 72 }
73 73
74 got = read (descriptor, buffer, size); 74 do
75 if (got < 0) 75 {
76 { 76 ssize_t got = read (descriptor, buffer, size);
77 *errmsg = "read"; 77 if (got == 0)
78 *err = errno; 78 break;
79 return 0; 79 else if (got > 0)
80 } 80 {
81 81 buffer += got;
82 if ((size_t) got < size) 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)
83 { 94 {
84 *errmsg = "file too short"; 95 *errmsg = "file too short";
85 *err = 0; 96 *err = 0;
86 return 0; 97 return 0;
87 } 98 }
95 int 106 int
96 simple_object_internal_write (int descriptor, off_t offset, 107 simple_object_internal_write (int descriptor, off_t offset,
97 const unsigned char *buffer, size_t size, 108 const unsigned char *buffer, size_t size,
98 const char **errmsg, int *err) 109 const char **errmsg, int *err)
99 { 110 {
100 ssize_t wrote;
101
102 if (lseek (descriptor, offset, SEEK_SET) < 0) 111 if (lseek (descriptor, offset, SEEK_SET) < 0)
103 { 112 {
104 *errmsg = "lseek"; 113 *errmsg = "lseek";
105 *err = errno; 114 *err = errno;
106 return 0; 115 return 0;
107 } 116 }
108 117
109 wrote = write (descriptor, buffer, size); 118 do
110 if (wrote < 0) 119 {
111 { 120 ssize_t wrote = write (descriptor, buffer, size);
112 *errmsg = "write"; 121 if (wrote == 0)
113 *err = errno; 122 break;
114 return 0; 123 else if (wrote > 0)
115 } 124 {
116 125 buffer += wrote;
117 if ((size_t) wrote < size) 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)
118 { 138 {
119 *errmsg = "short write"; 139 *errmsg = "short write";
120 *err = 0; 140 *err = 0;
121 return 0; 141 return 0;
122 } 142 }
228 if (!fosd.found) 248 if (!fosd.found)
229 return 0; 249 return 0;
230 return 1; 250 return 1;
231 } 251 }
232 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 int
257 handle_lto_debug_sections (const char **name)
258 {
259 /* ??? So we can't use .gnu.lto_ prefixed sections as the assembler
260 complains about bogus section flags. Which means we need to arrange
261 for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make
262 fat lto object tooling work for the fat part). */
263 /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
264 sections. */
265 /* Copy LTO debug sections and rename them to their non-LTO name. */
266 if (strncmp (*name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0)
267 {
268 *name = *name + sizeof (".gnu.debuglto_") - 1;
269 return 1;
270 }
271 else if (strncmp (*name, ".gnu.lto_.debug_", sizeof (".gnu.lto_.debug_") -1) == 0)
272 {
273 *name = *name + sizeof (".gnu.lto_") - 1;
274 return 1;
275 }
276 /* Copy over .note.GNU-stack section under the same name if present. */
277 else if (strcmp (*name, ".note.GNU-stack") == 0)
278 return 1;
279 return 0;
280 }
281
282 /* Copy LTO debug sections. */
283
284 const char *
285 simple_object_copy_lto_debug_sections (simple_object_read *sobj,
286 const char *dest, int *err)
287 {
288 const char *errmsg;
289 simple_object_write *dest_sobj;
290 simple_object_attributes *attrs;
291 int outfd;
292
293 if (! sobj->functions->copy_lto_debug_sections)
294 {
295 *err = EINVAL;
296 return "simple_object_copy_lto_debug_sections not implemented";
297 }
298
299 attrs = simple_object_fetch_attributes (sobj, &errmsg, err);
300 if (! attrs)
301 return errmsg;
302 dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err);
303 simple_object_release_attributes (attrs);
304 if (! dest_sobj)
305 return errmsg;
306
307 errmsg = sobj->functions->copy_lto_debug_sections (sobj, dest_sobj,
308 handle_lto_debug_sections,
309 err);
310 if (errmsg)
311 {
312 simple_object_release_write (dest_sobj);
313 return errmsg;
314 }
315
316 outfd = creat (dest, 00777);
317 if (outfd == -1)
318 {
319 *err = errno;
320 simple_object_release_write (dest_sobj);
321 return "open failed";
322 }
323
324 errmsg = simple_object_write_to_file (dest_sobj, outfd, err);
325 close (outfd);
326 if (errmsg)
327 {
328 simple_object_release_write (dest_sobj);
329 return errmsg;
330 }
331
332 simple_object_release_write (dest_sobj);
333 return NULL;
334 }
335
233 /* Fetch attributes. */ 336 /* Fetch attributes. */
234 337
235 simple_object_attributes * 338 simple_object_attributes *
236 simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg, 339 simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
237 int *err) 340 int *err)
294 data = attrs->functions->start_write (attrs->data, errmsg, err); 397 data = attrs->functions->start_write (attrs->data, errmsg, err);
295 if (data == NULL) 398 if (data == NULL)
296 return NULL; 399 return NULL;
297 ret = XNEW (simple_object_write); 400 ret = XNEW (simple_object_write);
298 ret->functions = attrs->functions; 401 ret->functions = attrs->functions;
299 ret->segment_name = xstrdup (segment_name); 402 ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
300 ret->sections = NULL; 403 ret->sections = NULL;
301 ret->last_section = NULL; 404 ret->last_section = NULL;
302 ret->data = data; 405 ret->data = data;
303 return ret; 406 return ret;
304 } 407 }