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);