aboutsummaryrefslogtreecommitdiff
path: root/libiberty/simple-object.c
diff options
context:
space:
mode:
Diffstat (limited to 'libiberty/simple-object.c')
-rw-r--r--libiberty/simple-object.c83
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;