author | redestad |
Thu, 20 Dec 2018 19:44:08 +0100 | |
changeset 53091 | 5bf5b773fc41 |
parent 51334 | cc2c79d22508 |
permissions | -rw-r--r-- |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
1 |
/* |
48975 | 2 |
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
4 |
* |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
7 |
* published by the Free Software Foundation. |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
8 |
* |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
13 |
* accompanied this code). |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
14 |
* |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
15 |
* You should have received a copy of the GNU General Public License version |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
18 |
* |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
20 |
* or visit www.oracle.com if you need additional information or have any |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
21 |
* questions. |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
22 |
* |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
23 |
*/ |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
24 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
25 |
#include "precompiled.hpp" |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
26 |
|
10565 | 27 |
#if !defined(_WINDOWS) && !defined(__APPLE__) |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
28 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
29 |
#include <string.h> |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
30 |
#include <stdio.h> |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
31 |
#include <limits.h> |
9403
6f3c6231c20a
7036747: 7017009 reappeared, problem with ElfStringTable
zgu
parents:
7447
diff
changeset
|
32 |
#include <new> |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
33 |
|
48975 | 34 |
#include "logging/log.hpp" |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
35 |
#include "memory/allocation.inline.hpp" |
48975 | 36 |
#include "memory/resourceArea.hpp" |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
37 |
#include "utilities/decoder.hpp" |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
38 |
#include "utilities/elfFile.hpp" |
22857
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
39 |
#include "utilities/elfFuncDescTable.hpp" |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
40 |
#include "utilities/elfStringTable.hpp" |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
41 |
#include "utilities/elfSymbolTable.hpp" |
48975 | 42 |
#include "utilities/ostream.hpp" |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
43 |
|
48975 | 44 |
// For test only, disable elf section cache and force to read from file directly. |
45 |
bool ElfFile::_do_not_cache_elf_section = false; |
|
46 |
||
47 |
ElfSection::ElfSection(FILE* fd, const Elf_Shdr& hdr) : _section_data(NULL) { |
|
48 |
_stat = load_section(fd, hdr); |
|
49 |
} |
|
50 |
||
51 |
ElfSection::~ElfSection() { |
|
52 |
if (_section_data != NULL) { |
|
53 |
os::free(_section_data); |
|
54 |
} |
|
55 |
} |
|
56 |
||
57 |
NullDecoder::decoder_status ElfSection::load_section(FILE* const fd, const Elf_Shdr& shdr) { |
|
58 |
memcpy((void*)&_section_hdr, (const void*)&shdr, sizeof(shdr)); |
|
59 |
||
60 |
if (ElfFile::_do_not_cache_elf_section) { |
|
61 |
log_debug(decoder)("Elf section cache is disabled"); |
|
62 |
return NullDecoder::no_error; |
|
63 |
} |
|
64 |
||
65 |
_section_data = os::malloc(shdr.sh_size, mtInternal); |
|
66 |
// No enough memory for caching. It is okay, we can try to read from |
|
67 |
// file instead. |
|
68 |
if (_section_data == NULL) return NullDecoder::no_error; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
69 |
|
48975 | 70 |
MarkedFileReader mfd(fd); |
71 |
if (mfd.has_mark() && |
|
72 |
mfd.set_position(shdr.sh_offset) && |
|
73 |
mfd.read(_section_data, shdr.sh_size)) { |
|
74 |
return NullDecoder::no_error; |
|
75 |
} else { |
|
76 |
os::free(_section_data); |
|
77 |
_section_data = NULL; |
|
78 |
return NullDecoder::file_invalid; |
|
79 |
} |
|
80 |
} |
|
81 |
||
82 |
bool FileReader::read(void* buf, size_t size) { |
|
83 |
assert(buf != NULL, "no buffer"); |
|
84 |
assert(size > 0, "no space"); |
|
85 |
return fread(buf, size, 1, _fd) == 1; |
|
86 |
} |
|
87 |
||
88 |
int FileReader::read_buffer(void* buf, size_t size) { |
|
89 |
assert(buf != NULL, "no buffer"); |
|
90 |
assert(size > 0, "no space"); |
|
91 |
return fread(buf, 1, size, _fd); |
|
92 |
} |
|
93 |
||
94 |
bool FileReader::set_position(long offset) { |
|
95 |
return fseek(_fd, offset, SEEK_SET) == 0; |
|
96 |
} |
|
97 |
||
98 |
MarkedFileReader::MarkedFileReader(FILE* fd) : FileReader(fd) { |
|
99 |
_marked_pos = ftell(fd); |
|
100 |
} |
|
101 |
||
102 |
MarkedFileReader::~MarkedFileReader() { |
|
103 |
if (_marked_pos != -1) { |
|
104 |
set_position(_marked_pos); |
|
105 |
} |
|
106 |
} |
|
107 |
||
108 |
ElfFile::ElfFile(const char* filepath) : |
|
51334
cc2c79d22508
8208671: Runtime, JFR, Serviceability changes to allow enabling -Wreorder
tschatzl
parents:
48975
diff
changeset
|
109 |
_next(NULL), _filepath(NULL), _file(NULL), |
cc2c79d22508
8208671: Runtime, JFR, Serviceability changes to allow enabling -Wreorder
tschatzl
parents:
48975
diff
changeset
|
110 |
_symbol_tables(NULL), _string_tables(NULL), _shdr_string_table(NULL), _funcDesc_table(NULL), |
cc2c79d22508
8208671: Runtime, JFR, Serviceability changes to allow enabling -Wreorder
tschatzl
parents:
48975
diff
changeset
|
111 |
_status(NullDecoder::no_error) { |
48975 | 112 |
memset(&_elfHdr, 0, sizeof(_elfHdr)); |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
113 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
114 |
int len = strlen(filepath) + 1; |
48975 | 115 |
_filepath = (char*)os::malloc(len * sizeof(char), mtInternal); |
116 |
if (_filepath == NULL) { |
|
117 |
_status = NullDecoder::out_of_memory; |
|
118 |
return; |
|
119 |
} |
|
120 |
strcpy(_filepath, filepath); |
|
121 |
||
122 |
_status = parse_elf(filepath); |
|
123 |
||
124 |
// we no longer need section header string table |
|
125 |
if (_shdr_string_table != NULL) { |
|
126 |
delete _shdr_string_table; |
|
127 |
_shdr_string_table = NULL; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
128 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
129 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
130 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
131 |
ElfFile::~ElfFile() { |
48975 | 132 |
if (_shdr_string_table != NULL) { |
133 |
delete _shdr_string_table; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
134 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
135 |
|
48975 | 136 |
cleanup_tables(); |
137 |
||
138 |
if (_file != NULL) { |
|
139 |
fclose(_file); |
|
140 |
} |
|
141 |
||
142 |
if (_filepath != NULL) { |
|
143 |
os::free((void*)_filepath); |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
144 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
145 |
|
48975 | 146 |
if (_next != NULL) { |
147 |
delete _next; |
|
148 |
} |
|
149 |
} |
|
150 |
||
151 |
void ElfFile::cleanup_tables() { |
|
152 |
if (_string_tables != NULL) { |
|
153 |
delete _string_tables; |
|
154 |
_string_tables = NULL; |
|
155 |
} |
|
156 |
||
157 |
if (_symbol_tables != NULL) { |
|
158 |
delete _symbol_tables; |
|
159 |
_symbol_tables = NULL; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
160 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
161 |
|
48975 | 162 |
if (_funcDesc_table != NULL) { |
163 |
delete _funcDesc_table; |
|
164 |
_funcDesc_table = NULL; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
165 |
} |
48975 | 166 |
} |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
167 |
|
48975 | 168 |
NullDecoder::decoder_status ElfFile::parse_elf(const char* filepath) { |
169 |
assert(filepath, "null file path"); |
|
170 |
||
171 |
_file = fopen(filepath, "r"); |
|
172 |
if (_file != NULL) { |
|
173 |
return load_tables(); |
|
174 |
} else { |
|
175 |
return NullDecoder::file_not_found; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
176 |
} |
48975 | 177 |
} |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
178 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
179 |
//Check elf header to ensure the file is valid. |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
180 |
bool ElfFile::is_elf_file(Elf_Ehdr& hdr) { |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
181 |
return (ELFMAG0 == hdr.e_ident[EI_MAG0] && |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
182 |
ELFMAG1 == hdr.e_ident[EI_MAG1] && |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
183 |
ELFMAG2 == hdr.e_ident[EI_MAG2] && |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
184 |
ELFMAG3 == hdr.e_ident[EI_MAG3] && |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
185 |
ELFCLASSNONE != hdr.e_ident[EI_CLASS] && |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
186 |
ELFDATANONE != hdr.e_ident[EI_DATA]); |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
187 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
188 |
|
48975 | 189 |
NullDecoder::decoder_status ElfFile::load_tables() { |
190 |
assert(_file, "file not open"); |
|
191 |
assert(!NullDecoder::is_error(_status), "already in error"); |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
192 |
|
48975 | 193 |
FileReader freader(fd()); |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
194 |
// read elf file header |
48975 | 195 |
if (!freader.read(&_elfHdr, sizeof(_elfHdr))) { |
196 |
return NullDecoder::file_invalid; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
197 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
198 |
|
48975 | 199 |
// Check signature |
200 |
if (!is_elf_file(_elfHdr)) { |
|
201 |
return NullDecoder::file_invalid; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
202 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
203 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
204 |
// walk elf file's section headers, and load string tables |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
205 |
Elf_Shdr shdr; |
48975 | 206 |
if (!freader.set_position(_elfHdr.e_shoff)) { |
207 |
return NullDecoder::file_invalid; |
|
208 |
} |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
209 |
|
48975 | 210 |
for (int index = 0; index < _elfHdr.e_shnum; index ++) { |
211 |
if (!freader.read(&shdr, sizeof(shdr))) { |
|
212 |
return NullDecoder::file_invalid; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
213 |
} |
22857
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
214 |
|
48975 | 215 |
if (shdr.sh_type == SHT_STRTAB) { |
216 |
// string tables |
|
217 |
ElfStringTable* table = new (std::nothrow) ElfStringTable(fd(), shdr, index); |
|
218 |
if (table == NULL) { |
|
219 |
return NullDecoder::out_of_memory; |
|
220 |
} |
|
221 |
if (index == _elfHdr.e_shstrndx) { |
|
222 |
assert(_shdr_string_table == NULL, "Only set once"); |
|
223 |
_shdr_string_table = table; |
|
224 |
} else { |
|
225 |
add_string_table(table); |
|
226 |
} |
|
227 |
} else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { |
|
228 |
// symbol tables |
|
229 |
ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(fd(), shdr); |
|
230 |
if (table == NULL) { |
|
231 |
return NullDecoder::out_of_memory; |
|
232 |
} |
|
233 |
add_symbol_table(table); |
|
22857
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
234 |
} |
48975 | 235 |
} |
236 |
#if defined(PPC64) && !defined(ABI_ELFv2) |
|
237 |
// Now read the .opd section wich contains the PPC64 function descriptor table. |
|
238 |
// The .opd section is only available on PPC64 (see for example: |
|
239 |
// http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html) |
|
240 |
// so this code should do no harm on other platforms but because of performance reasons we only |
|
241 |
// execute it on PPC64 platforms. |
|
242 |
// Notice that we can only find the .opd section after we have successfully read in the string |
|
243 |
// tables in the previous loop, because we need to query the name of each section which is |
|
244 |
// contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx). |
|
245 |
||
246 |
// Reset the file pointer |
|
247 |
int sect_index = section_by_name(".opd", shdr); |
|
248 |
||
249 |
if (sect_index == -1) { |
|
250 |
return NullDecoder::file_invalid; |
|
251 |
} |
|
252 |
||
253 |
_funcDesc_table = new (std::nothrow) ElfFuncDescTable(_file, shdr, sect_index); |
|
254 |
if (_funcDesc_table == NULL) { |
|
255 |
return NullDecoder::out_of_memory; |
|
256 |
} |
|
257 |
#endif |
|
258 |
return NullDecoder::no_error; |
|
259 |
} |
|
260 |
||
261 |
int ElfFile::section_by_name(const char* name, Elf_Shdr& hdr) { |
|
262 |
assert(name != NULL, "No section name"); |
|
263 |
size_t len = strlen(name) + 1; |
|
264 |
ResourceMark rm; |
|
265 |
char* buf = NEW_RESOURCE_ARRAY(char, len); |
|
266 |
if (buf == NULL) { |
|
267 |
return -1; |
|
268 |
} |
|
269 |
||
270 |
assert(_shdr_string_table != NULL, "Section header string table should be loaded"); |
|
271 |
ElfStringTable* const table = _shdr_string_table; |
|
272 |
MarkedFileReader mfd(fd()); |
|
273 |
if (!mfd.has_mark() || !mfd.set_position(_elfHdr.e_shoff)) return -1; |
|
274 |
||
275 |
int sect_index = -1; |
|
276 |
for (int index = 0; index < _elfHdr.e_shnum; index ++) { |
|
277 |
if (!mfd.read((void*)&hdr, sizeof(hdr))) { |
|
278 |
break; |
|
279 |
} |
|
280 |
if (table->string_at(hdr.sh_name, buf, len)) { |
|
281 |
if (strncmp(buf, name, len) == 0) { |
|
282 |
sect_index = index; |
|
283 |
break; |
|
22857
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
284 |
} |
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
285 |
} |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
286 |
} |
48975 | 287 |
return sect_index; |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
288 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
289 |
|
11483 | 290 |
bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
291 |
// something already went wrong, just give up |
48975 | 292 |
if (NullDecoder::is_error(_status)) { |
11483 | 293 |
return false; |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
294 |
} |
48975 | 295 |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
296 |
int string_table_index; |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
297 |
int pos_in_string_table; |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
298 |
int off = INT_MAX; |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
299 |
bool found_symbol = false; |
48975 | 300 |
ElfSymbolTable* symbol_table = _symbol_tables; |
301 |
||
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
302 |
while (symbol_table != NULL) { |
48975 | 303 |
if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, _funcDesc_table)) { |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
304 |
found_symbol = true; |
22857
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
305 |
break; |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
306 |
} |
48975 | 307 |
symbol_table = symbol_table->next(); |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
308 |
} |
48975 | 309 |
if (!found_symbol) { |
310 |
return false; |
|
311 |
} |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
312 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
313 |
ElfStringTable* string_table = get_string_table(string_table_index); |
11483 | 314 |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
315 |
if (string_table == NULL) { |
48975 | 316 |
_status = NullDecoder::file_invalid; |
11483 | 317 |
return false; |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
318 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
319 |
if (offset) *offset = off; |
11483 | 320 |
|
321 |
return string_table->string_at(pos_in_string_table, buf, buflen); |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
322 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
323 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
324 |
void ElfFile::add_symbol_table(ElfSymbolTable* table) { |
48975 | 325 |
if (_symbol_tables == NULL) { |
326 |
_symbol_tables = table; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
327 |
} else { |
48975 | 328 |
table->set_next(_symbol_tables); |
329 |
_symbol_tables = table; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
330 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
331 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
332 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
333 |
void ElfFile::add_string_table(ElfStringTable* table) { |
48975 | 334 |
if (_string_tables == NULL) { |
335 |
_string_tables = table; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
336 |
} else { |
48975 | 337 |
table->set_next(_string_tables); |
338 |
_string_tables = table; |
|
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
339 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
340 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
341 |
|
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
342 |
ElfStringTable* ElfFile::get_string_table(int index) { |
48975 | 343 |
ElfStringTable* p = _string_tables; |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
344 |
while (p != NULL) { |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
345 |
if (p->index() == index) return p; |
48975 | 346 |
p = p->next(); |
7447
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
347 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
348 |
return NULL; |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
349 |
} |
32c42d627f41
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
diff
changeset
|
350 |
|
22857
2167396cfc83
8019929: PPC64 (part 107): Extend ELF-decoder to support PPC64 function descriptor tables
simonis
parents:
15926
diff
changeset
|
351 |
#endif // !_WINDOWS && !__APPLE__ |