23 *
24 */
25
26 // According to the AIX OS doc #pragma alloca must be used
27 // with C++ compiler before referencing the function alloca()
28 #pragma alloca
29
30 // no precompiled headers
31 #include "classfile/classLoader.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "code/icBuffer.hpp"
35 #include "code/vtableStubs.hpp"
36 #include "compiler/compileBroker.hpp"
37 #include "interpreter/interpreter.hpp"
38 #include "jvm_aix.h"
39 #include "libperfstat_aix.hpp"
40 #include "loadlib_aix.hpp"
41 #include "memory/allocation.inline.hpp"
42 #include "memory/filemap.hpp"
43 #include "mutex_aix.inline.hpp"
44 #include "oops/oop.inline.hpp"
45 #include "os_aix.inline.hpp"
46 #include "os_share_aix.hpp"
47 #include "porting_aix.hpp"
48 #include "prims/jniFastGetField.hpp"
49 #include "prims/jvm.h"
50 #include "prims/jvm_misc.hpp"
51 #include "runtime/arguments.hpp"
52 #include "runtime/atomic.inline.hpp"
53 #include "runtime/extendedPC.hpp"
54 #include "runtime/globals.hpp"
55 #include "runtime/interfaceSupport.hpp"
56 #include "runtime/java.hpp"
57 #include "runtime/javaCalls.hpp"
58 #include "runtime/mutexLocker.hpp"
59 #include "runtime/objectMonitor.hpp"
60 #include "runtime/orderAccess.inline.hpp"
61 #include "runtime/os.hpp"
62 #include "runtime/osThread.hpp"
158 #define PV_8 0x300000 /* Power PC 8 */
159 #define PV_8_Compat 0x308000 /* Power PC 8 */
160 #endif
161
162 #define trcVerbose(fmt, ...) { /* PPC port */ \
163 if (Verbose) { \
164 fprintf(stderr, fmt, ##__VA_ARGS__); \
165 fputc('\n', stderr); fflush(stderr); \
166 } \
167 }
168 #define trc(fmt, ...) /* PPC port */
169
170 #define ERRBYE(s) { \
171 trcVerbose(s); \
172 return -1; \
173 }
174
175 // Query dimensions of the stack of the calling thread.
176 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
177
178 // function to check a given stack pointer against given stack limits
179 inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
180 if (((uintptr_t)sp) & 0x7) {
181 return false;
182 }
183 if (sp > stack_base) {
184 return false;
185 }
186 if (sp < (stackptr_t) ((address)stack_base - stack_size)) {
187 return false;
188 }
189 return true;
190 }
191
192 // returns true if function is a valid codepointer
193 inline bool is_valid_codepointer(codeptr_t p) {
194 if (!p) {
195 return false;
196 }
197 if (((uintptr_t)p) & 0x3) {
198 return false;
199 }
200 if (LoadedLibraries::find_for_text_address((address)p) == NULL) {
201 return false;
202 }
203 return true;
204 }
205
206 // Macro to check a given stack pointer against given stack limits and to die if test fails.
207 #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \
208 guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \
209 }
210
211 // Macro to check the current stack pointer against given stacklimits.
212 #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \
213 address sp; \
214 sp = os::current_stack_pointer(); \
215 CHECK_STACK_PTR(sp, stack_base, stack_size); \
216 }
217
218 ////////////////////////////////////////////////////////////////////////////////
219 // global variables (for a description see os_aix.hpp)
220
1370 for (int i = 0; i < n; i++) {
1371 if (pelements[i] != NULL) {
1372 FREE_C_HEAP_ARRAY(char, pelements[i]);
1373 }
1374 }
1375 if (pelements != NULL) {
1376 FREE_C_HEAP_ARRAY(char*, pelements);
1377 }
1378 } else {
1379 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
1380 retval = true;
1381 }
1382 return retval;
1383 }
1384
1385 // Check if addr is inside libjvm.so.
1386 bool os::address_is_in_vm(address addr) {
1387
1388 // Input could be a real pc or a function pointer literal. The latter
1389 // would be a function descriptor residing in the data segment of a module.
1390
1391 const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr);
1392 if (lib) {
1393 if (strcmp(lib->get_shortname(), "libjvm.so") == 0) {
1394 return true;
1395 } else {
1396 return false;
1397 }
1398 } else {
1399 lib = LoadedLibraries::find_for_data_address(addr);
1400 if (lib) {
1401 if (strcmp(lib->get_shortname(), "libjvm.so") == 0) {
1402 return true;
1403 } else {
1404 return false;
1405 }
1406 } else {
1407 return false;
1408 }
1409 }
1410 }
1411
1412 // Resolve an AIX function descriptor literal to a code pointer.
1413 // If the input is a valid code pointer to a text segment of a loaded module,
1414 // it is returned unchanged.
1415 // If the input is a valid AIX function descriptor, it is resolved to the
1416 // code entry point.
1417 // If the input is neither a valid function descriptor nor a valid code pointer,
1418 // NULL is returned.
1419 static address resolve_function_descriptor_to_code_pointer(address p) {
1420
1421 const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(p);
1422 if (lib) {
1423 // its a real code pointer
1424 return p;
1425 } else {
1426 lib = LoadedLibraries::find_for_data_address(p);
1427 if (lib) {
1428 // pointer to data segment, potential function descriptor
1429 address code_entry = (address)(((FunctionDescriptor*)p)->entry());
1430 if (LoadedLibraries::find_for_text_address(code_entry)) {
1431 // Its a function descriptor
1432 return code_entry;
1433 }
1434 }
1435 }
1436 return NULL;
1437 }
1438
1439 bool os::dll_address_to_function_name(address addr, char *buf,
1440 int buflen, int *offset,
1441 bool demangle) {
1442 if (offset) {
1443 *offset = -1;
1444 }
1445 // Buf is not optional, but offset is optional.
1446 assert(buf != NULL, "sanity check");
1447 buf[0] = '\0';
1448
1449 // Resolve function ptr literals first.
1450 addr = resolve_function_descriptor_to_code_pointer(addr);
1451 if (!addr) {
1452 return false;
1453 }
1454
1455 // Go through Decoder::decode to call getFuncName which reads the name from the traceback table.
1456 return Decoder::decode(addr, buf, buflen, offset, demangle);
1457 }
1458
1459 static int getModuleName(codeptr_t pc, // [in] program counter
1460 char* p_name, size_t namelen, // [out] optional: function name
1461 char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
1462 ) {
1463
1464 // initialize output parameters
1465 if (p_name && namelen > 0) {
1466 *p_name = '\0';
1467 }
1468 if (p_errmsg && errmsglen > 0) {
1469 *p_errmsg = '\0';
1470 }
1471
1472 const LoadedLibraryModule* const lib = LoadedLibraries::find_for_text_address((address)pc);
1473 if (lib) {
1474 if (p_name && namelen > 0) {
1475 sprintf(p_name, "%.*s", namelen, lib->get_shortname());
1476 }
1477 return 0;
1478 }
1479
1480 trcVerbose("pc outside any module");
1481
1482 return -1;
1483 }
1484
1485 bool os::dll_address_to_library_name(address addr, char* buf,
1486 int buflen, int* offset) {
1487 if (offset) {
1488 *offset = -1;
1489 }
1490 // Buf is not optional, but offset is optional.
1491 assert(buf != NULL, "sanity check");
1492 buf[0] = '\0';
1493
1494 // Resolve function ptr literals first.
1495 addr = resolve_function_descriptor_to_code_pointer(addr);
1496 if (!addr) {
1497 return false;
1498 }
1499
1500 if (::getModuleName((codeptr_t) addr, buf, buflen, 0, 0) == 0) {
1501 return true;
3770 return fetcher.result();
3771 }
3772
3773 ////////////////////////////////////////////////////////////////////////////////
3774 // debug support
3775
3776 static address same_page(address x, address y) {
3777 intptr_t page_bits = -os::vm_page_size();
3778 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
3779 return x;
3780 else if (x > y)
3781 return (address)(intptr_t(y) | ~page_bits) + 1;
3782 else
3783 return (address)(intptr_t(y) & page_bits);
3784 }
3785
3786 bool os::find(address addr, outputStream* st) {
3787
3788 st->print(PTR_FORMAT ": ", addr);
3789
3790 const LoadedLibraryModule* lib = LoadedLibraries::find_for_text_address(addr);
3791 if (lib) {
3792 lib->print(st);
3793 return true;
3794 } else {
3795 lib = LoadedLibraries::find_for_data_address(addr);
3796 if (lib) {
3797 lib->print(st);
3798 return true;
3799 } else {
3800 st->print_cr("(outside any module)");
3801 }
3802 }
3803
3804 return false;
3805 }
3806
3807 ////////////////////////////////////////////////////////////////////////////////
3808 // misc
3809
3810 // This does not do anything on Aix. This is basically a hook for being
3811 // able to use structured exception handling (thread-local exception filters)
3812 // on, e.g., Win32.
3813 void
3814 os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
3815 JavaCallArguments* args, Thread* thread) {
3816 f(value, method, args, thread);
3817 }
3818
3819 void os::print_statistics() {
3820 }
3821
|
23 *
24 */
25
26 // According to the AIX OS doc #pragma alloca must be used
27 // with C++ compiler before referencing the function alloca()
28 #pragma alloca
29
30 // no precompiled headers
31 #include "classfile/classLoader.hpp"
32 #include "classfile/systemDictionary.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "code/icBuffer.hpp"
35 #include "code/vtableStubs.hpp"
36 #include "compiler/compileBroker.hpp"
37 #include "interpreter/interpreter.hpp"
38 #include "jvm_aix.h"
39 #include "libperfstat_aix.hpp"
40 #include "loadlib_aix.hpp"
41 #include "memory/allocation.inline.hpp"
42 #include "memory/filemap.hpp"
43 #include "misc_aix.hpp"
44 #include "mutex_aix.inline.hpp"
45 #include "oops/oop.inline.hpp"
46 #include "os_aix.inline.hpp"
47 #include "os_share_aix.hpp"
48 #include "porting_aix.hpp"
49 #include "prims/jniFastGetField.hpp"
50 #include "prims/jvm.h"
51 #include "prims/jvm_misc.hpp"
52 #include "runtime/arguments.hpp"
53 #include "runtime/atomic.inline.hpp"
54 #include "runtime/extendedPC.hpp"
55 #include "runtime/globals.hpp"
56 #include "runtime/interfaceSupport.hpp"
57 #include "runtime/java.hpp"
58 #include "runtime/javaCalls.hpp"
59 #include "runtime/mutexLocker.hpp"
60 #include "runtime/objectMonitor.hpp"
61 #include "runtime/orderAccess.inline.hpp"
62 #include "runtime/os.hpp"
63 #include "runtime/osThread.hpp"
159 #define PV_8 0x300000 /* Power PC 8 */
160 #define PV_8_Compat 0x308000 /* Power PC 8 */
161 #endif
162
163 #define trcVerbose(fmt, ...) { /* PPC port */ \
164 if (Verbose) { \
165 fprintf(stderr, fmt, ##__VA_ARGS__); \
166 fputc('\n', stderr); fflush(stderr); \
167 } \
168 }
169 #define trc(fmt, ...) /* PPC port */
170
171 #define ERRBYE(s) { \
172 trcVerbose(s); \
173 return -1; \
174 }
175
176 // Query dimensions of the stack of the calling thread.
177 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
178
179 // Function to check a given stack pointer against given stack limits
180 inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) {
181 if (((uintptr_t)sp) & 0x7) {
182 return false;
183 }
184 if (sp > stack_base) {
185 return false;
186 }
187 if (sp < (stackptr_t) ((address)stack_base - stack_size)) {
188 return false;
189 }
190 return true;
191 }
192
193 // Returns true if function is a valid codepointer
194 inline bool is_valid_codepointer(codeptr_t p) {
195 if (!p) {
196 return false;
197 }
198 if (((uintptr_t)p) & 0x3) {
199 return false;
200 }
201 if (!LoadedLibraries::find_for_text_address(p, NULL)) {
202 return false;
203 }
204 return true;
205 }
206
207 // Macro to check a given stack pointer against given stack limits and to die if test fails.
208 #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \
209 guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \
210 }
211
212 // Macro to check the current stack pointer against given stacklimits.
213 #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \
214 address sp; \
215 sp = os::current_stack_pointer(); \
216 CHECK_STACK_PTR(sp, stack_base, stack_size); \
217 }
218
219 ////////////////////////////////////////////////////////////////////////////////
220 // global variables (for a description see os_aix.hpp)
221
1371 for (int i = 0; i < n; i++) {
1372 if (pelements[i] != NULL) {
1373 FREE_C_HEAP_ARRAY(char, pelements[i]);
1374 }
1375 }
1376 if (pelements != NULL) {
1377 FREE_C_HEAP_ARRAY(char*, pelements);
1378 }
1379 } else {
1380 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
1381 retval = true;
1382 }
1383 return retval;
1384 }
1385
1386 // Check if addr is inside libjvm.so.
1387 bool os::address_is_in_vm(address addr) {
1388
1389 // Input could be a real pc or a function pointer literal. The latter
1390 // would be a function descriptor residing in the data segment of a module.
1391 loaded_module_t lm;
1392 if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL) {
1393 return lm.is_in_vm;
1394 } else if (LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {
1395 return lm.is_in_vm;
1396 } else {
1397 return false;
1398 }
1399
1400 }
1401
1402 // Resolve an AIX function descriptor literal to a code pointer.
1403 // If the input is a valid code pointer to a text segment of a loaded module,
1404 // it is returned unchanged.
1405 // If the input is a valid AIX function descriptor, it is resolved to the
1406 // code entry point.
1407 // If the input is neither a valid function descriptor nor a valid code pointer,
1408 // NULL is returned.
1409 static address resolve_function_descriptor_to_code_pointer(address p) {
1410
1411 if (LoadedLibraries::find_for_text_address(p, NULL) != NULL) {
1412 // its a real code pointer
1413 return p;
1414 } else if (LoadedLibraries::find_for_data_address(p, NULL) != NULL) {
1415 // pointer to data segment, potential function descriptor
1416 address code_entry = (address)(((FunctionDescriptor*)p)->entry());
1417 if (LoadedLibraries::find_for_text_address(code_entry, NULL) != NULL) {
1418 // Its a function descriptor
1419 return code_entry;
1420 }
1421 }
1422
1423 return NULL;
1424 }
1425
1426 bool os::dll_address_to_function_name(address addr, char *buf,
1427 int buflen, int *offset,
1428 bool demangle) {
1429 if (offset) {
1430 *offset = -1;
1431 }
1432 // Buf is not optional, but offset is optional.
1433 assert(buf != NULL, "sanity check");
1434 buf[0] = '\0';
1435
1436 // Resolve function ptr literals first.
1437 addr = resolve_function_descriptor_to_code_pointer(addr);
1438 if (!addr) {
1439 return false;
1440 }
1441
1442 // Go through Decoder::decode to call getFuncName which reads the name from the traceback table.
1443 return Decoder::decode(addr, buf, buflen, offset, demangle);
1444 }
1445
1446 static int getModuleName(codeptr_t pc, // [in] program counter
1447 char* p_name, size_t namelen, // [out] optional: function name
1448 char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
1449 ) {
1450
1451 if (p_name && namelen > 0) {
1452 *p_name = '\0';
1453 }
1454 if (p_errmsg && errmsglen > 0) {
1455 *p_errmsg = '\0';
1456 }
1457
1458 if (p_name && namelen > 0) {
1459 loaded_module_t lm;
1460 if (LoadedLibraries::find_for_text_address(pc, &lm) != NULL) {
1461 strncpy(p_name, lm.shortname, namelen);
1462 p_name[namelen - 1] = '\0';
1463 }
1464 return 0;
1465 }
1466
1467 return -1;
1468 }
1469
1470 bool os::dll_address_to_library_name(address addr, char* buf,
1471 int buflen, int* offset) {
1472 if (offset) {
1473 *offset = -1;
1474 }
1475 // Buf is not optional, but offset is optional.
1476 assert(buf != NULL, "sanity check");
1477 buf[0] = '\0';
1478
1479 // Resolve function ptr literals first.
1480 addr = resolve_function_descriptor_to_code_pointer(addr);
1481 if (!addr) {
1482 return false;
1483 }
1484
1485 if (::getModuleName((codeptr_t) addr, buf, buflen, 0, 0) == 0) {
1486 return true;
3755 return fetcher.result();
3756 }
3757
3758 ////////////////////////////////////////////////////////////////////////////////
3759 // debug support
3760
3761 static address same_page(address x, address y) {
3762 intptr_t page_bits = -os::vm_page_size();
3763 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
3764 return x;
3765 else if (x > y)
3766 return (address)(intptr_t(y) | ~page_bits) + 1;
3767 else
3768 return (address)(intptr_t(y) & page_bits);
3769 }
3770
3771 bool os::find(address addr, outputStream* st) {
3772
3773 st->print(PTR_FORMAT ": ", addr);
3774
3775 loaded_module_t lm;
3776 if ( LoadedLibraries::find_for_text_address(addr, &lm) != NULL ||
3777 LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {
3778 st->print("%s", lm.path);
3779 return true;
3780 }
3781
3782 return false;
3783 }
3784
3785 ////////////////////////////////////////////////////////////////////////////////
3786 // misc
3787
3788 // This does not do anything on Aix. This is basically a hook for being
3789 // able to use structured exception handling (thread-local exception filters)
3790 // on, e.g., Win32.
3791 void
3792 os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
3793 JavaCallArguments* args, Thread* thread) {
3794 f(value, method, args, thread);
3795 }
3796
3797 void os::print_statistics() {
3798 }
3799
|