Mercurial > hg > truffle
comparison src/share/vm/utilities/elfFile.cpp @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | 89152779163c e5e8aa897002 |
children |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
32 #include <new> | 32 #include <new> |
33 | 33 |
34 #include "memory/allocation.inline.hpp" | 34 #include "memory/allocation.inline.hpp" |
35 #include "utilities/decoder.hpp" | 35 #include "utilities/decoder.hpp" |
36 #include "utilities/elfFile.hpp" | 36 #include "utilities/elfFile.hpp" |
37 #include "utilities/elfFuncDescTable.hpp" | |
37 #include "utilities/elfStringTable.hpp" | 38 #include "utilities/elfStringTable.hpp" |
38 #include "utilities/elfSymbolTable.hpp" | 39 #include "utilities/elfSymbolTable.hpp" |
39 | 40 |
40 | 41 |
41 ElfFile::ElfFile(const char* filepath) { | 42 ElfFile::ElfFile(const char* filepath) { |
42 assert(filepath, "null file path"); | 43 assert(filepath, "null file path"); |
43 memset(&m_elfHdr, 0, sizeof(m_elfHdr)); | 44 memset(&m_elfHdr, 0, sizeof(m_elfHdr)); |
44 m_string_tables = NULL; | 45 m_string_tables = NULL; |
45 m_symbol_tables = NULL; | 46 m_symbol_tables = NULL; |
47 m_funcDesc_table = NULL; | |
46 m_next = NULL; | 48 m_next = NULL; |
47 m_status = NullDecoder::no_error; | 49 m_status = NullDecoder::no_error; |
48 | 50 |
49 int len = strlen(filepath) + 1; | 51 int len = strlen(filepath) + 1; |
50 m_filepath = (const char*)os::malloc(len * sizeof(char), mtInternal); | 52 m_filepath = (const char*)os::malloc(len * sizeof(char), mtInternal); |
117 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { | 119 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { |
118 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { | 120 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { |
119 m_status = NullDecoder::file_invalid; | 121 m_status = NullDecoder::file_invalid; |
120 return false; | 122 return false; |
121 } | 123 } |
122 // string table | |
123 if (shdr.sh_type == SHT_STRTAB) { | 124 if (shdr.sh_type == SHT_STRTAB) { |
125 // string tables | |
124 ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); | 126 ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index); |
125 if (table == NULL) { | 127 if (table == NULL) { |
126 m_status = NullDecoder::out_of_memory; | 128 m_status = NullDecoder::out_of_memory; |
127 return false; | 129 return false; |
128 } | 130 } |
129 add_string_table(table); | 131 add_string_table(table); |
130 } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { | 132 } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { |
133 // symbol tables | |
131 ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); | 134 ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr); |
132 if (table == NULL) { | 135 if (table == NULL) { |
133 m_status = NullDecoder::out_of_memory; | 136 m_status = NullDecoder::out_of_memory; |
134 return false; | 137 return false; |
135 } | 138 } |
136 add_symbol_table(table); | 139 add_symbol_table(table); |
137 } | 140 } |
138 } | 141 } |
142 | |
143 #if defined(PPC64) && !defined(ABI_ELFv2) | |
144 // Now read the .opd section wich contains the PPC64 function descriptor table. | |
145 // The .opd section is only available on PPC64 (see for example: | |
146 // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html) | |
147 // so this code should do no harm on other platforms but because of performance reasons we only | |
148 // execute it on PPC64 platforms. | |
149 // Notice that we can only find the .opd section after we have successfully read in the string | |
150 // tables in the previous loop, because we need to query the name of each section which is | |
151 // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx). | |
152 | |
153 // Reset the file pointer | |
154 if (fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) { | |
155 m_status = NullDecoder::file_invalid; | |
156 return false; | |
157 } | |
158 for (int index = 0; index < m_elfHdr.e_shnum; index ++) { | |
159 if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) { | |
160 m_status = NullDecoder::file_invalid; | |
161 return false; | |
162 } | |
163 if (m_elfHdr.e_shstrndx != SHN_UNDEF && shdr.sh_type == SHT_PROGBITS) { | |
164 ElfStringTable* string_table = get_string_table(m_elfHdr.e_shstrndx); | |
165 if (string_table == NULL) { | |
166 m_status = NullDecoder::file_invalid; | |
167 return false; | |
168 } | |
169 char buf[8]; // '8' is enough because we only want to read ".opd" | |
170 if (string_table->string_at(shdr.sh_name, buf, sizeof(buf)) && !strncmp(".opd", buf, 4)) { | |
171 m_funcDesc_table = new (std::nothrow) ElfFuncDescTable(m_file, shdr, index); | |
172 if (m_funcDesc_table == NULL) { | |
173 m_status = NullDecoder::out_of_memory; | |
174 return false; | |
175 } | |
176 break; | |
177 } | |
178 } | |
179 } | |
180 #endif | |
181 | |
139 } | 182 } |
140 return true; | 183 return true; |
141 } | 184 } |
142 | 185 |
143 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { | 186 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { |
149 int string_table_index; | 192 int string_table_index; |
150 int pos_in_string_table; | 193 int pos_in_string_table; |
151 int off = INT_MAX; | 194 int off = INT_MAX; |
152 bool found_symbol = false; | 195 bool found_symbol = false; |
153 while (symbol_table != NULL) { | 196 while (symbol_table != NULL) { |
154 if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) { | 197 if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, m_funcDesc_table)) { |
155 found_symbol = true; | 198 found_symbol = true; |
199 break; | |
156 } | 200 } |
157 symbol_table = symbol_table->m_next; | 201 symbol_table = symbol_table->m_next; |
158 } | 202 } |
159 if (!found_symbol) return false; | 203 if (!found_symbol) return false; |
160 | 204 |
219 } | 263 } |
220 return false; | 264 return false; |
221 } | 265 } |
222 #endif | 266 #endif |
223 | 267 |
224 #endif // _WINDOWS | 268 #endif // !_WINDOWS && !__APPLE__ |