hotspot/src/share/vm/utilities/elfFuncDescTable.hpp
changeset 22857 2167396cfc83
child 35594 cc13089c6327
equal deleted inserted replaced
22856:03ad2cf18166 22857:2167396cfc83
       
     1 /*
       
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * Copyright 2012, 2013 SAP AG. All rights reserved.
       
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     5  *
       
     6  * This code is free software; you can redistribute it and/or modify it
       
     7  * under the terms of the GNU General Public License version 2 only, as
       
     8  * published by the Free Software Foundation.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  *
       
    24  */
       
    25 
       
    26 #ifndef SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP
       
    27 #define SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP
       
    28 
       
    29 #if !defined(_WINDOWS) && !defined(__APPLE__)
       
    30 
       
    31 
       
    32 #include "memory/allocation.hpp"
       
    33 #include "utilities/decoder.hpp"
       
    34 #include "utilities/elfFile.hpp"
       
    35 
       
    36 /*
       
    37 
       
    38 On PowerPC-64 (and other architectures like for example IA64) a pointer to a
       
    39 function is not just a plain code address, but instead a pointer to a so called
       
    40 function descriptor (which is simply a structure containing 3 pointers).
       
    41 This fact is also reflected in the ELF ABI for PowerPC-64.
       
    42 
       
    43 On architectures like x86 or SPARC, the ELF symbol table contains the start
       
    44 address and size of an object. So for example for a function object (i.e. type
       
    45 'STT_FUNC') the symbol table's 'st_value' and 'st_size' fields directly
       
    46 represent the starting address and size of that function. On PPC64 however, the
       
    47 symbol table's 'st_value' field only contains an index into another, PPC64
       
    48 specific '.opd' (official procedure descriptors) section, while the 'st_size'
       
    49 field still holds the size of the corresponding function. In order to get the
       
    50 actual start address of a function, it is necessary to read the corresponding
       
    51 function descriptor entry in the '.opd' section at the corresponding index and
       
    52 extract the start address from there.
       
    53 
       
    54 That's exactly what this 'ElfFuncDescTable' class is used for. If the HotSpot
       
    55 runs on a PPC64 machine, and the corresponding ELF files contains an '.opd'
       
    56 section (which is actually mandatory on PPC64) it will be read into an object
       
    57 of type 'ElfFuncDescTable' just like the string and symbol table sections.
       
    58 Later on, during symbol lookup in 'ElfSymbolTable::lookup()' this function
       
    59 descriptor table will be used if available to find the real function address.
       
    60 
       
    61 All this is how things work today (2013) on contemporary Linux distributions
       
    62 (i.e. SLES 10) and new version of GCC (i.e. > 4.0). However there is a history,
       
    63 and it goes like this:
       
    64 
       
    65 In SLES 9 times (sometimes before GCC 3.4) gcc/ld on PPC64 generated two
       
    66 entries in the symbol table for every function. The value of the symbol with
       
    67 the name of the function was the address of the function descriptor while the
       
    68 dot '.' prefixed name was reserved to hold the actual address of that function
       
    69 (http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES).
       
    70 
       
    71 For a C-function 'foo' this resulted in two symbol table entries like this
       
    72 (extracted from the output of 'readelf -a <lib.so>'):
       
    73 
       
    74 Section Headers:
       
    75   [ 9] .text             PROGBITS         0000000000000a20  00000a20
       
    76        00000000000005a0  0000000000000000  AX       0     0     16
       
    77   [21] .opd              PROGBITS         00000000000113b8  000013b8
       
    78        0000000000000138  0000000000000000  WA       0     0     8
       
    79 
       
    80 Symbol table '.symtab' contains 86 entries:
       
    81    Num:    Value          Size Type    Bind   Vis      Ndx Name
       
    82     76: 00000000000114c0    24 FUNC    GLOBAL DEFAULT   21 foo
       
    83     78: 0000000000000bb0    76 FUNC    GLOBAL DEFAULT    9 .foo
       
    84 
       
    85 You can see now that the '.foo' entry actually points into the '.text' segment
       
    86 ('Ndx'=9) and its value and size fields represent the functions actual address
       
    87 and size. On the other hand, the entry for plain 'foo' points into the '.opd'
       
    88 section ('Ndx'=21) and its value and size fields are the index into the '.opd'
       
    89 section and the size of the corresponding '.opd' section entry (3 pointers on
       
    90 PPC64).
       
    91 
       
    92 These so called 'dot symbols' were dropped around gcc 3.4 from GCC and BINUTILS,
       
    93 see http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html.
       
    94 But nevertheless it may still be necessary to support both formats because we
       
    95 either run on an old system or because it is possible at any time that functions
       
    96 appear in the stack trace which come from old-style libraries.
       
    97 
       
    98 Therefore we not only have to check for the presence of the function descriptor
       
    99 table during symbol lookup in 'ElfSymbolTable::lookup()'. We additionally have
       
   100 to check that the symbol table entry references the '.opd' section. Only in
       
   101 that case we can resolve the actual function address from there. Otherwise we
       
   102 use the plain 'st_value' field from the symbol table as function address. This
       
   103 way we can also lookup the symbols in old-style ELF libraries (although we get
       
   104 the 'dotted' versions in that case). However, if present, the 'dot' will be
       
   105 conditionally removed on PPC64 from the symbol in 'ElfDecoder::demangle()' in
       
   106 decoder_linux.cpp.
       
   107 
       
   108 Notice that we can not reliably get the function address from old-style
       
   109 libraries because the 'st_value' field of the symbol table entries which point
       
   110 into the '.opd' section denote the size of the corresponding '.opd' entry and
       
   111 not that of the corresponding function. This has changed for the symbol table
       
   112 entries in new-style libraries as described at the beginning of this
       
   113 documentation.
       
   114 
       
   115 */
       
   116 
       
   117 class ElfFuncDescTable: public CHeapObj<mtInternal> {
       
   118   friend class ElfFile;
       
   119  public:
       
   120   ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index);
       
   121   ~ElfFuncDescTable();
       
   122 
       
   123   // return the function address for the function descriptor at 'index' or NULL on error
       
   124   address lookup(Elf_Word index);
       
   125 
       
   126   int get_index() { return m_index; };
       
   127 
       
   128   NullDecoder::decoder_status get_status() { return m_status; };
       
   129 
       
   130  protected:
       
   131   // holds the complete function descriptor section if
       
   132   // we can allocate enough memory
       
   133   address*            m_funcDescs;
       
   134 
       
   135   // file contains string table
       
   136   FILE*               m_file;
       
   137 
       
   138   // section header
       
   139   Elf_Shdr            m_shdr;
       
   140 
       
   141   // The section index of this function descriptor (i.e. '.opd') section in the ELF file
       
   142   int                 m_index;
       
   143 
       
   144   NullDecoder::decoder_status  m_status;
       
   145 };
       
   146 
       
   147 #endif // !_WINDOWS && !__APPLE__
       
   148 
       
   149 #endif // SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP