Propagate InstructionSetFeatures to ElfBuilder.
This is subset of CL171665 and it separates it into two.
It will be needed to generate .MIPS.abiflags ELF section.
Change-Id: I5557e7cb98d0fa1dc57c85cf6161e119c6d50a1a
diff --git a/compiler/debug/dwarf/dwarf_test.h b/compiler/debug/dwarf/dwarf_test.h
index 41bfe79..e2f0a65 100644
--- a/compiler/debug/dwarf/dwarf_test.h
+++ b/compiler/debug/dwarf/dwarf_test.h
@@ -62,7 +62,7 @@
InstructionSet isa = (sizeof(typename ElfTypes::Addr) == 8) ? kX86_64 : kX86;
ScratchFile file;
FileOutputStream output_stream(file.GetFile());
- ElfBuilder<ElfTypes> builder(isa, &output_stream);
+ ElfBuilder<ElfTypes> builder(isa, nullptr, &output_stream);
builder.Start();
if (!debug_info_data_.empty()) {
builder.WriteSection(".debug_info", &debug_info_data_);
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 01bd679..79069d1 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -91,24 +91,34 @@
std::vector<uint8_t> MakeMiniDebugInfo(
InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_size,
size_t text_size,
const ArrayRef<const MethodDebugInfo>& method_infos) {
if (Is64BitInstructionSet(isa)) {
- return MakeMiniDebugInfoInternal<ElfTypes64>(isa, rodata_size, text_size, method_infos);
+ return MakeMiniDebugInfoInternal<ElfTypes64>(isa,
+ features,
+ rodata_size,
+ text_size,
+ method_infos);
} else {
- return MakeMiniDebugInfoInternal<ElfTypes32>(isa, rodata_size, text_size, method_infos);
+ return MakeMiniDebugInfoInternal<ElfTypes32>(isa,
+ features,
+ rodata_size,
+ text_size,
+ method_infos);
}
}
template <typename ElfTypes>
static ArrayRef<const uint8_t> WriteDebugElfFileForMethodInternal(
+ const InstructionSet isa,
+ const InstructionSetFeatures* features,
const MethodDebugInfo& method_info) {
- const InstructionSet isa = method_info.compiled_method->GetInstructionSet();
std::vector<uint8_t> buffer;
buffer.reserve(KB);
VectorOutputStream out("Debug ELF file", &buffer);
- std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, features, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(false /* write_program_headers */);
WriteDebugInfo(builder.get(),
@@ -124,23 +134,26 @@
return ArrayRef<const uint8_t>(result, buffer.size());
}
-ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const MethodDebugInfo& method_info) {
- const InstructionSet isa = method_info.compiled_method->GetInstructionSet();
+ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const InstructionSet isa,
+ const InstructionSetFeatures* features,
+ const MethodDebugInfo& method_info) {
if (Is64BitInstructionSet(isa)) {
- return WriteDebugElfFileForMethodInternal<ElfTypes64>(method_info);
+ return WriteDebugElfFileForMethodInternal<ElfTypes64>(isa, features, method_info);
} else {
- return WriteDebugElfFileForMethodInternal<ElfTypes32>(method_info);
+ return WriteDebugElfFileForMethodInternal<ElfTypes32>(isa, features, method_info);
}
}
template <typename ElfTypes>
static ArrayRef<const uint8_t> WriteDebugElfFileForClassesInternal(
- const InstructionSet isa, const ArrayRef<mirror::Class*>& types)
+ const InstructionSet isa,
+ const InstructionSetFeatures* features,
+ const ArrayRef<mirror::Class*>& types)
SHARED_REQUIRES(Locks::mutator_lock_) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
VectorOutputStream out("Debug ELF file", &buffer);
- std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, features, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(false /* write_program_headers */);
ElfDebugInfoWriter<ElfTypes> info_writer(builder.get());
@@ -159,11 +172,12 @@
}
ArrayRef<const uint8_t> WriteDebugElfFileForClasses(const InstructionSet isa,
+ const InstructionSetFeatures* features,
const ArrayRef<mirror::Class*>& types) {
if (Is64BitInstructionSet(isa)) {
- return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, types);
+ return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, features, types);
} else {
- return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, types);
+ return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, features, types);
}
}
diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h
index 103b501..d364521 100644
--- a/compiler/debug/elf_debug_writer.h
+++ b/compiler/debug/elf_debug_writer.h
@@ -37,13 +37,17 @@
bool write_oat_patches);
std::vector<uint8_t> MakeMiniDebugInfo(InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_section_size,
size_t text_section_size,
const ArrayRef<const MethodDebugInfo>& method_infos);
-ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const MethodDebugInfo& method_info);
+ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const InstructionSet isa,
+ const InstructionSetFeatures* features,
+ const MethodDebugInfo& method_info);
ArrayRef<const uint8_t> WriteDebugElfFileForClasses(const InstructionSet isa,
+ const InstructionSetFeatures* features,
const ArrayRef<mirror::Class*>& types)
SHARED_REQUIRES(Locks::mutator_lock_);
diff --git a/compiler/debug/elf_gnu_debugdata_writer.h b/compiler/debug/elf_gnu_debugdata_writer.h
index 5c7d1c7..fb63d62 100644
--- a/compiler/debug/elf_gnu_debugdata_writer.h
+++ b/compiler/debug/elf_gnu_debugdata_writer.h
@@ -79,13 +79,14 @@
template <typename ElfTypes>
static std::vector<uint8_t> MakeMiniDebugInfoInternal(
InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_section_size,
size_t text_section_size,
const ArrayRef<const MethodDebugInfo>& method_infos) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
VectorOutputStream out("Mini-debug-info ELF file", &buffer);
- std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, features, &out));
builder->Start();
// Mirror .rodata and .text as NOBITS sections.
// It is needed to detected relocations after compression.
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index f7da609..943e2a8 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -20,6 +20,7 @@
#include <vector>
#include "arch/instruction_set.h"
+#include "arch/mips/instruction_set_features_mips.h"
#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/unix_file/fd_file.h"
@@ -392,8 +393,9 @@
}
};
- ElfBuilder(InstructionSet isa, OutputStream* output)
+ ElfBuilder(InstructionSet isa, const InstructionSetFeatures* features, OutputStream* output)
: isa_(isa),
+ features_(features),
stream_(output),
rodata_(this, ".rodata", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0),
text_(this, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, nullptr, 0, kPageSize, 0),
@@ -818,6 +820,7 @@
}
InstructionSet isa_;
+ const InstructionSetFeatures* features_;
ErrorDelayingOutputStream stream_;
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 19346ec..e35662d 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -51,10 +51,12 @@
class DebugInfoTask : public Task {
public:
DebugInfoTask(InstructionSet isa,
+ const InstructionSetFeatures* features,
size_t rodata_section_size,
size_t text_section_size,
const ArrayRef<const debug::MethodDebugInfo>& method_infos)
: isa_(isa),
+ instruction_set_features_(features),
rodata_section_size_(rodata_section_size),
text_section_size_(text_section_size),
method_infos_(method_infos) {
@@ -62,6 +64,7 @@
void Run(Thread*) {
result_ = debug::MakeMiniDebugInfo(isa_,
+ instruction_set_features_,
rodata_section_size_,
text_section_size_,
method_infos_);
@@ -73,6 +76,7 @@
private:
InstructionSet isa_;
+ const InstructionSetFeatures* instruction_set_features_;
size_t rodata_section_size_;
size_t text_section_size_;
const ArrayRef<const debug::MethodDebugInfo>& method_infos_;
@@ -83,6 +87,7 @@
class ElfWriterQuick FINAL : public ElfWriter {
public:
ElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file);
~ElfWriterQuick();
@@ -107,6 +112,7 @@
std::vector<uint8_t>* buffer);
private:
+ const InstructionSetFeatures* instruction_set_features_;
const CompilerOptions* const compiler_options_;
File* const elf_file_;
size_t rodata_size_;
@@ -121,27 +127,36 @@
};
std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file) {
if (Is64BitInstructionSet(instruction_set)) {
- return MakeUnique<ElfWriterQuick<ElfTypes64>>(instruction_set, compiler_options, elf_file);
+ return MakeUnique<ElfWriterQuick<ElfTypes64>>(instruction_set,
+ features,
+ compiler_options,
+ elf_file);
} else {
- return MakeUnique<ElfWriterQuick<ElfTypes32>>(instruction_set, compiler_options, elf_file);
+ return MakeUnique<ElfWriterQuick<ElfTypes32>>(instruction_set,
+ features,
+ compiler_options,
+ elf_file);
}
}
template <typename ElfTypes>
ElfWriterQuick<ElfTypes>::ElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file)
: ElfWriter(),
+ instruction_set_features_(features),
compiler_options_(compiler_options),
elf_file_(elf_file),
rodata_size_(0u),
text_size_(0u),
bss_size_(0u),
output_stream_(MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file))),
- builder_(new ElfBuilder<ElfTypes>(instruction_set, output_stream_.get())) {}
+ builder_(new ElfBuilder<ElfTypes>(instruction_set, features, output_stream_.get())) {}
template <typename ElfTypes>
ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {}
@@ -205,7 +220,11 @@
// Prepare the mini-debug-info in background while we do other I/O.
Thread* self = Thread::Current();
debug_info_task_ = std::unique_ptr<DebugInfoTask>(
- new DebugInfoTask(builder_->GetIsa(), rodata_size_, text_size_, method_infos));
+ new DebugInfoTask(builder_->GetIsa(),
+ instruction_set_features_,
+ rodata_size_,
+ text_size_,
+ method_infos));
debug_info_thread_pool_ = std::unique_ptr<ThreadPool>(
new ThreadPool("Mini-debug-info writer", 1));
debug_info_thread_pool_->AddTask(self, debug_info_task_.get());
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index 347d372..3d5dd39 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -26,8 +26,10 @@
namespace art {
class CompilerOptions;
+class InstructionSetFeatures;
std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set,
+ const InstructionSetFeatures* features,
const CompilerOptions* compiler_options,
File* elf_file);
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 5763cec..3b622b5 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -99,6 +99,7 @@
const std::vector<const DexFile*>& dex_files = class_linker->GetBootClassPath();
std::unique_ptr<ElfWriter> elf_writer = CreateElfWriterQuick(
compiler_driver_->GetInstructionSet(),
+ compiler_driver_->GetInstructionSetFeatures(),
&compiler_driver_->GetCompilerOptions(),
oat_file.GetFile());
elf_writer->Start();
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 6ff1e2e..9a77946 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -69,7 +69,8 @@
DCHECK(jit_compiler != nullptr);
if (jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo()) {
const ArrayRef<mirror::Class*> types_array(types, count);
- ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForClasses(kRuntimeISA, types_array);
+ ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForClasses(
+ kRuntimeISA, jit_compiler->GetCompilerDriver()->GetInstructionSetFeatures(), types_array);
CreateJITCodeEntry(std::unique_ptr<const uint8_t[]>(elf_file.data()), elf_file.size());
}
}
diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h
index bc134fe..533dccf 100644
--- a/compiler/jit/jit_compiler.h
+++ b/compiler/jit/jit_compiler.h
@@ -42,6 +42,9 @@
CompilerOptions* GetCompilerOptions() const {
return compiler_options_.get();
}
+ CompilerDriver* GetCompilerDriver() const {
+ return compiler_driver_.get();
+ }
private:
std::unique_ptr<CompilerOptions> compiler_options_;
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 14fd105..d22044a 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -176,6 +176,7 @@
bool verify) {
std::unique_ptr<ElfWriter> elf_writer = CreateElfWriterQuick(
compiler_driver_->GetInstructionSet(),
+ compiler_driver_->GetInstructionSetFeatures(),
&compiler_driver_->GetCompilerOptions(),
file);
elf_writer->Start();
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index c1b4d24..b49b91d 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -940,7 +940,10 @@
code_address + code_allocator.GetSize(),
&compiled_method
};
- ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethod(method_debug_info);
+ ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethod(
+ GetCompilerDriver()->GetInstructionSet(),
+ GetCompilerDriver()->GetInstructionSetFeatures(),
+ method_debug_info);
CreateJITCodeEntryForAddress(code_address,
std::unique_ptr<const uint8_t[]>(elf_file.data()),
elf_file.size());
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index ea19059..374d0d3 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -2105,8 +2105,10 @@
elf_writers_.reserve(oat_files_.size());
oat_writers_.reserve(oat_files_.size());
for (const std::unique_ptr<File>& oat_file : oat_files_) {
- elf_writers_.emplace_back(
- CreateElfWriterQuick(instruction_set_, compiler_options_.get(), oat_file.get()));
+ elf_writers_.emplace_back(CreateElfWriterQuick(instruction_set_,
+ instruction_set_features_.get(),
+ compiler_options_.get(),
+ oat_file.get()));
elf_writers_.back()->Start();
oat_writers_.emplace_back(new OatWriter(IsBootImage(), timings_));
}
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index c187536..b52f30e 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -115,11 +115,13 @@
bool Symbolize() {
const InstructionSet isa = oat_file_->GetOatHeader().GetInstructionSet();
+ const InstructionSetFeatures* features = InstructionSetFeatures::FromBitmap(
+ isa, oat_file_->GetOatHeader().GetInstructionSetFeaturesBitmap());
File* elf_file = OS::CreateEmptyFile(output_name_.c_str());
std::unique_ptr<BufferedOutputStream> output_stream(
MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file)));
- builder_.reset(new ElfBuilder<ElfTypes32>(isa, output_stream.get()));
+ builder_.reset(new ElfBuilder<ElfTypes32>(isa, features, output_stream.get()));
builder_->Start();