Path: blob/master/src/hotspot/share/utilities/elfFile.hpp
64440 views
/*1* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_UTILITIES_ELFFILE_HPP25#define SHARE_UTILITIES_ELFFILE_HPP2627#if !defined(_WINDOWS) && !defined(__APPLE__) && !defined(_AIX)2829#if defined(__OpenBSD__)30#include <sys/exec_elf.h>31#else32#include <elf.h>33#endif34#include <stdio.h>3536#ifdef _LP643738typedef Elf64_Half Elf_Half;39typedef Elf64_Word Elf_Word;40typedef Elf64_Off Elf_Off;41typedef Elf64_Addr Elf_Addr;4243typedef Elf64_Ehdr Elf_Ehdr;44typedef Elf64_Shdr Elf_Shdr;45typedef Elf64_Phdr Elf_Phdr;46typedef Elf64_Sym Elf_Sym;4748#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)49#define ELF_ST_TYPE ELF64_ST_TYPE50#endif5152#else5354typedef Elf32_Half Elf_Half;55typedef Elf32_Word Elf_Word;56typedef Elf32_Off Elf_Off;57typedef Elf32_Addr Elf_Addr;5859typedef Elf32_Ehdr Elf_Ehdr;60typedef Elf32_Shdr Elf_Shdr;61typedef Elf32_Phdr Elf_Phdr;62typedef Elf32_Sym Elf_Sym;6364#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)65#define ELF_ST_TYPE ELF32_ST_TYPE66#endif67#endif6869#include "globalDefinitions.hpp"70#include "memory/allocation.hpp"71#include "utilities/decoder.hpp"7273class ElfStringTable;74class ElfSymbolTable;75class ElfFuncDescTable;7677// ELF section, may or may not have cached data78class ElfSection {79private:80Elf_Shdr _section_hdr;81void* _section_data;82NullDecoder::decoder_status _stat;83public:84ElfSection(FILE* fd, const Elf_Shdr& hdr);85~ElfSection();8687NullDecoder::decoder_status status() const { return _stat; }8889const Elf_Shdr* section_header() const { return &_section_hdr; }90const void* section_data() const { return (const void*)_section_data; }91private:92// load this section.93// it return no_error, when it fails to cache the section data due to lack of memory94NullDecoder::decoder_status load_section(FILE* const file, const Elf_Shdr& hdr);95};9697class FileReader : public StackObj {98protected:99FILE* const _fd;100public:101FileReader(FILE* const fd) : _fd(fd) {};102bool read(void* buf, size_t size);103int read_buffer(void* buf, size_t size);104bool set_position(long offset);105};106107// Mark current position, so we can get back to it after108// reads.109class MarkedFileReader : public FileReader {110private:111long _marked_pos;112public:113MarkedFileReader(FILE* const fd);114~MarkedFileReader();115116bool has_mark() const { return _marked_pos >= 0; }117};118119// ElfFile is basically an elf file parser, which can lookup the symbol120// that is the nearest to the given address.121// Beware, this code is called from vm error reporting code, when vm is already122// in "error" state, so there are scenarios, lookup will fail. We want this123// part of code to be very defensive, and bait out if anything went wrong.124class ElfFile: public CHeapObj<mtInternal> {125friend class ElfDecoder;126127private:128// link ElfFiles129ElfFile* _next;130131// Elf file132char* _filepath;133FILE* _file;134135// Elf header136Elf_Ehdr _elfHdr;137138// symbol tables139ElfSymbolTable* _symbol_tables;140141// regular string tables142ElfStringTable* _string_tables;143144// section header string table, used for finding section name145ElfStringTable* _shdr_string_table;146147// function descriptors table148ElfFuncDescTable* _funcDesc_table;149150NullDecoder::decoder_status _status;151152public:153ElfFile(const char* filepath);154~ElfFile();155156bool decode(address addr, char* buf, int buflen, int* offset);157158const char* filepath() const {159return _filepath;160}161162bool same_elf_file(const char* filepath) const {163assert(filepath != NULL, "null file path");164return (_filepath != NULL && !strcmp(filepath, _filepath));165}166167NullDecoder::decoder_status get_status() const {168return _status;169}170171// Returns true if the elf file is marked NOT to require an executable stack,172// or if the file could not be opened.173// Returns false if the elf file requires an executable stack, the stack flag174// is not set at all, or if the file can not be read.175// On systems other than linux it always returns false.176static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; });177private:178// sanity check, if the file is a real elf file179static bool is_elf_file(Elf_Ehdr&);180181// parse this elf file182NullDecoder::decoder_status parse_elf(const char* filename);183184// load string, symbol and function descriptor tables from the elf file185NullDecoder::decoder_status load_tables();186187ElfFile* next() const { return _next; }188void set_next(ElfFile* file) { _next = file; }189190// find a section by name, return section index191// if there is no such section, return -1192int section_by_name(const char* name, Elf_Shdr& hdr);193194// string tables are stored in a linked list195void add_string_table(ElfStringTable* table);196197// symbol tables are stored in a linked list198void add_symbol_table(ElfSymbolTable* table);199200// return a string table at specified section index201ElfStringTable* get_string_table(int index);202203204FILE* const fd() const { return _file; }205206// Cleanup string, symbol and function descriptor tables207void cleanup_tables();208209public:210// For whitebox test211static bool _do_not_cache_elf_section;212};213214#endif // !_WINDOWS && !__APPLE__215216#endif // SHARE_UTILITIES_ELFFILE_HPP217218219