Implement --just-symbols, including -R FILE. Fix symbol values when
authorIan Lance Taylor <iant@google.com>
Thu, 7 Feb 2008 01:51:25 +0000 (01:51 +0000)
committerIan Lance Taylor <iant@google.com>
Thu, 7 Feb 2008 01:51:25 +0000 (01:51 +0000)
doing a relocatable link.

16 files changed:
elfcpp/elfcpp_file.h
gold/dynobj.h
gold/fileread.cc
gold/fileread.h
gold/layout.cc
gold/object.cc
gold/object.h
gold/options.cc
gold/options.h
gold/script.cc
gold/symtab.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/justsyms.t [new file with mode: 0644]
gold/testsuite/justsyms_1.cc [new file with mode: 0644]
gold/testsuite/justsyms_2.cc [new file with mode: 0644]

index f9f28efdb4340936230e0b8bb7393fb04233c179..431f8efabeef8aa7365a1f626c09b0e905dbeac8 100644 (file)
@@ -139,6 +139,10 @@ class Elf_file
   typename Elf_types<size>::Elf_WXword
   section_flags(unsigned int shndx);
 
+  // Return the address of section SHNDX.
+  typename Elf_types<size>::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<size, big_endian, File>::section_flags(unsigned int shndx)
   return shdr.get_sh_flags();
 }
 
+// Return the address of section SHNDX.
+
+template<int size, bool big_endian, typename File>
+typename Elf_types<size>::Elf_Addr
+Elf_file<size, big_endian, 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<int size, bool big_endian, typename File>
index 67b0f51d4620ecb21da111974539d965344e7b2c..d61df16b92fbcc7856e52f6d34e5ebcfeedc4055 100644 (file)
@@ -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)
index 668151a677cc800e6ca6d8e07428208199c6cd88..c21c6eecd39133d168bfab33a630e683e74c1a28 100644 (file)
@@ -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.
 
index 5d3674b93c260fdcbc4b735493f6210dcc5ea155..2a9e797fc6bdfeccf177f50a1ba4b684d0a97072 100644 (file)
@@ -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&);
index faae577336cb0da7b8aa23aeec232081b57d8bd0..98617f97fed8e2293bc6a83d07862f0ed712c8cf 100644 (file)
@@ -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();
 
index f82827c3b2f36299ec26810c5bef8cbde4f1da3a..1adb851ba1dd9f2e4f251cb7aaa75f7da6363511 100644 (file)
@@ -574,6 +574,17 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
   std::vector<Map_to_output>& 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.
index b83d420f65c454495528cafb1be97832d06ee754..36a2e1f495f9c1e1eaf8de136724215eb57d823a 100644 (file)
@@ -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)
index a4b4c2f24681f03141ad3df72e1f26502fbf8fe6..420f795201b3f5ccccdee7e9269296da13810240 100644 (file)
@@ -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);
 }
 
index aa51126d82657809654a11e25fb8ad2fcdd233b0..dbfb3bd15adda9e41932f081a8b82454b9336db4 100644 (file)
@@ -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);
index da2a228b52aa93c85fe6671932a0ab514b37ef12..7cf3c7e6e104dcc121c9003f8079e310931bd756 100644 (file)
@@ -1412,7 +1412,7 @@ read_script_file(const char* filename, Command_line* cmdline,
   // so we invent a fake value.
   const Task* task = reinterpret_cast<const Task*>(-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);
 }
 
index c7f68166a46b177aafb175eb466cf7b88d126b56..85761fd2425d33256aae015bc655b105b13133b8 100644 (file)
@@ -634,6 +634,8 @@ Symbol_table::add_from_relobj(
 
   const int sym_size = elfcpp::Elf_sizes<size>::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<size, big_endian> 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<size>* 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<size>::Elf_Addr sym_value = sym->value();
+      typename elfcpp::Elf_types<size>::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));
        }
     }
index b0b149d4fd9939014e34e6759dc1f94d0413b9ff..c1a081c07df28cbd8363aafbb4bc83c0a012ecaf 100644 (file)
@@ -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
index fe30a06d3117fc85bb58528553bb8f26d01bdb94..10119ebc1ff094b89b9f877be78abd11f0f29671 100644 (file)
@@ -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 (file)
index 0000000..4d68893
--- /dev/null
@@ -0,0 +1,31 @@
+/* justsyms.t -- test --just-symbols for gold.
+
+   Copyright 2008 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor <iant@google.com>.
+
+   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 (file)
index 0000000..599d8c9
--- /dev/null
@@ -0,0 +1,54 @@
+// justsyms_1.cc -- test --just-symbols for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// 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 <cassert>
+#include <csignal>
+#include <cstddef>
+#include <cstdlib>
+#include <stdint.h>
+
+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<uintptr_t>(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 (file)
index 0000000..dbbf4b5
--- /dev/null
@@ -0,0 +1,27 @@
+// justsyms_2.cc -- test --just-symbols for gold
+
+// Copyright 2008 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// 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";