compiler: Move import of Go export data to gcc side of interface.
authorIan Lance Taylor <iant@google.com>
Wed, 14 Dec 2011 01:36:11 +0000 (01:36 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 14 Dec 2011 01:36:11 +0000 (01:36 +0000)
* 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

gcc/go/ChangeLog
gcc/go/go-backend.c
gcc/go/go-c.h
gcc/go/gofrontend/import.cc
gcc/go/gofrontend/import.h

index 47910fd75a9e9fdc093d98361e2f3838600cf99a..9b17bf4b2341eea391b66ee5a50eb08ab2323083 100644 (file)
@@ -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>
 
index 62102a2e08bca62fc0d92b8c6ba7b44a7c4b8d9a..4d1ea827c5e2fe3a9c66adbc8c28e9366b6d37a5 100644 (file)
@@ -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;
+}
index f5ecbebace381eb641d154c036a5c23b116b4162..5e65dead72e567e19faf0abe6fa5f441a2b311eb 100644 (file)
@@ -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
index 075109c0c04851d21d0447ac039ad692d2df216a..a62069e8e23ce724b0e7c53abb5e7546b2e404c6 100644 (file)
@@ -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.
index f5b4b3d2be3a689250a2da27d0e42c6b7ad88eea..bdff0c2a9e1b4ce20c57e983d176b4c73b081b1e 100644 (file)
@@ -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