< prev index next >

src/hotspot/share/utilities/elfFile.cpp

Print this page

        

@@ -103,13 +103,13 @@
   if (_marked_pos != -1) {
     set_position(_marked_pos);
   }
 }
 
-ElfFile::ElfFile(const char* filepath) :
+ElfFile::ElfFile(const char* filepath, bool load_debug_info) :
   _string_tables(NULL), _symbol_tables(NULL), _funcDesc_table(NULL),
-  _next(NULL), _status(NullDecoder::no_error),
+  _next(NULL), _status(NullDecoder::no_error), _debuginfo(NULL),
   _shdr_string_table(NULL),  _file(NULL), _filepath(NULL) {
   memset(&_elfHdr, 0, sizeof(_elfHdr));
 
   int len = strlen(filepath) + 1;
   _filepath = (char*)os::malloc(len * sizeof(char), mtInternal);

@@ -119,15 +119,27 @@
   }
   strcpy(_filepath, filepath);
 
   _status = parse_elf(filepath);
 
-  // we no longer need section header string table
+  // See if we should try to load external debug info
+  if (_status == NullDecoder::no_debug_symbols && load_debug_info) {
+    log_debug(decoder)("No debug symbols in %s, trying external debuginfo", _filepath);
+    _debuginfo = load_debuginfo();
+  }
+
+  if (NullDecoder::is_error(_status)) {
+    // Not be able to decode, cleanup
+    cleanup_tables();
+  } else {
+    log_debug(decoder)("%s contains debug symbols", _filepath);
+    // No longer need section header string table, which is not used for decoding
   if (_shdr_string_table != NULL) {
     delete _shdr_string_table;
     _shdr_string_table = NULL;
   }
+  }
 }
 
 ElfFile::~ElfFile() {
   if (_shdr_string_table != NULL) {
     delete _shdr_string_table;

@@ -199,10 +211,13 @@
   // Check signature
   if (!is_elf_file(_elfHdr)) {
     return NullDecoder::file_invalid;
   }
 
+  // test if the file contains debug symbols
+  NullDecoder::decoder_status stat = NullDecoder::no_debug_symbols;
+
   // walk elf file's section headers, and load string tables
   Elf_Shdr shdr;
   if (!freader.set_position(_elfHdr.e_shoff)) {
     return NullDecoder::file_invalid;
   }

@@ -228,10 +243,14 @@
       // symbol tables
       ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(fd(), shdr);
       if (table == NULL) {
         return NullDecoder::out_of_memory;
       }
+      // see if we have debug symbols
+      if (shdr.sh_type == SHT_SYMTAB) {
+        stat = NullDecoder::no_error;
+      }
       add_symbol_table(table);
     }
   }
 #if defined(PPC64) && !defined(ABI_ELFv2)
   // Now read the .opd section wich contains the PPC64 function descriptor table.

@@ -253,11 +272,11 @@
   _funcDesc_table = new (std::nothrow) ElfFuncDescTable(_file, shdr, sect_index);
   if (_funcDesc_table == NULL) {
       return NullDecoder::out_of_memory;
   }
 #endif
-  return NullDecoder::no_error;
+  return stat;
 }
 
 int ElfFile::section_by_name(const char* name, Elf_Shdr& hdr) {
   assert(name != NULL, "No section name");
   size_t len = strlen(name) + 1;

@@ -286,10 +305,18 @@
   }
   return sect_index;
 }
 
 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
+  if (_debuginfo != NULL) {
+    return _debuginfo->decode(addr, buf, buflen, offset);
+  } else {
+    return decode_impl(addr, buf, buflen, offset);
+  }
+}
+
+bool ElfFile::decode_impl(address addr, char* buf, int buflen, int* offset) {
   // something already went wrong, just give up
   if (NullDecoder::is_error(_status)) {
     return false;
   }
 
< prev index next >