# HG changeset patch # User simonis # Date 1386267549 -3600 # Node ID d8ff2e550bcc15067e9062ad3d0dee6092bfe762 # Parent 41b780b43b7485b23d8ea7e906f412955935cb87 8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables diff --git a/make/aix/makefiles/vm.make b/make/aix/makefiles/vm.make --- a/make/aix/makefiles/vm.make +++ b/make/aix/makefiles/vm.make @@ -202,8 +202,8 @@ Src_Files_EXCLUDE += $(Src_Files_EXCLUDE/$(TYPE)) -# Disable 155427 on aix. -Src_Files_EXCLUDE += decoder_elf.cpp elfFile.cpp elfStringTable.cpp elfSymbolTable.cpp +# Disable ELF decoder on AIX (AIX uses XCOFF). +Src_Files_EXCLUDE += decoder_elf.cpp elfFile.cpp elfStringTable.cpp elfSymbolTable.cpp elfFuncDescTable.cpp # Special handling of arch model. ifeq ($(Platform_arch_model), x86_32) diff --git a/src/os/linux/vm/decoder_linux.cpp b/src/os/linux/vm/decoder_linux.cpp --- a/src/os/linux/vm/decoder_linux.cpp +++ b/src/os/linux/vm/decoder_linux.cpp @@ -32,6 +32,12 @@ char* result; size_t size = (size_t)buflen; +#ifdef PPC64 + // On PPC64 ElfDecoder::decode() may return a dot (.) prefixed name + // (see elfFuncDescTable.hpp for details) + if (symbol && *symbol == '.') symbol += 1; +#endif + // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small, // __cxa_demangle will call system "realloc" for additional memory, which // may use different malloc/realloc mechanism that allocates 'buf'. diff --git a/src/share/vm/utilities/decoder_elf.cpp b/src/share/vm/utilities/decoder_elf.cpp --- a/src/share/vm/utilities/decoder_elf.cpp +++ b/src/share/vm/utilities/decoder_elf.cpp @@ -73,4 +73,4 @@ return file; } -#endif +#endif // !_WINDOWS && !__APPLE__ diff --git a/src/share/vm/utilities/decoder_elf.hpp b/src/share/vm/utilities/decoder_elf.hpp --- a/src/share/vm/utilities/decoder_elf.hpp +++ b/src/share/vm/utilities/decoder_elf.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,5 +55,5 @@ ElfFile* _opened_elf_files; }; -#endif +#endif // !_WINDOWS && !__APPLE__ #endif // SHARE_VM_UTILITIES_DECODER_ELF_HPP diff --git a/src/share/vm/utilities/elfFile.cpp b/src/share/vm/utilities/elfFile.cpp --- a/src/share/vm/utilities/elfFile.cpp +++ b/src/share/vm/utilities/elfFile.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ #include "memory/allocation.inline.hpp" #include "utilities/decoder.hpp" #include "utilities/elfFile.hpp" +#include "utilities/elfFuncDescTable.hpp" #include "utilities/elfStringTable.hpp" #include "utilities/elfSymbolTable.hpp" @@ -43,6 +44,7 @@ memset(&m_elfHdr, 0, sizeof(m_elfHdr)); m_string_tables = NULL; m_symbol_tables = NULL; + m_funcDesc_table = NULL; m_next = NULL; m_status = NullDecoder::no_error; @@ -119,8 +121,8 @@ m_status = NullDecoder::file_invalid; return false; } - // string table if (shdr.sh_type == SHT_STRTAB) { + // string tables ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); if (table == NULL) { m_status = NullDecoder::out_of_memory; @@ -128,6 +130,7 @@ } add_string_table(table); } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { + // symbol tables ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); if (table == NULL) { m_status = NullDecoder::out_of_memory; @@ -136,6 +139,46 @@ add_symbol_table(table); } } + +#if defined(PPC64) + // Now read the .opd section wich contains the PPC64 function descriptor table. + // The .opd section is only available on PPC64 (see for example: + // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html) + // so this code should do no harm on other platforms but because of performance reasons we only + // execute it on PPC64 platforms. + // Notice that we can only find the .opd section after we have successfully read in the string + // tables in the previous loop, because we need to query the name of each section which is + // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx). + + // 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]; // '8' is enough because 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, index); + if (m_funcDesc_table == NULL) { + m_status = NullDecoder::out_of_memory; + return false; + } + break; + } + } + } +#endif + } return true; } @@ -151,8 +194,9 @@ int off = INT_MAX; bool found_symbol = false; while (symbol_table != NULL) { - if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { + if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, m_funcDesc_table)) { found_symbol = true; + break; } symbol_table = symbol_table->m_next; } @@ -221,4 +265,4 @@ } #endif -#endif // _WINDOWS +#endif // !_WINDOWS && !__APPLE__ diff --git a/src/share/vm/utilities/elfFile.hpp b/src/share/vm/utilities/elfFile.hpp --- a/src/share/vm/utilities/elfFile.hpp +++ b/src/share/vm/utilities/elfFile.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ class ElfStringTable; class ElfSymbolTable; +class ElfFuncDescTable; // On Solaris/Linux platforms, libjvm.so does contain all private symbols. @@ -150,9 +151,12 @@ // string tables ElfStringTable* m_string_tables; + // function descriptors table + ElfFuncDescTable* m_funcDesc_table; + NullDecoder::decoder_status m_status; }; -#endif // _WINDOWS +#endif // !_WINDOWS && !__APPLE__ #endif // SHARE_VM_UTILITIES_ELF_FILE_HPP diff --git a/src/share/vm/utilities/elfFuncDescTable.cpp b/src/share/vm/utilities/elfFuncDescTable.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/elfFuncDescTable.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2013 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#if !defined(_WINDOWS) && !defined(__APPLE__) + +#include "memory/allocation.inline.hpp" +#include "utilities/elfFuncDescTable.hpp" + +ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) { + assert(file, "null file handle"); + // The actual function address (i.e. function entry point) is always the + // first value in the function descriptor (on IA64 and PPC64 they look as follows): + // PPC64: [function entry point, TOC pointer, environment pointer] + // IA64 : [function entry point, GP (global pointer) value] + // Unfortunately 'shdr.sh_entsize' doesn't always seem to contain this size (it's zero on PPC64) so we can't assert + // assert(IA64_ONLY(2) PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries"); + + m_funcDescs = NULL; + m_file = file; + m_index = index; + m_status = NullDecoder::no_error; + + // try to load the function descriptor table + long cur_offset = ftell(file); + if (cur_offset != -1) { + // call malloc so we can back up if memory allocation fails. + m_funcDescs = (address*)os::malloc(shdr.sh_size, mtInternal); + if (m_funcDescs) { + if (fseek(file, shdr.sh_offset, SEEK_SET) || + fread((void*)m_funcDescs, shdr.sh_size, 1, file) != 1 || + fseek(file, cur_offset, SEEK_SET)) { + m_status = NullDecoder::file_invalid; + os::free(m_funcDescs); + m_funcDescs = NULL; + } + } + if (!NullDecoder::is_error(m_status)) { + memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr)); + } + } else { + m_status = NullDecoder::file_invalid; + } +} + +ElfFuncDescTable::~ElfFuncDescTable() { + if (m_funcDescs != NULL) { + os::free(m_funcDescs); + } +} + +address ElfFuncDescTable::lookup(Elf_Word index) { + if (NullDecoder::is_error(m_status)) { + return NULL; + } + + if (m_funcDescs != NULL) { + if (m_shdr.sh_size > 0 && m_shdr.sh_addr <= index && index <= m_shdr.sh_addr + m_shdr.sh_size) { + // Notice that 'index' is a byte-offset into the function descriptor table. + return m_funcDescs[(index - m_shdr.sh_addr) / sizeof(address)]; + } + return NULL; + } + else { + long cur_pos; + address addr; + if (!(m_shdr.sh_size > 0 && m_shdr.sh_addr <= index && index <= m_shdr.sh_addr + m_shdr.sh_size)) { + // don't put the whole decoder in error mode if we just tried a wrong index + return NULL; + } + if ((cur_pos = ftell(m_file)) == -1 || + fseek(m_file, m_shdr.sh_offset + index - m_shdr.sh_addr, SEEK_SET) || + fread(&addr, sizeof(addr), 1, m_file) != 1 || + fseek(m_file, cur_pos, SEEK_SET)) { + m_status = NullDecoder::file_invalid; + return NULL; + } + return addr; + } +} + +#endif // !_WINDOWS && !__APPLE__ diff --git a/src/share/vm/utilities/elfFuncDescTable.hpp b/src/share/vm/utilities/elfFuncDescTable.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/elfFuncDescTable.hpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2013 SAP AG. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP +#define SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP + +#if !defined(_WINDOWS) && !defined(__APPLE__) + + +#include "memory/allocation.hpp" +#include "utilities/decoder.hpp" +#include "utilities/elfFile.hpp" + +/* + +On PowerPC-64 (and other architectures like for example IA64) a pointer to a +function is not just a plain code address, but instead a pointer to a so called +function descriptor (which is simply a structure containing 3 pointers). +This fact is also reflected in the ELF ABI for PowerPC-64. + +On architectures like x86 or SPARC, the ELF symbol table contains the start +address and size of an object. So for example for a function object (i.e. type +'STT_FUNC') the symbol table's 'st_value' and 'st_size' fields directly +represent the starting address and size of that function. On PPC64 however, the +symbol table's 'st_value' field only contains an index into another, PPC64 +specific '.opd' (official procedure descriptors) section, while the 'st_size' +field still holds the size of the corresponding function. In order to get the +actual start address of a function, it is necessary to read the corresponding +function descriptor entry in the '.opd' section at the corresponding index and +extract the start address from there. + +That's exactly what this 'ElfFuncDescTable' class is used for. If the HotSpot +runs on a PPC64 machine, and the corresponding ELF files contains an '.opd' +section (which is actually mandatory on PPC64) it will be read into an object +of type 'ElfFuncDescTable' just like the string and symbol table sections. +Later on, during symbol lookup in 'ElfSymbolTable::lookup()' this function +descriptor table will be used if available to find the real function address. + +All this is how things work today (2013) on contemporary Linux distributions +(i.e. SLES 10) and new version of GCC (i.e. > 4.0). However there is a history, +and it goes like this: + +In SLES 9 times (sometimes before GCC 3.4) gcc/ld on PPC64 generated two +entries in the symbol table for every function. The value of the symbol with +the name of the function was the address of the function descriptor while the +dot '.' prefixed name was reserved to hold the actual address of that function +(http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES). + +For a C-function 'foo' this resulted in two symbol table entries like this +(extracted from the output of 'readelf -a '): + +Section Headers: + [ 9] .text PROGBITS 0000000000000a20 00000a20 + 00000000000005a0 0000000000000000 AX 0 0 16 + [21] .opd PROGBITS 00000000000113b8 000013b8 + 0000000000000138 0000000000000000 WA 0 0 8 + +Symbol table '.symtab' contains 86 entries: + Num: Value Size Type Bind Vis Ndx Name + 76: 00000000000114c0 24 FUNC GLOBAL DEFAULT 21 foo + 78: 0000000000000bb0 76 FUNC GLOBAL DEFAULT 9 .foo + +You can see now that the '.foo' entry actually points into the '.text' segment +('Ndx'=9) and its value and size fields represent the functions actual address +and size. On the other hand, the entry for plain 'foo' points into the '.opd' +section ('Ndx'=21) and its value and size fields are the index into the '.opd' +section and the size of the corresponding '.opd' section entry (3 pointers on +PPC64). + +These so called 'dot symbols' were dropped around gcc 3.4 from GCC and BINUTILS, +see http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html. +But nevertheless it may still be necessary to support both formats because we +either run on an old system or because it is possible at any time that functions +appear in the stack trace which come from old-style libraries. + +Therefore we not only have to check for the presence of the function descriptor +table during symbol lookup in 'ElfSymbolTable::lookup()'. We additionally have +to check that the symbol table entry references the '.opd' section. Only in +that case we can resolve the actual function address from there. Otherwise we +use the plain 'st_value' field from the symbol table as function address. This +way we can also lookup the symbols in old-style ELF libraries (although we get +the 'dotted' versions in that case). However, if present, the 'dot' will be +conditionally removed on PPC64 from the symbol in 'ElfDecoder::demangle()' in +decoder_linux.cpp. + +Notice that we can not reliably get the function address from old-style +libraries because the 'st_value' field of the symbol table entries which point +into the '.opd' section denote the size of the corresponding '.opd' entry and +not that of the corresponding function. This has changed for the symbol table +entries in new-style libraries as described at the beginning of this +documentation. + +*/ + +class ElfFuncDescTable: public CHeapObj { + friend class ElfFile; + public: + ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index); + ~ElfFuncDescTable(); + + // return the function address for the function descriptor at 'index' or NULL on error + address lookup(Elf_Word index); + + int get_index() { return m_index; }; + + NullDecoder::decoder_status get_status() { return m_status; }; + + protected: + // holds the complete function descriptor section if + // we can allocate enough memory + address* m_funcDescs; + + // file contains string table + FILE* m_file; + + // section header + Elf_Shdr m_shdr; + + // The section index of this function descriptor (i.e. '.opd') section in the ELF file + int m_index; + + NullDecoder::decoder_status m_status; +}; + +#endif // !_WINDOWS && !__APPLE__ + +#endif // SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP diff --git a/src/share/vm/utilities/elfStringTable.cpp b/src/share/vm/utilities/elfStringTable.cpp --- a/src/share/vm/utilities/elfStringTable.cpp +++ b/src/share/vm/utilities/elfStringTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,4 +87,4 @@ } } -#endif // _WINDOWS +#endif // !_WINDOWS && !__APPLE__ diff --git a/src/share/vm/utilities/elfStringTable.hpp b/src/share/vm/utilities/elfStringTable.hpp --- a/src/share/vm/utilities/elfStringTable.hpp +++ b/src/share/vm/utilities/elfStringTable.hpp @@ -70,6 +70,6 @@ NullDecoder::decoder_status m_status; }; -#endif // _WINDOWS and _APPLE +#endif // !_WINDOWS && !__APPLE__ #endif // SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP diff --git a/src/share/vm/utilities/elfSymbolTable.cpp b/src/share/vm/utilities/elfSymbolTable.cpp --- a/src/share/vm/utilities/elfSymbolTable.cpp +++ b/src/share/vm/utilities/elfSymbolTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #if !defined(_WINDOWS) && !defined(__APPLE__) #include "memory/allocation.inline.hpp" +#include "utilities/elfFuncDescTable.hpp" #include "utilities/elfSymbolTable.hpp" ElfSymbolTable::ElfSymbolTable(FILE* file, Elf_Shdr shdr) { @@ -68,7 +69,7 @@ } } -bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) { +bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable) { assert(stringtableIndex, "null string table index pointer"); assert(posIndex, "null string table offset pointer"); assert(offset, "null offset pointer"); @@ -77,19 +78,25 @@ return false; } - address pc = 0; size_t sym_size = sizeof(Elf_Sym); assert((m_shdr.sh_size % sym_size) == 0, "check size"); int count = m_shdr.sh_size / sym_size; if (m_symbols != NULL) { for (int index = 0; index < count; index ++) { if (STT_FUNC == ELF_ST_TYPE(m_symbols[index].st_info)) { - address sym_addr = (address)m_symbols[index].st_value; - if (sym_addr < addr && (addr - sym_addr) < *offset) { - pc = (address)m_symbols[index].st_value; - *offset = (int)(addr - pc); + Elf_Word st_size = m_symbols[index].st_size; + address sym_addr; + if (funcDescTable != NULL && funcDescTable->get_index() == m_symbols[index].st_shndx) { + // We need to go another step trough the function descriptor table (currently PPC64 only) + sym_addr = funcDescTable->lookup(m_symbols[index].st_value); + } else { + sym_addr = (address)m_symbols[index].st_value; + } + if (sym_addr <= addr && (Elf_Word)(addr - sym_addr) < st_size) { + *offset = (int)(addr - sym_addr); *posIndex = m_symbols[index].st_name; *stringtableIndex = m_shdr.sh_link; + return true; } } } @@ -105,12 +112,19 @@ for (int index = 0; index < count; index ++) { if (fread(&sym, sym_size, 1, m_file) == 1) { if (STT_FUNC == ELF_ST_TYPE(sym.st_info)) { - address sym_addr = (address)sym.st_value; - if (sym_addr < addr && (addr - sym_addr) < *offset) { - pc = (address)sym.st_value; - *offset = (int)(addr - pc); + Elf_Word st_size = sym.st_size; + address sym_addr; + if (funcDescTable != NULL && funcDescTable->get_index() == sym.st_shndx) { + // We need to go another step trough the function descriptor table (currently PPC64 only) + sym_addr = funcDescTable->lookup(sym.st_value); + } else { + sym_addr = (address)sym.st_value; + } + if (sym_addr <= addr && (Elf_Word)(addr - sym_addr) < st_size) { + *offset = (int)(addr - sym_addr); *posIndex = sym.st_name; *stringtableIndex = m_shdr.sh_link; + return true; } } } else { @@ -123,4 +137,4 @@ return true; } -#endif // _WINDOWS +#endif // !_WINDOWS && !__APPLE__ diff --git a/src/share/vm/utilities/elfSymbolTable.hpp b/src/share/vm/utilities/elfSymbolTable.hpp --- a/src/share/vm/utilities/elfSymbolTable.hpp +++ b/src/share/vm/utilities/elfSymbolTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ ~ElfSymbolTable(); // search the symbol that is nearest to the specified address. - bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset); + bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable); NullDecoder::decoder_status get_status() { return m_status; }; @@ -65,6 +65,6 @@ NullDecoder::decoder_status m_status; }; -#endif // _WINDOWS and _APPLE +#endif // !_WINDOWS and !__APPLE__ #endif // SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP