aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/go/ChangeLog9
-rw-r--r--gcc/go/go-backend.c97
-rw-r--r--gcc/go/go-c.h2
-rw-r--r--gcc/go/gofrontend/import.cc46
-rw-r--r--gcc/go/gofrontend/import.h4
5 files changed, 120 insertions, 38 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 47910fd..9b17bf4 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,12 @@
+2011-12-13 Ian Lance Taylor <iant@google.com>
+
+ * 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.
+
2011-11-29 Sanjoy Das <thedigitalangel@gmail.com>
Ian Lance Taylor <iant@google.com>
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;
+}
diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h
index f5ecbeb..5e65dea 100644
--- a/gcc/go/go-c.h
+++ b/gcc/go/go-c.h
@@ -69,6 +69,8 @@ extern void go_imported_unsafe (void);
extern void go_write_export_data (const char *, unsigned int);
+extern const char *go_read_export_data (int, off_t, char **, size_t *, int *);
+
#if defined(__cplusplus) && !defined(ENABLE_BUILD_WITH_CXX)
} /* End extern "C". */
#endif
diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc
index 075109c..a62069e 100644
--- a/gcc/go/gofrontend/import.cc
+++ b/gcc/go/gofrontend/import.cc
@@ -215,46 +215,24 @@ Import::find_object_export_data(const std::string& filename,
off_t offset,
Location location)
{
- const char* errmsg;
+ char *buf;
+ size_t len;
int err;
- simple_object_read* sobj = simple_object_start_read(fd, offset,
- "__GNU_GO",
- &errmsg, &err);
- if (sobj == NULL)
- return NULL;
-
- off_t sec_offset;
- off_t sec_length;
- int found = simple_object_find_section(sobj, ".go_export", &sec_offset,
- &sec_length, &errmsg, &err);
-
- simple_object_release_read(sobj);
-
- if (!found)
- return NULL;
-
- if (lseek(fd, offset + sec_offset, SEEK_SET) < 0)
+ const char *errmsg = go_read_export_data(fd, offset, &buf, &len, &err);
+ if (errmsg != NULL)
{
- error_at(location, "lseek %s failed: %m", filename.c_str());
+ if (err == 0)
+ error_at(location, "%s: %s", filename.c_str(), errmsg);
+ else
+ error_at(location, "%s: %s: %s", filename.c_str(), errmsg,
+ xstrerror(err));
return NULL;
}
- char* buf = new char[sec_length];
- ssize_t c = read(fd, buf, sec_length);
- if (c < 0)
- {
- error_at(location, "read %s failed: %m", filename.c_str());
- delete[] buf;
- return NULL;
- }
- if (c < sec_length)
- {
- error_at(location, "%s: short read", filename.c_str());
- delete[] buf;
- return NULL;
- }
+ if (buf == NULL)
+ return NULL;
- return new Stream_from_buffer(buf, sec_length);
+ return new Stream_from_buffer(buf, len);
}
// Class Import.
diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h
index f5b4b3d..bdff0c2 100644
--- a/gcc/go/gofrontend/import.h
+++ b/gcc/go/gofrontend/import.h
@@ -287,7 +287,7 @@ class Stream_from_string : public Import::Stream
size_t pos_;
};
-// Read import data from an allocated buffer.
+// Read import data from a buffer allocated using malloc.
class Stream_from_buffer : public Import::Stream
{
@@ -297,7 +297,7 @@ class Stream_from_buffer : public Import::Stream
{ }
~Stream_from_buffer()
- { delete[] this->buf_; }
+ { free(this->buf_); }
protected:
bool