aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/go-backend.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2011-12-14 01:36:11 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-12-14 01:36:11 +0000
commitc990877a412109c1e7eac6506239a27ab309051f (patch)
tree017c5531c568d8f5cbcec96d54dfb41febb26294 /gcc/go/go-backend.c
parent6fdc547369f2ae57120d8fa1eb91cbff24374a21 (diff)
downloadgcc-c990877a412109c1e7eac6506239a27ab309051f.zip
gcc-c990877a412109c1e7eac6506239a27ab309051f.tar.gz
gcc-c990877a412109c1e7eac6506239a27ab309051f.tar.bz2
compiler: Move import of Go export data to gcc side of interface.
* go-backend.c: #include "simple-object.h" and "intl.h". (GO_EXPORT_SEGMENT_NAME): Define if not defined. (GO_EXPORT_SECTION_NAME): Likewise. (go_write_export_data): Use GO_EXPORT_SECTION_NAME. (go_read_export_data): New function. * go-c.h (go_read_export_data): Declare. From-SVN: r182321
Diffstat (limited to 'gcc/go/go-backend.c')
-rw-r--r--gcc/go/go-backend.c97
1 files changed, 95 insertions, 2 deletions
diff --git a/gcc/go/go-backend.c b/gcc/go/go-backend.c
index 62102a2e..4d1ea82 100644
--- a/gcc/go/go-backend.c
+++ b/gcc/go/go-backend.c
@@ -20,16 +20,31 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "simple-object.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
+#include "intl.h"
#include "output.h"
#include "target.h"
#include "common/common-target.h"
#include "go-c.h"
+/* The segment name we pass to simple_object_start_read to find Go
+ export data. */
+
+#ifndef GO_EXPORT_SEGMENT_NAME
+#define GO_EXPORT_SEGMENT_NAME "__GNU_GO"
+#endif
+
+/* The section name we use when reading and writing export data. */
+
+#ifndef GO_EXPORT_SECTION_NAME
+#define GO_EXPORT_SECTION_NAME ".go_export"
+#endif
+
/* This file holds all the cases where the Go frontend needs
information from gcc's backend. */
@@ -95,7 +110,7 @@ go_imported_unsafe (void)
}
/* This is called by the Go frontend proper to add data to the
- .go_export section. */
+ section containing Go export data. */
void
go_write_export_data (const char *bytes, unsigned int size)
@@ -105,9 +120,87 @@ go_write_export_data (const char *bytes, unsigned int size)
if (sec == NULL)
{
gcc_assert (targetm_common.have_named_sections);
- sec = get_section (".go_export", SECTION_DEBUG, NULL);
+ sec = get_section (GO_EXPORT_SECTION_NAME, SECTION_DEBUG, NULL);
}
switch_to_section (sec);
assemble_string (bytes, size);
}
+
+/* The go_read_export_data function is called by the Go frontend
+ proper to read Go export data from an object file. FD is a file
+ descriptor open for reading. OFFSET is the offset within the file
+ where the object file starts; this will be 0 except when reading an
+ archive. On success this returns NULL and sets *PBUF to a buffer
+ allocated using malloc, of size *PLEN, holding the export data. If
+ the data is not found, this returns NULL and sets *PBUF to NULL and
+ *PLEN to 0. If some error occurs, this returns an error message
+ and sets *PERR to an errno value or 0 if there is no relevant
+ errno. */
+
+const char *
+go_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
+ int *perr)
+{
+ simple_object_read *sobj;
+ const char *errmsg;
+ off_t sec_offset;
+ off_t sec_length;
+ int found;
+ char *buf;
+ ssize_t c;
+
+ *pbuf = NULL;
+ *plen = 0;
+
+ sobj = simple_object_start_read (fd, offset, GO_EXPORT_SEGMENT_NAME,
+ &errmsg, perr);
+ if (sobj == NULL)
+ {
+ /* If we get an error here, just pretend that we didn't find any
+ export data. This is the right thing to do if the error is
+ that the file was not recognized as an object file. This
+ will ignore file I/O errors, but it's not too big a deal
+ because we will wind up giving some other error later. */
+ return NULL;
+ }
+
+ found = simple_object_find_section (sobj, GO_EXPORT_SECTION_NAME,
+ &sec_offset, &sec_length,
+ &errmsg, perr);
+ simple_object_release_read (sobj);
+ if (!found)
+ return errmsg;
+
+ if (lseek (fd, offset + sec_offset, SEEK_SET) < 0)
+ {
+ *perr = errno;
+ return _("lseek failed while reading export data");
+ }
+
+ buf = XNEWVEC (char, sec_length);
+ if (buf == NULL)
+ {
+ *perr = errno;
+ return _("memory allocation failed while reading export data");
+ }
+
+ c = read (fd, buf, sec_length);
+ if (c < 0)
+ {
+ *perr = errno;
+ free (buf);
+ return _("read failed while reading export data");
+ }
+
+ if (c < sec_length)
+ {
+ free (buf);
+ return _("short read while reading export data");
+ }
+
+ *pbuf = buf;
+ *plen = sec_length;
+
+ return NULL;
+}