Mercurial > hg > CbC > CbC_gcc
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 } |