hotspot/src/os/aix/vm/porting_aix.cpp
author stefank
Tue, 04 Jul 2017 15:58:10 +0200
changeset 46619 a3919f5e8d2b
parent 46576 0b817584e8a9
child 46625 edefffab74e2
permissions -rw-r--r--
8178499: Remove _ptr_ and _size_ infixes from align functions Reviewed-by: rehn, tschatzl
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     1
/*
35594
cc13089c6327 8147937: Adapt SAP copyrights to new company name.
goetz
parents: 33743
diff changeset
     2
 * Copyright (c) 2012, 2013 SAP SE. All rights reserved.
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     4
 *
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     7
 * published by the Free Software Foundation.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     8
 *
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    13
 * accompanied this code).
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    14
 *
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    18
 *
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    21
 * questions.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    22
 *
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    23
 */
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    24
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    25
#include "asm/assembler.hpp"
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    26
#include "compiler/disassembler.hpp"
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
    27
#include "loadlib_aix.hpp"
24430
47a764232b9c 8039805: Fix the signature of the global new/delete operators in allocation.cpp.
simonis
parents: 22831
diff changeset
    28
#include "memory/allocation.hpp"
25949
34557722059b 6424123: JVM crashes on failed 'strdup' call
zgu
parents: 24430
diff changeset
    29
#include "memory/allocation.inline.hpp"
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
    30
#include "misc_aix.hpp"
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
    31
#include "porting_aix.hpp"
25949
34557722059b 6424123: JVM crashes on failed 'strdup' call
zgu
parents: 24430
diff changeset
    32
#include "runtime/os.hpp"
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    33
#include "runtime/thread.hpp"
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    34
#include "utilities/debug.hpp"
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    35
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    36
#include <demangle.h>
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    37
#include <sys/debug.h>
46576
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
    38
#include <pthread.h>
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    39
#include <ucontext.h>
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    40
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    41
//////////////////////////////////
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    42
// Provide implementation for dladdr based on LoadedLibraries pool and
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    43
// traceback table scan
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    44
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    45
// Search traceback table in stack,
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    46
// return procedure name from trace back table.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    47
#define MAX_FUNC_SEARCH_LEN 0x10000
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    48
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    49
#define PTRDIFF_BYTES(p1,p2) (((ptrdiff_t)p1) - ((ptrdiff_t)p2))
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    50
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    51
// Typedefs for stackslots, stack pointers, pointers to op codes.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    52
typedef unsigned long stackslot_t;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    53
typedef stackslot_t* stackptr_t;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    54
typedef unsigned int* codeptr_t;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
    55
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    56
// Unfortunately, the interface of dladdr makes the implementator
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    57
// responsible for maintaining memory for function name/library
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    58
// name. I guess this is because most OS's keep those values as part
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    59
// of the mapped executable image ready to use. On AIX, this doesn't
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    60
// work, so I have to keep the returned strings. For now, I do this in
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    61
// a primitive string map. Should this turn out to be a performance
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    62
// problem, a better hashmap has to be used.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    63
class fixed_strings {
24430
47a764232b9c 8039805: Fix the signature of the global new/delete operators in allocation.cpp.
simonis
parents: 22831
diff changeset
    64
  struct node : public CHeapObj<mtInternal> {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    65
    char* v;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    66
    node* next;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    67
  };
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    68
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    69
  node* first;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    70
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    71
  public:
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    72
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    73
  fixed_strings() : first(0) {}
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    74
  ~fixed_strings() {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    75
    node* n = first;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    76
    while (n) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    77
      node* p = n;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    78
      n = n->next;
25949
34557722059b 6424123: JVM crashes on failed 'strdup' call
zgu
parents: 24430
diff changeset
    79
      os::free(p->v);
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    80
      delete p;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    81
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    82
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    83
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    84
  char* intern(const char* s) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    85
    for (node* n = first; n; n = n->next) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    86
      if (strcmp(n->v, s) == 0) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    87
        return n->v;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    88
      }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    89
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    90
    node* p = new node;
25949
34557722059b 6424123: JVM crashes on failed 'strdup' call
zgu
parents: 24430
diff changeset
    91
    p->v = os::strdup_check_oom(s);
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    92
    p->next = first;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    93
    first = p;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    94
    return p->v;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    95
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    96
};
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    97
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    98
static fixed_strings dladdr_fixed_strings;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
    99
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   100
bool AixSymbols::get_function_name (
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   101
    address pc0,                     // [in] program counter
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   102
    char* p_name, size_t namelen,    // [out] optional: function name ("" if not available)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   103
    int* p_displacement,             // [out] optional: displacement (-1 if not available)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   104
    const struct tbtable** p_tb,     // [out] optional: ptr to traceback table to get further
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   105
                                     //                 information (NULL if not available)
31352
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   106
    bool demangle                    // [in] whether to demangle the name
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   107
  ) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   108
  struct tbtable* tb = 0;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   109
  unsigned int searchcount = 0;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   110
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   111
  // initialize output parameters
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   112
  if (p_name && namelen > 0) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   113
    *p_name = '\0';
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   114
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   115
  if (p_displacement) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   116
    *p_displacement = -1;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   117
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   118
  if (p_tb) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   119
    *p_tb = NULL;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   120
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   121
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   122
  codeptr_t pc = (codeptr_t)pc0;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   123
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   124
  // weed out obvious bogus states
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   125
  if (pc < (codeptr_t)0x1000) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   126
    trcVerbose("invalid program counter");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   127
    return false;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   128
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   129
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   130
  // We see random but frequent crashes in this function since some months mainly on shutdown
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   131
  // (-XX:+DumpInfoAtExit). It appears the page we are reading is randomly disappearing while
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   132
  // we read it (?).
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   133
  // As the pc cannot be trusted to be anything sensible lets make all reads via SafeFetch. Also
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   134
  // bail if this is not a text address right now.
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   135
  if (!LoadedLibraries::find_for_text_address(pc, NULL)) {
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   136
    trcVerbose("not a text address");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   137
    return false;
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   138
  }
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   139
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   140
  // .. (Note that is_readable_pointer returns true if safefetch stubs are not there yet;
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   141
  // in that case I try reading the traceback table unsafe - I rather risk secondary crashes in
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   142
  // error files than not having a callstack.)
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   143
#define CHECK_POINTER_READABLE(p) \
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   144
  if (!MiscUtils::is_readable_pointer(p)) { \
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   145
    trcVerbose("pc not readable"); \
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   146
    return false; \
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   147
  }
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   148
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   149
  codeptr_t pc2 = (codeptr_t) pc;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   150
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   151
  // Make sure the pointer is word aligned.
