aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2008-02-06 19:32:32 +0000
committerIan Lance Taylor <iant@google.com>2008-02-06 19:32:32 +0000
commit755ab8af10558c40e5090e92c46bbbd89815c292 (patch)
treec2d87009c2ebc0af8507f0e2dddebdab5b91c608 /gold
parent06b1d59cd626db8764130ba2a03daa42feefc968 (diff)
downloadgdb-755ab8af10558c40e5090e92c46bbbd89815c292.zip
gdb-755ab8af10558c40e5090e92c46bbbd89815c292.tar.gz
gdb-755ab8af10558c40e5090e92c46bbbd89815c292.tar.bz2
Fix group signature handling for relocatable link, add bootstrap
relocatable test.
Diffstat (limited to 'gold')
-rw-r--r--gold/Makefile.am32
-rw-r--r--gold/Makefile.in48
-rw-r--r--gold/gold.cc3
-rw-r--r--gold/layout.cc50
-rw-r--r--gold/layout.h25
-rw-r--r--gold/output.cc18
-rw-r--r--gold/output.h65
7 files changed, 204 insertions, 37 deletions
diff --git a/gold/Makefile.am b/gold/Makefile.am
index cef759e..0f09afa 100644
--- a/gold/Makefile.am
+++ b/gold/Makefile.am
@@ -175,15 +175,41 @@ ld2_DEPENDENCIES = $(deps_var) gcctestdir2/ld
ld2_LDADD = $(ldadd_var)
ld2_LDFLAGS = -Bgcctestdir2/
-check_PROGRAMS = ld1 ld2
-
bootstrap-test: ld2
rm -f $@
echo "#!/bin/sh" > $@
echo "cmp ld1 ld2" > $@
chmod +x $@
-TESTS = bootstrap-test
+libgold-1-r.o: gcctestdir1/ld libgold.a
+ gcctestdir1/ld -o $@ -r --whole-archive libgold.a
+
+ld1_r_SOURCES = $(sources_var)
+ld1_r_DEPENDENCIES = libgold-1-r.o $(deps_var) gcctestdir1/ld
+ld1_r_LDADD = libgold-1-r.o $(ldadd_var)
+ld1_r_LDFLAGS = -Bgcctestdir1/
+
+gcctestdir2-r/ld: ld1-r
+ test -d gcctestdir2-r || mkdir -p gcctestdir2-r
+ rm -f gcctestdir2-r/ld
+ (cd gcctestdir2-r && $(LN_S) ../ld1-r ld)
+
+libgold-2-r.o: gcctestdir2-r/ld libgold.a
+ gcctestdir2-r/ld -o $@ -r --whole-archive libgold.a
+
+ld2_r_SOURCES = $(sources_var)
+ld2_r_DEPENDENCIES = libgold-2-r.o $(deps_var) gcctestdir2-r/ld
+ld2_r_LDADD = libgold-2-r.o $(ldadd_var)
+ld2_r_LDFLAGS = -Bgcctestdir2-r/
+
+bootstrap-test-r: ld2-r
+ rm -f $@
+ echo "#!/bin/sh" > $@
+ echo "cmp ld1-r ld2-r" > $@
+ chmod +x $@
+
+check_PROGRAMS = ld1 ld2 ld1-r ld2-r
+TESTS = bootstrap-test bootstrap-test-r
endif
endif
diff --git a/gold/Makefile.in b/gold/Makefile.in
index 22bae57..a315718 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -42,7 +42,8 @@ host_triplet = @host@
target_triplet = @target@
noinst_PROGRAMS = ld-new$(EXEEXT)
@GCC_TRUE@@NATIVE_LINKER_TRUE@check_PROGRAMS = ld1$(EXEEXT) \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2$(EXEEXT)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2$(EXEEXT) ld1-r$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2-r$(EXEEXT)
DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \
$(srcdir)/../config.sub $(srcdir)/../depcomp \
$(srcdir)/../install-sh $(srcdir)/../missing \
@@ -100,9 +101,15 @@ am__DEPENDENCIES_4 = @LIBOBJS@
am__ld1_SOURCES_DIST = main.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_OBJECTS = $(am__objects_4)
ld1_OBJECTS = $(am_ld1_OBJECTS)
+am__ld1_r_SOURCES_DIST = main.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_r_OBJECTS = $(am__objects_4)
+ld1_r_OBJECTS = $(am_ld1_r_OBJECTS)
am__ld2_SOURCES_DIST = main.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld2_OBJECTS = $(am__objects_4)
ld2_OBJECTS = $(am_ld2_OBJECTS)
+am__ld2_r_SOURCES_DIST = main.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld2_r_OBJECTS = $(am__objects_4)
+ld2_r_OBJECTS = $(am_ld2_r_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -117,10 +124,12 @@ CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES) \
- $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) $(ld2_SOURCES)
+ $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) $(ld1_r_SOURCES) \
+ $(ld2_SOURCES) $(ld2_r_SOURCES)
DIST_SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES) \
$(EXTRA_ld_new_SOURCES) $(am__ld1_SOURCES_DIST) \
- $(am__ld2_SOURCES_DIST)
+ $(am__ld1_r_SOURCES_DIST) $(am__ld2_SOURCES_DIST) \
+ $(am__ld2_r_SOURCES_DIST)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
@@ -382,7 +391,15 @@ POTFILES = $(CCFILES) $(HFILES) $(TARGETSOURCES)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_DEPENDENCIES = $(deps_var) gcctestdir2/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDADD = $(ldadd_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDFLAGS = -Bgcctestdir2/
-@GCC_TRUE@@NATIVE_LINKER_TRUE@TESTS = bootstrap-test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_SOURCES = $(sources_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_DEPENDENCIES = libgold-1-r.o $(deps_var) gcctestdir1/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_LDADD = libgold-1-r.o $(ldadd_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_LDFLAGS = -Bgcctestdir1/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_SOURCES = $(sources_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_DEPENDENCIES = libgold-2-r.o $(deps_var) gcctestdir2-r/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_LDADD = libgold-2-r.o $(ldadd_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_LDFLAGS = -Bgcctestdir2-r/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@TESTS = bootstrap-test bootstrap-test-r
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -464,9 +481,15 @@ ld-new$(EXEEXT): $(ld_new_OBJECTS) $(ld_new_DEPENDENCIES)
ld1$(EXEEXT): $(ld1_OBJECTS) $(ld1_DEPENDENCIES)
@rm -f ld1$(EXEEXT)
$(CXXLINK) $(ld1_LDFLAGS) $(ld1_OBJECTS) $(ld1_LDADD) $(LIBS)
+ld1-r$(EXEEXT): $(ld1_r_OBJECTS) $(ld1_r_DEPENDENCIES)
+ @rm -f ld1-r$(EXEEXT)
+ $(CXXLINK) $(ld1_r_LDFLAGS) $(ld1_r_OBJECTS) $(ld1_r_LDADD) $(LIBS)
ld2$(EXEEXT): $(ld2_OBJECTS) $(ld2_DEPENDENCIES)
@rm -f ld2$(EXEEXT)
$(CXXLINK) $(ld2_LDFLAGS) $(ld2_OBJECTS) $(ld2_LDADD) $(LIBS)
+ld2-r$(EXEEXT): $(ld2_r_OBJECTS) $(ld2_r_DEPENDENCIES)
+ @rm -f ld2-r$(EXEEXT)
+ $(CXXLINK) $(ld2_r_LDFLAGS) $(ld2_r_OBJECTS) $(ld2_r_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -1060,6 +1083,23 @@ po/POTFILES.in: @MAINT@ Makefile
@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "#!/bin/sh" > $@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "cmp ld1 ld2" > $@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ chmod +x $@
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@libgold-1-r.o: gcctestdir1/ld libgold.a
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir1/ld -o $@ -r --whole-archive libgold.a
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gcctestdir2-r/ld: ld1-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ test -d gcctestdir2-r || mkdir -p gcctestdir2-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f gcctestdir2-r/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ (cd gcctestdir2-r && $(LN_S) ../ld1-r ld)
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@libgold-2-r.o: gcctestdir2-r/ld libgold.a
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir2-r/ld -o $@ -r --whole-archive libgold.a
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@bootstrap-test-r: ld2-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "#!/bin/sh" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "cmp ld1-r ld2-r" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ chmod +x $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/gold/gold.cc b/gold/gold.cc
index 2aee1b7..71dac86 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -214,6 +214,9 @@ queue_middle_tasks(const General_options& options,
layout->define_section_symbols(symtab);
}
+ // Make sure we have symbols for any required group signatures.
+ layout->define_group_signatures(symtab);
+
// Read the relocations of the input files. We do this to find
// which symbols are used by relocations which require a GOT and/or
// a PLT entry, or a COPY reloc. When we implement garbage
diff --git a/gold/layout.cc b/gold/layout.cc
index 006a384..8b17f83 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -73,7 +73,7 @@ Layout::Layout(const General_options& options, Script_options* script_options)
unattached_section_list_(), special_output_list_(),
section_headers_(NULL), tls_segment_(NULL), symtab_section_(NULL),
dynsym_section_(NULL), dynamic_section_(NULL), dynamic_data_(NULL),
- eh_frame_section_(NULL), output_file_size_(-1),
+ eh_frame_section_(NULL), group_signatures_(), output_file_size_(-1),
input_requires_executable_stack_(false),
input_with_gnu_stack_note_(false),
input_without_gnu_stack_note_(false),
@@ -433,16 +433,19 @@ Layout::layout_group(Symbol_table* symtab,
shdr.get_sh_flags());
// We need to find a symbol with the signature in the symbol table.
- // This is a hack to force that to happen.
+ // If we don't find one now, we need to look again later.
Symbol* sym = symtab->lookup(signature, NULL);
- if (sym == NULL)
- sym = symtab->define_as_constant(signature, NULL, 0, 0,
- elfcpp::STT_NOTYPE,
- elfcpp::STB_WEAK,
- elfcpp::STV_HIDDEN, 0, false);
+ if (sym != NULL)
+ os->set_info_symndx(sym);
+ else
+ {
+ // We will wind up using a symbol whose name is the signature.
+ // So just put the signature in the symbol name pool to save it.
+ signature = symtab->canonicalize_name(signature);
+ this->group_signatures_.push_back(Group_signature(os, signature));
+ }
os->set_should_link_to_symtab();
- os->set_info_symndx(sym);
os->set_entsize(4);
section_size_type entry_count =
@@ -798,6 +801,37 @@ Layout::define_section_symbols(Symbol_table* symtab)
}
}
+// Define symbols for group signatures.
+
+void
+Layout::define_group_signatures(Symbol_table* symtab)
+{
+ for (Group_signatures::iterator p = this->group_signatures_.begin();
+ p != this->group_signatures_.end();
+ ++p)
+ {
+ Symbol* sym = symtab->lookup(p->signature, NULL);
+ if (sym != NULL)
+ p->section->set_info_symndx(sym);
+ else
+ {
+ // Force the name of the group section to the group
+ // signature, and use the group's section symbol as the
+ // signature symbol.
+ if (strcmp(p->section->name(), p->signature) != 0)
+ {
+ const char* name = this->namepool_.add(p->signature,
+ true, NULL);
+ p->section->set_name(name);
+ }
+ p->section->set_needs_symtab_index();
+ p->section->set_info_section_symndx(p->section);
+ }
+ }
+
+ this->group_signatures_.clear();
+}
+
// Find the first read-only PT_LOAD segment, creating one if
// necessary.
diff --git a/gold/layout.h b/gold/layout.h
index e050df3..674956e 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -171,6 +171,10 @@ class Layout
define_script_symbols(Symbol_table* symtab)
{ this->script_options_->add_symbols_to_table(symtab); }
+ // Define symbols for group signatures.
+ void
+ define_group_signatures(Symbol_table*);
+
// Return the Stringpool used for symbol names.
const Stringpool*
sympool() const
@@ -332,6 +336,25 @@ class Layout
static const Linkonce_mapping linkonce_mapping[];
static const int linkonce_mapping_count;
+ // During a relocatable link, a list of group sections and
+ // signatures.
+ struct Group_signature
+ {
+ // The group section.
+ Output_section* section;
+ // The signature.
+ const char* signature;
+
+ Group_signature()
+ : section(NULL), signature(NULL)
+ { }
+
+ Group_signature(Output_section* sectiona, const char* signaturea)
+ : section(sectiona), signature(signaturea)
+ { }
+ };
+ typedef std::vector<Group_signature> Group_signatures;
+
// Create a .note section for gold.
void
create_gold_note();
@@ -537,6 +560,8 @@ class Layout
Eh_frame* eh_frame_data_;
// The exception frame header output section if there is one.
Output_section* eh_frame_hdr_section_;
+ // A list of group sections and their signatures.
+ Group_signatures group_signatures_;
// The size of the output file.
off_t output_file_size_;
// Whether we have seen an object file marked to require an
diff --git a/gold/output.cc b/gold/output.cc
index 0e05ff7..332aa2c 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1610,6 +1610,7 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
requires_postprocessing_(false),
found_in_sections_clause_(false),
has_load_address_(false),
+ info_uses_section_index_(false),
tls_offset_(0)
{
// An unallocated section has no address. Forcing this means that
@@ -2005,7 +2006,7 @@ Output_section::write_header(const Layout* layout,
oshdr->put_sh_type(this->type_);
elfcpp::Elf_Xword flags = this->flags_;
- if (this->info_section_ != NULL)
+ if (this->info_section_ != NULL && this->info_uses_section_index_)
flags |= elfcpp::SHF_INFO_LINK;
oshdr->put_sh_flags(flags);
@@ -2020,12 +2021,21 @@ Output_section::write_header(const Layout* layout,
oshdr->put_sh_link(layout->dynsym_section()->out_shndx());
else
oshdr->put_sh_link(this->link_);
+
+ elfcpp::Elf_Word info;
if (this->info_section_ != NULL)
- oshdr->put_sh_info(this->info_section_->out_shndx());
+ {
+ if (this->info_uses_section_index_)
+ info = this->info_section_->out_shndx();
+ else
+ info = this->info_section_->symtab_index();
+ }
else if (this->info_symndx_ != NULL)
- oshdr->put_sh_info(this->info_symndx_->symtab_index());
+ info = this->info_symndx_->symtab_index();
else
- oshdr->put_sh_info(this->info_);
+ info = this->info_;
+ oshdr->put_sh_info(info);
+
oshdr->put_sh_addralign(this->addralign_);
oshdr->put_sh_entsize(this->entsize_);
}
diff --git a/gold/output.h b/gold/output.h
index b327eb2..7333513 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -1669,31 +1669,56 @@ class Output_section : public Output_data
unsigned int
info() const
{
- gold_assert(this->info_section_ == NULL);
+ gold_assert(this->info_section_ == NULL
+ && this->info_symndx_ == NULL);
return this->info_;
}
// Set the info field to the output section index of a section.
void
- set_info_section(const Output_data* od)
+ set_info_section(const Output_section* os)
{
- gold_assert(this->info_symndx_ == NULL && this->info_ == 0);
- this->info_section_ = od;
+ gold_assert((this->info_section_ == NULL
+ || (this->info_section_ == os
+ && this->info_uses_section_index_))
+ && this->info_symndx_ == NULL
+ && this->info_ == 0);
+ this->info_section_ = os;
+ this->info_uses_section_index_= true;
}
// Set the info field to the symbol table index of a symbol.
void
set_info_symndx(const Symbol* sym)
{
- gold_assert(this->info_section_ == NULL && this->info_ == 0);
+ gold_assert(this->info_section_ == NULL
+ && (this->info_symndx_ == NULL
+ || this->info_symndx_ == sym)
+ && this->info_ == 0);
this->info_symndx_ = sym;
}
+ // Set the info field to the symbol table index of a section symbol.
+ void
+ set_info_section_symndx(const Output_section* os)
+ {
+ gold_assert((this->info_section_ == NULL
+ || (this->info_section_ == os
+ && !this->info_uses_section_index_))
+ && this->info_symndx_ == NULL
+ && this->info_ == 0);
+ this->info_section_ = os;
+ this->info_uses_section_index_ = false;
+ }
+
// Set the info field to a constant.
void
set_info(unsigned int v)
{
- gold_assert(this->info_section_ == NULL && this->info_symndx_ == NULL);
+ gold_assert(this->info_section_ == NULL
+ && this->info_symndx_ == NULL
+ && (this->info_ == 0
+ || this->info_ == v));
this->info_ = v;
}
@@ -1790,6 +1815,17 @@ class Output_section : public Output_data
postprocessing_buffer_size() const
{ return this->current_data_size_for_child(); }
+ // Modify the section name. This is only permitted for an
+ // unallocated section, and only before the size has been finalized.
+ // Otherwise the name will not get into Layout::namepool_.
+ void
+ set_name(const char* newname)
+ {
+ gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0);
+ gold_assert(!this->is_data_size_valid());
+ this->name_ = newname;
+ }
+
// Return whether the offset OFFSET in the input section SHNDX in
// object OBJECT is being included in the link.
bool
@@ -1944,17 +1980,6 @@ class Output_section : public Output_data
do_tls_offset() const
{ return this->tls_offset_; }
- // Modify the section name. This is only permitted for an
- // unallocated section, and only before the size has been finalized.
- // Otherwise the name will not get into Layout::namepool_.
- void
- set_name(const char* newname)
- {
- gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0);
- gold_assert(!this->is_data_size_valid());
- this->name_ = newname;
- }
-
// This may be implemented by a child class.
virtual void
do_finalize_name(Layout*)
@@ -2259,7 +2284,7 @@ class Output_section : public Output_data
// If link_section_ is NULL, this is the link field.
unsigned int link_;
// Set the section info field to the index of this section.
- const Output_data* info_section_;
+ const Output_section* info_section_;
// If info_section_ is NULL, set the info field to the symbol table
// index of this symbol.
const Symbol* info_symndx_;
@@ -2319,6 +2344,10 @@ class Output_section : public Output_data
bool found_in_sections_clause_ : 1;
// Whether this section has an explicitly specified load address.
bool has_load_address_ : 1;
+ // True if the info_section_ field means the section index of the
+ // section, false if it means the symbol index of the corresponding
+ // section symbol.
+ bool info_uses_section_index_ : 1;
// For SHT_TLS sections, the offset of this section relative to the base
// of the TLS segment.
uint64_t tls_offset_;