< prev index next >

src/hotspot/share/utilities/elfFile.cpp

Print this page




  88 int FileReader::read_buffer(void* buf, size_t size) {
  89   assert(buf != NULL, "no buffer");
  90   assert(size > 0, "no space");
  91   return fread(buf, 1, size, _fd);
  92 }
  93 
  94 bool FileReader::set_position(long offset) {
  95   return fseek(_fd, offset, SEEK_SET) == 0;
  96 }
  97 
  98 MarkedFileReader::MarkedFileReader(FILE* fd) : FileReader(fd) {
  99   _marked_pos = ftell(fd);
 100 }
 101 
 102 MarkedFileReader::~MarkedFileReader() {
 103   if (_marked_pos != -1) {
 104     set_position(_marked_pos);
 105   }
 106 }
 107 
 108 ElfFile::ElfFile(const char* filepath) :
 109   _string_tables(NULL), _symbol_tables(NULL), _funcDesc_table(NULL),
 110   _next(NULL), _status(NullDecoder::no_error),
 111   _shdr_string_table(NULL),  _file(NULL), _filepath(NULL) {
 112   memset(&_elfHdr, 0, sizeof(_elfHdr));
 113 
 114   int len = strlen(filepath) + 1;
 115   _filepath = (char*)os::malloc(len * sizeof(char), mtInternal);
 116   if (_filepath == NULL) {
 117     _status = NullDecoder::out_of_memory;
 118     return;
 119   }
 120   strcpy(_filepath, filepath);
 121 
 122   _status = parse_elf(filepath);
 123 
 124   // we no longer need section header string table











 125   if (_shdr_string_table != NULL) {
 126     delete _shdr_string_table;
 127     _shdr_string_table = NULL;
 128   }

 129 }
 130 
 131 ElfFile::~ElfFile() {
 132   if (_shdr_string_table != NULL) {
 133     delete _shdr_string_table;
 134   }
 135 
 136   cleanup_tables();
 137 
 138   if (_file != NULL) {
 139     fclose(_file);
 140   }
 141 
 142   if (_filepath != NULL) {
 143     os::free((void*)_filepath);
 144   }
 145 
 146   if (_next != NULL) {
 147     delete _next;
 148   }


 184       ELFMAG3 == hdr.e_ident[EI_MAG3] &&
 185       ELFCLASSNONE != hdr.e_ident[EI_CLASS] &&
 186       ELFDATANONE != hdr.e_ident[EI_DATA]);
 187 }
 188 
 189 NullDecoder::decoder_status ElfFile::load_tables() {
 190   assert(_file, "file not open");
 191   assert(!NullDecoder::is_error(_status), "already in error");
 192 
 193   FileReader freader(fd());
 194   // read elf file header
 195   if (!freader.read(&_elfHdr, sizeof(_elfHdr))) {
 196     return NullDecoder::file_invalid;
 197   }
 198 
 199   // Check signature
 200   if (!is_elf_file(_elfHdr)) {
 201     return NullDecoder::file_invalid;
 202   }
 203 



 204   // walk elf file's section headers, and load string tables
 205   Elf_Shdr shdr;
 206   if (!freader.set_position(_elfHdr.e_shoff)) {
 207     return NullDecoder::file_invalid;
 208   }
 209 
 210   for (int index = 0; index < _elfHdr.e_shnum; index ++) {
 211     if (!freader.read(&shdr, sizeof(shdr))) {
 212       return NullDecoder::file_invalid;
 213     }
 214 
 215     if (shdr.sh_type == SHT_STRTAB) {
 216       // string tables
 217       ElfStringTable* table = new (std::nothrow) ElfStringTable(fd(), shdr, index);
 218       if (table == NULL) {
 219         return NullDecoder::out_of_memory;
 220       }
 221       if (index == _elfHdr.e_shstrndx) {
 222         assert(_shdr_string_table == NULL, "Only set once");
 223         _shdr_string_table = table;
 224       } else {
 225         add_string_table(table);
 226       }
 227     } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
 228       // symbol tables
 229       ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(fd(), shdr);
 230       if (table == NULL) {
 231         return NullDecoder::out_of_memory;
 232       }




 233       add_symbol_table(table);
 234     }
 235   }
 236 #if defined(PPC64) && !defined(ABI_ELFv2)
 237   // Now read the .opd section wich contains the PPC64 function descriptor table.
 238   // The .opd section is only available on PPC64 (see for example:
 239   // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
 240   // so this code should do no harm on other platforms but because of performance reasons we only
 241   // execute it on PPC64 platforms.
 242   // Notice that we can only find the .opd section after we have successfully read in the string
 243   // tables in the previous loop, because we need to query the name of each section which is
 244   // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx).
 245 
 246   // Reset the file pointer
 247   int sect_index = section_by_name(".opd", shdr);
 248 
 249   if (sect_index == -1) {
 250     return NullDecoder::file_invalid;
 251   }
 252 
 253   _funcDesc_table = new (std::nothrow) ElfFuncDescTable(_file, shdr, sect_index);
 254   if (_funcDesc_table == NULL) {
 255       return NullDecoder::out_of_memory;
 256   }
 257 #endif
 258   return NullDecoder::no_error;
 259 }
 260 
 261 int ElfFile::section_by_name(const char* name, Elf_Shdr& hdr) {
 262   assert(name != NULL, "No section name");
 263   size_t len = strlen(name) + 1;
 264   ResourceMark rm;
 265   char* buf = NEW_RESOURCE_ARRAY(char, len);
 266   if (buf == NULL) {
 267     return -1;
 268   }
 269 
 270   assert(_shdr_string_table != NULL, "Section header string table should be loaded");
 271   ElfStringTable* const table = _shdr_string_table;
 272   MarkedFileReader mfd(fd());
 273   if (!mfd.has_mark() || !mfd.set_position(_elfHdr.e_shoff)) return -1;
 274 
 275   int sect_index = -1;
 276   for (int index = 0; index < _elfHdr.e_shnum; index ++) {
 277     if (!mfd.read((void*)&hdr, sizeof(hdr))) {
 278       break;
 279     }
 280     if (table->string_at(hdr.sh_name, buf, len)) {
 281       if (strncmp(buf, name, len) == 0) {
 282         sect_index = index;
 283         break;
 284       }
 285     }
 286   }
 287   return sect_index;
 288 }
 289 
 290 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {








 291   // something already went wrong, just give up
 292   if (NullDecoder::is_error(_status)) {
 293     return false;
 294   }
 295 
 296   int string_table_index;
 297   int pos_in_string_table;
 298   int off = INT_MAX;
 299   bool found_symbol = false;
 300   ElfSymbolTable* symbol_table = _symbol_tables;
 301 
 302   while (symbol_table != NULL) {
 303     if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, _funcDesc_table)) {
 304       found_symbol = true;
 305       break;
 306     }
 307     symbol_table = symbol_table->next();
 308   }
 309   if (!found_symbol) {
 310     return false;




  88 int FileReader::read_buffer(void* buf, size_t size) {
  89   assert(buf != NULL, "no buffer");
  90   assert(size > 0, "no space");
  91   return fread(buf, 1, size, _fd);
  92 }
  93 
  94 bool FileReader::set_position(long offset) {
  95   return fseek(_fd, offset, SEEK_SET) == 0;
  96 }
  97 
  98 MarkedFileReader::MarkedFileReader(FILE* fd) : FileReader(fd) {
  99   _marked_pos = ftell(fd);
 100 }
 101 
 102 MarkedFileReader::~MarkedFileReader() {
 103   if (_marked_pos != -1) {
 104     set_position(_marked_pos);
 105   }
 106 }
 107 
 108 ElfFile::ElfFile(const char* filepath, bool load_debug_info) :
 109   _string_tables(NULL), _symbol_tables(NULL), _funcDesc_table(NULL),
 110   _next(NULL), _status(NullDecoder::no_error), _debuginfo(NULL),
 111   _shdr_string_table(NULL),  _file(NULL), _filepath(NULL) {
 112   memset(&_elfHdr, 0, sizeof(_elfHdr));
 113 
 114   int len = strlen(filepath) + 1;
 115   _filepath = (char*)os::malloc(len * sizeof(char), mtInternal);
 116   if (_filepath == NULL) {
 117     _status = NullDecoder::out_of_memory;
 118     return;
 119   }
 120   strcpy(_filepath, filepath);
 121 
 122   _status = parse_elf(filepath);
 123 
 124   // See if we should try to load external debug info
 125   if (_status == NullDecoder::no_debug_symbols && load_debug_info) {
 126     log_debug(decoder)("No debug symbols in %s, trying external debuginfo", _filepath);
 127     _debuginfo = load_debuginfo();
 128   }
 129 
 130   if (NullDecoder::is_error(_status)) {
 131     // Not be able to decode, cleanup
 132     cleanup_tables();
 133   } else {
 134     log_debug(decoder)("%s contains debug symbols", _filepath);
 135     // No longer need section header string table, which is not used for decoding
 136     if (_shdr_string_table != NULL) {
 137       delete _shdr_string_table;
 138       _shdr_string_table = NULL;
 139     }
 140   }
 141 }
 142 
 143 ElfFile::~ElfFile() {
 144   if (_shdr_string_table != NULL) {
 145     delete _shdr_string_table;
 146   }
 147 
 148   cleanup_tables();
 149 
 150   if (_file != NULL) {
 151     fclose(_file);
 152   }
 153 
 154   if (_filepath != NULL) {
 155     os::free((void*)_filepath);
 156   }
 157 
 158   if (_next != NULL) {
 159     delete _next;
 160   }


 196       ELFMAG3 == hdr.e_ident[EI_MAG3] &&
 197       ELFCLASSNONE != hdr.e_ident[EI_CLASS] &&
 198       ELFDATANONE != hdr.e_ident[EI_DATA]);
 199 }
 200 
 201 NullDecoder::decoder_status ElfFile::load_tables() {
 202   assert(_file, "file not open");
 203   assert(!NullDecoder::is_error(_status), "already in error");
 204 
 205   FileReader freader(fd());
 206   // read elf file header
 207   if (!freader.read(&_elfHdr, sizeof(_elfHdr))) {
 208     return NullDecoder::file_invalid;
 209   }
 210 
 211   // Check signature
 212   if (!is_elf_file(_elfHdr)) {
 213     return NullDecoder::file_invalid;
 214   }
 215 
 216   // test if the file contains debug symbols
 217   NullDecoder::decoder_status stat = NullDecoder::no_debug_symbols;
 218 
 219   // walk elf file's section headers, and load string tables
 220   Elf_Shdr shdr;
 221   if (!freader.set_position(_elfHdr.e_shoff)) {
 222     return NullDecoder::file_invalid;
 223   }
 224 
 225   for (int index = 0; index < _elfHdr.e_shnum; index ++) {
 226     if (!freader.read(&shdr, sizeof(shdr))) {
 227       return NullDecoder::file_invalid;
 228     }
 229 
 230     if (shdr.sh_type == SHT_STRTAB) {
 231       // string tables
 232       ElfStringTable* table = new (std::nothrow) ElfStringTable(fd(), shdr, index);
 233       if (table == NULL) {
 234         return NullDecoder::out_of_memory;
 235       }
 236       if (index == _elfHdr.e_shstrndx) {
 237         assert(_shdr_string_table == NULL, "Only set once");
 238         _shdr_string_table = table;
 239       } else {
 240         add_string_table(table);
 241       }
 242     } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
 243       // symbol tables
 244       ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(fd(), shdr);
 245       if (table == NULL) {
 246         return NullDecoder::out_of_memory;
 247       }
 248       // see if we have debug symbols
 249       if (shdr.sh_type == SHT_SYMTAB) {
 250         stat = NullDecoder::no_error;
 251       }
 252       add_symbol_table(table);
 253     }
 254   }
 255 #if defined(PPC64) && !defined(ABI_ELFv2)
 256   // Now read the .opd section wich contains the PPC64 function descriptor table.
 257   // The .opd section is only available on PPC64 (see for example:
 258   // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
 259   // so this code should do no harm on other platforms but because of performance reasons we only
 260   // execute it on PPC64 platforms.
 261   // Notice that we can only find the .opd section after we have successfully read in the string
 262   // tables in the previous loop, because we need to query the name of each section which is
 263   // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx).
 264 
 265   // Reset the file pointer
 266   int sect_index = section_by_name(".opd", shdr);
 267 
 268   if (sect_index == -1) {
 269     return NullDecoder::file_invalid;
 270   }
 271 
 272   _funcDesc_table = new (std::nothrow) ElfFuncDescTable(_file, shdr, sect_index);
 273   if (_funcDesc_table == NULL) {
 274       return NullDecoder::out_of_memory;
 275   }
 276 #endif
 277   return stat;
 278 }
 279 
 280 int ElfFile::section_by_name(const char* name, Elf_Shdr& hdr) {
 281   assert(name != NULL, "No section name");
 282   size_t len = strlen(name) + 1;
 283   ResourceMark rm;
 284   char* buf = NEW_RESOURCE_ARRAY(char, len);
 285   if (buf == NULL) {
 286     return -1;
 287   }
 288 
 289   assert(_shdr_string_table != NULL, "Section header string table should be loaded");
 290   ElfStringTable* const table = _shdr_string_table;
 291   MarkedFileReader mfd(fd());
 292   if (!mfd.has_mark() || !mfd.set_position(_elfHdr.e_shoff)) return -1;
 293 
 294   int sect_index = -1;
 295   for (int index = 0; index < _elfHdr.e_shnum; index ++) {
 296     if (!mfd.read((void*)&hdr, sizeof(hdr))) {
 297       break;
 298     }
 299     if (table->string_at(hdr.sh_name, buf, len)) {
 300       if (strncmp(buf, name, len) == 0) {
 301         sect_index = index;
 302         break;
 303       }
 304     }
 305   }
 306   return sect_index;
 307 }
 308 
 309 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
 310   if (_debuginfo != NULL) {
 311     return _debuginfo->decode(addr, buf, buflen, offset);
 312   } else {
 313     return decode_impl(addr, buf, buflen, offset);
 314   }
 315 }
 316 
 317 bool ElfFile::decode_impl(address addr, char* buf, int buflen, int* offset) {
 318   // something already went wrong, just give up
 319   if (NullDecoder::is_error(_status)) {
 320     return false;
 321   }
 322 
 323   int string_table_index;
 324   int pos_in_string_table;
 325   int off = INT_MAX;
 326   bool found_symbol = false;
 327   ElfSymbolTable* symbol_table = _symbol_tables;
 328 
 329   while (symbol_table != NULL) {
 330     if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, _funcDesc_table)) {
 331       found_symbol = true;
 332       break;
 333     }
 334     symbol_table = symbol_table->next();
 335   }
 336   if (!found_symbol) {
 337     return false;


< prev index next >