diff options
Diffstat (limited to 'libiberty/simple-object.c')
-rw-r--r-- | libiberty/simple-object.c | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/libiberty/simple-object.c b/libiberty/simple-object.c index 8ea9cf1..553e90f 100644 --- a/libiberty/simple-object.c +++ b/libiberty/simple-object.c @@ -22,6 +22,7 @@ Boston, MA 02110-1301, USA. */ #include "simple-object.h" #include <errno.h> +#include <fcntl.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> @@ -249,6 +250,86 @@ simple_object_find_section (simple_object_read *sobj, const char *name, return 1; } +/* Callback to identify and rename LTO debug sections by name. + Returns 1 if NAME is a LTO debug section, 0 if not. */ + +static int +handle_lto_debug_sections (const char **name) +{ + /* ??? So we can't use .gnu.lto_ prefixed sections as the assembler + complains about bogus section flags. Which means we need to arrange + for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make + fat lto object tooling work for the fat part). */ + /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed + sections. */ + /* Copy LTO debug sections and rename them to their non-LTO name. */ + if (strncmp (*name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0) + { + *name = *name + sizeof (".gnu.debuglto_") - 1; + return 1; + } + else if (strncmp (*name, ".gnu.lto_.debug_", sizeof (".gnu.lto_.debug_") -1) == 0) + { + *name = *name + sizeof (".gnu.lto_") - 1; + return 1; + } + return 0; +} + +/* Copy LTO debug sections. */ + +const char * +simple_object_copy_lto_debug_sections (simple_object_read *sobj, + const char *dest, int *err) +{ + const char *errmsg; + simple_object_write *dest_sobj; + simple_object_attributes *attrs; + int outfd; + + if (! sobj->functions->copy_lto_debug_sections) + { + *err = EINVAL; + return "simple_object_copy_lto_debug_sections not implemented"; + } + + attrs = simple_object_fetch_attributes (sobj, &errmsg, err); + if (! attrs) + return errmsg; + dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err); + simple_object_release_attributes (attrs); + if (! dest_sobj) + return errmsg; + + errmsg = sobj->functions->copy_lto_debug_sections (sobj, dest_sobj, + handle_lto_debug_sections, + err); + if (errmsg) + { + simple_object_release_write (dest_sobj); + return errmsg; + } + + outfd = creat (dest, 00777); + if (outfd == -1) + { + *err = errno; + simple_object_release_write (dest_sobj); + return "open failed"; + } + + errmsg = simple_object_write_to_file (dest_sobj, outfd, err); + close (outfd); + if (errmsg) + { + simple_object_release_write (dest_sobj); + return errmsg; + } + + simple_object_release_write (dest_sobj); + return NULL; +} + /* Fetch attributes. */ simple_object_attributes * @@ -315,7 +396,7 @@ simple_object_start_write (simple_object_attributes *attrs, return NULL; ret = XNEW (simple_object_write); ret->functions = attrs->functions; - ret->segment_name = xstrdup (segment_name); + ret->segment_name = segment_name ? xstrdup (segment_name) : NULL; ret->sections = NULL; ret->last_section = NULL; ret->data = data; |