From: Torbjörn SVENSSON <[email protected]>

On systems without mmap support, cc1plus can crash when finishing module
output after earlier errors prevented elf_out::begin from running.  In
that case elf_out::end attempts to fill in the ELF header even though
hdr.buffer was never initialized.

gcc/cp/ChangeLog:

        PR c++/124806
        * module.cc (elf_out::begun): New data member.
        (elf_out::begin): Set it after successful initialization.
        (elf_out::end): Do not finalize output that was never begun.

Signed-off-by: Torbjörn SVENSSON <[email protected]>
---
 gcc/cp/module.cc | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index f7569e688a26..156df4457463 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -1511,6 +1511,7 @@ class elf_out : public elf, public data::allocator {
 private:
   ptr_int_hash_map identtab;   /* Map of IDENTIFIERS to strtab offsets. */
   unsigned pos;                        /* Write position in file.  */
+  bool begun;                  /* True if begin initialized output state.  */
 #if MAPPED_WRITING
   unsigned offset;             /* Offset of the mapping.  */
   unsigned extent;             /* Length of mapping.  */
@@ -1519,7 +1520,7 @@ private:
 
 public:
   elf_out (int fd, int e)
-    :parent (fd, e), identtab (500), pos (0)
+    :parent (fd, e), identtab (500), pos (0), begun (false)
   {
 #if MAPPED_WRITING
     offset = extent = 0;
@@ -2231,7 +2232,10 @@ elf_out::begin ()
   memset (h, 0, sizeof (header));
   hdr.pos = hdr.size;
   write (hdr);
-  return !get_error ();
+  if (get_error ())
+    return false;
+  begun = true;
+  return true;
 }
 
 /* Finish writing the file.  Write out the string & section tables.
@@ -2240,7 +2244,7 @@ elf_out::begin ()
 bool
 elf_out::end ()
 {
-  if (fd >= 0)
+  if (fd >= 0 && begun)
     {
       /* Write the string table.  */
       unsigned strnam = name (".strtab");
-- 
2.54.0

Reply via email to