Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c
32287 views
1
/*
2
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
#include <sys/types.h>
42
#include <sys/stat.h>
43
#include <fcntl.h>
44
45
#if !defined(LINUX) && !defined(_ALLBSD_SOURCE) && !defined(AIX)
46
#include <procfs.h>
47
#endif
48
49
#include <stdio.h>
50
#include <stdlib.h>
51
#include <string.h>
52
#include <sys/socket.h>
53
#include <sys/errno.h>
54
#include <unistd.h>
55
#include <errno.h>
56
#include <dlfcn.h>
57
#include <sys/time.h>
58
59
#include <netdb.h>
60
#include <netinet/in.h>
61
#include <sys/param.h>
62
#include <time.h>
63
64
#include "jni.h"
65
#include "jvm_md.h"
66
#include "hprof.h"
67
68
#ifdef AIX
69
#include "porting_aix.h" /* For the 'dladdr' function. */
70
#endif
71
72
int
73
md_getpid(void)
74
{
75
static int pid = -1;
76
77
if ( pid >= 0 ) {
78
return pid;
79
}
80
pid = getpid();
81
return pid;
82
}
83
84
void
85
md_sleep(unsigned seconds)
86
{
87
sleep(seconds);
88
}
89
90
void
91
md_init(void)
92
{
93
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
94
/* No Hi-Res timer option? */
95
#else
96
if ( gdata->micro_state_accounting ) {
97
char proc_ctl_fn[48];
98
int procfd;
99
100
/* Turn on micro state accounting, once per process */
101
(void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
102
"/proc/%d/ctl", md_getpid());
103
104
procfd = open(proc_ctl_fn, O_WRONLY);
105
if (procfd >= 0) {
106
long ctl_op[2];
107
108
ctl_op[0] = PCSET;
109
ctl_op[1] = PR_MSACCT;
110
(void)write(procfd, ctl_op, sizeof(ctl_op));
111
(void)close(procfd);
112
}
113
}
114
#endif
115
}
116
117
int
118
md_connect(char *hostname, unsigned short port)
119
{
120
struct hostent *hentry;
121
struct sockaddr_in s;
122
int fd;
123
124
/* create a socket */
125
fd = socket(AF_INET, SOCK_STREAM, 0);
126
if ( fd < 0 ) {
127
return -1;
128
}
129
130
/* find remote host's addr from name */
131
if ((hentry = gethostbyname(hostname)) == NULL) {
132
(void)close(fd);
133
return -1;
134
}
135
(void)memset((char *)&s, 0, sizeof(s));
136
/* set remote host's addr; its already in network byte order */
137
(void)memcpy(&s.sin_addr.s_addr, *(hentry->h_addr_list),
138
(int)sizeof(s.sin_addr.s_addr));
139
/* set remote host's port */
140
s.sin_port = htons(port);
141
s.sin_family = AF_INET;
142
143
/* now try connecting */
144
if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
145
(void)close(fd);
146
return 0;
147
}
148
return fd;
149
}
150
151
int
152
md_recv(int f, char *buf, int len, int option)
153
{
154
return recv(f, buf, len, option);
155
}
156
157
int
158
md_shutdown(int filedes, int option)
159
{
160
return shutdown(filedes, option);
161
}
162
163
int
164
md_open(const char *filename)
165
{
166
return open(filename, O_RDONLY);
167
}
168
169
int
170
md_open_binary(const char *filename)
171
{
172
return md_open(filename);
173
}
174
175
int
176
md_creat(const char *filename)
177
{
178
return open(filename, O_WRONLY | O_CREAT | O_TRUNC,
179
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
180
}
181
182
int
183
md_creat_binary(const char *filename)
184
{
185
return md_creat(filename);
186
}
187
188
jlong
189
md_seek(int filedes, jlong cur)
190
{
191
jlong new_pos;
192
193
if ( cur == (jlong)-1 ) {
194
new_pos = lseek(filedes, 0, SEEK_END);
195
} else {
196
new_pos = lseek(filedes, cur, SEEK_SET);
197
}
198
return new_pos;
199
}
200
201
void
202
md_close(int filedes)
203
{
204
(void)close(filedes);
205
}
206
207
int
208
md_send(int s, const char *msg, int len, int flags)
209
{
210
int res;
211
212
do {
213
res = send(s, msg, len, flags);
214
} while ((res < 0) && (errno == EINTR));
215
216
return res;
217
}
218
219
int
220
md_write(int filedes, const void *buf, int nbyte)
221
{
222
int res;
223
224
do {
225
res = write(filedes, buf, nbyte);
226
} while ((res < 0) && (errno == EINTR));
227
228
return res;
229
}
230
231
int
232
md_read(int filedes, void *buf, int nbyte)
233
{
234
int res;
235
236
do {
237
res = read(filedes, buf, nbyte);
238
} while ((res < 0) && (errno == EINTR));
239
240
return res;
241
}
242
243
/* Time of day in milli-seconds */
244
static jlong
245
md_timeofday(void)
246
{
247
struct timeval tv;
248
249
if ( gettimeofday(&tv, (void *)0) != 0 ) {
250
return (jlong)0; /* EOVERFLOW ? */
251
}
252
/*LINTED*/
253
return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
254
}
255
256
/* Hi-res timer in micro-seconds */
257
jlong
258
md_get_microsecs(void)
259
{
260
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
261
return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
262
#else
263
return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
264
#endif
265
}
266
267
/* Time of day in milli-seconds */
268
jlong
269
md_get_timemillis(void)
270
{
271
return md_timeofday();
272
}
273
274
/* Current CPU hi-res CPU time used */
275
jlong
276
md_get_thread_cpu_timemillis(void)
277
{
278
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
279
return md_timeofday();
280
#else
281
return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
282
#endif
283
}
284
285
void
286
md_get_prelude_path(char *path, int path_len, char *filename)
287
{
288
void *addr;
289
char libdir[FILENAME_MAX+1];
290
Dl_info dlinfo;
291
292
libdir[0] = 0;
293
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
294
addr = (void*)&Agent_OnLoad;
295
#else
296
/* Just using &Agent_OnLoad will get the first external symbol with
297
* this name in the first .so, which may not be libhprof.so.
298
* On Solaris we can actually ask for the address of our Agent_OnLoad.
299
*/
300
addr = dlsym(RTLD_SELF, "Agent_OnLoad");
301
/* Just in case the above didn't work (missing linker patch?). */
302
if ( addr == NULL ) {
303
addr = (void*)&Agent_OnLoad;
304
}
305
#endif
306
307
/* Use dladdr() to get the full path to libhprof.so, which we use to find
308
* the prelude file.
309
*/
310
dlinfo.dli_fname = NULL;
311
(void)dladdr(addr, &dlinfo);
312
if ( dlinfo.dli_fname != NULL ) {
313
char * lastSlash;
314
315
/* Full path to library name, need to move up one directory to 'lib' */
316
(void)strcpy(libdir, (char *)dlinfo.dli_fname);
317
lastSlash = strrchr(libdir, '/');
318
if ( lastSlash != NULL ) {
319
*lastSlash = '\0';
320
}
321
#ifndef __APPLE__
322
// not sure why other platforms have to go up two levels, but on macos we only need up one
323
lastSlash = strrchr(libdir, '/');
324
if ( lastSlash != NULL ) {
325
*lastSlash = '\0';
326
}
327
#endif /* __APPLE__ */
328
}
329
(void)snprintf(path, path_len, "%s/%s", libdir, filename);
330
}
331
332
333
int
334
md_vsnprintf(char *s, int n, const char *format, va_list ap)
335
{
336
return vsnprintf(s, n, format, ap);
337
}
338
339
int
340
md_snprintf(char *s, int n, const char *format, ...)
341
{
342
int ret;
343
va_list ap;
344
345
va_start(ap, format);
346
ret = md_vsnprintf(s, n, format, ap);
347
va_end(ap);
348
return ret;
349
}
350
351
void
352
md_system_error(char *buf, int len)
353
{
354
char *p;
355
356
buf[0] = 0;
357
p = strerror(errno);
358
if ( p != NULL ) {
359
(void)strcpy(buf, p);
360
}
361
}
362
363
unsigned
364
md_htons(unsigned short s)
365
{
366
return htons(s);
367
}
368
369
unsigned
370
md_htonl(unsigned l)
371
{
372
return htonl(l);
373
}
374
375
unsigned
376
md_ntohs(unsigned short s)
377
{
378
return ntohs(s);
379
}
380
381
unsigned
382
md_ntohl(unsigned l)
383
{
384
return ntohl(l);
385
}
386
387
static void dll_build_name(char* buffer, size_t buflen,
388
const char* paths, const char* fname) {
389
char *path, *paths_copy, *next_token;
390
391
paths_copy = strdup(paths);
392
if (paths_copy == NULL) {
393
return;
394
}
395
396
next_token = NULL;
397
path = strtok_r(paths_copy, ":", &next_token);
398
399
while (path != NULL) {
400
snprintf(buffer, buflen, "%s/lib%s" JNI_LIB_SUFFIX, path, fname);
401
if (access(buffer, F_OK) == 0) {
402
break;
403
}
404
*buffer = '\0';
405
path = strtok_r(NULL, ":", &next_token);
406
}
407
408
free(paths_copy);
409
}
410
411
/* Create the actual fill filename for a dynamic library. */
412
void
413
md_build_library_name(char *holder, int holderlen, const char *pname, const char *fname)
414
{
415
int pnamelen;
416
417
/* Length of options directory location. */
418
pnamelen = pname ? strlen(pname) : 0;
419
420
*holder = '\0';
421
/* Quietly truncate on buffer overflow. Should be an error. */
422
if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
423
return;
424
}
425
426
/* Construct path to library */
427
if (pnamelen == 0) {
428
(void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname);
429
} else {
430
dll_build_name(holder, holderlen, pname, fname);
431
}
432
}
433
434
/* Load this library (return NULL on error, and error message in err_buf) */
435
void *
436
md_load_library(const char *name, char *err_buf, int err_buflen)
437
{
438
void * result;
439
440
result = dlopen(name, RTLD_LAZY);
441
if (result == NULL) {
442
(void)strncpy(err_buf, dlerror(), err_buflen-2);
443
err_buf[err_buflen-1] = '\0';
444
}
445
return result;
446
}
447
448
/* Unload this library */
449
void
450
md_unload_library(void *handle)
451
{
452
(void)dlclose(handle);
453
}
454
455
/* Find an entry point inside this library (return NULL if not found) */
456
void *
457
md_find_library_entry(void *handle, const char *name)
458
{
459
void * sym;
460
461
sym = dlsym(handle, name);
462
return sym;
463
}
464
465
466
467