From: Ian Lance Taylor Date: Thu, 7 Feb 2008 01:51:25 +0000 (+0000) Subject: Implement --just-symbols, including -R FILE. Fix symbol values when X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=88dd47ac00ee5a932bca9abbd2245c429dfd8f5b;p=deliverable%2Fbinutils-gdb.git Implement --just-symbols, including -R FILE. Fix symbol values when doing a relocatable link. --- diff --git a/elfcpp/elfcpp_file.h b/elfcpp/elfcpp_file.h index f9f28efdb4..431f8efabe 100644 --- a/elfcpp/elfcpp_file.h +++ b/elfcpp/elfcpp_file.h @@ -139,6 +139,10 @@ class Elf_file typename Elf_types::Elf_WXword section_flags(unsigned int shndx); + // Return the address of section SHNDX. + typename Elf_types::Elf_Addr + section_addr(unsigned int shndx); + // Return the type of section SHNDX. Elf_Word section_type(unsigned int shndx); @@ -341,6 +345,25 @@ Elf_file::section_flags(unsigned int shndx) return shdr.get_sh_flags(); } +// Return the address of section SHNDX. + +template +typename Elf_types::Elf_Addr +Elf_file::section_addr(unsigned int shndx) +{ + File* const file = this->file_; + + if (shndx >= this->shnum()) + file->error(_("section_flags: bad shndx %u >= %u"), + shndx, this->shnum()); + + typename File::View v(file->view(this->section_header_offset(shndx), + This::shdr_size)); + + Ef_shdr shdr(v.data()); + return shdr.get_sh_addr(); +} + // Return the type of section SHNDX. template diff --git a/gold/dynobj.h b/gold/dynobj.h index 67b0f51d46..d61df16b92 100644 --- a/gold/dynobj.h +++ b/gold/dynobj.h @@ -197,6 +197,11 @@ class Sized_dynobj : public Dynobj do_section_flags(unsigned int shndx) { return this->elf_file_.section_flags(shndx); } + // Return section address. + uint64_t + do_section_address(unsigned int shndx) + { return this->elf_file_.section_addr(shndx); } + // Return section type. unsigned int do_section_type(unsigned int shndx) diff --git a/gold/fileread.cc b/gold/fileread.cc index 668151a677..c21c6eecd3 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -576,7 +576,8 @@ Input_file::Input_file(const Task* task, const char* name, : file_() { this->input_argument_ = - new Input_file_argument(name, false, "", Position_dependent_options()); + new Input_file_argument(name, false, "", false, + Position_dependent_options()); bool ok = file_.open(task, name, contents, size); gold_assert(ok); } @@ -593,7 +594,17 @@ Input_file::options() const const char* Input_file::name() const -{ return this->input_argument_->name(); } +{ + return this->input_argument_->name(); +} + +// Return whether we are only reading symbols. + +bool +Input_file::just_symbols() const +{ + return this->input_argument_->just_symbols(); +} // Open the file. diff --git a/gold/fileread.h b/gold/fileread.h index 5d3674b93c..2a9e797fc6 100644 --- a/gold/fileread.h +++ b/gold/fileread.h @@ -418,6 +418,10 @@ class Input_file is_in_sysroot() const { return this->is_in_sysroot_; } + // Return whether this file is to be read only for its symbols. + bool + just_symbols() const; + private: Input_file(const Input_file&); Input_file& operator=(const Input_file&); diff --git a/gold/layout.cc b/gold/layout.cc index faae577336..98617f97fe 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -942,10 +942,10 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, // If there is a SECTIONS clause, put all the input sections into // the required order. Output_segment* load_seg; - if (parameters->output_is_object()) - load_seg = NULL; - else if (this->script_options_->saw_sections_clause()) + if (this->script_options_->saw_sections_clause()) load_seg = this->set_section_addresses_from_script(symtab); + else if (parameters->output_is_object()) + load_seg = NULL; else load_seg = this->find_first_load_seg(); diff --git a/gold/object.cc b/gold/object.cc index f82827c3b2..1adb851ba1 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -574,6 +574,17 @@ Sized_relobj::do_layout(Symbol_table* symtab, std::vector& map_sections(this->map_to_output()); map_sections.resize(shnum); + // If we are only linking for symbols, then there is nothing else to + // do here. + if (this->input_file()->just_symbols()) + { + delete sd->section_headers; + sd->section_headers = NULL; + delete sd->section_names; + sd->section_names = NULL; + return; + } + // Whether we've seen a .note.GNU-stack section. bool seen_gnu_stack = false; // The flags of a .note.GNU-stack section. diff --git a/gold/object.h b/gold/object.h index b83d420f65..36a2e1f495 100644 --- a/gold/object.h +++ b/gold/object.h @@ -190,6 +190,11 @@ class Object release() { this->input_file_->file().release(); } + // Return whether we should just read symbols from this file. + bool + just_symbols() const + { return this->input_file()->just_symbols(); } + // Return the sized target structure associated with this object. // This is like the target method but it returns a pointer of // appropriate checked type. @@ -222,6 +227,11 @@ class Object section_flags(unsigned int shndx) { return this->do_section_flags(shndx); } + // Return the section address given a section index. + uint64_t + section_address(unsigned int shndx) + { return this->do_section_address(shndx); } + // Return the section type given a section index. unsigned int section_type(unsigned int shndx) @@ -366,6 +376,10 @@ class Object virtual uint64_t do_section_flags(unsigned int shndx) = 0; + // Get section address--implemented by child class. + virtual uint64_t + do_section_address(unsigned int shndx) = 0; + // Get section type--implemented by child class. virtual unsigned int do_section_type(unsigned int shndx) = 0; @@ -1211,6 +1225,11 @@ class Sized_relobj : public Relobj do_section_flags(unsigned int shndx) { return this->elf_file_.section_flags(shndx); } + // Return section address. + uint64_t + do_section_address(unsigned int shndx) + { return this->elf_file_.section_addr(shndx); } + // Return section type. unsigned int do_section_type(unsigned int shndx) diff --git a/gold/options.cc b/gold/options.cc index a4b4c2f246..420f795201 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -144,6 +144,42 @@ library(int argc, char** argv, char* arg, bool long_option, return cmdline->process_l_option(argc, argv, arg, long_option); } +// Handle the -R option. Historically the GNU linker made -R a +// synonym for --just-symbols. ELF linkers have traditionally made -R +// a synonym for -rpath. When ELF support was added to the GNU +// linker, -R was changed to switch based on the argument: if the +// argument is an ordinary file, we treat it as --just-symbols, +// otherwise we treat it as -rpath. We need to be compatible with +// this, because existing build scripts rely on it. + +int +handle_r_option(int argc, char** argv, char* arg, bool long_option, + gold::Command_line* cmdline) +{ + int ret; + const char* val = cmdline->get_special_argument("R", argc, argv, arg, + long_option, &ret); + struct stat s; + if (::stat(val, &s) != 0 || S_ISDIR(s.st_mode)) + cmdline->add_to_rpath(val); + else + cmdline->add_just_symbols_file(val); + return ret; +} + +// Handle the --just-symbols option. + +int +handle_just_symbols_option(int argc, char** argv, char* arg, + bool long_option, gold::Command_line* cmdline) +{ + int ret; + const char* val = cmdline->get_special_argument("just-symbols", argc, argv, + arg, long_option, &ret); + cmdline->add_just_symbols_file(val); + return ret; +} + // Handle the special -T/--script option, which reads a linker script. int @@ -223,7 +259,7 @@ help(int, char**, char*, bool, gold::Command_line*) len += 2; } printf(options[j].help_output); - len += std::strlen(options[i].help_output); + len += std::strlen(options[j].help_output); comma = true; } else @@ -443,9 +479,16 @@ options::Command_line_options::options[] = &General_options::set_optimization_level), GENERAL_NOARG('r', NULL, N_("Generate relocatable output"), NULL, ONE_DASH, &General_options::set_relocatable), - GENERAL_ARG('R', "rpath", N_("Add DIR to runtime search path"), - N_("-R DIR, -rpath DIR"), ONE_DASH, - &General_options::add_to_rpath), + // -R really means -rpath, but can mean --just-symbols for + // compatibility with GNU ld. -rpath is always -rpath, so we list + // it separately. + SPECIAL('R', NULL, N_("Add DIR to runtime search path"), + N_("-R DIR"), ONE_DASH, &handle_r_option), + GENERAL_ARG('\0', "rpath", NULL, N_("-rpath DIR"), ONE_DASH, + &General_options::add_to_rpath), + SPECIAL('\0', "just-symbols", N_("Read only symbol values from file"), + N_("-R FILE, --just-symbols FILE"), TWO_DASHES, + &handle_just_symbols_option), GENERAL_ARG('\0', "rpath-link", N_("Add DIR to link time shared library search path"), N_("--rpath-link DIR"), TWO_DASHES, @@ -1023,7 +1066,7 @@ Command_line::apply_option(const options::One_option& opt, void Command_line::add_file(const char* name, bool is_lib) { - Input_file_argument file(name, is_lib, "", this->position_options_); + Input_file_argument file(name, is_lib, "", false, this->position_options_); this->inputs_.add_file(file); } diff --git a/gold/options.h b/gold/options.h index aa51126d82..dbfb3bd15a 100644 --- a/gold/options.h +++ b/gold/options.h @@ -636,17 +636,20 @@ class Input_file_argument // extra_search_path: an extra directory to look for the file, prior // to checking the normal library search path. If this is "", // then no extra directory is added. + // just_symbols: whether this file only defines symbols. // options: The position dependent options at this point in the // command line, such as --whole-archive. Input_file_argument() - : name_(), is_lib_(false), extra_search_path_(""), options_() + : name_(), is_lib_(false), extra_search_path_(""), just_symbols_(false), + options_() { } Input_file_argument(const char* name, bool is_lib, const char* extra_search_path, + bool just_symbols, const Position_dependent_options& options) : name_(name), is_lib_(is_lib), extra_search_path_(extra_search_path), - options_(options) + just_symbols_(just_symbols), options_(options) { } const char* @@ -669,6 +672,11 @@ class Input_file_argument : this->extra_search_path_.c_str()); } + // Return whether we should only read symbols from this file. + bool + just_symbols() const + { return this->just_symbols_; } + // Return whether this file may require a search using the -L // options. bool @@ -682,6 +690,7 @@ class Input_file_argument std::string name_; bool is_lib_; std::string extra_search_path_; + bool just_symbols_; Position_dependent_options options_; }; @@ -848,6 +857,19 @@ class Command_line int process_l_option(int, char**, char*, bool); + // Handle a -R option when it means --rpath. + void + add_to_rpath(const char* arg) + { this->options_.add_to_rpath(arg); } + + // Add a file for which we just read the symbols. + void + add_just_symbols_file(const char* arg) + { + this->inputs_.add_file(Input_file_argument(arg, false, "", true, + this->position_options_)); + } + // Handle a --start-group option. void start_group(const char* arg); diff --git a/gold/script.cc b/gold/script.cc index da2a228b52..7cf3c7e6e1 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -1412,7 +1412,7 @@ read_script_file(const char* filename, Command_line* cmdline, // so we invent a fake value. const Task* task = reinterpret_cast(-1); - Input_file_argument input_argument(filename, false, "", + Input_file_argument input_argument(filename, false, "", false, cmdline->position_dependent_options()); Input_file input_file(&input_argument); if (!input_file.open(cmdline->options(), dirsearch, task)) @@ -2038,7 +2038,7 @@ script_add_file(void* closurev, const char* name, size_t length) } Input_file_argument file(name_string.c_str(), false, extra_search_path, - closure->position_dependent_options()); + false, closure->position_dependent_options()); closure->inputs()->add_file(file); } diff --git a/gold/symtab.cc b/gold/symtab.cc index c7f68166a4..85761fd242 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -634,6 +634,8 @@ Symbol_table::add_from_relobj( const int sym_size = elfcpp::Elf_sizes::sym_size; + const bool just_symbols = relobj->just_symbols(); + const unsigned char* p = syms; for (size_t i = 0; i < count; ++i, p += sym_size) { @@ -701,6 +703,27 @@ Symbol_table::add_from_relobj( local = true; } + if (just_symbols) + { + if (psym != &sym2) + memcpy(symbuf, p, sym_size); + elfcpp::Sym_write sw(symbuf); + sw.put_st_shndx(elfcpp::SHN_ABS); + if (st_shndx != elfcpp::SHN_UNDEF + && st_shndx < elfcpp::SHN_LORESERVE) + { + // Symbol values in object files are section relative. + // This is normally what we want, but since here we are + // converting the symbol to absolute we need to add the + // section address. The section address in an object + // file is normally zero, but people can use a linker + // script to change it. + sw.put_st_value(sym2.get_st_value() + + relobj->section_address(st_shndx)); + } + psym = &sym2; + } + Sized_symbol* res; if (ver == NULL) { @@ -744,6 +767,12 @@ Symbol_table::add_from_dynobj( gold_assert(size == dynobj->target()->get_size()); gold_assert(size == parameters->get_size()); + if (dynobj->just_symbols()) + { + gold_error(_("--just-symbols does not make sense with a shared object")); + return; + } + if (versym != NULL && versym_size / 2 < count) { dynobj->error(_("too few symbol versions")); @@ -1833,7 +1862,8 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, } unsigned int shndx; - typename elfcpp::Elf_types<32>::Elf_Addr value = sym->value(); + typename elfcpp::Elf_types::Elf_Addr sym_value = sym->value(); + typename elfcpp::Elf_types::Elf_Addr dynsym_value = sym_value; switch (sym->source()) { case Symbol::FROM_OBJECT: @@ -1854,7 +1884,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, if (symobj->is_dynamic()) { if (sym->needs_dynsym_value()) - value = target->dynsym_value(sym); + dynsym_value = target->dynsym_value(sym); shndx = elfcpp::SHN_UNDEF; } else if (in_shndx == elfcpp::SHN_UNDEF @@ -1868,6 +1898,11 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, &secoff); gold_assert(os != NULL); shndx = os->out_shndx(); + + // In object files symbol values are section + // relative. + if (parameters->output_is_object()) + sym_value -= os->address(); } } } @@ -1895,7 +1930,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, gold_assert(sym_index < output_count); unsigned char* ps = psyms + (sym_index * sym_size); this->sized_write_symbol SELECT_SIZE_ENDIAN_NAME(size, big_endian) ( - sym, sym->value(), shndx, sympool, ps + sym, sym_value, shndx, sympool, ps SELECT_SIZE_ENDIAN(size, big_endian)); } @@ -1905,7 +1940,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, gold_assert(dynsym_index < dynamic_count); unsigned char* pd = dynamic_view + (dynsym_index * sym_size); this->sized_write_symbol SELECT_SIZE_ENDIAN_NAME(size, big_endian) ( - sym, value, shndx, dynpool, pd + sym, dynsym_value, shndx, dynpool, pd SELECT_SIZE_ENDIAN(size, big_endian)); } } diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index b0b149d4fd..c1a081c07d 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -541,6 +541,15 @@ script_test_2_SOURCES = script_test_2.cc script_test_2a.cc script_test_2b.cc script_test_2_DEPENDENCIES = gcctestdir/ld script_test_2.t script_test_2_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -T $(srcdir)/script_test_2.t +check_PROGRAMS += justsyms +justsyms_SOURCES = justsyms_1.cc +justsyms_DEPENDENCIES = gcctestdir/ld justsyms_2r.o +justsyms_LDFLAGS = -Bgcctestdir/ -Wl,-R,justsyms_2r.o +justsyms_2.o: justsyms_2.cc + $(CXXCOMPILE) -c -o $@ $< +justsyms_2r.o: justsyms_2.o gcctestdir/ld + gcctestdir/ld -o $@ -r -T $(srcdir)/justsyms.t justsyms_2.o + if OBJDUMP_AND_CPPFILT check_SCRIPTS += ver_matching_test.sh check_DATA += ver_matching_test.stdout diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index fe30a06d31..10119ebc1f 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -176,7 +176,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) $(am__EXEEXT_1) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test script_test_1 \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2 +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2 justsyms @GCC_FALSE@script_test_1_DEPENDENCIES = libgoldtest.a ../libgold.a \ @GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ @GCC_FALSE@ $(am__DEPENDENCIES_1) @@ -191,6 +191,13 @@ check_PROGRAMS = object_unittest$(EXEEXT) $(am__EXEEXT_1) \ @NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ @NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \ @NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) +@GCC_FALSE@justsyms_DEPENDENCIES = libgoldtest.a ../libgold.a \ +@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ +@GCC_FALSE@ $(am__DEPENDENCIES_1) +@NATIVE_LINKER_FALSE@justsyms_DEPENDENCIES = libgoldtest.a \ +@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@am__append_11 = ver_matching_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ script_test_3.sh @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@am__append_12 = ver_matching_test.stdout \ @@ -264,7 +271,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS) @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_1$(EXEEXT) \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2$(EXEEXT) +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2$(EXEEXT) \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ justsyms$(EXEEXT) @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@am__EXEEXT_8 = script_test_3$(EXEEXT) basic_pic_test_SOURCES = basic_pic_test.c basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT) @@ -375,6 +383,11 @@ flagstest_o_specialfile_and_compress_debug_sections_LDADD = $(LDADD) flagstest_o_specialfile_and_compress_debug_sections_DEPENDENCIES = \ libgoldtest.a ../libgold.a ../../libiberty/libiberty.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__justsyms_SOURCES_DIST = justsyms_1.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@am_justsyms_OBJECTS = \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ justsyms_1.$(OBJEXT) +justsyms_OBJECTS = $(am_justsyms_OBJECTS) +justsyms_LDADD = $(LDADD) am_object_unittest_OBJECTS = object_unittest.$(OBJEXT) object_unittest_OBJECTS = $(am_object_unittest_OBJECTS) object_unittest_LDADD = $(LDADD) @@ -573,9 +586,10 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \ $(exception_static_test_SOURCES) $(exception_test_SOURCES) \ flagstest_compress_debug_sections.c flagstest_o_specialfile.c \ flagstest_o_specialfile_and_compress_debug_sections.c \ - $(object_unittest_SOURCES) $(script_test_1_SOURCES) \ - $(script_test_2_SOURCES) script_test_3.c \ - $(tls_pic_test_SOURCES) $(tls_shared_ie_test_SOURCES) \ + $(justsyms_SOURCES) $(object_unittest_SOURCES) \ + $(script_test_1_SOURCES) $(script_test_2_SOURCES) \ + script_test_3.c $(tls_pic_test_SOURCES) \ + $(tls_shared_ie_test_SOURCES) \ $(tls_shared_nonpic_test_SOURCES) $(tls_shared_test_SOURCES) \ $(tls_static_pic_test_SOURCES) $(tls_static_test_SOURCES) \ $(tls_test_SOURCES) $(two_file_mixed_2_shared_test_SOURCES) \ @@ -609,7 +623,8 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \ $(am__exception_test_SOURCES_DIST) \ flagstest_compress_debug_sections.c flagstest_o_specialfile.c \ flagstest_o_specialfile_and_compress_debug_sections.c \ - $(object_unittest_SOURCES) $(am__script_test_1_SOURCES_DIST) \ + $(am__justsyms_SOURCES_DIST) $(object_unittest_SOURCES) \ + $(am__script_test_1_SOURCES_DIST) \ $(am__script_test_2_SOURCES_DIST) script_test_3.c \ $(am__tls_pic_test_SOURCES_DIST) \ $(am__tls_shared_ie_test_SOURCES_DIST) \ @@ -1007,6 +1022,9 @@ object_unittest_SOURCES = object_unittest.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_2_SOURCES = script_test_2.cc script_test_2a.cc script_test_2b.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_2_DEPENDENCIES = gcctestdir/ld script_test_2.t @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_2_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -T $(srcdir)/script_test_2.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_SOURCES = justsyms_1.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_DEPENDENCIES = gcctestdir/ld justsyms_2r.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_LDFLAGS = -Bgcctestdir/ -Wl,-R,justsyms_2r.o all: all-am .SUFFIXES: @@ -1119,6 +1137,9 @@ exception_test$(EXEEXT): $(exception_test_OBJECTS) $(exception_test_DEPENDENCIES @NATIVE_LINKER_FALSE@flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT): $(flagstest_o_specialfile_and_compress_debug_sections_OBJECTS) $(flagstest_o_specialfile_and_compress_debug_sections_DEPENDENCIES) @NATIVE_LINKER_FALSE@ @rm -f flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT) @NATIVE_LINKER_FALSE@ $(LINK) $(flagstest_o_specialfile_and_compress_debug_sections_LDFLAGS) $(flagstest_o_specialfile_and_compress_debug_sections_OBJECTS) $(flagstest_o_specialfile_and_compress_debug_sections_LDADD) $(LIBS) +justsyms$(EXEEXT): $(justsyms_OBJECTS) $(justsyms_DEPENDENCIES) + @rm -f justsyms$(EXEEXT) + $(CXXLINK) $(justsyms_LDFLAGS) $(justsyms_OBJECTS) $(justsyms_LDADD) $(LIBS) object_unittest$(EXEEXT): $(object_unittest_OBJECTS) $(object_unittest_DEPENDENCIES) @rm -f object_unittest$(EXEEXT) $(CXXLINK) $(object_unittest_LDFLAGS) $(object_unittest_OBJECTS) $(object_unittest_LDADD) $(LIBS) @@ -1236,6 +1257,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_compress_debug_sections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile_and_compress_debug_sections.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/justsyms_1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script_test_1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script_test_2.Po@am__quote@ @@ -1692,6 +1714,10 @@ uninstall-am: uninstall-info-am @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $< @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_4.o: ver_test_4.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_2.o: justsyms_2.cc +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -o $@ $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_2r.o: justsyms_2.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ -r -T $(srcdir)/justsyms.t justsyms_2.o @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ver_matching_def.so: ver_matching_def.cc gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ $(CXXLINK) -O0 -Bgcctestdir/ -shared $(srcdir)/ver_matching_def.cc -Wl,--version-script=$(srcdir)/version_script.map @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ver_matching_test.stdout: ver_matching_def.so diff --git a/gold/testsuite/justsyms.t b/gold/testsuite/justsyms.t new file mode 100644 index 0000000000..4d68893d0b --- /dev/null +++ b/gold/testsuite/justsyms.t @@ -0,0 +1,31 @@ +/* justsyms.t -- test --just-symbols for gold. + + Copyright 2008 Free Software Foundation, Inc. + Written by Ian Lance Taylor . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +SECTIONS +{ + /* This script is only used for a .o file. */ + . = 0x10000; + .gold_test : { *(.gold_test) } + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss) } +} diff --git a/gold/testsuite/justsyms_1.cc b/gold/testsuite/justsyms_1.cc new file mode 100644 index 0000000000..599d8c9be0 --- /dev/null +++ b/gold/testsuite/justsyms_1.cc @@ -0,0 +1,54 @@ +// justsyms_1.cc -- test --just-symbols for gold + +// Copyright 2008 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +// The Linux kernel builds an object file using a linker script, and +// then links against that object file using the -R option. This is a +// test for that usage. + +#include +#include +#include +#include +#include + +extern char justsyms_string[]; + +// We expect to get a SIGSEGV. +static void +handle_sigsegv(int) +{ + exit(0); +} + +int +main(int, char**) +{ + // The linker script should arrange for this symbol to be exactly at + // address 0x10000. + assert(reinterpret_cast(justsyms_string) == 0x10000); + + // However, since the file was linked with --just-symbols, we should + // not be able to actually access the symbol. + signal(SIGSEGV, handle_sigsegv); + char c = justsyms_string[0]; + exit(c == '\0' ? 1 : c); +} diff --git a/gold/testsuite/justsyms_2.cc b/gold/testsuite/justsyms_2.cc new file mode 100644 index 0000000000..dbbf4b54f4 --- /dev/null +++ b/gold/testsuite/justsyms_2.cc @@ -0,0 +1,27 @@ +// justsyms_2.cc -- test --just-symbols for gold + +// Copyright 2008 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +// This test goes with justsyms_1.cc. We compile this file, then +// apply a linker script with -r to set the section addresses. + +char justsyms_string[] __attribute__ ((section(".gold_test"))) = + "justsyms string";