1/*
2 * Copyright (c) 1997, 2018, 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#include "precompiled.hpp"
27
28#if !defined(_WINDOWS) && !defined(__APPLE__)
29
30#include "memory/allocation.inline.hpp"
31#include "utilities/elfFuncDescTable.hpp"
32
33ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) :
34 _section(file, shdr), _file(file), _index(index) {
35 assert(file, "null file handle");
36 // The actual function address (i.e. function entry point) is always the
37 // first value in the function descriptor (on IA64 and PPC64 they look as follows):
38 // PPC64: [function entry point, TOC pointer, environment pointer]
39 // IA64 : [function entry point, GP (global pointer) value]
40 // Unfortunately 'shdr.sh_entsize' doesn't always seem to contain this size (it's zero on PPC64) so we can't assert
41 // assert(IA64_ONLY(2) PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries");
42
43 _status = _section.status();
44}
45
46ElfFuncDescTable::~ElfFuncDescTable() {
47}
48
49address ElfFuncDescTable::lookup(Elf_Word index) {
50 if (NullDecoder::is_error(_status)) {
51 return NULL;
52 }
53
54 address* func_descs = cached_func_descs();
55 const Elf_Shdr* shdr = _section.section_header();
56 if (!(shdr->sh_size > 0 && shdr->sh_addr <= index && index <= shdr->sh_addr + shdr->sh_size)) {
57 // don't put the whole decoder in error mode if we just tried a wrong index
58 return NULL;
59 }
60
61 if (func_descs != NULL) {
62 return func_descs[(index - shdr->sh_addr) / sizeof(address)];
63 } else {
64 MarkedFileReader mfd(_file);
65 address addr;
66 if (!mfd.has_mark() ||
67 !mfd.set_position(shdr->sh_offset + index - shdr->sh_addr) ||
68 !mfd.read((void*)&addr, sizeof(addr))) {
69 _status = NullDecoder::file_invalid;
70 return NULL;
71 }
72 return addr;
73 }
74}
75
76#endif // !_WINDOWS && !__APPLE__
77