[PATCH] gold: Call gold_fatal on bad ELF inputs

H.J. Lu hjl.tools@gmail.com
Sun Oct 18 13:36:53 GMT 2020


Abort on bad ELF inputs instead of SEGV later.

elfcpp/

	PR gold/26747
	PR gold/26748
	* elfcpp_file.h (Elf_file<size, big_endian, File>::construct):
	Call file->fatal instead of file->error.

gold/

	PR gold/26747
	PR gold/26748
	* incremental.cc (Incremental_binary::fatal): New.
	* incremental.h (Incremental_binary::fatal): Likewise.
	* nacl.cc (Sniff_file::fatal): Likewise.
	* nacl.h (Sniff_file::fatal): Likewise.
	* object.cc (Object::fatal): Likewise.
	* object.h (Object::fatal): Likewise.
---
 elfcpp/elfcpp_file.h |  4 ++--
 gold/incremental.cc  | 16 ++++++++++++++++
 gold/incremental.h   |  4 ++++
 gold/nacl.cc         | 14 ++++++++++++++
 gold/nacl.h          |  4 ++++
 gold/object.cc       | 17 +++++++++++++++++
 gold/object.h        |  4 ++++
 7 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/elfcpp/elfcpp_file.h b/elfcpp/elfcpp_file.h
index 92898c37646..a7213b2ea32 100644
--- a/elfcpp/elfcpp_file.h
+++ b/elfcpp/elfcpp_file.h
@@ -410,10 +410,10 @@ Elf_file<size, big_endian, File>::construct(File* file, const Ef_ehdr& ehdr)
   this->shstrndx_ = ehdr.get_e_shstrndx();
   this->large_shndx_offset_ = 0;
   if (ehdr.get_e_ehsize() != This::ehdr_size)
-    file->error(_("bad e_ehsize (%d != %d)"),
+    file->fatal(_("bad e_ehsize (%d != %d)"),
 		ehdr.get_e_ehsize(), This::ehdr_size);
   if (ehdr.get_e_shentsize() != This::shdr_size)
-    file->error(_("bad e_shentsize (%d != %d)"),
+    file->fatal(_("bad e_shentsize (%d != %d)"),
 		ehdr.get_e_shentsize(), This::shdr_size);
 }
 
diff --git a/gold/incremental.cc b/gold/incremental.cc
index 8d0df2d7bcc..a30a5c6e699 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -171,6 +171,22 @@ Incremental_binary::error(const char* format, ...) const
   va_end(args);
 }
 
+// Report a fatal error.
+
+void
+Incremental_binary::fatal(const char* format, ...) const
+{
+  va_list args;
+  va_start(args, format);
+  // Current code only checks if the file can be used for incremental linking,
+  // so errors shouldn't fail the build, but only result in a fallback to a
+  // full build.
+  // TODO: when we implement incremental editing of the file, we may need a
+  // flag that will cause errors to be treated seriously.
+  vexplain_no_incremental(format, args);
+  va_end(args);
+}
+
 // Return TRUE if a section of type SH_TYPE can be updated in place
 // during an incremental update.  We can update sections of type PROGBITS,
 // NOBITS, INIT_ARRAY, FINI_ARRAY, PREINIT_ARRAY, NOTE, and
diff --git a/gold/incremental.h b/gold/incremental.h
index e072b96fcb2..eb1d1aac6cd 100644
--- a/gold/incremental.h
+++ b/gold/incremental.h
@@ -1360,6 +1360,10 @@ class Incremental_binary
   void
   error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
 
+  // Report a fatal error.
+  void
+  fatal(const char* format, ...) const ATTRIBUTE_PRINTF_2;
+
   // Proxy class for a sized Incremental_input_entry_reader.
 
   class Input_reader
diff --git a/gold/nacl.cc b/gold/nacl.cc
index 115d9912f28..8e07c946a6f 100644
--- a/gold/nacl.cc
+++ b/gold/nacl.cc
@@ -44,4 +44,18 @@ Sniff_file::error(const char* format, ...) const
   free(buf);
 }
 
+// Copied from object.cc:Object::fatal.
+void
+Sniff_file::fatal(const char* format, ...) const
+{
+  va_list args;
+  va_start(args, format);
+  char* buf = NULL;
+  if (vasprintf(&buf, format, args) < 0)
+    gold_nomem();
+  va_end(args);
+  gold_fatal(_("%s: %s"), this->file_.filename().c_str(), buf);
+  free(buf);
+}
+
 } // end namespace gold
diff --git a/gold/nacl.h b/gold/nacl.h
index 5b3dac5e5b9..2f093e33f5a 100644
--- a/gold/nacl.h
+++ b/gold/nacl.h
@@ -84,6 +84,10 @@ class Sniff_file
   void
   error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
 
+  // Report a fatal error.
+  void
+  fatal(const char* format, ...) const ATTRIBUTE_PRINTF_2;
+
  private:
   File_read& file_;
   off_t offset_;
diff --git a/gold/object.cc b/gold/object.cc
index c486a2011d5..498e58e2b01 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -175,6 +175,23 @@ Object::error(const char* format, ...) const
   free(buf);
 }
 
+// Report a fatal error for this object file.  This is used by the
+// elfcpp::Elf_file interface, and also called by the Object code
+// itself.
+
+void
+Object::fatal(const char* format, ...) const
+{
+  va_list args;
+  va_start(args, format);
+  char* buf = NULL;
+  if (vasprintf(&buf, format, args) < 0)
+    gold_nomem();
+  va_end(args);
+  gold_fatal(_("%s: %s"), this->name().c_str(), buf);
+  free(buf);
+}
+
 // Return a view of the contents of a section.
 
 const unsigned char*
diff --git a/gold/object.h b/gold/object.h
index b7bd38faaf8..656443f062b 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -706,6 +706,10 @@ class Object
   void
   error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
 
+  // Report a fatal error.
+  void
+  fatal(const char* format, ...) const ATTRIBUTE_PRINTF_2;
+
   // A location in the file.
   struct Location
   {
-- 
2.26.2



More information about the Binutils mailing list