Skip to content

Commit

Permalink
Add minimal riscv64 elf support to allow create_minidebuginfo on risc…
Browse files Browse the repository at this point in the history
…v64 binaries

This adds support for riscv64 elf files so that create_minidebuginfo
can be used strip riscv64 binaries.

Test: m create_minidebuginfo
Change-Id: I0cb0348d46ffb216af2f5c61701406504fae3b22
  • Loading branch information
colincross authored and enh-google committed Oct 31, 2022
1 parent 9983553 commit ebc548c
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 4 deletions.
2 changes: 2 additions & 0 deletions build/art.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,14 @@ func globalFlags(ctx android.LoadHookContext) ([]string, []string) {
cflags = append(cflags,
"-DART_STACK_OVERFLOW_GAP_arm=16384",
"-DART_STACK_OVERFLOW_GAP_arm64=16384",
"-DART_STACK_OVERFLOW_GAP_riscv64=16384",
"-DART_STACK_OVERFLOW_GAP_x86=16384",
"-DART_STACK_OVERFLOW_GAP_x86_64=20480")
} else {
cflags = append(cflags,
"-DART_STACK_OVERFLOW_GAP_arm=8192",
"-DART_STACK_OVERFLOW_GAP_arm64=8192",
"-DART_STACK_OVERFLOW_GAP_riscv64=8192",
"-DART_STACK_OVERFLOW_GAP_x86=8192",
"-DART_STACK_OVERFLOW_GAP_x86_64=8192")
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/debug/elf_debug_frame_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ static void WriteCIE(InstructionSet isa, /*inout*/ std::vector<uint8_t>* buffer)
WriteCIE(is64bit, return_reg, opcodes, buffer);
return;
}
case InstructionSet::kRiscv64: {
UNIMPLEMENTED(FATAL);
return;
}
case InstructionSet::kX86: {
// FIXME: Add fp registers once libunwind adds support for them. Bug: 20491296
constexpr bool generate_opcodes_for_x86_fp = false;
Expand Down
1 change: 1 addition & 0 deletions compiler/debug/elf_debug_line_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ElfDebugLineWriter {
code_factor_bits_ = 2; // 32-bit instructions
break;
case InstructionSet::kNone:
case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
break;
Expand Down
4 changes: 4 additions & 0 deletions compiler/debug/elf_debug_loc_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ static Reg GetDwarfCoreReg(InstructionSet isa, int machine_reg) {
return Reg::ArmCore(machine_reg);
case InstructionSet::kArm64:
return Reg::Arm64Core(machine_reg);
case InstructionSet::kRiscv64:
return Reg::Riscv64Core(machine_reg);
case InstructionSet::kX86:
return Reg::X86Core(machine_reg);
case InstructionSet::kX86_64:
Expand All @@ -54,6 +56,8 @@ static Reg GetDwarfFpReg(InstructionSet isa, int machine_reg) {
return Reg::ArmFp(machine_reg);
case InstructionSet::kArm64:
return Reg::Arm64Fp(machine_reg);
case InstructionSet::kRiscv64:
return Reg::Riscv64Fp(machine_reg);
case InstructionSet::kX86:
return Reg::X86Fp(machine_reg);
case InstructionSet::kX86_64:
Expand Down
7 changes: 7 additions & 0 deletions libartbase/arch/instruction_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void InstructionSetAbort(InstructionSet isa) {
case InstructionSet::kArm:
case InstructionSet::kThumb2:
case InstructionSet::kArm64:
case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
case InstructionSet::kNone:
Expand All @@ -46,6 +47,8 @@ const char* GetInstructionSetString(InstructionSet isa) {
return "arm";
case InstructionSet::kArm64:
return "arm64";
case InstructionSet::kRiscv64:
return "riscv64";
case InstructionSet::kX86:
return "x86";
case InstructionSet::kX86_64:
Expand All @@ -64,6 +67,8 @@ InstructionSet GetInstructionSetFromString(const char* isa_str) {
return InstructionSet::kArm;
} else if (strcmp("arm64", isa_str) == 0) {
return InstructionSet::kArm64;
} else if (strcmp("riscv64", isa_str) == 0) {
return InstructionSet::kRiscv64;
} else if (strcmp("x86", isa_str) == 0) {
return InstructionSet::kX86;
} else if (strcmp("x86_64", isa_str) == 0) {
Expand Down Expand Up @@ -93,6 +98,8 @@ std::vector<InstructionSet> GetSupportedInstructionSets(std::string* error_msg)
*error_msg = android::base::StringPrintf("Unknown Zygote kinds '%s'", zygote_kinds.c_str());
return {};
}
case InstructionSet::kRiscv64:
return {InstructionSet::kRiscv64};
case InstructionSet::kX86:
case InstructionSet::kX86_64:
if (zygote_kinds == "zygote64_32" || zygote_kinds == "zygote32_64") {
Expand Down
35 changes: 31 additions & 4 deletions libartbase/arch/instruction_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum class InstructionSet {
kArm,
kArm64,
kThumb2,
kRiscv64,
kX86,
kX86_64,
kLast = kX86_64
Expand All @@ -41,6 +42,8 @@ std::ostream& operator<<(std::ostream& os, InstructionSet rhs);
static constexpr InstructionSet kRuntimeISA = InstructionSet::kArm;
#elif defined(__aarch64__)
static constexpr InstructionSet kRuntimeISA = InstructionSet::kArm64;
#elif defined (__riscv)
static constexpr InstructionSet kRuntimeISA = InstructionSet::kRiscv64;
#elif defined(__i386__)
static constexpr InstructionSet kRuntimeISA = InstructionSet::kX86;
#elif defined(__x86_64__)
Expand All @@ -52,6 +55,7 @@ static constexpr InstructionSet kRuntimeISA = InstructionSet::kNone;
// Architecture-specific pointer sizes
static constexpr PointerSize kArmPointerSize = PointerSize::k32;
static constexpr PointerSize kArm64PointerSize = PointerSize::k64;
static constexpr PointerSize kRiscv64PointerSize = PointerSize::k64;
static constexpr PointerSize kX86PointerSize = PointerSize::k32;
static constexpr PointerSize kX86_64PointerSize = PointerSize::k64;

Expand All @@ -63,12 +67,17 @@ static constexpr size_t kArm64DefaultSVEVectorLength = 256;
// ARM processors require code to be 4-byte aligned, but ARM ELF requires 8.
static constexpr size_t kArmCodeAlignment = 8;
static constexpr size_t kArm64CodeAlignment = 16;
static constexpr size_t kRiscv64CodeAlignment = 16;
static constexpr size_t kX86CodeAlignment = 16;

// Instruction alignment (every instruction must be aligned at this boundary). This differs from
// code alignment, which applies only to the first instruction of a subroutine.
// Android requires the RISC-V compressed instruction extension, and that allows
// *all* instructions (not just compressed ones) to be 2-byte aligned rather
// than the usual 4-byte alignment requirement.
static constexpr size_t kThumb2InstructionAlignment = 2;
static constexpr size_t kArm64InstructionAlignment = 4;
static constexpr size_t kRiscv64InstructionAlignment = 2;
static constexpr size_t kX86InstructionAlignment = 1;
static constexpr size_t kX86_64InstructionAlignment = 1;

Expand All @@ -88,6 +97,8 @@ constexpr PointerSize GetInstructionSetPointerSize(InstructionSet isa) {
return kArmPointerSize;
case InstructionSet::kArm64:
return kArm64PointerSize;
case InstructionSet::kRiscv64:
return kRiscv64PointerSize;
case InstructionSet::kX86:
return kX86PointerSize;
case InstructionSet::kX86_64:
Expand All @@ -104,6 +115,7 @@ constexpr bool IsValidInstructionSet(InstructionSet isa) {
case InstructionSet::kArm:
case InstructionSet::kThumb2:
case InstructionSet::kArm64:
case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
return true;
Expand All @@ -122,6 +134,8 @@ constexpr size_t GetInstructionSetInstructionAlignment(InstructionSet isa) {
return kThumb2InstructionAlignment;
case InstructionSet::kArm64:
return kArm64InstructionAlignment;
case InstructionSet::kRiscv64:
return kRiscv64InstructionAlignment;
case InstructionSet::kX86:
return kX86InstructionAlignment;
case InstructionSet::kX86_64:
Expand All @@ -141,6 +155,8 @@ constexpr size_t GetInstructionSetCodeAlignment(InstructionSet isa) {
return kArmCodeAlignment;
case InstructionSet::kArm64:
return kArm64CodeAlignment;
case InstructionSet::kRiscv64:
return kRiscv64CodeAlignment;
case InstructionSet::kX86:
// Fall-through.
case InstructionSet::kX86_64:
Expand All @@ -158,6 +174,7 @@ constexpr size_t GetInstructionSetEntryPointAdjustment(InstructionSet isa) {
switch (isa) {
case InstructionSet::kArm:
case InstructionSet::kArm64:
case InstructionSet::kRiscv64:
case InstructionSet::kX86:
case InstructionSet::kX86_64:
return 0;
Expand All @@ -180,6 +197,7 @@ constexpr bool Is64BitInstructionSet(InstructionSet isa) {
return false;

case InstructionSet::kArm64:
case InstructionSet::kRiscv64:
case InstructionSet::kX86_64:
return true;

Expand All @@ -201,6 +219,8 @@ constexpr size_t GetBytesPerGprSpillLocation(InstructionSet isa) {
return 4;
case InstructionSet::kArm64:
return 8;
case InstructionSet::kRiscv64:
return 8;
case InstructionSet::kX86:
return 4;
case InstructionSet::kX86_64:
Expand All @@ -220,6 +240,8 @@ constexpr size_t GetBytesPerFprSpillLocation(InstructionSet isa) {
return 4;
case InstructionSet::kArm64:
return 8;
case InstructionSet::kRiscv64:
return 8;
case InstructionSet::kX86:
return 8;
case InstructionSet::kX86_64:
Expand All @@ -237,14 +259,16 @@ std::vector<InstructionSet> GetSupportedInstructionSets(std::string* error_msg);
namespace instruction_set_details {

#if !defined(ART_STACK_OVERFLOW_GAP_arm) || !defined(ART_STACK_OVERFLOW_GAP_arm64) || \
!defined(ART_STACK_OVERFLOW_GAP_riscv64) || \
!defined(ART_STACK_OVERFLOW_GAP_x86) || !defined(ART_STACK_OVERFLOW_GAP_x86_64)
#error "Missing defines for stack overflow gap"
#endif

static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm;
static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64;
static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86;
static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;
static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm;
static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64;
static constexpr size_t kRiscv64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_riscv64;
static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86;
static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64;

NO_RETURN void GetStackOverflowReservedBytesFailure(const char* error_msg);

Expand All @@ -260,6 +284,9 @@ constexpr size_t GetStackOverflowReservedBytes(InstructionSet isa) {
case InstructionSet::kArm64:
return instruction_set_details::kArm64StackOverflowReservedBytes;

case InstructionSet::kRiscv64:
return instruction_set_details::kRiscv64StackOverflowReservedBytes;

case InstructionSet::kX86:
return instruction_set_details::kX86StackOverflowReservedBytes;

Expand Down
2 changes: 2 additions & 0 deletions libelffile/dwarf/register.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class Reg {
static Reg ArmDp(int num) { return Reg(256 + num); } // D0–D31.
static Reg Arm64Core(int num) { return Reg(num); } // X0-X31.
static Reg Arm64Fp(int num) { return Reg(64 + num); } // V0-V31.
static Reg Riscv64Core(int num) { return Reg(num); } // X0-X31
static Reg Riscv64Fp(int num) { return Reg(32 + num); } // F0-F31
static Reg X86Core(int num) { return Reg(num); }
static Reg X86Fp(int num) { return Reg(21 + num); }
static Reg X86_64Core(int num) {
Expand Down
7 changes: 7 additions & 0 deletions libelffile/elf/elf_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,8 @@ class ElfBuilder final {
return InstructionSet::kThumb2;
case EM_AARCH64:
return InstructionSet::kArm64;
case EM_RISCV:
return InstructionSet::kRiscv64;
case EM_386:
return InstructionSet::kX86;
case EM_X86_64:
Expand All @@ -839,6 +841,11 @@ class ElfBuilder final {
elf_header.e_flags = 0;
break;
}
case InstructionSet::kRiscv64: {
elf_header.e_machine = EM_RISCV;
elf_header.e_flags = EF_RISCV_RVC | EF_RISCV_FLOAT_ABI_DOUBLE;
break;
}
case InstructionSet::kX86: {
elf_header.e_machine = EM_386;
elf_header.e_flags = 0;
Expand Down
9 changes: 9 additions & 0 deletions libelffile/elf/elf_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ struct ElfTypes64 {

#define EM_AARCH64 183

#ifndef EM_RISCV
#define EM_RISCV 243
#endif

#ifndef EF_RISCV_RVC
#define EF_RISCV_RVC 0x1
#define EF_RISCV_FLOAT_ABI_DOUBLE 0x4
#endif

#define DT_BIND_NOW 24
#define DT_INIT_ARRAY 25
#define DT_FINI_ARRAY 26
Expand Down
1 change: 1 addition & 0 deletions odrefresh/odr_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ class OdrConfig final {
case art::InstructionSet::kX86:
case art::InstructionSet::kX86_64:
return std::make_pair(art::InstructionSet::kX86, art::InstructionSet::kX86_64);
case art::InstructionSet::kRiscv64:
case art::InstructionSet::kThumb2:
case art::InstructionSet::kNone:
LOG(FATAL) << "Invalid instruction set " << isa_;
Expand Down
2 changes: 2 additions & 0 deletions runtime/metrics/statsd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ constexpr int32_t EncodeInstructionSet(InstructionSet isa) {
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM;
case InstructionSet::kArm64:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_ARM64;
case InstructionSet::kRiscv64:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_RISCV64;
case InstructionSet::kX86:
return statsd::ART_DATUM_REPORTED__ISA__ART_ISA_X86;
case InstructionSet::kX86_64:
Expand Down

0 comments on commit ebc548c

Please sign in to comment.