summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/compiler.h3
-rw-r--r--compiler/dex/quick/quick_compiler.cc9
-rw-r--r--compiler/optimizing/optimizing_compiler.cc9
-rw-r--r--runtime/elf_file.cc41
-rw-r--r--runtime/elf_file.h4
-rw-r--r--runtime/elf_file_impl.h15
6 files changed, 55 insertions, 26 deletions
diff --git a/compiler/compiler.h b/compiler/compiler.h
index 6ec39f9..a04641e 100644
--- a/compiler/compiler.h
+++ b/compiler/compiler.h
@@ -107,6 +107,9 @@ class Compiler {
return driver_;
}
+ // Whether to produce 64-bit ELF files for 64-bit targets. Leave this off for now.
+ static constexpr bool kProduce64BitELFFiles = false;
+
private:
CompilerDriver* const driver_;
const uint64_t maximum_compilation_time_before_warning_;
diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc
index 8baafc7..01652d6 100644
--- a/compiler/dex/quick/quick_compiler.cc
+++ b/compiler/dex/quick/quick_compiler.cc
@@ -798,8 +798,13 @@ bool QuickCompiler::WriteElf(art::File* file,
const std::vector<const art::DexFile*>& dex_files,
const std::string& android_root,
bool is_host) const {
- return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host,
- *GetCompilerDriver());
+ if (kProduce64BitELFFiles && Is64BitInstructionSet(GetCompilerDriver()->GetInstructionSet())) {
+ return art::ElfWriterQuick64::Create(file, oat_writer, dex_files, android_root, is_host,
+ *GetCompilerDriver());
+ } else {
+ return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host,
+ *GetCompilerDriver());
+ }
}
Mir2Lir* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 90a530a..12798ed 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -204,8 +204,13 @@ class OptimizingCompiler FINAL : public Compiler {
const std::vector<const art::DexFile*>& dex_files,
const std::string& android_root,
bool is_host) const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host,
- *GetCompilerDriver());
+ if (kProduce64BitELFFiles && Is64BitInstructionSet(GetCompilerDriver()->GetInstructionSet())) {
+ return art::ElfWriterQuick64::Create(file, oat_writer, dex_files, android_root, is_host,
+ *GetCompilerDriver());
+ } else {
+ return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host,
+ *GetCompilerDriver());
+ }
}
void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE;
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);