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,143 **** 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 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) { ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); if (table == NULL) { m_status = NullDecoder::out_of_memory; return false; } add_symbol_table(table); } } } return true; } bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { --- 117,174 ---- 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 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); ! } ! // 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,160 **** --- 180,196 ---- 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;