aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/vm/utilities')
-rw-r--r--src/share/vm/utilities/accessFlags.cpp3
-rw-r--r--src/share/vm/utilities/bitMap.cpp3
-rw-r--r--src/share/vm/utilities/debug.hpp2
-rw-r--r--src/share/vm/utilities/decoder.cpp4
-rw-r--r--src/share/vm/utilities/decoder_elf.cpp2
-rw-r--r--src/share/vm/utilities/decoder_elf.hpp4
-rw-r--r--src/share/vm/utilities/elfFile.cpp50
-rw-r--r--src/share/vm/utilities/elfFile.hpp6
-rw-r--r--src/share/vm/utilities/elfFuncDescTable.cpp104
-rw-r--r--src/share/vm/utilities/elfFuncDescTable.hpp149
-rw-r--r--src/share/vm/utilities/elfStringTable.cpp4
-rw-r--r--src/share/vm/utilities/elfStringTable.hpp2
-rw-r--r--src/share/vm/utilities/elfSymbolTable.cpp38
-rw-r--r--src/share/vm/utilities/elfSymbolTable.hpp6
-rw-r--r--src/share/vm/utilities/globalDefinitions.hpp14
-rw-r--r--src/share/vm/utilities/globalDefinitions_xlc.hpp202
-rw-r--r--src/share/vm/utilities/histogram.hpp3
-rw-r--r--src/share/vm/utilities/macros.hpp36
-rw-r--r--src/share/vm/utilities/ostream.cpp5
-rw-r--r--src/share/vm/utilities/resourceHash.hpp8
-rw-r--r--src/share/vm/utilities/taskqueue.hpp3
21 files changed, 617 insertions, 31 deletions
diff --git a/src/share/vm/utilities/accessFlags.cpp b/src/share/vm/utilities/accessFlags.cpp
index 6ae8e74c2..d9279428e 100644
--- a/src/share/vm/utilities/accessFlags.cpp
+++ b/src/share/vm/utilities/accessFlags.cpp
@@ -34,6 +34,9 @@
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
+#ifdef TARGET_OS_FAMILY_aix
+# include "os_aix.inline.hpp"
+#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
diff --git a/src/share/vm/utilities/bitMap.cpp b/src/share/vm/utilities/bitMap.cpp
index 8431395a6..b2a2ab7b2 100644
--- a/src/share/vm/utilities/bitMap.cpp
+++ b/src/share/vm/utilities/bitMap.cpp
@@ -35,6 +35,9 @@
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
+#ifdef TARGET_OS_FAMILY_aix
+# include "os_aix.inline.hpp"
+#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
diff --git a/src/share/vm/utilities/debug.hpp b/src/share/vm/utilities/debug.hpp
index 85b26f35f..ccadc0772 100644
--- a/src/share/vm/utilities/debug.hpp
+++ b/src/share/vm/utilities/debug.hpp
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_UTILITIES_DEBUG_HPP
#define SHARE_VM_UTILITIES_DEBUG_HPP
-#include "prims/jvm.h"
#include "utilities/globalDefinitions.hpp"
+#include "prims/jvm.h"
#include <stdarg.h>
diff --git a/src/share/vm/utilities/decoder.cpp b/src/share/vm/utilities/decoder.cpp
index b812acbe4..7ed913abe 100644
--- a/src/share/vm/utilities/decoder.cpp
+++ b/src/share/vm/utilities/decoder.cpp
@@ -32,6 +32,8 @@
#include "decoder_windows.hpp"
#elif defined(__APPLE__)
#include "decoder_machO.hpp"
+#elif defined(AIX)
+ #include "decoder_aix.hpp"
#else
#include "decoder_elf.hpp"
#endif
@@ -66,6 +68,8 @@ AbstractDecoder* Decoder::create_decoder() {
decoder = new (std::nothrow) WindowsDecoder();
#elif defined (__APPLE__)
decoder = new (std::nothrow)MachODecoder();
+#elif defined(AIX)
+ decoder = new (std::nothrow)AIXDecoder();
#else
decoder = new (std::nothrow)ElfDecoder();
#endif
diff --git a/src/share/vm/utilities/decoder_elf.cpp b/src/share/vm/utilities/decoder_elf.cpp
index 6e23f5eeb..973088321 100644
--- a/src/share/vm/utilities/decoder_elf.cpp
+++ b/src/share/vm/utilities/decoder_elf.cpp
@@ -73,4 +73,4 @@ ElfFile* ElfDecoder::get_elf_file(const char* filepath) {
return file;
}
-#endif
+#endif // !_WINDOWS && !__APPLE__
diff --git a/src/share/vm/utilities/decoder_elf.hpp b/src/share/vm/utilities/decoder_elf.hpp
index 79652aeff..f0d3372a9 100644
--- a/src/share/vm/utilities/decoder_elf.hpp
+++ b/src/share/vm/utilities/decoder_elf.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -55,5 +55,5 @@ private:
ElfFile* _opened_elf_files;
};
-#endif
+#endif // !_WINDOWS && !__APPLE__
#endif // SHARE_VM_UTILITIES_DECODER_ELF_HPP
diff --git a/src/share/vm/utilities/elfFile.cpp b/src/share/vm/utilities/elfFile.cpp
index 70194bef8..371a03640 100644
--- a/src/share/vm/utilities/elfFile.cpp
+++ b/src/share/vm/utilities/elfFile.cpp
@@ -34,6 +34,7 @@
#include "memory/allocation.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
+#include "utilities/elfFuncDescTable.hpp"
#include "utilities/elfStringTable.hpp"
#include "utilities/elfSymbolTable.hpp"
@@ -43,6 +44,7 @@ ElfFile::ElfFile(const char* filepath) {
memset(&m_elfHdr, 0, sizeof(m_elfHdr));
m_string_tables = NULL;
m_symbol_tables = NULL;
+ m_funcDesc_table = NULL;
m_next = NULL;
m_status = NullDecoder::no_error;
@@ -119,8 +121,8 @@ bool ElfFile::load_tables() {
m_status = NullDecoder::file_invalid;
return false;
}
- // string table
if (shdr.sh_type == SHT_STRTAB) {
+ // string tables
ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
if (table == NULL) {
m_status = NullDecoder::out_of_memory;
@@ -128,6 +130,7 @@ bool ElfFile::load_tables() {
}
add_string_table(table);
} else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
+ // symbol tables
ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
if (table == NULL) {
m_status = NullDecoder::out_of_memory;
@@ -136,6 +139,46 @@ bool ElfFile::load_tables() {
add_symbol_table(table);
}
}
+
+#if defined(PPC64)
+ // Now read the .opd section wich contains the PPC64 function descriptor table.
+ // The .opd section is only available on PPC64 (see for example:
+ // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
+ // so this code should do no harm on other platforms but because of performance reasons we only
+ // execute it on PPC64 platforms.
+ // Notice that we can only find the .opd section after we have successfully read in the string
+ // tables in the previous loop, because we need to query the name of each section which is
+ // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx).
+
+ // Reset the file pointer
+ if (fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
+ m_status = NullDecoder::file_invalid;
+ return false;
+ }
+ for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
+ if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
+ m_status = NullDecoder::file_invalid;
+ return false;
+ }
+ if (m_elfHdr.e_shstrndx != SHN_UNDEF && shdr.sh_type == SHT_PROGBITS) {
+ ElfStringTable* string_table = get_string_table(m_elfHdr.e_shstrndx);
+ if (string_table == NULL) {
+ m_status = NullDecoder::file_invalid;
+ return false;
+ }
+ char buf[8]; // '8' is enough because we only want to read ".opd"
+ if (string_table->string_at(shdr.sh_name, buf, sizeof(buf)) && !strncmp(".opd", buf, 4)) {
+ m_funcDesc_table = new (std::nothrow) ElfFuncDescTable(m_file, shdr, index);
+ if (m_funcDesc_table == NULL) {
+ m_status = NullDecoder::out_of_memory;
+ return false;
+ }
+ break;
+ }
+ }
+ }
+#endif
+
}
return true;
}
@@ -151,8 +194,9 @@ bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
int off = INT_MAX;
bool found_symbol = false;
while (symbol_table != NULL) {
- if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
+ if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, m_funcDesc_table)) {
found_symbol = true;
+ break;
}
symbol_table = symbol_table->m_next;
}
@@ -221,4 +265,4 @@ bool ElfFile::specifies_noexecstack() {
}
#endif
-#endif // _WINDOWS
+#endif // !_WINDOWS && !__APPLE__
diff --git a/src/share/vm/utilities/elfFile.hpp b/src/share/vm/utilities/elfFile.hpp
index ca97be909..3ce8e92cc 100644
--- a/src/share/vm/utilities/elfFile.hpp
+++ b/src/share/vm/utilities/elfFile.hpp
@@ -75,6 +75,7 @@ typedef Elf32_Sym Elf_Sym;
class ElfStringTable;
class ElfSymbolTable;
+class ElfFuncDescTable;
// On Solaris/Linux platforms, libjvm.so does contain all private symbols.
@@ -150,9 +151,12 @@ protected:
// string tables
ElfStringTable* m_string_tables;
+ // function descriptors table
+ ElfFuncDescTable* m_funcDesc_table;
+
NullDecoder::decoder_status m_status;
};
-#endif // _WINDOWS
+#endif // !_WINDOWS && !__APPLE__
#endif // SHARE_VM_UTILITIES_ELF_FILE_HPP
diff --git a/src/share/vm/utilities/elfFuncDescTable.cpp b/src/share/vm/utilities/elfFuncDescTable.cpp
new file mode 100644
index 000000000..c5a00606d
--- /dev/null
+++ b/src/share/vm/utilities/elfFuncDescTable.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2013 SAP AG. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+#include "memory/allocation.inline.hpp"
+#include "utilities/elfFuncDescTable.hpp"
+
+ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) {
+ assert(file, "null file handle");
+ // The actual function address (i.e. function entry point) is always the
+ // first value in the function descriptor (on IA64 and PPC64 they look as follows):
+ // PPC64: [function entry point, TOC pointer, environment pointer]
+ // IA64 : [function entry point, GP (global pointer) value]
+ // Unfortunately 'shdr.sh_entsize' doesn't always seem to contain this size (it's zero on PPC64) so we can't assert
+ // assert(IA64_ONLY(2) PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries");
+
+ m_funcDescs = NULL;
+ m_file = file;
+ m_index = index;
+ m_status = NullDecoder::no_error;
+
+ // try to load the function descriptor table
+ long cur_offset = ftell(file);
+ if (cur_offset != -1) {
+ // call malloc so we can back up if memory allocation fails.
+ m_funcDescs = (address*)os::malloc(shdr.sh_size, mtInternal);
+ if (m_funcDescs) {
+ if (fseek(file, shdr.sh_offset, SEEK_SET) ||
+ fread((void*)m_funcDescs, shdr.sh_size, 1, file) != 1 ||
+ fseek(file, cur_offset, SEEK_SET)) {
+ m_status = NullDecoder::file_invalid;
+ os::free(m_funcDescs);
+ m_funcDescs = NULL;
+ }
+ }
+ if (!NullDecoder::is_error(m_status)) {
+ memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
+ }
+ } else {
+ m_status = NullDecoder::file_invalid;
+ }
+}
+
+ElfFuncDescTable::~ElfFuncDescTable() {
+ if (m_funcDescs != NULL) {
+ os::free(m_funcDescs);
+ }
+}
+
+address ElfFuncDescTable::lookup(Elf_Word index) {
+ if (NullDecoder::is_error(m_status)) {
+ return NULL;
+ }
+
+ if (m_funcDescs != NULL) {
+ if (m_shdr.sh_size > 0 && m_shdr.sh_addr <= index && index <= m_shdr.sh_addr + m_shdr.sh_size) {
+ // Notice that 'index' is a byte-offset into the function descriptor table.
+ return m_funcDescs[(index - m_shdr.sh_addr) / sizeof(address)];
+ }
+ return NULL;
+ } else {
+ long cur_pos;
+ address addr;
+ if (!(m_shdr.sh_size > 0 && m_shdr.sh_addr <= index && index <= m_shdr.sh_addr + m_shdr.sh_size)) {
+ // don't put the whole decoder in error mode if we just tried a wrong index
+ return NULL;
+ }
+ if ((cur_pos = ftell(m_file)) == -1 ||
+ fseek(m_file, m_shdr.sh_offset + index - m_shdr.sh_addr, SEEK_SET) ||
+ fread(&addr, sizeof(addr), 1, m_file) != 1 ||
+ fseek(m_file, cur_pos, SEEK_SET)) {
+ m_status = NullDecoder::file_invalid;
+ return NULL;
+ }
+ return addr;
+ }
+}
+
+#endif // !_WINDOWS && !__APPLE__
diff --git a/src/share/vm/utilities/elfFuncDescTable.hpp b/src/share/vm/utilities/elfFuncDescTable.hpp
new file mode 100644
index 000000000..0b767a2c7
--- /dev/null
+++ b/src/share/vm/utilities/elfFuncDescTable.hpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2013 SAP AG. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP
+#define SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP
+
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+
+
+#include "memory/allocation.hpp"
+#include "utilities/decoder.hpp"
+#include "utilities/elfFile.hpp"
+
+/*
+
+On PowerPC-64 (and other architectures like for example IA64) a pointer to a
+function is not just a plain code address, but instead a pointer to a so called
+function descriptor (which is simply a structure containing 3 pointers).
+This fact is also reflected in the ELF ABI for PowerPC-64.
+
+On architectures like x86 or SPARC, the ELF symbol table contains the start
+address and size of an object. So for example for a function object (i.e. type
+'STT_FUNC') the symbol table's 'st_value' and 'st_size' fields directly
+represent the starting address and size of that function. On PPC64 however, the
+symbol table's 'st_value' field only contains an index into another, PPC64
+specific '.opd' (official procedure descriptors) section, while the 'st_size'
+field still holds the size of the corresponding function. In order to get the
+actual start address of a function, it is necessary to read the corresponding
+function descriptor entry in the '.opd' section at the corresponding index and
+extract the start address from there.
+
+That's exactly what this 'ElfFuncDescTable' class is used for. If the HotSpot
+runs on a PPC64 machine, and the corresponding ELF files contains an '.opd'
+section (which is actually mandatory on PPC64) it will be read into an object
+of type 'ElfFuncDescTable' just like the string and symbol table sections.
+Later on, during symbol lookup in 'ElfSymbolTable::lookup()' this function
+descriptor table will be used if available to find the real function address.
+
+All this is how things work today (2013) on contemporary Linux distributions
+(i.e. SLES 10) and new version of GCC (i.e. > 4.0). However there is a history,
+and it goes like this:
+
+In SLES 9 times (sometimes before GCC 3.4) gcc/ld on PPC64 generated two
+entries in the symbol table for every function. The value of the symbol with
+the name of the function was the address of the function descriptor while the
+dot '.' prefixed name was reserved to hold the actual address of that function
+(http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES).
+
+For a C-function 'foo' this resulted in two symbol table entries like this
+(extracted from the output of 'readelf -a <lib.so>'):
+
+Section Headers:
+ [ 9] .text PROGBITS 0000000000000a20 00000a20
+ 00000000000005a0 0000000000000000 AX 0 0 16
+ [21] .opd PROGBITS 00000000000113b8 000013b8
+ 0000000000000138 0000000000000000 WA 0 0 8
+
+Symbol table '.symtab' contains 86 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 76: 00000000000114c0 24 FUNC GLOBAL DEFAULT 21 foo
+ 78: 0000000000000bb0 76 FUNC GLOBAL DEFAULT 9 .foo
+
+You can see now that the '.foo' entry actually points into the '.text' segment
+('Ndx'=9) and its value and size fields represent the functions actual address
+and size. On the other hand, the entry for plain 'foo' points into the '.opd'
+section ('Ndx'=21) and its value and size fields are the index into the '.opd'
+section and the size of the corresponding '.opd' section entry (3 pointers on
+PPC64).
+
+These so called 'dot symbols' were dropped around gcc 3.4 from GCC and BINUTILS,
+see http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html.
+But nevertheless it may still be necessary to support both formats because we
+either run on an old system or because it is possible at any time that functions
+appear in the stack trace which come from old-style libraries.
+
+Therefore we not only have to check for the presence of the function descriptor
+table during symbol lookup in 'ElfSymbolTable::lookup()'. We additionally have
+to check that the symbol table entry references the '.opd' section. Only in
+that case we can resolve the actual function address from there. Otherwise we
+use the plain 'st_value' field from the symbol table as function address. This
+way we can also lookup the symbols in old-style ELF libraries (although we get
+the 'dotted' versions in that case). However, if present, the 'dot' will be
+conditionally removed on PPC64 from the symbol in 'ElfDecoder::demangle()' in
+decoder_linux.cpp.
+
+Notice that we can not reliably get the function address from old-style
+libraries because the 'st_value' field of the symbol table entries which point
+into the '.opd' section denote the size of the corresponding '.opd' entry and
+not that of the corresponding function. This has changed for the symbol table
+entries in new-style libraries as described at the beginning of this
+documentation.
+
+*/
+
+class ElfFuncDescTable: public CHeapObj<mtInternal> {
+ friend class ElfFile;
+ public:
+ ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index);
+ ~ElfFuncDescTable();
+
+ // return the function address for the function descriptor at 'index' or NULL on error
+ address lookup(Elf_Word index);
+
+ int get_index() { return m_index; };
+
+ NullDecoder::decoder_status get_status() { return m_status; };
+
+ protected:
+ // holds the complete function descriptor section if
+ // we can allocate enough memory
+ address* m_funcDescs;
+
+ // file contains string table
+ FILE* m_file;
+
+ // section header
+ Elf_Shdr m_shdr;
+
+ // The section index of this function descriptor (i.e. '.opd') section in the ELF file
+ int m_index;
+
+ NullDecoder::decoder_status m_status;
+};
+
+#endif // !_WINDOWS && !__APPLE__
+
+#endif // SHARE_VM_UTILITIES_ELF_FUNC_DESC_TABLE_HPP
diff --git a/src/share/vm/utilities/elfStringTable.cpp b/src/share/vm/utilities/elfStringTable.cpp
index 6a07a7db3..5d6ad5f30 100644
--- a/src/share/vm/utilities/elfStringTable.cpp
+++ b/src/share/vm/utilities/elfStringTable.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -87,4 +87,4 @@ bool ElfStringTable::string_at(int pos, char* buf, int buflen) {
}
}
-#endif // _WINDOWS
+#endif // !_WINDOWS && !__APPLE__
diff --git a/src/share/vm/utilities/elfStringTable.hpp b/src/share/vm/utilities/elfStringTable.hpp
index bb671481b..53a2fa030 100644
--- a/src/share/vm/utilities/elfStringTable.hpp
+++ b/src/share/vm/utilities/elfStringTable.hpp
@@ -70,6 +70,6 @@ class ElfStringTable: CHeapObj<mtInternal> {
NullDecoder::decoder_status m_status;
};
-#endif // _WINDOWS and _APPLE
+#endif // !_WINDOWS && !__APPLE__
#endif // SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
diff --git a/src/share/vm/utilities/elfSymbolTable.cpp b/src/share/vm/utilities/elfSymbolTable.cpp
index 079c2b81d..2c8c3c4da 100644
--- a/src/share/vm/utilities/elfSymbolTable.cpp
+++ b/src/share/vm/utilities/elfSymbolTable.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -27,6 +27,7 @@
#if !defined(_WINDOWS) && !defined(__APPLE__)
#include "memory/allocation.inline.hpp"
+#include "utilities/elfFuncDescTable.hpp"
#include "utilities/elfSymbolTable.hpp"
ElfSymbolTable::ElfSymbolTable(FILE* file, Elf_Shdr shdr) {
@@ -68,7 +69,7 @@ ElfSymbolTable::~ElfSymbolTable() {
}
}
-bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
+bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable) {
assert(stringtableIndex, "null string table index pointer");
assert(posIndex, "null string table offset pointer");
assert(offset, "null offset pointer");
@@ -77,19 +78,25 @@ bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex,
return false;
}
- address pc = 0;
size_t sym_size = sizeof(Elf_Sym);
assert((m_shdr.sh_size % sym_size) == 0, "check size");
int count = m_shdr.sh_size / sym_size;
if (m_symbols != NULL) {
for (int index = 0; index < count; index ++) {
if (STT_FUNC == ELF_ST_TYPE(m_symbols[index].st_info)) {
- address sym_addr = (address)m_symbols[index].st_value;
- if (sym_addr < addr && (addr - sym_addr) < *offset) {
- pc = (address)m_symbols[index].st_value;
- *offset = (int)(addr - pc);
+ Elf_Word st_size = m_symbols[index].st_size;
+ address sym_addr;
+ if (funcDescTable != NULL && funcDescTable->get_index() == m_symbols[index].st_shndx) {
+ // We need to go another step trough the function descriptor table (currently PPC64 only)
+ sym_addr = funcDescTable->lookup(m_symbols[index].st_value);
+ } else {
+ sym_addr = (address)m_symbols[index].st_value;
+ }
+ if (sym_addr <= addr && (Elf_Word)(addr - sym_addr) < st_size) {
+ *offset = (int)(addr - sym_addr);
*posIndex = m_symbols[index].st_name;
*stringtableIndex = m_shdr.sh_link;
+ return true;
}
}
}
@@ -105,12 +112,19 @@ bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex,
for (int index = 0; index < count; index ++) {
if (fread(&sym, sym_size, 1, m_file) == 1) {
if (STT_FUNC == ELF_ST_TYPE(sym.st_info)) {
- address sym_addr = (address)sym.st_value;
- if (sym_addr < addr && (addr - sym_addr) < *offset) {
- pc = (address)sym.st_value;
- *offset = (int)(addr - pc);
+ Elf_Word st_size = sym.st_size;
+ address sym_addr;
+ if (funcDescTable != NULL && funcDescTable->get_index() == sym.st_shndx) {
+ // We need to go another step trough the function descriptor table (currently PPC64 only)
+ sym_addr = funcDescTable->lookup(sym.st_value);
+ } else {
+ sym_addr = (address)sym.st_value;
+ }
+ if (sym_addr <= addr && (Elf_Word)(addr - sym_addr) < st_size) {
+ *offset = (int)(addr - sym_addr);
*posIndex = sym.st_name;
*stringtableIndex = m_shdr.sh_link;
+ return true;
}
}
} else {
@@ -123,4 +137,4 @@ bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex,
return true;
}
-#endif // _WINDOWS
+#endif // !_WINDOWS && !__APPLE__
diff --git a/src/share/vm/utilities/elfSymbolTable.hpp b/src/share/vm/utilities/elfSymbolTable.hpp
index b4e43fd1c..75d04e1ef 100644
--- a/src/share/vm/utilities/elfSymbolTable.hpp
+++ b/src/share/vm/utilities/elfSymbolTable.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -45,7 +45,7 @@ class ElfSymbolTable: public CHeapObj<mtInternal> {
~ElfSymbolTable();
// search the symbol that is nearest to the specified address.
- bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
+ bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable);
NullDecoder::decoder_status get_status() { return m_status; };
@@ -65,6 +65,6 @@ class ElfSymbolTable: public CHeapObj<mtInternal> {
NullDecoder::decoder_status m_status;
};
-#endif // _WINDOWS and _APPLE
+#endif // !_WINDOWS and !__APPLE__
#endif // SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp
index ecb5429c7..6461d8303 100644
--- a/src/share/vm/utilities/globalDefinitions.hpp
+++ b/src/share/vm/utilities/globalDefinitions.hpp
@@ -38,6 +38,9 @@
#ifdef TARGET_COMPILER_sparcWorks
# include "utilities/globalDefinitions_sparcWorks.hpp"
#endif
+#ifdef TARGET_COMPILER_xlc
+# include "utilities/globalDefinitions_xlc.hpp"
+#endif
#include "utilities/macros.hpp"
@@ -395,6 +398,17 @@ const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlass
#define PLATFORM_NATIVE_STACK_WALKING_SUPPORTED 1
#endif
+// To assure the IRIW property on processors that are not multiple copy
+// atomic, sync instructions must be issued between volatile reads to
+// assure their ordering, instead of after volatile stores.
+// (See "A Tutorial Introduction to the ARM and POWER Relaxed Memory Models"
+// by Luc Maranget, Susmit Sarkar and Peter Sewell, INRIA/Cambridge)
+#ifdef CPU_NOT_MULTIPLE_COPY_ATOMIC
+const bool support_IRIW_for_not_multiple_copy_atomic_cpu = true;
+#else
+const bool support_IRIW_for_not_multiple_copy_atomic_cpu = false;
+#endif
+
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
// Note: this value must be a power of 2
diff --git a/src/share/vm/utilities/globalDefinitions_xlc.hpp b/src/share/vm/utilities/globalDefinitions_xlc.hpp
new file mode 100644
index 000000000..8a3400621
--- /dev/null
+++ b/src/share/vm/utilities/globalDefinitions_xlc.hpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2013 SAP AG. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
+#define SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
+
+#include "prims/jni.h"
+
+// This file holds compiler-dependent includes,
+// globally used constants & types, class (forward)
+// declarations and a few frequently used utility functions.
+
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#include <math.h>
+#ifndef FP_PZERO
+// Linux doesn't have positive/negative zero
+#define FP_PZERO FP_ZERO
+#endif
+#if (!defined fpclass)
+#define fpclass fpclassify
+#endif
+
+#include <time.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <pthread.h>
+
+#include <limits.h>
+#include <errno.h>
+
+#include <stdint.h>
+
+// Use XLC compiler builtins instead of inline assembler
+#define USE_XLC_BUILTINS
+#ifdef USE_XLC_BUILTINS
+#include <builtins.h>
+ #if __IBMCPP__ < 1000
+ // the funtion prototype for __dcbtst(void *) is missing in XLC V8.0
+ // I could compile a little test, where I provided the prototype.
+ // The generated code was correct there. This is the prototype:
+ // extern "builtin" void __dcbtst (void *);
+ // For now we don't make use of it when compiling with XLC V8.0
+ #else
+ // __IBMCPP__ >= 1000
+ // XLC V10 provides the prototype for __dcbtst (void *);
+ #define USE_XLC_PREFETCH_WRITE_BUILTIN
+ #endif
+#endif // USE_XLC_BUILTINS
+
+// NULL vs NULL_WORD:
+// On Linux NULL is defined as a special type '__null'. Assigning __null to
+// integer variable will cause gcc warning. Use NULL_WORD in places where a
+// pointer is stored as integer value. On some platforms, sizeof(intptr_t) >
+// sizeof(void*), so here we want something which is integer type, but has the
+// same size as a pointer.
+#ifdef __GNUC__
+ #error XLC and __GNUC__?
+#else
+ #define NULL_WORD NULL
+#endif
+
+// AIX also needs a 64 bit NULL to work as a null address pointer.
+// Most system includes on AIX would define it as an int 0 if not already defined with one
+// exception: /usr/include/dirent.h will unconditionally redefine NULL to int 0 again.
+// In this case you need to copy the following defines to a position after #include <dirent.h>
+// (see jmv_aix.h).
+#ifdef AIX
+ #ifdef _LP64
+ #undef NULL
+ #define NULL 0L
+ #else
+ #ifndef NULL
+ #define NULL 0
+ #endif
+ #endif
+#endif // AIX
+
+// Compiler-specific primitive types
+// All defs of int (uint16_6 etc) are defined in AIX' /usr/include/stdint.h
+
+// Additional Java basic types
+
+typedef uint8_t jubyte;
+typedef uint16_t jushort;
+typedef uint32_t juint;
+typedef uint64_t julong;
+
+//----------------------------------------------------------------------------------------------------
+// Special (possibly not-portable) casts
+// Cast floats into same-size integers and vice-versa w/o changing bit-pattern
+// %%%%%% These seem like standard C++ to me--how about factoring them out? - Ungar
+
+inline jint jint_cast (jfloat x) { return *(jint* )&x; }
+inline jlong jlong_cast (jdouble x) { return *(jlong* )&x; }
+
+inline jfloat jfloat_cast (jint x) { return *(jfloat* )&x; }
+inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; }
+
+//----------------------------------------------------------------------------------------------------
+// Constant for jlong (specifying an long long canstant is C++ compiler specific)
+
+// Build a 64bit integer constant
+#define CONST64(x) (x ## LL)
+#define UCONST64(x) (x ## ULL)
+
+const jlong min_jlong = CONST64(0x8000000000000000);
+const jlong max_jlong = CONST64(0x7fffffffffffffff);
+
+//----------------------------------------------------------------------------------------------------
+// Debugging
+
+#define DEBUG_EXCEPTION ::abort();
+
+extern "C" void breakpoint();
+#define BREAKPOINT ::breakpoint()
+
+// checking for nanness
+#ifdef AIX
+inline int g_isnan(float f) { return isnan(f); }
+inline int g_isnan(double f) { return isnan(f); }
+#else
+#error "missing platform-specific definition here"
+#endif
+
+// Checking for finiteness
+
+inline int g_isfinite(jfloat f) { return finite(f); }
+inline int g_isfinite(jdouble f) { return finite(f); }
+
+
+// Wide characters
+
+inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
+
+
+// Portability macros
+#define PRAGMA_INTERFACE #pragma interface
+#define PRAGMA_IMPLEMENTATION #pragma implementation
+#define VALUE_OBJ_CLASS_SPEC
+
+// Formatting.
+#ifdef _LP64
+#define FORMAT64_MODIFIER "l"
+#else // !_LP64
+#define FORMAT64_MODIFIER "ll"
+#endif // _LP64
+
+// Cannot use xlc's offsetof as implementation of hotspot's
+// offset_of(), because xlc warns about applying offsetof() to non-POD
+// object and xlc cannot compile the expression offsetof(DataLayout,
+// _cells[index]) in DataLayout::cell_offset() . Therefore we define
+// offset_of as it is defined for gcc.
+#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)
+
+// Some constant sizes used throughout the AIX port
+#define SIZE_1K ((uint64_t) 0x400ULL)
+#define SIZE_4K ((uint64_t) 0x1000ULL)
+#define SIZE_64K ((uint64_t) 0x10000ULL)
+#define SIZE_1M ((uint64_t) 0x100000ULL)
+#define SIZE_4M ((uint64_t) 0x400000ULL)
+#define SIZE_8M ((uint64_t) 0x800000ULL)
+#define SIZE_16M ((uint64_t) 0x1000000ULL)
+#define SIZE_256M ((uint64_t) 0x10000000ULL)
+#define SIZE_1G ((uint64_t) 0x40000000ULL)
+#define SIZE_2G ((uint64_t) 0x80000000ULL)
+#define SIZE_4G ((uint64_t) 0x100000000ULL)
+#define SIZE_16G ((uint64_t) 0x400000000ULL)
+#define SIZE_32G ((uint64_t) 0x800000000ULL)
+#define SIZE_64G ((uint64_t) 0x1000000000ULL)
+#define SIZE_1T ((uint64_t) 0x10000000000ULL)
+
+
+#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
diff --git a/src/share/vm/utilities/histogram.hpp b/src/share/vm/utilities/histogram.hpp
index a969ed457..c03d48893 100644
--- a/src/share/vm/utilities/histogram.hpp
+++ b/src/share/vm/utilities/histogram.hpp
@@ -37,6 +37,9 @@
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
+#ifdef TARGET_OS_FAMILY_aix
+# include "os_aix.inline.hpp"
+#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
diff --git a/src/share/vm/utilities/macros.hpp b/src/share/vm/utilities/macros.hpp
index 718294ba0..b6fa44e14 100644
--- a/src/share/vm/utilities/macros.hpp
+++ b/src/share/vm/utilities/macros.hpp
@@ -254,6 +254,14 @@
#define NOT_LINUX(code) code
#endif
+#ifdef AIX
+#define AIX_ONLY(code) code
+#define NOT_AIX(code)
+#else
+#define AIX_ONLY(code)
+#define NOT_AIX(code) code
+#endif
+
#ifdef SOLARIS
#define SOLARIS_ONLY(code) code
#define NOT_SOLARIS(code)
@@ -320,7 +328,11 @@
#define NOT_IA32(code) code
#endif
-#ifdef IA64
+// This is a REALLY BIG HACK, but on AIX <sys/systemcfg.h> unconditionally defines IA64.
+// At least on AIX 7.1 this is a real problem because 'systemcfg.h' is indirectly included
+// by 'pthread.h' and other common system headers.
+
+#if defined(IA64) && !defined(AIX)
#define IA64_ONLY(code) code
#define NOT_IA64(code)
#else
@@ -344,14 +356,34 @@
#define NOT_SPARC(code) code
#endif
-#ifdef PPC
+#if defined(PPC32) || defined(PPC64)
+#ifndef PPC
+#define PPC
+#endif
#define PPC_ONLY(code) code
#define NOT_PPC(code)
#else
+#undef PPC
#define PPC_ONLY(code)
#define NOT_PPC(code) code
#endif
+#ifdef PPC32
+#define PPC32_ONLY(code) code
+#define NOT_PPC32(code)
+#else
+#define PPC32_ONLY(code)
+#define NOT_PPC32(code) code
+#endif
+
+#ifdef PPC64
+#define PPC64_ONLY(code) code
+#define NOT_PPC64(code)
+#else
+#define PPC64_ONLY(code)
+#define NOT_PPC64(code) code
+#endif
+
#ifdef E500V2
#define E500V2_ONLY(code) code
#define NOT_E500V2(code)
diff --git a/src/share/vm/utilities/ostream.cpp b/src/share/vm/utilities/ostream.cpp
index 39f87a477..90b3559e4 100644
--- a/src/share/vm/utilities/ostream.cpp
+++ b/src/share/vm/utilities/ostream.cpp
@@ -39,6 +39,9 @@
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
+#ifdef TARGET_OS_FAMILY_aix
+# include "os_aix.inline.hpp"
+#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
@@ -1238,7 +1241,7 @@ bufferedStream::~bufferedStream() {
#ifndef PRODUCT
-#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
+#if defined(SOLARIS) || defined(LINUX) || defined(AIX) || defined(_ALLBSD_SOURCE)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
diff --git a/src/share/vm/utilities/resourceHash.hpp b/src/share/vm/utilities/resourceHash.hpp
index 87cc8ffdb..2fe5dec94 100644
--- a/src/share/vm/utilities/resourceHash.hpp
+++ b/src/share/vm/utilities/resourceHash.hpp
@@ -44,8 +44,12 @@ template<typename K> bool primitive_equals(const K& k0, const K& k1) {
template<
typename K, typename V,
- typename ResourceHashtableFns<K>::hash_fn HASH = primitive_hash<K>,
- typename ResourceHashtableFns<K>::equals_fn EQUALS = primitive_equals<K>,
+ // xlC does not compile this:
+ // http://stackoverflow.com/questions/8532961/template-argument-of-type-that-is-defined-by-inner-typedef-from-other-template-c
+ //typename ResourceHashtableFns<K>::hash_fn HASH = primitive_hash<K>,
+ //typename ResourceHashtableFns<K>::equals_fn EQUALS = primitive_equals<K>,
+ unsigned (*HASH) (K const&) = primitive_hash<K>,
+ bool (*EQUALS)(K const&, K const&) = primitive_equals<K>,
unsigned SIZE = 256
>
class ResourceHashtable : public ResourceObj {
diff --git a/src/share/vm/utilities/taskqueue.hpp b/src/share/vm/utilities/taskqueue.hpp
index 1d4e06353..2577d7943 100644
--- a/src/share/vm/utilities/taskqueue.hpp
+++ b/src/share/vm/utilities/taskqueue.hpp
@@ -53,6 +53,9 @@
#ifdef TARGET_OS_ARCH_linux_ppc
# include "orderAccess_linux_ppc.inline.hpp"
#endif
+#ifdef TARGET_OS_ARCH_aix_ppc
+# include "orderAccess_aix_ppc.inline.hpp"
+#endif
#ifdef TARGET_OS_ARCH_bsd_x86
# include "orderAccess_bsd_x86.inline.hpp"
#endif