src/share/vm/utilities/elfFile.cpp
Print this page
rev 5729 : 8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
@@ -117,27 +117,58 @@
for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
m_status = NullDecoder::file_invalid;
return false;
}
- // string table
+ // string tables
if (shdr.sh_type == SHT_STRTAB) {
ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
if (table == NULL) {
m_status = NullDecoder::out_of_memory;
return false;
}
add_string_table(table);
- } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
+ }
+ // symbol tables
+ else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
if (table == NULL) {
m_status = NullDecoder::out_of_memory;
return false;
}
add_symbol_table(table);
}
}
+
+#if defined(PPC64)
+ // Now read the .opd section wich contains the PPC64 function descriptor table.
+ // This is only possible after we have successfully read in the string tables in te previous loop.
+ m_funcDesc_table = NULL;
+ // Reset the file pointer
+ if (fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
+ m_status = NullDecoder::file_invalid;
+ return false;
+ }
+ for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
+ if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
+ m_status = NullDecoder::file_invalid;
+ return false;
+ }
+ if (m_elfHdr.e_shstrndx != SHN_UNDEF && shdr.sh_type == SHT_PROGBITS) {
+ ElfStringTable* string_table = get_string_table(m_elfHdr.e_shstrndx);
+ if (string_table == NULL) {
+ m_status = NullDecoder::file_invalid;
+ return false;
+ }
+ char buf[8]; // We only want to read ".opd"
+ if (string_table->string_at(shdr.sh_name, buf, sizeof(buf)) && !strncmp(".opd", buf, 4)) {
+ m_funcDesc_table = new (std::nothrow) ElfFuncDescTable(m_file, shdr);
+ }
+ }
+ }
+#endif
+
}
return true;
}
bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
@@ -149,12 +180,17 @@
int string_table_index;
int pos_in_string_table;
int off = INT_MAX;
bool found_symbol = false;
while (symbol_table != NULL) {
+#if defined(PPC64)
+ if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, m_funcDesc_table)) {
+#else
if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
+#endif
found_symbol = true;
+ break;
}
symbol_table = symbol_table->m_next;
}
if (!found_symbol) return false;