diff options
author | Andreas Gampe <agampe@google.com> | 2015-04-08 00:37:23 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-08 00:37:25 +0000 |
commit | 40f65560b5ecd79aeaadc16b03834d11aea1e0a5 (patch) | |
tree | b93fb2f045a4f47f8b6e3c8541a07781dcce2c77 /runtime | |
parent | d2b9c0ca73a01cc31482a54cbcae1b3ac85379b8 (diff) | |
parent | 3c54b0023fca579aae006dfa607fb14de5846c42 (diff) | |
download | art-40f65560b5ecd79aeaadc16b03834d11aea1e0a5.zip art-40f65560b5ecd79aeaadc16b03834d11aea1e0a5.tar.gz art-40f65560b5ecd79aeaadc16b03834d11aea1e0a5.tar.bz2 |
Merge "ART: Fix 64-bit ELF file support"
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/elf_file.cc | 41 | ||||
-rw-r--r-- | runtime/elf_file.h | 4 | ||||
-rw-r--r-- | runtime/elf_file_impl.h | 15 |
3 files changed, 38 insertions, 22 deletions
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc index bc5cf9b..411ec43 100644 --- a/runtime/elf_file.cc +++ b/runtime/elf_file.cc @@ -1630,8 +1630,10 @@ static bool IsFDE(FDE64* frame) { return frame->CIE_pointer != 0; } -static bool FixupEHFrame(off_t base_address_delta, - uint8_t* eh_frame, size_t eh_frame_size) { +template <typename Elf_SOff> +static bool FixupEHFrame(Elf_SOff base_address_delta, uint8_t* eh_frame, size_t eh_frame_size) { + // TODO: Check the spec whether this is really data-dependent, or whether it's clear from the + // ELF file whether we should expect 32-bit or 64-bit. if (*(reinterpret_cast<uint32_t*>(eh_frame)) == 0xffffffff) { FDE64* last_frame = reinterpret_cast<FDE64*>(eh_frame + eh_frame_size); FDE64* frame = NextFDE(reinterpret_cast<FDE64*>(eh_frame)); @@ -1643,6 +1645,7 @@ static bool FixupEHFrame(off_t base_address_delta, } return true; } else { + CHECK(IsInt<32>(base_address_delta)); FDE32* last_frame = reinterpret_cast<FDE32*>(eh_frame + eh_frame_size); FDE32* frame = NextFDE(reinterpret_cast<FDE32*>(eh_frame)); for (; frame < last_frame; frame = NextFDE(frame)) { @@ -1772,7 +1775,9 @@ class DebugLineInstructionIterator FINAL { uint8_t* current_instruction_; }; -static bool FixupDebugLine(off_t base_offset_delta, DebugLineInstructionIterator* iter) { +template <typename Elf_SOff> +static bool FixupDebugLine(Elf_SOff base_offset_delta, DebugLineInstructionIterator* iter) { + CHECK(IsInt<32>(base_offset_delta)); for (; iter->GetInstruction(); iter->Next()) { if (iter->IsExtendedOpcode() && iter->GetOpcode() == dwarf::DW_LNE_set_address) { *reinterpret_cast<uint32_t*>(iter->GetArguments()) += base_offset_delta; @@ -2044,7 +2049,9 @@ class DebugInfoIterator { DebugTag* current_tag_; }; -static bool FixupDebugInfo(off_t base_address_delta, DebugInfoIterator* iter) { +template <typename Elf_SOff> +static bool FixupDebugInfo(Elf_SOff base_address_delta, DebugInfoIterator* iter) { + CHECK(IsInt<32>(base_address_delta)); do { if (iter->GetCurrentTag()->GetAttrSize(dwarf::DW_AT_low_pc) != sizeof(int32_t) || iter->GetCurrentTag()->GetAttrSize(dwarf::DW_AT_high_pc) != sizeof(int32_t)) { @@ -2066,7 +2073,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupDebugSections(off_t base_address_delta) { + ::FixupDebugSections(typename std::make_signed<Elf_Off>::type base_address_delta) { const Elf_Shdr* debug_info = FindSectionByName(".debug_info"); const Elf_Shdr* debug_abbrev = FindSectionByName(".debug_abbrev"); const Elf_Shdr* eh_frame = FindSectionByName(".eh_frame"); @@ -2280,7 +2287,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Fixup(uintptr_t base_address) { + ::Fixup(Elf_Addr base_address) { if (!FixupDynamic(base_address)) { LOG(WARNING) << "Failed to fixup .dynamic in " << file_->GetPath(); return false; @@ -2305,7 +2312,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, LOG(WARNING) << "Failed to fixup .rel.dyn in " << file_->GetPath(); return false; } - if (!FixupDebugSections(base_address)) { + static_assert(sizeof(Elf_Off) >= sizeof(base_address), "Potentially losing precision."); + if (!FixupDebugSections(static_cast<Elf_Off>(base_address))) { LOG(WARNING) << "Failed to fixup debug sections in " << file_->GetPath(); return false; } @@ -2317,7 +2325,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupDynamic(uintptr_t base_address) { + ::FixupDynamic(Elf_Addr base_address) { for (Elf_Word i = 0; i < GetDynamicNum(); i++) { Elf_Dyn& elf_dyn = GetDynamic(i); Elf_Word d_tag = elf_dyn.d_tag; @@ -2341,7 +2349,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupSectionHeaders(uintptr_t base_address) { + ::FixupSectionHeaders(Elf_Addr base_address) { for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { Elf_Shdr* sh = GetSectionHeader(i); CHECK(sh != nullptr); @@ -2365,7 +2373,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupProgramHeaders(uintptr_t base_address) { + ::FixupProgramHeaders(Elf_Addr base_address) { // TODO: ELFObjectFile doesn't have give to Elf_Phdr, so we do that ourselves for now. for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { Elf_Phdr* ph = GetProgramHeader(i); @@ -2392,7 +2400,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupSymbols(uintptr_t base_address, bool dynamic) { + ::FixupSymbols(Elf_Addr base_address, bool dynamic) { Elf_Word section_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB; // TODO: Unfortunate ELFObjectFile has protected symbol access, so use ElfFile Elf_Shdr* symbol_section = FindSectionByType(section_type); @@ -2422,7 +2430,7 @@ template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_ typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupRelocations(uintptr_t base_address) { + ::FixupRelocations(Elf_Addr base_address) { for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { Elf_Shdr* sh = GetSectionHeader(i); CHECK(sh != nullptr); @@ -2622,7 +2630,14 @@ bool ElfFile::Strip(File* file, std::string* error_msg) { return elf_file->elf32_->Strip(error_msg); } -bool ElfFile::Fixup(uintptr_t base_address) { +bool ElfFile::Fixup(uint64_t base_address) { + if (elf64_.get() != nullptr) { + return elf64_->Fixup(static_cast<Elf64_Addr>(base_address)); + } else { + DCHECK(elf32_.get() != nullptr); + CHECK(IsUint<32>(base_address)) << std::hex << base_address; + return elf32_->Fixup(static_cast<Elf32_Addr>(base_address)); + } DELEGATE_TO_IMPL(Fixup, base_address); } diff --git a/runtime/elf_file.h b/runtime/elf_file.h index 41c54bc..286c2a6 100644 --- a/runtime/elf_file.h +++ b/runtime/elf_file.h @@ -78,9 +78,9 @@ class ElfFile { // Fixup an ELF file so that that oat header will be loaded at oat_begin. // Returns true on success, false on failure. - static bool Fixup(File* file, uintptr_t oat_data_begin); + static bool Fixup(File* file, uint64_t oat_data_begin); - bool Fixup(uintptr_t base_address); + bool Fixup(uint64_t base_address); bool Is64Bit() const { return elf64_.get() != nullptr; diff --git a/runtime/elf_file_impl.h b/runtime/elf_file_impl.h index a70fa17..16d3857 100644 --- a/runtime/elf_file_impl.h +++ b/runtime/elf_file_impl.h @@ -19,6 +19,7 @@ #include <map> #include <memory> +#include <type_traits> #include <vector> // Explicitly include our own elf.h to avoid Linux and other dependencies. @@ -102,13 +103,13 @@ class ElfFileImpl { // executable is true at run time, false at compile time. bool Load(bool executable, std::string* error_msg); - bool Fixup(uintptr_t base_address); - bool FixupDynamic(uintptr_t base_address); - bool FixupSectionHeaders(uintptr_t base_address); - bool FixupProgramHeaders(uintptr_t base_address); - bool FixupSymbols(uintptr_t base_address, bool dynamic); - bool FixupRelocations(uintptr_t base_address); - bool FixupDebugSections(off_t base_address_delta); + bool Fixup(Elf_Addr base_address); + bool FixupDynamic(Elf_Addr base_address); + bool FixupSectionHeaders(Elf_Addr base_address); + bool FixupProgramHeaders(Elf_Addr base_address); + bool FixupSymbols(Elf_Addr base_address, bool dynamic); + bool FixupRelocations(Elf_Addr base_address); + bool FixupDebugSections(typename std::make_signed<Elf_Off>::type base_address_delta); bool Strip(std::string* error_msg); |