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