Fix group signature handling for relocatable link, add bootstrap

relocatable test.
This commit is contained in:
Ian Lance Taylor 2008-02-06 19:32:32 +00:00
parent 06b1d59cd6
commit 755ab8af10
7 changed files with 204 additions and 37 deletions

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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_);
}

View file

@ -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_;