Add 64-bit archive support.
gold/ * archive.cc (Archive::sym64name): New const. (Archive::setup): Add support for SYM64 armap. (Archive::read_armap): Likewise. (Archive::interpret_header): Likewise. (Archive::const_iterator::read_next_header): Likewise. * archive.h (Archive::sym64name): New const. (Archive::read_armap): Add mapsize template parameter.
This commit is contained in:
parent
8d9743bd43
commit
6f97897dbe
3 changed files with 38 additions and 6 deletions
|
@ -1,3 +1,13 @@
|
|||
2015-10-28 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
|
||||
* archive.cc (Archive::sym64name): New const.
|
||||
(Archive::setup): Add support for SYM64 armap.
|
||||
(Archive::read_armap): Likewise.
|
||||
(Archive::interpret_header): Likewise.
|
||||
(Archive::const_iterator::read_next_header): Likewise.
|
||||
* archive.h (Archive::sym64name): New const.
|
||||
(Archive::read_armap): Add mapsize template parameter.
|
||||
|
||||
2015-10-28 Marcin Kościelnicki <koriakin@0x04.net>
|
||||
|
||||
* dynobj.cc (Dynobj::create_elf_hash_table): Create hash table with
|
||||
|
|
|
@ -193,6 +193,8 @@ const char Archive::armagt[sarmag] =
|
|||
|
||||
const char Archive::arfmag[2] = { '`', '\n' };
|
||||
|
||||
const char Archive::sym64name[7] = { '/', 'S', 'Y', 'M', '6', '4', '/' };
|
||||
|
||||
Archive::Archive(const std::string& name, Input_file* input_file,
|
||||
bool is_thin_archive, Dirsearch* dirpath, Task* task)
|
||||
: Library_base(task), name_(name), input_file_(input_file), armap_(),
|
||||
|
@ -225,7 +227,12 @@ Archive::setup()
|
|||
off_t off = sarmag;
|
||||
if (armap_name.empty())
|
||||
{
|
||||
this->read_armap(sarmag + sizeof(Archive_header), armap_size);
|
||||
this->read_armap<32>(sarmag + sizeof(Archive_header), armap_size);
|
||||
off = sarmag + sizeof(Archive_header) + armap_size;
|
||||
}
|
||||
else if (armap_name == "/SYM64/")
|
||||
{
|
||||
this->read_armap<64>(sarmag + sizeof(Archive_header), armap_size);
|
||||
off = sarmag + sizeof(Archive_header) + armap_size;
|
||||
}
|
||||
else if (!this->input_file_->options().whole_archive())
|
||||
|
@ -277,6 +284,7 @@ Archive::unlock_nested_archives()
|
|||
|
||||
// Read the archive symbol map.
|
||||
|
||||
template<int mapsize>
|
||||
void
|
||||
Archive::read_armap(off_t start, section_size_type size)
|
||||
{
|
||||
|
@ -290,8 +298,10 @@ Archive::read_armap(off_t start, section_size_type size)
|
|||
const unsigned char* p = this->get_view(start, size, true, false);
|
||||
|
||||
// Numbers in the armap are always big-endian.
|
||||
const elfcpp::Elf_Word* pword = reinterpret_cast<const elfcpp::Elf_Word*>(p);
|
||||
unsigned int nsyms = elfcpp::Swap<32, true>::readval(pword);
|
||||
typedef typename elfcpp::Elf_types<mapsize>::Elf_Addr Entry_type;
|
||||
const Entry_type* pword = reinterpret_cast<const Entry_type*>(p);
|
||||
unsigned long nsyms = convert_types<unsigned long, Entry_type>(
|
||||
elfcpp::Swap<mapsize, true>::readval(pword));
|
||||
++pword;
|
||||
|
||||
// Note that the addition is in units of sizeof(elfcpp::Elf_Word).
|
||||
|
@ -303,10 +313,11 @@ Archive::read_armap(off_t start, section_size_type size)
|
|||
this->armap_.resize(nsyms);
|
||||
|
||||
section_offset_type name_offset = 0;
|
||||
for (unsigned int i = 0; i < nsyms; ++i)
|
||||
for (unsigned long i = 0; i < nsyms; ++i)
|
||||
{
|
||||
this->armap_[i].name_offset = name_offset;
|
||||
this->armap_[i].file_offset = elfcpp::Swap<32, true>::readval(pword);
|
||||
this->armap_[i].file_offset = convert_types<off_t, Entry_type>(
|
||||
elfcpp::Swap<mapsize, true>::readval(pword));
|
||||
name_offset += strlen(pnames + name_offset) + 1;
|
||||
++pword;
|
||||
if (this->armap_[i].file_offset != last_seen_offset)
|
||||
|
@ -394,6 +405,11 @@ Archive::interpret_header(const Archive_header* hdr, off_t off,
|
|||
if (!pname->empty())
|
||||
pname->clear();
|
||||
}
|
||||
else if (memcmp(hdr->ar_name, sym64name, sizeof sym64name) == 0)
|
||||
{
|
||||
// This is the symbol table, 64-bit version.
|
||||
pname->assign(sym64name, sizeof sym64name);
|
||||
}
|
||||
else if (hdr->ar_name[1] == '/')
|
||||
{
|
||||
// This is the extended name table.
|
||||
|
@ -544,7 +560,9 @@ Archive::const_iterator::read_next_header()
|
|||
this->header_.off = this->off_;
|
||||
|
||||
// Skip special members.
|
||||
if (!this->header_.name.empty() && this->header_.name != "/")
|
||||
if (!this->header_.name.empty()
|
||||
&& this->header_.name != "/"
|
||||
&& this->header_.name != "/SYM64/")
|
||||
return;
|
||||
|
||||
this->off_ += sizeof(Archive_header) + this->header_.size;
|
||||
|
|
|
@ -175,6 +175,9 @@ class Archive : public Library_base
|
|||
// The string expected at the end of an archive member header.
|
||||
static const char arfmag[2];
|
||||
|
||||
// Name of 64-bit symbol table member.
|
||||
static const char sym64name[7];
|
||||
|
||||
// The name of the object. This is the name used on the command
|
||||
// line; e.g., if "-lgcc" is on the command line, this will be
|
||||
// "gcc".
|
||||
|
@ -290,6 +293,7 @@ class Archive : public Library_base
|
|||
{ return this->input_file_->file().get_view(0, start, size, aligned, cache); }
|
||||
|
||||
// Read the archive symbol map.
|
||||
template<int mapsize>
|
||||
void
|
||||
read_armap(off_t start, section_size_type size);
|
||||
|
||||
|
|
Loading…
Reference in a new issue