diff options
| -rw-r--r-- | runtime/Android.mk | 1 | ||||
| -rw-r--r-- | runtime/elf_file.cc | 83 | ||||
| -rw-r--r-- | runtime/jit/debugger_interface.cc | 97 | ||||
| -rw-r--r-- | runtime/jit/debugger_interface.h | 36 |
4 files changed, 137 insertions, 80 deletions
diff --git a/runtime/Android.mk b/runtime/Android.mk index 40961179d3..07fa2fdffd 100644 --- a/runtime/Android.mk +++ b/runtime/Android.mk @@ -102,6 +102,7 @@ LIBART_COMMON_SRC_FILES := \ jdwp/jdwp_socket.cc \ jdwp/object_registry.cc \ jni_env_ext.cc \ + jit/debugger_interface.cc \ jit/jit.cc \ jit/jit_code_cache.cc \ jit/jit_instrumentation.cc \ diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc index 281967054d..57d623e987 100644 --- a/runtime/elf_file.cc +++ b/runtime/elf_file.cc @@ -27,89 +27,12 @@ #include "base/unix_file/fd_file.h" #include "elf_file_impl.h" #include "elf_utils.h" +#include "jit/debugger_interface.h" #include "leb128.h" #include "utils.h" namespace art { -// ------------------------------------------------------------------- -// Binary GDB JIT Interface as described in -// http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html -extern "C" { - typedef enum { - JIT_NOACTION = 0, - JIT_REGISTER_FN, - JIT_UNREGISTER_FN - } JITAction; - - struct JITCodeEntry { - JITCodeEntry* next_; - JITCodeEntry* prev_; - const uint8_t *symfile_addr_; - uint64_t symfile_size_; - }; - - struct JITDescriptor { - uint32_t version_; - uint32_t action_flag_; - JITCodeEntry* relevant_entry_; - JITCodeEntry* first_entry_; - }; - - // GDB will place breakpoint into this function. - // To prevent GCC from inlining or removing it we place noinline attribute - // and inline assembler statement inside. - void __attribute__((noinline)) __jit_debug_register_code(); - void __attribute__((noinline)) __jit_debug_register_code() { - __asm__(""); - } - - // GDB will inspect contents of this descriptor. - // Static initialization is necessary to prevent GDB from seeing - // uninitialized descriptor. - JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, nullptr, nullptr }; -} - - -static JITCodeEntry* CreateCodeEntry(const uint8_t *symfile_addr, - uintptr_t symfile_size) { - JITCodeEntry* entry = new JITCodeEntry; - entry->symfile_addr_ = symfile_addr; - entry->symfile_size_ = symfile_size; - entry->prev_ = nullptr; - - // TODO: Do we need a lock here? - entry->next_ = __jit_debug_descriptor.first_entry_; - if (entry->next_ != nullptr) { - entry->next_->prev_ = entry; - } - __jit_debug_descriptor.first_entry_ = entry; - __jit_debug_descriptor.relevant_entry_ = entry; - - __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; - __jit_debug_register_code(); - return entry; -} - - -static void UnregisterCodeEntry(JITCodeEntry* entry) { - // TODO: Do we need a lock here? - if (entry->prev_ != nullptr) { - entry->prev_->next_ = entry->next_; - } else { - __jit_debug_descriptor.first_entry_ = entry->next_; - } - - if (entry->next_ != nullptr) { - entry->next_->prev_ = entry->prev_; - } - - __jit_debug_descriptor.relevant_entry_ = entry; - __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; - __jit_debug_register_code(); - delete entry; -} - template <typename ElfTypes> ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable, bool program_header_only, @@ -352,7 +275,7 @@ ElfFileImpl<ElfTypes>::~ElfFileImpl() { delete dynsym_symbol_table_; delete jit_elf_image_; if (jit_gdb_entry_) { - UnregisterCodeEntry(jit_gdb_entry_); + DeleteJITCodeEntry(jit_gdb_entry_); } } @@ -1511,7 +1434,7 @@ void ElfFileImpl<ElfTypes>::GdbJITSupport() { return; } - jit_gdb_entry_ = CreateCodeEntry(all.Begin(), all.Size()); + jit_gdb_entry_ = CreateJITCodeEntry(all.Begin(), all.Size()); gdb_file_mapping_.reset(all_ptr.release()); } diff --git a/runtime/jit/debugger_interface.cc b/runtime/jit/debugger_interface.cc new file mode 100644 index 0000000000..3c2898b8ac --- /dev/null +++ b/runtime/jit/debugger_interface.cc @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "debugger_interface.h" + +namespace art { + +// ------------------------------------------------------------------- +// Binary GDB JIT Interface as described in +// http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html +// ------------------------------------------------------------------- +extern "C" { + typedef enum { + JIT_NOACTION = 0, + JIT_REGISTER_FN, + JIT_UNREGISTER_FN + } JITAction; + + struct JITCodeEntry { + JITCodeEntry* next_; + JITCodeEntry* prev_; + const uint8_t *symfile_addr_; + uint64_t symfile_size_; + }; + + struct JITDescriptor { + uint32_t version_; + uint32_t action_flag_; + JITCodeEntry* relevant_entry_; + JITCodeEntry* first_entry_; + }; + + // GDB will place breakpoint into this function. + // To prevent GCC from inlining or removing it we place noinline attribute + // and inline assembler statement inside. + void __attribute__((noinline)) __jit_debug_register_code(); + void __attribute__((noinline)) __jit_debug_register_code() { + __asm__(""); + } + + // GDB will inspect contents of this descriptor. + // Static initialization is necessary to prevent GDB from seeing + // uninitialized descriptor. + JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, nullptr, nullptr }; +} + +JITCodeEntry* CreateJITCodeEntry(const uint8_t *symfile_addr, uintptr_t symfile_size) { + JITCodeEntry* entry = new JITCodeEntry; + entry->symfile_addr_ = symfile_addr; + entry->symfile_size_ = symfile_size; + entry->prev_ = nullptr; + + // TODO: Do we need a lock here? + entry->next_ = __jit_debug_descriptor.first_entry_; + if (entry->next_ != nullptr) { + entry->next_->prev_ = entry; + } + __jit_debug_descriptor.first_entry_ = entry; + __jit_debug_descriptor.relevant_entry_ = entry; + + __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; + __jit_debug_register_code(); + return entry; +} + +void DeleteJITCodeEntry(JITCodeEntry* entry) { + // TODO: Do we need a lock here? + if (entry->prev_ != nullptr) { + entry->prev_->next_ = entry->next_; + } else { + __jit_debug_descriptor.first_entry_ = entry->next_; + } + + if (entry->next_ != nullptr) { + entry->next_->prev_ = entry->prev_; + } + + __jit_debug_descriptor.relevant_entry_ = entry; + __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; + __jit_debug_register_code(); + delete entry; +} + +} // namespace art diff --git a/runtime/jit/debugger_interface.h b/runtime/jit/debugger_interface.h new file mode 100644 index 0000000000..a784ef5990 --- /dev/null +++ b/runtime/jit/debugger_interface.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_JIT_DEBUGGER_INTERFACE_H_ +#define ART_RUNTIME_JIT_DEBUGGER_INTERFACE_H_ + +#include <inttypes.h> + +namespace art { + +extern "C" { + struct JITCodeEntry; +} + +// Notify native debugger about new JITed code by passing in-memory ELF. +JITCodeEntry* CreateJITCodeEntry(const uint8_t *symfile_addr, uintptr_t symfile_size); + +// Notify native debugger that JITed code has been removed. +void DeleteJITCodeEntry(JITCodeEntry* entry); + +} // namespace art + +#endif // ART_RUNTIME_JIT_DEBUGGER_INTERFACE_H_ |