Skip to content

Commit

Permalink
Create libelffile library for ELF file manipulation.
Browse files Browse the repository at this point in the history
Move some of our tooling to library to make it reusable.

Remove MIPS support from the ELF builder.  This is slightly
easier than making it independent of the runtime.

Bug: 110133331
Test: test.py -b --host
Change-Id: I93343808d0e27ee8e1117e713a2503e8179fc245
  • Loading branch information
dsrbecky committed Mar 20, 2019
1 parent 5f1465f commit 2faab00
Show file tree
Hide file tree
Showing 60 changed files with 255 additions and 342 deletions.
7 changes: 2 additions & 5 deletions compiler/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@ art_cc_defaults {
srcs: [
"compiled_method.cc",
"debug/elf_debug_writer.cc",
"debug/xz_utils.cc",
"dex/inline_method_analyser.cc",
"dex/verified_method.cc",
"dex/verification_results.cc",
"driver/compiled_method_storage.cc",
"driver/compiler_options.cc",
"driver/dex_compilation_unit.cc",
"linker/buffered_output_stream.cc",
"linker/file_output_stream.cc",
"linker/output_stream.cc",
"linker/vector_output_stream.cc",
"jit/jit_compiler.cc",
"jit/jit_logger.cc",
"jni/quick/calling_convention.cc",
Expand Down Expand Up @@ -254,6 +249,7 @@ art_cc_library {
"libprofile",
"libdexfile",
],
whole_static_libs: ["libelffile"],

target: {
android: {
Expand Down Expand Up @@ -317,6 +313,7 @@ art_cc_library {
"libprofiled",
"libdexfiled",
],
whole_static_libs: ["libelffiled"],
}

cc_defaults {
Expand Down
4 changes: 2 additions & 2 deletions compiler/cfi_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@

#include "arch/instruction_set.h"
#include "base/enums.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/dwarf/dwarf_test.h"
#include "debug/dwarf/headers.h"
#include "disassembler.h"
#include "dwarf/dwarf_constants.h"
#include "dwarf/headers.h"
#include "gtest/gtest.h"
#include "thread.h"

Expand Down
10 changes: 5 additions & 5 deletions compiler/debug/dwarf/dwarf_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

#include "dwarf_test.h"

#include "debug/dwarf/debug_frame_opcode_writer.h"
#include "debug/dwarf/debug_info_entry_writer.h"
#include "debug/dwarf/debug_line_opcode_writer.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/dwarf/headers.h"
#include "dwarf/debug_frame_opcode_writer.h"
#include "dwarf/debug_info_entry_writer.h"
#include "dwarf/debug_line_opcode_writer.h"
#include "dwarf/dwarf_constants.h"
#include "dwarf/headers.h"
#include "gtest/gtest.h"

namespace art {
Expand Down
8 changes: 4 additions & 4 deletions compiler/debug/dwarf/dwarf_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
#include "base/os.h"
#include "base/unix_file/fd_file.h"
#include "common_compiler_test.h"
#include "elf/elf_builder.h"
#include "gtest/gtest.h"
#include "linker/elf_builder.h"
#include "linker/file_output_stream.h"
#include "stream/file_output_stream.h"

namespace art {
namespace dwarf {
Expand Down Expand Up @@ -63,8 +63,8 @@ class DwarfTest : public CommonCompilerTest {
InstructionSet isa =
(sizeof(typename ElfTypes::Addr) == 8) ? InstructionSet::kX86_64 : InstructionSet::kX86;
ScratchFile file;
linker::FileOutputStream output_stream(file.GetFile());
linker::ElfBuilder<ElfTypes> builder(isa, nullptr, &output_stream);
FileOutputStream output_stream(file.GetFile());
ElfBuilder<ElfTypes> builder(isa, &output_stream);
builder.Start();
if (!debug_info_data_.empty()) {
builder.WriteSection(".debug_info", &debug_info_data_);
Expand Down
10 changes: 5 additions & 5 deletions compiler/debug/elf_debug_frame_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
#include <vector>

#include "arch/instruction_set.h"
#include "debug/dwarf/debug_frame_opcode_writer.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/dwarf/headers.h"
#include "debug/method_debug_info.h"
#include "linker/elf_builder.h"
#include "dwarf/debug_frame_opcode_writer.h"
#include "dwarf/dwarf_constants.h"
#include "dwarf/headers.h"
#include "elf/elf_builder.h"

namespace art {
namespace debug {
Expand Down Expand Up @@ -166,7 +166,7 @@ static void WriteCIE(InstructionSet isa, /*inout*/ std::vector<uint8_t>* buffer)
}

template<typename ElfTypes>
void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder,
void WriteCFISection(ElfBuilder<ElfTypes>* builder,
const ArrayRef<const MethodDebugInfo>& method_infos) {
typedef typename ElfTypes::Addr Elf_Addr;

Expand Down
10 changes: 5 additions & 5 deletions compiler/debug/elf_debug_info_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@
#include <vector>

#include "art_field-inl.h"
#include "debug/dwarf/debug_abbrev_writer.h"
#include "debug/dwarf/debug_info_entry_writer.h"
#include "debug/elf_compilation_unit.h"
#include "debug/elf_debug_loc_writer.h"
#include "debug/method_debug_info.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file.h"
#include "dwarf/debug_abbrev_writer.h"
#include "dwarf/debug_info_entry_writer.h"
#include "elf/elf_builder.h"
#include "heap_poisoning.h"
#include "linear_alloc.h"
#include "linker/elf_builder.h"
#include "mirror/array.h"
#include "mirror/class-inl.h"
#include "mirror/class.h"
Expand All @@ -59,7 +59,7 @@ class ElfDebugInfoWriter {
using Elf_Addr = typename ElfTypes::Addr;

public:
explicit ElfDebugInfoWriter(linker::ElfBuilder<ElfTypes>* builder)
explicit ElfDebugInfoWriter(ElfBuilder<ElfTypes>* builder)
: builder_(builder),
debug_abbrev_(&debug_abbrev_buffer_) {
}
Expand All @@ -80,7 +80,7 @@ class ElfDebugInfoWriter {
}

private:
linker::ElfBuilder<ElfTypes>* builder_;
ElfBuilder<ElfTypes>* builder_;
std::vector<uint8_t> debug_abbrev_buffer_;
dwarf::DebugAbbrevWriter<> debug_abbrev_;
std::vector<uint8_t> debug_loc_;
Expand Down
10 changes: 5 additions & 5 deletions compiler/debug/elf_debug_line_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
#include <unordered_set>
#include <vector>

#include "debug/dwarf/debug_line_opcode_writer.h"
#include "debug/dwarf/headers.h"
#include "debug/elf_compilation_unit.h"
#include "debug/src_map_elem.h"
#include "dex/dex_file-inl.h"
#include "linker/elf_builder.h"
#include "dwarf/debug_line_opcode_writer.h"
#include "dwarf/headers.h"
#include "elf/elf_builder.h"
#include "oat_file.h"
#include "stack_map.h"

Expand All @@ -39,7 +39,7 @@ class ElfDebugLineWriter {
using Elf_Addr = typename ElfTypes::Addr;

public:
explicit ElfDebugLineWriter(linker::ElfBuilder<ElfTypes>* builder) : builder_(builder) {
explicit ElfDebugLineWriter(ElfBuilder<ElfTypes>* builder) : builder_(builder) {
}

void Start() {
Expand Down Expand Up @@ -273,7 +273,7 @@ class ElfDebugLineWriter {
}

private:
linker::ElfBuilder<ElfTypes>* builder_;
ElfBuilder<ElfTypes>* builder_;
};

} // namespace debug
Expand Down
4 changes: 2 additions & 2 deletions compiler/debug/elf_debug_loc_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

#include "arch/instruction_set.h"
#include "compiled_method.h"
#include "debug/dwarf/debug_info_entry_writer.h"
#include "debug/dwarf/register.h"
#include "debug/method_debug_info.h"
#include "dwarf/debug_info_entry_writer.h"
#include "dwarf/register.h"
#include "stack_map.h"

namespace art {
Expand Down
51 changes: 23 additions & 28 deletions compiler/debug/elf_debug_writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,28 @@

#include "base/array_ref.h"
#include "base/stl_util.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/elf_compilation_unit.h"
#include "debug/elf_debug_frame_writer.h"
#include "debug/elf_debug_info_writer.h"
#include "debug/elf_debug_line_writer.h"
#include "debug/elf_debug_loc_writer.h"
#include "debug/elf_debug_reader.h"
#include "debug/elf_symtab_writer.h"
#include "debug/method_debug_info.h"
#include "debug/xz_utils.h"
#include "elf.h"
#include "linker/elf_builder.h"
#include "linker/vector_output_stream.h"
#include "dwarf/dwarf_constants.h"
#include "elf/elf.h"
#include "elf/elf_builder.h"
#include "elf/elf_debug_reader.h"
#include "elf/xz_utils.h"
#include "oat.h"
#include "stream/vector_output_stream.h"

namespace art {
namespace debug {

using ElfRuntimeTypes = std::conditional<sizeof(void*) == 4, ElfTypes32, ElfTypes64>::type;

template <typename ElfTypes>
void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder,
void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
const DebugInfo& debug_info) {
// Write .strtab and .symtab.
WriteDebugSymbols(builder, /* mini-debug-info= */ false, debug_info);
Expand Down Expand Up @@ -112,17 +112,16 @@ void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder,
template <typename ElfTypes>
static std::vector<uint8_t> MakeMiniDebugInfoInternal(
InstructionSet isa,
const InstructionSetFeatures* features,
const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
typename ElfTypes::Addr text_section_address,
size_t text_section_size,
typename ElfTypes::Addr dex_section_address,
size_t dex_section_size,
const DebugInfo& debug_info) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
linker::VectorOutputStream out("Mini-debug-info ELF file", &buffer);
std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
new linker::ElfBuilder<ElfTypes>(isa, features, &out));
VectorOutputStream out("Mini-debug-info ELF file", &buffer);
std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start(/* write_program_headers= */ false);
// Mirror ELF sections as NOBITS since the added symbols will reference them.
if (text_section_size != 0) {
Expand Down Expand Up @@ -174,7 +173,7 @@ std::vector<uint8_t> MakeMiniDebugInfo(

std::vector<uint8_t> MakeElfFileForJIT(
InstructionSet isa,
const InstructionSetFeatures* features,
const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
bool mini_debug_info,
const MethodDebugInfo& method_info) {
using ElfTypes = ElfRuntimeTypes;
Expand All @@ -184,9 +183,8 @@ std::vector<uint8_t> MakeElfFileForJIT(
debug_info.compiled_methods = ArrayRef<const MethodDebugInfo>(&method_info, 1);
std::vector<uint8_t> buffer;
buffer.reserve(KB);
linker::VectorOutputStream out("Debug ELF file", &buffer);
std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
new linker::ElfBuilder<ElfTypes>(isa, features, &out));
VectorOutputStream out("Debug ELF file", &buffer);
std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(/* write_program_headers= */ false);
builder->GetText()->AllocateVirtualMemory(method_info.code_address, method_info.code_size);
Expand Down Expand Up @@ -230,7 +228,7 @@ std::vector<uint8_t> MakeElfFileForJIT(
// Combine several mini-debug-info ELF files into one, while filtering some symbols.
std::vector<uint8_t> PackElfFileForJIT(
InstructionSet isa,
const InstructionSetFeatures* features,
const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
std::vector<ArrayRef<const uint8_t>>& added_elf_files,
std::vector<const void*>& removed_symbols,
/*out*/ size_t* num_symbols) {
Expand All @@ -250,9 +248,8 @@ std::vector<uint8_t> PackElfFileForJIT(
std::vector<uint8_t> inner_elf_file;
{
inner_elf_file.reserve(1 * KB); // Approximate size of ELF file with a single symbol.
linker::VectorOutputStream out("Mini-debug-info ELF file for JIT", &inner_elf_file);
std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
new linker::ElfBuilder<ElfTypes>(isa, features, &out));
VectorOutputStream out("Mini-debug-info ELF file for JIT", &inner_elf_file);
std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start(/*write_program_headers=*/ false);
auto* text = builder->GetText();
auto* strtab = builder->GetStrTab();
Expand Down Expand Up @@ -328,9 +325,8 @@ std::vector<uint8_t> PackElfFileForJIT(
XzCompress(ArrayRef<const uint8_t>(inner_elf_file), &gnu_debugdata);

outer_elf_file.reserve(KB + gnu_debugdata.size());
linker::VectorOutputStream out("Mini-debug-info ELF file for JIT", &outer_elf_file);
std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
new linker::ElfBuilder<ElfTypes>(isa, features, &out));
VectorOutputStream out("Mini-debug-info ELF file for JIT", &outer_elf_file);
std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start(/*write_program_headers=*/ false);
if (max_address > min_address) {
builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address);
Expand All @@ -345,16 +341,15 @@ std::vector<uint8_t> PackElfFileForJIT(

std::vector<uint8_t> WriteDebugElfFileForClasses(
InstructionSet isa,
const InstructionSetFeatures* features,
const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
const ArrayRef<mirror::Class*>& types)
REQUIRES_SHARED(Locks::mutator_lock_) {
using ElfTypes = ElfRuntimeTypes;
CHECK_EQ(sizeof(ElfTypes::Addr), static_cast<size_t>(GetInstructionSetPointerSize(isa)));
std::vector<uint8_t> buffer;
buffer.reserve(KB);
linker::VectorOutputStream out("Debug ELF file", &buffer);
std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
new linker::ElfBuilder<ElfTypes>(isa, features, &out));
VectorOutputStream out("Debug ELF file", &buffer);
std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(/* write_program_headers= */ false);
ElfDebugInfoWriter<ElfTypes> info_writer(builder.get());
Expand All @@ -370,10 +365,10 @@ std::vector<uint8_t> WriteDebugElfFileForClasses(

// Explicit instantiations
template void WriteDebugInfo<ElfTypes32>(
linker::ElfBuilder<ElfTypes32>* builder,
ElfBuilder<ElfTypes32>* builder,
const DebugInfo& debug_info);
template void WriteDebugInfo<ElfTypes64>(
linker::ElfBuilder<ElfTypes64>* builder,
ElfBuilder<ElfTypes64>* builder,
const DebugInfo& debug_info);

} // namespace debug
Expand Down
7 changes: 4 additions & 3 deletions compiler/debug/elf_debug_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@

#include <vector>

#include "arch/instruction_set_features.h"
#include "base/array_ref.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/debug_info.h"
#include "linker/elf_builder.h"
#include "dwarf/dwarf_constants.h"
#include "elf/elf_builder.h"

namespace art {
class OatHeader;
Expand All @@ -36,7 +37,7 @@ struct MethodDebugInfo;

template <typename ElfTypes>
void WriteDebugInfo(
linker::ElfBuilder<ElfTypes>* builder,
ElfBuilder<ElfTypes>* builder,
const DebugInfo& debug_info);

std::vector<uint8_t> MakeMiniDebugInfo(
Expand Down
4 changes: 2 additions & 2 deletions compiler/debug/elf_symtab_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "debug/method_debug_info.h"
#include "dex/dex_file-inl.h"
#include "dex/code_item_accessors.h"
#include "linker/elf_builder.h"
#include "elf/elf_builder.h"

namespace art {
namespace debug {
Expand All @@ -45,7 +45,7 @@ constexpr bool kGenerateArmMappingSymbol = true;
constexpr const char* kDexFileSymbolName = "$dexfile";

template <typename ElfTypes>
static void WriteDebugSymbols(linker::ElfBuilder<ElfTypes>* builder,
static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder,
bool mini_debug_info,
const DebugInfo& debug_info) {
uint64_t mapping_symbol_address = std::numeric_limits<uint64_t>::max();
Expand Down
2 changes: 1 addition & 1 deletion compiler/jni/quick/jni_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include "base/utils.h"
#include "calling_convention.h"
#include "class_linker.h"
#include "debug/dwarf/debug_frame_opcode_writer.h"
#include "dwarf/debug_frame_opcode_writer.h"
#include "dex/dex_file-inl.h"
#include "driver/compiler_options.h"
#include "entrypoints/quick/quick_entrypoints.h"
Expand Down
Loading

0 comments on commit 2faab00

Please sign in to comment.