summaryrefslogtreecommitdiffstats
path: root/compiler/utils
diff options
context:
space:
mode:
authorYevgeny Rouban <yevgeny.y.rouban@intel.com>2014-08-08 16:29:38 +0700
committerTong Shen <endlessroad@google.com>2014-08-15 15:04:12 -0700
commite3ea83811d47152c00abea24a9b420651a33b496 (patch)
treedd3b8018176ada85d51b2f8ca46e515fbf55b50f /compiler/utils
parent9dcf75c80187504ec88e7ef91d64a6a68279eb9d (diff)
downloadart-e3ea83811d47152c00abea24a9b420651a33b496.zip
art-e3ea83811d47152c00abea24a9b420651a33b496.tar.gz
art-e3ea83811d47152c00abea24a9b420651a33b496.tar.bz2
ART source line debug info in OAT files
OAT files have source line information enough for ART runtime needs like jump to/from interpreter and thread suspension. But this information is not enough for finer grained source level debugging and low-level profiling (VTune or perf). This patch adds to OAT files two additional sections: .debug_line - DWARF formatted Elf32 section with detailed source line information (mapping from native PC to Java source lines). In addition to the debugging symbols added using the dex2oat option --include-debug-symbols, the source line information is added to the section .debug_line. The source line info can be read by many Elf reading tools like objdump, readelf, dwarfdump, gdb, perf, VTune, ... gdb can use this debug line information in x86. In 64-bit mode the information can be used if the oat file is mapped in the lower address space (address has higher 32 bits zeroed). Relocation works. Testing: 1. art/test/run-test --host --gdb [--64] 001-HelloWorld 2. in gdb: break Main.java:19 3. in gdb: break Runtime.java:111 4. in gdb: run - stops at void java.lang.Runtime.<init>() 5. in gdb: backtrace - shows call stack down to main() 6. in gdb: continue - stops at void Main.main() (only in 32-bit mode) 7. in gdb: backtrace - shows call stack down to main() 8. objdump -W <oat-file> - addresses are from VMA range of .text section reported by objdump -h <file> 9. dwarfdump -ka <oat-file> - no errors expected Size of aosp-x86-eng boot.oat increased by 11% from 80.5Mb to 89.2Mb with two sections added .debug_line (7.2Mb) and .rel.debug (1.5Mb). Change-Id: Ib8828832686e49782a63d5529008ff4814ed9cda Signed-off-by: Yevgeny Rouban <yevgeny.y.rouban@intel.com>
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/dwarf_cfi.cc82
-rw-r--r--compiler/utils/dwarf_cfi.h10
-rw-r--r--compiler/utils/x86/assembler_x86.cc6
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.cc6
4 files changed, 75 insertions, 29 deletions
diff --git a/compiler/utils/dwarf_cfi.cc b/compiler/utils/dwarf_cfi.cc
index b3d1a47..83e5f5a 100644
--- a/compiler/utils/dwarf_cfi.cc
+++ b/compiler/utils/dwarf_cfi.cc
@@ -65,44 +65,86 @@ void DW_CFA_restore_state(std::vector<uint8_t>* buf) {
buf->push_back(0x0b);
}
-void WriteFDEHeader(std::vector<uint8_t>* buf) {
+void WriteFDEHeader(std::vector<uint8_t>* buf, bool is_64bit) {
// 'length' (filled in by other functions).
- PushWord(buf, 0);
+ if (is_64bit) {
+ PushWord(buf, 0xffffffff); // Indicates 64bit
+ PushWord(buf, 0);
+ PushWord(buf, 0);
+ } else {
+ PushWord(buf, 0);
+ }
// 'CIE_pointer' (filled in by linker).
- PushWord(buf, 0);
+ if (is_64bit) {
+ PushWord(buf, 0);
+ PushWord(buf, 0);
+ } else {
+ PushWord(buf, 0);
+ }
// 'initial_location' (filled in by linker).
- PushWord(buf, 0);
+ if (is_64bit) {
+ PushWord(buf, 0);
+ PushWord(buf, 0);
+ } else {
+ PushWord(buf, 0);
+ }
// 'address_range' (filled in by other functions).
- PushWord(buf, 0);
+ if (is_64bit) {
+ PushWord(buf, 0);
+ PushWord(buf, 0);
+ } else {
+ PushWord(buf, 0);
+ }
// Augmentation length: 0
buf->push_back(0);
}
-void WriteFDEAddressRange(std::vector<uint8_t>* buf, uint32_t data) {
- const int kOffsetOfAddressRange = 12;
- CHECK(buf->size() >= kOffsetOfAddressRange + sizeof(uint32_t));
+void WriteFDEAddressRange(std::vector<uint8_t>* buf, uint64_t data, bool is_64bit) {
+ const size_t kOffsetOfAddressRange = is_64bit? 28 : 12;
+ CHECK(buf->size() >= kOffsetOfAddressRange + (is_64bit? 8 : 4));
uint8_t *p = buf->data() + kOffsetOfAddressRange;
- p[0] = data;
- p[1] = data >> 8;
- p[2] = data >> 16;
- p[3] = data >> 24;
+ if (is_64bit) {
+ p[0] = data;
+ p[1] = data >> 8;
+ p[2] = data >> 16;
+ p[3] = data >> 24;
+ p[4] = data >> 32;
+ p[5] = data >> 40;
+ p[6] = data >> 48;
+ p[7] = data >> 56;
+ } else {
+ p[0] = data;
+ p[1] = data >> 8;
+ p[2] = data >> 16;
+ p[3] = data >> 24;
+ }
}
-void WriteCFILength(std::vector<uint8_t>* buf) {
- uint32_t length = buf->size() - 4;
+void WriteCFILength(std::vector<uint8_t>* buf, bool is_64bit) {
+ uint64_t length = is_64bit ? buf->size() - 12 : buf->size() - 4;
DCHECK_EQ((length & 0x3), 0U);
- DCHECK_GT(length, 4U);
- uint8_t *p = buf->data();
- p[0] = length;
- p[1] = length >> 8;
- p[2] = length >> 16;
- p[3] = length >> 24;
+ uint8_t *p = is_64bit? buf->data() + 4 : buf->data();
+ if (is_64bit) {
+ p[0] = length;
+ p[1] = length >> 8;
+ p[2] = length >> 16;
+ p[3] = length >> 24;
+ p[4] = length >> 32;
+ p[5] = length >> 40;
+ p[6] = length >> 48;
+ p[7] = length >> 56;
+ } else {
+ p[0] = length;
+ p[1] = length >> 8;
+ p[2] = length >> 16;
+ p[3] = length >> 24;
+ }
}
void PadCFI(std::vector<uint8_t>* buf) {
diff --git a/compiler/utils/dwarf_cfi.h b/compiler/utils/dwarf_cfi.h
index e5acc0e..0c8b151 100644
--- a/compiler/utils/dwarf_cfi.h
+++ b/compiler/utils/dwarf_cfi.h
@@ -66,20 +66,24 @@ void DW_CFA_restore_state(std::vector<uint8_t>* buf);
/**
* @brief Write FDE header into an FDE buffer
* @param buf FDE buffer.
+ * @param is_64bit If FDE is for 64bit application.
*/
-void WriteFDEHeader(std::vector<uint8_t>* buf);
+void WriteFDEHeader(std::vector<uint8_t>* buf, bool is_64bit);
/**
* @brief Set 'address_range' field of an FDE buffer
* @param buf FDE buffer.
+ * @param data Data value.
+ * @param is_64bit If FDE is for 64bit application.
*/
-void WriteFDEAddressRange(std::vector<uint8_t>* buf, uint32_t data);
+void WriteFDEAddressRange(std::vector<uint8_t>* buf, uint64_t data, bool is_64bit);
/**
* @brief Set 'length' field of an FDE buffer
* @param buf FDE buffer.
+ * @param is_64bit If FDE is for 64bit application.
*/
-void WriteCFILength(std::vector<uint8_t>* buf);
+void WriteCFILength(std::vector<uint8_t>* buf, bool is_64bit);
/**
* @brief Pad an FDE buffer with 0 until its size is a multiple of 4
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc
index 48edb15..2c9bc28 100644
--- a/compiler/utils/x86/assembler_x86.cc
+++ b/compiler/utils/x86/assembler_x86.cc
@@ -1409,13 +1409,13 @@ void X86Assembler::EmitGenericShift(int reg_or_opcode,
}
void X86Assembler::InitializeFrameDescriptionEntry() {
- WriteFDEHeader(&cfi_info_);
+ WriteFDEHeader(&cfi_info_, false /* is_64bit */);
}
void X86Assembler::FinalizeFrameDescriptionEntry() {
- WriteFDEAddressRange(&cfi_info_, buffer_.Size());
+ WriteFDEAddressRange(&cfi_info_, buffer_.Size(), false /* is_64bit */);
PadCFI(&cfi_info_);
- WriteCFILength(&cfi_info_);
+ WriteCFILength(&cfi_info_, false /* is_64bit */);
}
constexpr size_t kFramePointerSize = 4;
diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc
index 62b72c2..1e2884a 100644
--- a/compiler/utils/x86_64/assembler_x86_64.cc
+++ b/compiler/utils/x86_64/assembler_x86_64.cc
@@ -1716,13 +1716,13 @@ void X86_64Assembler::EmitOptionalByteRegNormalizingRex32(CpuRegister dst, const
}
void X86_64Assembler::InitializeFrameDescriptionEntry() {
- WriteFDEHeader(&cfi_info_);
+ WriteFDEHeader(&cfi_info_, true /* is_64bit */);
}
void X86_64Assembler::FinalizeFrameDescriptionEntry() {
- WriteFDEAddressRange(&cfi_info_, buffer_.Size());
+ WriteFDEAddressRange(&cfi_info_, buffer_.Size(), true /* is_64bit */);
PadCFI(&cfi_info_);
- WriteCFILength(&cfi_info_);
+ WriteCFILength(&cfi_info_, true /* is_64bit */);
}
constexpr size_t kFramePointerSize = 8;