Initial -r support.

This commit is contained in:
Ian Lance Taylor
2008-02-06 08:13:50 +00:00
parent 0797561a54
commit 6a74a71947
18 changed files with 1696 additions and 90 deletions

View File

@@ -378,8 +378,10 @@ Sized_relobj<size, big_endian>::symbol_section_and_value(unsigned int sym,
template<int size, bool big_endian>
bool
Sized_relobj<size, big_endian>::include_section_group(
Symbol_table* symtab,
Layout* layout,
unsigned int index,
const char* name,
const elfcpp::Shdr<size, big_endian>& shdr,
std::vector<bool>* omit)
{
@@ -393,13 +395,11 @@ Sized_relobj<size, big_endian>::include_section_group(
// groups. Other section groups are always included in the link
// just like ordinary sections.
elfcpp::Elf_Word flags = elfcpp::Swap<32, big_endian>::readval(pword);
if ((flags & elfcpp::GRP_COMDAT) == 0)
return true;
// Look up the group signature, which is the name of a symbol. This
// is a lot of effort to go to to read a string. Why didn't they
// just use the name of the SHT_GROUP section as the group
// signature?
// just have the group signature point into the string table, rather
// than indirect through a symbol?
// Get the appropriate symbol table header (this will normally be
// the single SHT_SYMTAB section, but in principle it need not be).
@@ -447,8 +447,15 @@ Sized_relobj<size, big_endian>::include_section_group(
// Record this section group, and see whether we've already seen one
// with the same signature.
if (layout->add_comdat(signature, true))
return true;
if ((flags & elfcpp::GRP_COMDAT) == 0
|| layout->add_comdat(signature, true))
{
if (parameters->output_is_object())
layout->layout_group(symtab, this, index, name, signature, shdr,
pword);
return true;
}
// This is a duplicate. We want to discard the sections in this
// group.
@@ -575,6 +582,10 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
// Keep track of which sections to omit.
std::vector<bool> omit(shnum, false);
// Keep track of reloc sections when doing a relocatable link.
const bool output_is_object = parameters->output_is_object();
std::vector<unsigned int> reloc_sections;
// Keep track of .eh_frame sections.
std::vector<unsigned int> eh_frame_sections;
@@ -595,7 +606,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
if (this->handle_gnu_warning_section(name, i, symtab))
{
if (!parameters->output_is_object())
if (!output_is_object)
omit[i] = true;
}
@@ -614,7 +625,8 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
{
if (shdr.get_sh_type() == elfcpp::SHT_GROUP)
{
if (!this->include_section_group(layout, i, shdr, &omit))
if (!this->include_section_group(symtab, layout, i, name, shdr,
&omit))
discard = true;
}
else if ((shdr.get_sh_flags() & elfcpp::SHF_GROUP) == 0
@@ -632,13 +644,29 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
continue;
}
// When doing a relocatable link we are going to copy input
// reloc sections into the output. We only want to copy the
// ones associated with sections which are not being discarded.
// However, we don't know that yet for all sections. So save
// reloc sections and process them later.
if (output_is_object
&& (shdr.get_sh_type() == elfcpp::SHT_REL
|| shdr.get_sh_type() == elfcpp::SHT_RELA))
{
reloc_sections.push_back(i);
continue;
}
if (output_is_object && shdr.get_sh_type() == elfcpp::SHT_GROUP)
continue;
// The .eh_frame section is special. It holds exception frame
// information that we need to read in order to generate the
// exception frame header. We process these after all the other
// sections so that the exception frame reader can reliably
// determine which sections are being discarded, and discard the
// corresponding information.
if (!parameters->output_is_object()
if (!output_is_object
&& strcmp(name, ".eh_frame") == 0
&& this->check_eh_frame_flags(&shdr))
{
@@ -663,6 +691,42 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags);
// When doing a relocatable link handle the reloc sections at the
// end.
if (output_is_object)
this->size_relocatable_relocs();
for (std::vector<unsigned int>::const_iterator p = reloc_sections.begin();
p != reloc_sections.end();
++p)
{
unsigned int i = *p;
const unsigned char* pshdr;
pshdr = sd->section_headers->data() + i * This::shdr_size;
typename This::Shdr shdr(pshdr);
unsigned int data_shndx = shdr.get_sh_info();
if (data_shndx >= shnum)
{
// We already warned about this above.
continue;
}
Output_section* data_section = map_sections[data_shndx].output_section;
if (data_section == NULL)
{
map_sections[i].output_section = NULL;
continue;
}
Relocatable_relocs* rr = new Relocatable_relocs();
this->set_relocatable_relocs(i, rr);
Output_section* os = layout->layout_reloc(this, i, shdr, data_section,
rr);
map_sections[i].output_section = os;
map_sections[i].offset = -1;
}
// Handle the .eh_frame sections at the end.
for (std::vector<unsigned int>::const_iterator p = eh_frame_sections.begin();
p != eh_frame_sections.end();