1 /* 2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 27 #if !defined(_WINDOWS) && !defined(__APPLE__) 28 29 #include <string.h> 30 #include <stdio.h> 31 #include <limits.h> 32 #include <new> 33 34 #include "logging/log.hpp" 35 #include "memory/allocation.inline.hpp" 36 #include "memory/resourceArea.hpp" 37 #include "utilities/decoder.hpp" 38 #include "utilities/elfFile.hpp" 39 #include "utilities/elfFuncDescTable.hpp" 40 #include "utilities/elfStringTable.hpp" 41 #include "utilities/elfSymbolTable.hpp" 42 #include "utilities/ostream.hpp" 43 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; 69 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) : 109 _string_tables(NULL), _symbol_tables(NULL), _funcDesc_table(NULL), 110 _next(NULL), _status(NullDecoder::no_error), 111 _shdr_string_table(NULL), _file(NULL), _filepath(NULL) { 112 memset(&_elfHdr, 0, sizeof(_elfHdr)); 113 114 int len = strlen(filepath) + 1; 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; 128 } 129 } 130 131 ElfFile::~ElfFile() { 132 if (_shdr_string_table != NULL) { 133 delete _shdr_string_table; 134 } 135 136 cleanup_tables(); 137 138 if (_file != NULL) { 139 fclose(_file); 140 } 141 142 if (_filepath != NULL) { 143 os::free((void*)_filepath); 144 } 145 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; 160 } 161 162 if (_funcDesc_table != NULL) { 163 delete _funcDesc_table; 164 _funcDesc_table = NULL; 165 } 166 } 167 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; 176 } 177 } 178 179 //Check elf header to ensure the file is valid. 180 bool ElfFile::is_elf_file(Elf_Ehdr& hdr) { 181 return (ELFMAG0 == hdr.e_ident[EI_MAG0] && 182 ELFMAG1 == hdr.e_ident[EI_MAG1] && 183 ELFMAG2 == hdr.e_ident[EI_MAG2] && 184 ELFMAG3 == hdr.e_ident[EI_MAG3] && 185 ELFCLASSNONE != hdr.e_ident[EI_CLASS] && 186 ELFDATANONE != hdr.e_ident[EI_DATA]); 187 } 188 189 NullDecoder::decoder_status ElfFile::load_tables() { 190 assert(_file, "file not open"); 191 assert(!NullDecoder::is_error(_status), "already in error"); 192 193 FileReader freader(fd()); 194 // read elf file header 195 if (!freader.read(&_elfHdr, sizeof(_elfHdr))) { 196 return NullDecoder::file_invalid; 197 } 198 199 // Check signature 200 if (!is_elf_file(_elfHdr)) { 201 return NullDecoder::file_invalid; 202 } 203 204 // walk elf file's section headers, and load string tables 205 Elf_Shdr shdr; 206 if (!freader.set_position(_elfHdr.e_shoff)) { 207 return NullDecoder::file_invalid; 208 } 209 210 for (int index = 0; index < _elfHdr.e_shnum; index ++) { 211 if (!freader.read(&shdr, sizeof(shdr))) { 212 return NullDecoder::file_invalid; 213 } 214 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); 234 } 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; 284 } 285 } 286 } 287 return sect_index; 288 } 289 290 bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) { 291 // something already went wrong, just give up 292 if (NullDecoder::is_error(_status)) { 293 return false; 294 } 295 296 int string_table_index; 297 int pos_in_string_table; 298 int off = INT_MAX; 299 bool found_symbol = false; 300 ElfSymbolTable* symbol_table = _symbol_tables; 301 302 while (symbol_table != NULL) { 303 if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, _funcDesc_table)) { 304 found_symbol = true; 305 break; 306 } 307 symbol_table = symbol_table->next(); 308 } 309 if (!found_symbol) { 310 return false; 311 } 312 313 ElfStringTable* string_table = get_string_table(string_table_index); 314 315 if (string_table == NULL) { 316 _status = NullDecoder::file_invalid; 317 return false; 318 } 319 if (offset) *offset = off; 320 321 return string_table->string_at(pos_in_string_table, buf, buflen); 322 } 323 324 void ElfFile::add_symbol_table(ElfSymbolTable* table) { 325 if (_symbol_tables == NULL) { 326 _symbol_tables = table; 327 } else { 328 table->set_next(_symbol_tables); 329 _symbol_tables = table; 330 } 331 } 332 333 void ElfFile::add_string_table(ElfStringTable* table) { 334 if (_string_tables == NULL) { 335 _string_tables = table; 336 } else { 337 table->set_next(_string_tables); 338 _string_tables = table; 339 } 340 } 341 342 ElfStringTable* ElfFile::get_string_table(int index) { 343 ElfStringTable* p = _string_tables; 344 while (p != NULL) { 345 if (p->index() == index) return p; 346 p = p->next(); 347 } 348 return NULL; 349 } 350 351 #endif // !_WINDOWS && !__APPLE__