46619
a3919f5e8d2b 8178499: Remove _ptr_ and _size_ infixes from align functions
stefank
parents: 46576
diff changeset
   152
  pc2 = (codeptr_t) align_up((char*)pc2, 4);
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   153
  CHECK_POINTER_READABLE(pc2)
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   154
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   155
  // Find start of traceback table.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   156
  // (starts after code, is marked by word-aligned (32bit) zeros)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   157
  while ((*pc2 != NULL) && (searchcount++ < MAX_FUNC_SEARCH_LEN)) {
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   158
    CHECK_POINTER_READABLE(pc2)
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   159
    pc2++;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   160
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   161
  if (*pc2 != 0) {
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   162
    trcVerbose("no traceback table found");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   163
    return false;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   164
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   165
  //
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   166
  // Set up addressability to the traceback table
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   167
  //
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   168
  tb = (struct tbtable*) (pc2 + 1);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   169
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   170
  // Is this really a traceback table? No way to be sure but
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   171
  // some indicators we can check.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   172
  if (tb->tb.lang >= 0xf && tb->tb.lang <= 0xfb) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   173
    // Language specifiers, go from 0 (C) to 14 (Objective C).
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   174
    // According to spec, 0xf-0xfa reserved, 0xfb-0xff reserved for ibm.
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   175
    trcVerbose("no traceback table found");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   176
    return false;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   177
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   178
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   179
  // Existence of fields in the tbtable extension are contingent upon
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   180
  // specific fields in the base table.  Check for their existence so
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   181
  // that we can address the function name if it exists.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   182
  pc2 = (codeptr_t) tb +
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   183
    sizeof(struct tbtable_short)/sizeof(int);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   184
  if (tb->tb.fixedparms != 0 || tb->tb.floatparms != 0)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   185
    pc2++;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   186
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   187
  CHECK_POINTER_READABLE(pc2)
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   188
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   189
  if (tb->tb.has_tboff == TRUE) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   190
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   191
    // I want to know the displacement
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   192
    const unsigned int tb_offset = *pc2;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   193
    codeptr_t start_of_procedure =
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   194
    (codeptr_t)(((char*)tb) - 4 - tb_offset);  // (-4 to omit leading 0000)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   195
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   196
    // Weed out the cases where we did find the wrong traceback table.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   197
    if (pc < start_of_procedure) {
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   198
      trcVerbose("no traceback table found");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   199
      return false;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   200
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   201
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   202
    // return the displacement
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   203
    if (p_displacement) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   204
      (*p_displacement) = (int) PTRDIFF_BYTES(pc, start_of_procedure);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   205
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   206
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   207
    pc2++;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   208
  } else {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   209
    // return -1 for displacement
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   210
    if (p_displacement) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   211
      (*p_displacement) = -1;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   212
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   213
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   214
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   215
  if (tb->tb.int_hndl == TRUE)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   216
    pc2++;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   217
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   218
  if (tb->tb.has_ctl == TRUE)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   219
    pc2 += (*pc2) + 1; // don't care
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   220
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   221
  CHECK_POINTER_READABLE(pc2)
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   222
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   223
  //
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   224
  // return function name if it exists.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   225
  //
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   226
  if (p_name && namelen > 0) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   227
    if (tb->tb.name_present) {
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   228
      // Copy name from text because it may not be zero terminated.
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   229
      const short l = MIN2<short>(*((short*)pc2), namelen - 1);
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   230
      // Be very careful.
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   231
      int i = 0; char* const p = (char*)pc2 + sizeof(short);
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   232
      while (i < l && MiscUtils::is_readable_pointer(p + i)) {
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   233
        p_name[i] = p[i];
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   234
        i++;
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   235
      }
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   236
      p_name[i] = '\0';
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   237
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   238
      // If it is a C++ name, try and demangle it using the Demangle interface (see demangle.h).
31352
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   239
      if (demangle) {
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   240
        char* rest;
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   241
        Name* const name = Demangle(p_name, rest);
31352
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   242
        if (name) {
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   243
          const char* const demangled_name = name->Text();
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   244
          if (demangled_name) {
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   245
            strncpy(p_name, demangled_name, namelen-1);
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   246
            p_name[namelen-1] = '\0';
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   247
          }
a6ab7217b5cc 8079473: allow demangling to be optional in dll_address_to_function_name
bdelsart
parents: 25949
diff changeset
   248
          delete name;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   249
        }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   250
      }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   251
    } else {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   252
      strncpy(p_name, "<nameless function>", namelen-1);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   253
      p_name[namelen-1] = '\0';
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   254
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   255
  }
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   256
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   257
  // Return traceback table, if user wants it.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   258
  if (p_tb) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   259
    (*p_tb) = tb;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   260
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   261
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   262
  return true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   263
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   264
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   265
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   266
bool AixSymbols::get_module_name(address pc,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   267
                         char* p_name, size_t namelen) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   268
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   269
  if (p_name && namelen > 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   270
    p_name[0] = '\0';
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   271
    loaded_module_t lm;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   272
    if (LoadedLibraries::find_for_text_address(pc, &lm) != NULL) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   273
      strncpy(p_name, lm.shortname, namelen);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   274
      p_name[namelen - 1] = '\0';
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   275
      return true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   276
    }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   277
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   278
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   279
  return false;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   280
}
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   281
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   282
// Special implementation of dladdr for Aix based on LoadedLibraries
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   283
// Note: dladdr returns non-zero for ok, 0 for error!
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   284
// Note: dladdr is not posix, but a non-standard GNU extension. So this tries to
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   285
//   fulfill the contract of dladdr on Linux (see http://linux.die.net/man/3/dladdr)
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   286
// Note: addr may be both an AIX function descriptor or a real code pointer
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   287
//   to the entry of a function.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   288
extern "C"
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   289
int dladdr(void* addr, Dl_info* info) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   290
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   291
  if (!addr) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   292
    return 0;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   293
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   294
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   295
  assert(info, "");
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   296
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   297
  int rc = 0;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   298
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   299
  const char* const ZEROSTRING = "";
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   300
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   301
  // Always return a string, even if a "" one. Linux dladdr manpage
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   302
  // does not say anything about returning NULL
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   303
  info->dli_fname = ZEROSTRING;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   304
  info->dli_sname = ZEROSTRING;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   305
  info->dli_saddr = NULL;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   306
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   307
  address p = (address) addr;
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   308
  loaded_module_t lm;
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   309
  bool found = false;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   310
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   311
  enum { noclue, code, data } type = noclue;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   312
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   313
  trcVerbose("dladdr(%p)...", p);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   314
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   315
  // Note: input address may be a function. I accept both a pointer to
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   316
  // the entry of a function and a pointer to the function decriptor.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   317
  // (see ppc64 ABI)
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   318
  found = LoadedLibraries::find_for_text_address(p, &lm);
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   319
  if (found) {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   320
    type = code;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   321
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   322
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   323
  if (!found) {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   324
    // Not a pointer into any text segment. Is it a function descriptor?
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   325
    const FunctionDescriptor* const pfd = (const FunctionDescriptor*) p;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   326
    p = pfd->entry();
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   327
    if (p) {
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   328
      found = LoadedLibraries::find_for_text_address(p, &lm);
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   329
      if (found) {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   330
        type = code;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   331
      }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   332
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   333
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   334
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   335
  if (!found) {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   336
    // Neither direct code pointer nor function descriptor. A data ptr?
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   337
    p = (address)addr;
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   338
    found = LoadedLibraries::find_for_data_address(p, &lm);
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   339
    if (found) {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   340
      type = data;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   341
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   342
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   343
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   344
  // If we did find the shared library this address belongs to (either
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   345
  // code or data segment) resolve library path and, if possible, the
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   346
  // symbol name.
33743
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   347
  if (found) {
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   348
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   349
    // No need to intern the libpath, that one is already interned one layer below.
e21d93a9e062 8140645: Recent Developments for AIX
stuefe
parents: 31352
diff changeset
   350
    info->dli_fname = lm.path;
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   351
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   352
    if (type == code) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   353
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   354
      // For code symbols resolve function name and displacement. Use
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   355
      // displacement to calc start of function.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   356
      char funcname[256] = "";
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   357
      int displacement = 0;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   358
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   359
      if (AixSymbols::get_function_name(p, funcname, sizeof(funcname),
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   360
                      &displacement, NULL, true)) {
22831
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   361
        if (funcname[0] != '\0') {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   362
          const char* const interned = dladdr_fixed_strings.intern(funcname);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   363
          info->dli_sname = interned;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   364
          trcVerbose("... function name: %s ...", interned);
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   365
        }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   366
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   367
        // From the displacement calculate the start of the function.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   368
        if (displacement != -1) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   369
          info->dli_saddr = p - displacement;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   370
        } else {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   371
          info->dli_saddr = p;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   372
        }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   373
      } else {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   374
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   375
        // No traceback table found. Just assume the pointer is it.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   376
        info->dli_saddr = p;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   377
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   378
      }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   379
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   380
    } else if (type == data) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   381
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   382
      // For data symbols.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   383
      info->dli_saddr = p;
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   384
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   385
    } else {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   386
      ShouldNotReachHere();
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   387
    }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   388
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   389
    rc = 1; // success: return 1 [sic]
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   390
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   391
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   392
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   393
  // sanity checks.
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   394
  if (rc) {
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   395
    assert(info->dli_fname, "");
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   396
    assert(info->dli_sname, "");
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   397
    assert(info->dli_saddr, "");
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   398
  }
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   399
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   400
  return rc; // error: return 0 [sic]
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   401
1e2ba1d62103 8023038: PPC64 (part 15): Platform files for AIX/PPC64 support
simonis
parents:
diff changeset
   402
}
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   403
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   404
/////////////////////////////////////////////////////////////////////////////
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   405
// Native callstack dumping
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   406
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   407
// Print the traceback table for one stack frame.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   408
static void print_tbtable (outputStream* st, const struct tbtable* p_tb) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   409
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   410
  if (p_tb == NULL) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   411
    st->print("<null>");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   412
    return;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   413
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   414
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   415
  switch(p_tb->tb.lang) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   416
    case TB_C: st->print("C"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   417
    case TB_FORTRAN: st->print("FORTRAN"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   418
    case TB_PASCAL: st->print("PASCAL"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   419
    case TB_ADA: st->print("ADA"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   420
    case TB_PL1: st->print("PL1"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   421
    case TB_BASIC: st->print("BASIC"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   422
    case TB_LISP: st->print("LISP"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   423
    case TB_COBOL: st->print("COBOL"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   424
    case TB_MODULA2: st->print("MODULA2"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   425
    case TB_CPLUSPLUS: st->print("C++"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   426
    case TB_RPG: st->print("RPG"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   427
    case TB_PL8: st->print("PL8"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   428
    case TB_ASM: st->print("ASM"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   429
    case TB_HPJ: st->print("HPJ"); break;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   430
    default: st->print("unknown");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   431
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   432
  st->print(" ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   433
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   434
  if (p_tb->tb.globallink) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   435
    st->print("globallink ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   436
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   437
  if (p_tb->tb.is_eprol) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   438
    st->print("eprol ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   439
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   440
  if (p_tb->tb.int_proc) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   441
    st->print("int_proc ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   442
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   443
  if (p_tb->tb.tocless) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   444
    st->print("tocless ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   445
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   446
  if (p_tb->tb.fp_present) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   447
    st->print("fp_present ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   448
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   449
  if (p_tb->tb.int_hndl) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   450
    st->print("interrupt_handler ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   451
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   452
  if (p_tb->tb.uses_alloca) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   453
    st->print("uses_alloca ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   454
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   455
  if (p_tb->tb.saves_cr) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   456
    st->print("saves_cr ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   457
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   458
  if (p_tb->tb.saves_lr) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   459
    st->print("saves_lr ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   460
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   461
  if (p_tb->tb.stores_bc) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   462
    st->print("stores_bc ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   463
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   464
  if (p_tb->tb.fixup) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   465
    st->print("fixup ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   466
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   467
  if (p_tb->tb.fpr_saved > 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   468
    st->print("fpr_saved:%d ", p_tb->tb.fpr_saved);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   469
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   470
  if (p_tb->tb.gpr_saved > 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   471
    st->print("gpr_saved:%d ", p_tb->tb.gpr_saved);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   472
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   473
  if (p_tb->tb.fixedparms > 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   474
    st->print("fixedparms:%d ", p_tb->tb.fixedparms);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   475
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   476
  if (p_tb->tb.floatparms > 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   477
    st->print("floatparms:%d ", p_tb->tb.floatparms);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   478
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   479
  if (p_tb->tb.parmsonstk > 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   480
    st->print("parmsonstk:%d", p_tb->tb.parmsonstk);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   481
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   482
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   483
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   484
// Print information for pc (module, function, displacement, traceback table)
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   485
// on one line.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   486
static void print_info_for_pc (outputStream* st, codeptr_t pc, char* buf,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   487
                               size_t buf_size, bool demangle) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   488
  const struct tbtable* tb = NULL;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   489
  int displacement = -1;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   490
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   491
  if (!MiscUtils::is_readable_pointer(pc)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   492
    st->print("(invalid)");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   493
    return;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   494
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   495
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   496
  if (AixSymbols::get_module_name((address)pc, buf, buf_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   497
    st->print("%s", buf);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   498
  } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   499
    st->print("(unknown module)");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   500
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   501
  st->print("::");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   502
  if (AixSymbols::get_function_name((address)pc, buf, buf_size,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   503
                                     &displacement, &tb, demangle)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   504
    st->print("%s", buf);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   505
  } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   506
    st->print("(unknown function)");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   507
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   508
  if (displacement == -1) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   509
    st->print("+?");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   510
  } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   511
    st->print("+0x%x", displacement);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   512
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   513
  if (tb) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   514
    st->fill_to(64);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   515
    st->print("  (");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   516
    print_tbtable(st, tb);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   517
    st->print(")");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   518
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   519
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   520
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   521
static void print_stackframe(outputStream* st, stackptr_t sp, char* buf,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   522
                             size_t buf_size, bool demangle) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   523
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   524
  stackptr_t sp2 = sp;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   525
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   526
  // skip backchain
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   527
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   528
  sp2++;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   529
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   530
  // skip crsave
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   531
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   532
  sp2++;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   533
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   534
  // retrieve lrsave. That is the only info I need to get the function/displacement
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   535
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   536
  codeptr_t lrsave = (codeptr_t) *(sp2);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   537
  st->print (PTR64_FORMAT " - " PTR64_FORMAT " ", sp2, lrsave);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   538
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   539
  if (lrsave != NULL) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   540
    print_info_for_pc(st, lrsave, buf, buf_size, demangle);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   541
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   542
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   543
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   544
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   545
// Function to check a given stack pointer against given stack limits.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   546
static bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   547
  if (((uintptr_t)sp) & 0x7) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   548
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   549
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   550
  if (sp > stack_base) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   551
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   552
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   553
  if (sp < (stackptr_t) ((address)stack_base - stack_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   554
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   555
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   556
  return true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   557
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   558
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   559
// Returns true if function is a valid codepointer.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   560
static bool is_valid_codepointer(codeptr_t p) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   561
  if (!p) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   562
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   563
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   564
  if (((uintptr_t)p) & 0x3) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   565
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   566
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   567
  if (LoadedLibraries::find_for_text_address(p, NULL) == NULL) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   568
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   569
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   570
  return true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   571
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   572
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   573
// Function tries to guess if the given combination of stack pointer, stack base
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   574
// and stack size is a valid stack frame.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   575
static bool is_valid_frame (stackptr_t p, stackptr_t stack_base, size_t stack_size) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   576
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   577
  if (!is_valid_stackpointer(p, stack_base, stack_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   578
    return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   579
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   580
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   581
  // First check - the occurrence of a valid backchain pointer up the stack, followed by a
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   582
  // valid codeptr, counts as a good candidate.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   583
  stackptr_t sp2 = (stackptr_t) *p;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   584
  if (is_valid_stackpointer(sp2, stack_base, stack_size) && // found a valid stack pointer in the stack...
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   585
     ((sp2 - p) > 6) &&  // ... pointing upwards and not into my frame...
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   586
     is_valid_codepointer((codeptr_t)(*(sp2 + 2)))) // ... followed by a code pointer after two slots...
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   587
  {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   588
    return true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   589
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   590
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   591
  return false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   592
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   593
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   594
// Try to relocate a stack back chain in a given stack.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   595
// Used in callstack dumping, when the backchain is broken by an overwriter
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   596
static stackptr_t try_find_backchain (stackptr_t last_known_good_frame,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   597
                                      stackptr_t stack_base, size_t stack_size)
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   598
{
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   599
  if (!is_valid_stackpointer(last_known_good_frame, stack_base, stack_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   600
    return NULL;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   601
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   602
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   603
  stackptr_t sp = last_known_good_frame;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   604
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   605
  sp += 6; // Omit next fixed frame slots.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   606
  while (sp < stack_base) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   607
    if (is_valid_frame(sp, stack_base, stack_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   608
      return sp;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   609
    }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   610
    sp ++;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   611
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   612
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   613
  return NULL;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   614
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   615
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   616
static void decode_instructions_at_pc(const char* header,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   617
                                      codeptr_t pc, int num_before,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   618
                                      int num_after, outputStream* st) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   619
  // TODO: PPC port Disassembler::decode(pc, 16, 16, st);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   620
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   621
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   622
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   623
void AixNativeCallstack::print_callstack_for_context(outputStream* st, const ucontext_t* context,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   624
                                                     bool demangle, char* buf, size_t buf_size) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   625
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   626
#define MAX_CALLSTACK_DEPTH 50
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   627
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   628
  unsigned long* sp;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   629
  unsigned long* sp_last;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   630
  int frame;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   631
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   632
  // To print the first frame, use the current value of iar:
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   633
  // current entry indicated by iar (the current pc)
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   634
  codeptr_t cur_iar = 0;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   635
  stackptr_t cur_sp = 0;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   636
  codeptr_t cur_rtoc = 0;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   637
  codeptr_t cur_lr = 0;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   638
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   639
  const ucontext_t* uc = (const ucontext_t*) context;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   640
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   641
  // fallback: use the current context
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   642
  ucontext_t local_context;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   643
  if (!uc) {
46567
30efdd5f0dc9 8182864: [aix] os::print_native_callstack should not assert for primordial threadness
stuefe
parents: 35606
diff changeset
   644
    st->print_cr("No context given, using current context.");
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   645
    if (getcontext(&local_context) == 0) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   646
      uc = &local_context;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   647
    } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   648
      st->print_cr("No context given and getcontext failed. ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   649
      return;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   650
    }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   651
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   652
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   653
  cur_iar = (codeptr_t)uc->uc_mcontext.jmp_context.iar;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   654
  cur_sp = (stackptr_t)uc->uc_mcontext.jmp_context.gpr[1];
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   655
  cur_rtoc = (codeptr_t)uc->uc_mcontext.jmp_context.gpr[2];
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   656
  cur_lr = (codeptr_t)uc->uc_mcontext.jmp_context.lr;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   657
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   658
  // syntax used here:
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   659
  //  n   --------------   <-- stack_base,   stack_to
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   660
  //  n-1 |            |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   661
  //  ... | older      |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   662
  //  ... |   frames   | |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   663
  //      |            | | stack grows downward
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   664
  //  ... | younger    | |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   665
  //  ... |   frames   | V
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   666
  //      |            |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   667
  //      |------------|   <-- cur_sp, current stack ptr
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   668
  //      |            |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   669
  //      |  unsused   |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   670
  //      |    stack   |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   671
  //      |            |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   672
  //      .            .
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   673
  //      .            .
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   674
  //      .            .
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   675
  //      .            .
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   676
  //      |            |
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   677
  //   0  --------------   <-- stack_from
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   678
  //
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   679
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   680
  // Retrieve current stack base, size from the current thread. If there is none,
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   681
  // retrieve it from the OS.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   682
  stackptr_t stack_base = NULL;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   683
  size_t stack_size = NULL;
46576
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   684
  {
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   685
    AixMisc::stackbounds_t stackbounds;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   686
    if (!AixMisc::query_stack_bounds_for_current_thread(&stackbounds)) {
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   687
      st->print_cr("Cannot retrieve stack bounds.");
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   688
      return;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   689
    }
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   690
    stack_base = (stackptr_t)stackbounds.base;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   691
    stack_size = stackbounds.size;
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   692
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   693
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   694
  st->print_cr("------ current frame:");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   695
  st->print("iar:  " PTR64_FORMAT " ", p2i(cur_iar));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   696
  print_info_for_pc(st, cur_iar, buf, buf_size, demangle);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   697
  st->cr();
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   698
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   699
  if (cur_iar && MiscUtils::is_readable_pointer(cur_iar)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   700
    decode_instructions_at_pc(
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   701
      "Decoded instructions at iar:",
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   702
      cur_iar, 32, 16, st);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   703
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   704
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   705
  // Print out lr too, which may be interesting if we did jump to some bogus location;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   706
  // in those cases the new frame is not built up yet and the caller location is only
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   707
  // preserved via lr register.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   708
  st->print("lr:   " PTR64_FORMAT " ", p2i(cur_lr));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   709
  print_info_for_pc(st, cur_lr, buf, buf_size, demangle);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   710
  st->cr();
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   711
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   712
  if (cur_lr && MiscUtils::is_readable_pointer(cur_lr)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   713
    decode_instructions_at_pc(
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   714
      "Decoded instructions at lr:",
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   715
      cur_lr, 32, 16, st);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   716
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   717
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   718
  // Check and print sp.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   719
  st->print("sp:   " PTR64_FORMAT " ", p2i(cur_sp));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   720
  if (!is_valid_stackpointer(cur_sp, stack_base, stack_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   721
    st->print("(invalid) ");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   722
    goto cleanup;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   723
  } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   724
    st->print("(base - 0x%X) ", PTRDIFF_BYTES(stack_base, cur_sp));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   725
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   726
  st->cr();
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   727
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   728
  // Check and print rtoc.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   729
  st->print("rtoc: "  PTR64_FORMAT " ", p2i(cur_rtoc));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   730
  if (cur_rtoc == NULL || cur_rtoc == (codeptr_t)-1 ||
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   731
      !MiscUtils::is_readable_pointer(cur_rtoc)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   732
    st->print("(invalid)");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   733
  } else if (((uintptr_t)cur_rtoc) & 0x7) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   734
    st->print("(unaligned)");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   735
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   736
  st->cr();
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   737
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   738
  st->print_cr("|---stackaddr----|   |----lrsave------|:   <function name>");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   739
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   740
  ///
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   741
  // Walk callstack.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   742
  //
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   743
  // (if no context was given, use the current stack)
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   744
  sp = (unsigned long*)(*(unsigned long*)cur_sp); // Stack pointer
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   745
  sp_last = cur_sp;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   746
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   747
  frame = 0;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   748
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   749
  while (frame < MAX_CALLSTACK_DEPTH) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   750
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   751
    // Check sp.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   752
    bool retry = false;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   753
    if (sp == NULL) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   754
      // The backchain pointer was NULL. This normally means the end of the chain. But the
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   755
      // stack might be corrupted, and it may be worth looking for the stack chain.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   756
      if (is_valid_stackpointer(sp_last, stack_base, stack_size) && (stack_base - 0x10) > sp_last) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   757
        // If we are not within <guess> 0x10 stackslots of the stack base, we assume that this
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   758
        // is indeed not the end of the chain but that the stack was corrupted. So lets try to
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   759
        // find the end of the chain.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   760
        st->print_cr("*** back chain pointer is NULL - end of stack or broken backchain ? ***");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   761
        retry = true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   762
      } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   763
        st->print_cr("*** end of backchain ***");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   764
        goto end_walk_callstack;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   765
      }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   766
    } else if (!is_valid_stackpointer(sp, stack_base, stack_size)) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   767
      st->print_cr("*** stack pointer invalid - backchain corrupted (" PTR_FORMAT ") ***", p2i(sp));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   768
      retry = true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   769
    } else if (sp < sp_last) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   770
      st->print_cr("invalid stack pointer: " PTR_FORMAT " (not monotone raising)", p2i(sp));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   771
      retry = true;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   772
    }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   773
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   774
    // If backchain is broken, try to recover, by manually scanning the stack for a pattern
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   775
    // which looks like a valid stack.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   776
    if (retry) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   777
      st->print_cr("trying to recover and find backchain...");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   778
      sp = try_find_backchain(sp_last, stack_base, stack_size);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   779
      if (sp) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   780
        st->print_cr("found something which looks like a backchain at " PTR64_FORMAT ", after 0x%x bytes... ",
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   781
            p2i(sp), PTRDIFF_BYTES(sp, sp_last));
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   782
      } else {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   783
        st->print_cr("did not find a backchain, giving up.");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   784
        goto end_walk_callstack;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   785
      }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   786
    }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   787
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   788
    // Print stackframe.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   789
    print_stackframe(st, sp, buf, buf_size, demangle);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   790
    st->cr();
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   791
    frame ++;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   792
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   793
    // Next stack frame and link area.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   794
    sp_last = sp;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   795
    sp = (unsigned long*)(*sp);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   796
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   797
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   798
  // Prevent endless loops in case of invalid callstacks.
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   799
  if (frame == MAX_CALLSTACK_DEPTH) {
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   800
    st->print_cr("...(stopping after %d frames.", MAX_CALLSTACK_DEPTH);
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   801
  }
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   802
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   803
end_walk_callstack:
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   804
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   805
  st->print_cr("-----------------------");
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   806
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   807
cleanup:
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   808
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   809
  return;
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   810
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   811
}
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   812
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   813
46576
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   814
bool AixMisc::query_stack_bounds_for_current_thread(stackbounds_t* out) {
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   815
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   816
  // Information about this api can be found (a) in the pthread.h header and
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   817
  // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   818
  //
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   819
  // The use of this API to find out the current stack is kind of undefined.
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   820
  // But after a lot of tries and asking IBM about it, I concluded that it is safe
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   821
  // enough for cases where I let the pthread library create its stacks. For cases
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   822
  // where I create an own stack and pass this to pthread_create, it seems not to
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   823
  // work (the returned stack size in that case is 0).
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   824
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   825
  pthread_t tid = pthread_self();
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   826
  struct __pthrdsinfo pinfo;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   827
  char dummy[1]; // Just needed to satisfy pthread_getthrds_np.
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   828
  int dummy_size = sizeof(dummy);
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   829
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   830
  memset(&pinfo, 0, sizeof(pinfo));
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   831
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   832
  const int rc = pthread_getthrds_np(&tid, PTHRDSINFO_QUERY_ALL, &pinfo,
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   833
                                     sizeof(pinfo), dummy, &dummy_size);
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   834
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   835
  if (rc != 0) {
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   836
    fprintf(stderr, "pthread_getthrds_np failed (%d)\n", rc);
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   837
    fflush(stdout);
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   838
    return false;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   839
  }
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   840
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   841
  // The following may happen when invoking pthread_getthrds_np on a pthread
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   842
  // running on a user provided stack (when handing down a stack to pthread
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   843
  // create, see pthread_attr_setstackaddr).
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   844
  // Not sure what to do then.
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   845
  if (pinfo.__pi_stackend == NULL || pinfo.__pi_stackaddr == NULL) {
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   846
    fprintf(stderr, "pthread_getthrds_np - invalid values\n");
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   847
    fflush(stdout);
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   848
    return false;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   849
  }
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   850
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   851
  // Note: we get three values from pthread_getthrds_np:
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   852
  //       __pi_stackaddr, __pi_stacksize, __pi_stackend
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   853
  //
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   854
  // high addr    ---------------------                                                           base, high
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   855
  //
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   856
  //    |         pthread internal data, like ~2K
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   857
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   858
  //    |         ---------------------   __pi_stackend   (usually not page aligned, (xxxxF890))
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   859
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   860
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   861
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   862
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   863
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   864
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   865
  //    |          ---------------------   (__pi_stackend - __pi_stacksize)
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   866
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   867
  //    |          padding to align the following AIX guard pages, if enabled.
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   868
  //    |
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   869
  //    V          ---------------------   __pi_stackaddr                                        low, base - size
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   870
  //
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   871
  // low addr      AIX guard pages, if enabled (AIXTHREAD_GUARDPAGES > 0)
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   872
  //
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   873
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   874
  out->base = (address)pinfo.__pi_stackend;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   875
  address low = (address)pinfo.__pi_stackaddr;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   876
  out->size = out->base - low;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   877
  return true;
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   878
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   879
}
35515
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   880
179755aaa4e0 8145184: [aix] Implement os::platform_print_native_stack on AIX
stuefe
parents: 33743
diff changeset
   881
46576
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   882
0b817584e8a9 8182984: [aix] Make stack traces independent on successful vm initialization
stuefe
parents: 46567
diff changeset
   883