1/*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2013 SAP SE. 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_UTILITIES_ELFFUNCDESCTABLE_HPP
27#define SHARE_UTILITIES_ELFFUNCDESCTABLE_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
38On PowerPC-64 (and other architectures like for example IA64) a pointer to a
39function is not just a plain code address, but instead a pointer to a so called
40function descriptor (which is simply a structure containing 3 pointers).
41This fact is also reflected in the ELF ABI for PowerPC-64.
42
43On architectures like x86 or SPARC, the ELF symbol table contains the start
44address 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
46represent the starting address and size of that function. On PPC64 however, the
47symbol table's 'st_value' field only contains an index into another, PPC64
48specific '.opd' (official procedure descriptors) section, while the 'st_size'
49field still holds the size of the corresponding function. In order to get the
50actual start address of a function, it is necessary to read the corresponding
51function descriptor entry in the '.opd' section at the corresponding index and
52extract the start address from there.
53
54That's exactly what this 'ElfFuncDescTable' class is used for. If the HotSpot
55runs on a PPC64 machine, and the corresponding ELF files contains an '.opd'
56section (which is actually mandatory on PPC64) it will be read into an object
57of type 'ElfFuncDescTable' just like the string and symbol table sections.
58Later on, during symbol lookup in 'ElfSymbolTable::lookup()' this function
59descriptor table will be used if available to find the real function address.
60
61All 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,
63and it goes like this:
64
65In SLES 9 times (sometimes before GCC 3.4) gcc/ld on PPC64 generated two
66entries in the symbol table for every function. The value of the symbol with
67the name of the function was the address of the function descriptor while the
68dot '.' 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
71For a C-function 'foo' this resulted in two symbol table entries like this
72(extracted from the output of 'readelf -a <lib.so>'):
73
74Section 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
80Symbol 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
85You 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
87and size. On the other hand, the entry for plain 'foo' points into the '.opd'
88section ('Ndx'=21) and its value and size fields are the index into the '.opd'
89section and the size of the corresponding '.opd' section entry (3 pointers on
90PPC64).
91
92These so called 'dot symbols' were dropped around gcc 3.4 from GCC and BINUTILS,
93see http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html.
94But nevertheless it may still be necessary to support both formats because we
95either run on an old system or because it is possible at any time that functions
96appear in the stack trace which come from old-style libraries.
97
98Therefore we not only have to check for the presence of the function descriptor
99table during symbol lookup in 'ElfSymbolTable::lookup()'. We additionally have
100to check that the symbol table entry references the '.opd' section. Only in
101that case we can resolve the actual function address from there. Otherwise we
102use the plain 'st_value' field from the symbol table as function address. This
103way we can also lookup the symbols in old-style ELF libraries (although we get
104the 'dotted' versions in that case). However, if present, the 'dot' will be
105conditionally removed on PPC64 from the symbol in 'ElfDecoder::demangle()' in
106decoder_linux.cpp.
107
108Notice that we can not reliably get the function address from old-style
109libraries because the 'st_value' field of the symbol table entries which point
110into the '.opd' section denote the size of the corresponding '.opd' entry and
111not that of the corresponding function. This has changed for the symbol table
112entries in new-style libraries as described at the beginning of this
113documentation.
114
115*/
116
117class ElfFuncDescTable: public CHeapObj<mtInternal> {
118 friend class ElfFile;
119private:
120 // holds the complete function descriptor section if
121 // we can allocate enough memory
122 ElfSection _section;
123
124 // file contains string table
125 FILE* const _file;
126
127 // The section index of this function descriptor (i.e. '.opd') section in the ELF file
128 const int _index;
129
130 NullDecoder::decoder_status _status;
131public:
132 ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index);
133 ~ElfFuncDescTable();
134
135 // return the function address for the function descriptor at 'index' or NULL on error
136 address lookup(Elf_Word index);
137
138 int get_index() const { return _index; };
139
140 NullDecoder::decoder_status get_status() const { return _status; };
141
142private:
143 address* cached_func_descs() const { return (address*)_section.section_data(); }
144};
145
146#endif // !_WINDOWS && !__APPLE__
147
148#endif // SHARE_UTILITIES_ELFFUNCDESCTABLE_HPP
149