Hey, y'all!

I was playing with directly invoking ld and then ld.gold to link c++
files, instead of using g++.

I inadvertently passed the -nostartfiles to the linker.

Since the linkers do not recognize this option, they interpreted it as
" -n -ostartfiles".

GNU ld created 2.2 Meg output files which seemed to work.

In ld.gold, the -n caused an assertion in this code in output.cc (line 4773)


  if (this->type_ == elfcpp::PT_GNU_RELRO)
    {
      uint64_t page_align = parameters->target().abi_pagesize();
      uint64_t segment_end = this->vaddr_ + this->memsz_;
      if (parameters->incremental_update())
        {
          // The INCREASE_RELRO calculation is bypassed for an incremental
          // update, so we need to adjust the segment size manually here.
          segment_end = align_address(segment_end, page_align);
          this->memsz_ = segment_end - this->vaddr_;
        }
      else
        gold_assert(segment_end == align_address(segment_end, page_align));
    }

It makes sense that if -n (do not page align data) is specified,
the data would not be page aligned, but I was not sure whether to
simply test options->nmagic() and options->omagic() before the
assertion, or if I should tell gold to page align PT_GNU_RELRO
sections in spite of the -n or -N flags.

I thought, however, that it would be a good idea for ld.gold to
ignore the -nostartfiles parameter, as it does the -nodefaultlibs
parameter, so I'm enclosing a patch to do that.

While debugging the issue, I found an annoying problem with running
the /tmp/ld-run-a.out.sh files which are created when main.cc is
compiled with the -DDEBUG option:  the bash process was reporting an
unexpected EOF on the script.  I've seen this before, it comes from
truncating a running script, so I am also enclosing a patch to cause
the write_debug_script function to create the new script as
/tmp/ld-run-a.out.sh-new, and then rename it to it's final name.


If somebody tells me what the proper behavior would be if -n is
specified and there is a PT_GNU_RELRO section, I could fix that
as well.

Thanks for ld.gold, it is SO MUCH faster than ld!


-------
http://ElectNobody.comĀ -- Vote for Nobody
Because Nobody should rule you ... but you!


diff --git a/gold/main.cc b/gold/main.cc
index db3d1e4430..9c4c61dc12 100644
--- a/gold/main.cc
+++ b/gold/main.cc
@@ -98,11 +98,12 @@ write_debug_script(std::string filename_str,
 {
   size_t slash = filename_str.rfind('/');
   if (slash != std::string::npos)
-    filename_str = filename_str.c_str() + slash + 1;
-  filename_str = std::string("/tmp/ld-run-") + filename_str + ".sh";
-  const char* filename = filename_str.c_str();
-  FILE* fp = fopen(filename, "w");
-  if (fp)
+    filename_str.erase(0,slash+1);
+  filename_str = "/tmp/ld-run-" + filename_str + ".sh";
+  const std::string filename_new = filename_str+"-new";
+  FILE* fp = fopen(filename_new.c_str(), "w");
+  fputs("Welcome to gold!  ",stderr);
+  if (fp && !rename(filename_new.c_str(),filename_str.c_str()) )
     {
       fprintf(fp, "[ \"$1\" = debug ]"
               " && PREFIX=\"${GDB-gdb} --annotate=3 --fullname %s --args\""
@@ -110,16 +111,15 @@ write_debug_script(std::string filename_str,
               argv_0);
       fprintf(fp, "$PREFIX%s $*\n", args);
       fclose(fp);
-      chmod(filename, 0755);
+      chmod(filename_str.c_str(), 0755);
+      fprintf(stderr,"Commandline written to %s.\n", filename_str.c_str());
     }
   else
-    filename = "[none]";
-  fprintf(stderr, "Welcome to gold!  Commandline written to %s.\n", filename);
+    fputs("Failed to write debug script\n",stderr);
   fflush(stderr);
 }
 
 #else // !defined(DEBUG)
-
 static inline std::string
 collect_argv(int, char**)
 {
diff --git a/gold/options.h b/gold/options.h
index f7c127953c..8c022ee94d 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1065,6 +1065,10 @@ class General_options
   DEFINE_bool(noinhibit_exec, options::TWO_DASHES, '\0', false,
 	      N_("Create an output file even if errors occur"), NULL);
 
+  DEFINE_bool(nostartfiles, options::ONE_DASH, '\0', false,
+      N_("Ignored for compatibility"),
+      NULL);
+
   DEFINE_bool(nostdlib, options::ONE_DASH, '\0', false,
 	      N_("Only search directories specified on the command line"),
 	      NULL);

Reply via email to