src/hotspot/share/utilities/elfFile.hpp
changeset 48975 2c35fd3c5789
parent 47216 71c04702a3d5
child 48988 c2cd23e1d9cb
--- a/src/hotspot/share/utilities/elfFile.hpp	Wed Feb 14 16:42:00 2018 +0100
+++ b/src/hotspot/share/utilities/elfFile.hpp	Wed Feb 14 17:20:59 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,6 @@
 typedef Elf32_Off       Elf_Off;
 typedef Elf32_Addr      Elf_Addr;
 
-
 typedef Elf32_Ehdr      Elf_Ehdr;
 typedef Elf32_Shdr      Elf_Shdr;
 typedef Elf32_Phdr      Elf_Phdr;
@@ -72,46 +71,126 @@
 #include "memory/allocation.hpp"
 #include "utilities/decoder.hpp"
 
-
 class ElfStringTable;
 class ElfSymbolTable;
 class ElfFuncDescTable;
 
+// ELF section, may or may not have cached data
+class ElfSection VALUE_OBJ_CLASS_SPEC {
+private:
+  Elf_Shdr      _section_hdr;
+  void*         _section_data;
+  NullDecoder::decoder_status _stat;
+public:
+  ElfSection(FILE* fd, const Elf_Shdr& hdr);
+  ~ElfSection();
 
-// On Solaris/Linux platforms, libjvm.so does contain all private symbols.
+  NullDecoder::decoder_status status() const { return _stat; }
+
+  const Elf_Shdr* section_header() const { return &_section_hdr; }
+  const void*     section_data()   const { return (const void*)_section_data; }
+private:
+  // load this section.
+  // it return no_error, when it fails to cache the section data due to lack of memory
+  NullDecoder::decoder_status load_section(FILE* const file, const Elf_Shdr& hdr);
+};
+
+class FileReader : public StackObj {
+protected:
+  FILE* const _fd;
+public:
+  FileReader(FILE* const fd) : _fd(fd) {};
+  bool read(void* buf, size_t size);
+  int  read_buffer(void* buf, size_t size);
+  bool set_position(long offset);
+};
+
+// Mark current position, so we can get back to it after
+// reads.
+class MarkedFileReader : public FileReader {
+private:
+  long  _marked_pos;
+public:
+  MarkedFileReader(FILE* const fd);
+  ~MarkedFileReader();
+
+  bool has_mark() const { return _marked_pos >= 0; }
+};
+
 // ElfFile is basically an elf file parser, which can lookup the symbol
 // that is the nearest to the given address.
 // Beware, this code is called from vm error reporting code, when vm is already
 // in "error" state, so there are scenarios, lookup will fail. We want this
 // part of code to be very defensive, and bait out if anything went wrong.
-
 class ElfFile: public CHeapObj<mtInternal> {
   friend class ElfDecoder;
- public:
+
+private:
+  // link ElfFiles
+  ElfFile*          _next;
+
+  // Elf file
+  char*             _filepath;
+  FILE*             _file;
+
+  // Elf header
+  Elf_Ehdr          _elfHdr;
+
+  // symbol tables
+  ElfSymbolTable*   _symbol_tables;
+
+  // regular string tables
+  ElfStringTable*   _string_tables;
+
+  // section header string table, used for finding section name
+  ElfStringTable*   _shdr_string_table;
+
+  // function descriptors table
+  ElfFuncDescTable* _funcDesc_table;
+
+  NullDecoder::decoder_status  _status;
+
+public:
   ElfFile(const char* filepath);
   ~ElfFile();
 
   bool decode(address addr, char* buf, int buflen, int* offset);
-  const char* filepath() {
-    return m_filepath;
+
+  const char* filepath() const {
+    return _filepath;
+  }
+
+  bool same_elf_file(const char* filepath) const {
+    assert(filepath != NULL, "null file path");
+    return (_filepath != NULL && !strcmp(filepath, _filepath));
   }
 
-  bool same_elf_file(const char* filepath) {
-    assert(filepath, "null file path");
-    assert(m_filepath, "already out of memory");
-    return (m_filepath && !strcmp(filepath, m_filepath));
+  NullDecoder::decoder_status get_status() const {
+    return _status;
   }
 
-  NullDecoder::decoder_status get_status() {
-    return m_status;
-  }
-
- private:
+  // Returns true if the elf file is marked NOT to require an executable stack,
+  // or if the file could not be opened.
+  // Returns false if the elf file requires an executable stack, the stack flag
+  // is not set at all, or if the file can not be read.
+  // On systems other than linux it always returns false.
+  static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; });
+private:
   // sanity check, if the file is a real elf file
   static bool is_elf_file(Elf_Ehdr&);
 
-  // load string tables from the elf file
-  bool load_tables();
+  // parse this elf file
+  NullDecoder::decoder_status parse_elf(const char* filename);
+
+  // load string, symbol and function descriptor tables from the elf file
+  NullDecoder::decoder_status load_tables();
+
+  ElfFile*  next() const { return _next; }
+  void set_next(ElfFile* file) { _next = file; }
+
+  // find a section by name, return section index
+  // if there is no such section, return -1
+  int section_by_name(const char* name, Elf_Shdr& hdr);
 
   // string tables are stored in a linked list
   void add_string_table(ElfStringTable* table);
@@ -122,39 +201,15 @@
   // return a string table at specified section index
   ElfStringTable* get_string_table(int index);
 
-protected:
-   ElfFile*  next() const { return m_next; }
-   void set_next(ElfFile* file) { m_next = file; }
 
- public:
-  // Returns true if the elf file is marked NOT to require an executable stack,
-  // or if the file could not be opened.
-  // Returns false if the elf file requires an executable stack, the stack flag
-  // is not set at all, or if the file can not be read.
-  // On systems other than linux it always returns false.
-  static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; });
-
- protected:
-    ElfFile*         m_next;
+  FILE* const fd() const { return _file; }
 
- private:
-  // file
-  const char* m_filepath;
-  FILE* m_file;
-
-  // Elf header
-  Elf_Ehdr                     m_elfHdr;
+  // Cleanup string, symbol and function descriptor tables
+  void cleanup_tables();
 
-  // symbol tables
-  ElfSymbolTable*              m_symbol_tables;
-
-  // string tables
-  ElfStringTable*              m_string_tables;
-
-  // function descriptors table
-  ElfFuncDescTable*            m_funcDesc_table;
-
-  NullDecoder::decoder_status  m_status;
+public:
+  // For whitebox test
+  static bool _do_not_cache_elf_section;
 };
 
 #endif // !_WINDOWS && !__APPLE__