jdk
1/*
2* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*
5* This code is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License version 2 only, as
7* published by the Free Software Foundation. Oracle designates this
8* particular file as subject to the "Classpath" exception as provided
9* by Oracle in the LICENSE file that accompanied this code.
10*
11* This code is distributed in the hope that it will be useful, but WITHOUT
12* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14* version 2 for more details (a copy is included in the LICENSE file that
15* accompanied this code).
16*
17* You should have received a copy of the GNU General Public License version
18* 2 along with this work; if not, write to the Free Software Foundation,
19* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*
21* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22* or visit www.oracle.com if you need additional information or have any
23* questions.
24*
25*/
26
27#include <stdio.h>28#include <string.h>29#include <sys/ldr.h>30#include <errno.h>31
32#include "porting_aix.h"33
34static unsigned char dladdr_buffer[0x8000];35
36static void fill_dll_info(void) {37int rc = loadquery(L_GETINFO,dladdr_buffer, sizeof(dladdr_buffer));38if (rc == -1) {39fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno));40fflush(stderr);41}42}
43
44static int dladdr_dont_reload(void* addr, Dl_info* info) {45const struct ld_info* p = (struct ld_info*) dladdr_buffer;46memset((void *)info, 0, sizeof(Dl_info));47for (;;) {48if (addr >= p->ldinfo_textorg &&49(char*)addr < (char*)(p->ldinfo_textorg) + p->ldinfo_textsize) {50info->dli_fname = p->ldinfo_filename;51info->dli_fbase = p->ldinfo_textorg;52return 1; /* [sic] */53}54if (!p->ldinfo_next) {55break;56}57p = (struct ld_info*)(((char*)p) + p->ldinfo_next);58}59return 0; /* [sic] */60}
61
62#ifdef __cplusplus63extern "C"64#endif65int dladdr(void *addr, Dl_info *info) {66static int loaded = 0;67if (!loaded) {68fill_dll_info();69loaded = 1;70}71if (!addr) {72return 0; /* [sic] */73}74/* Address could be AIX function descriptor? */75void* const addr0 = *( (void**) addr );76int rc = dladdr_dont_reload(addr, info);77if (rc == 0) {78rc = dladdr_dont_reload(addr0, info);79if (rc == 0) { /* [sic] */80fill_dll_info(); /* refill, maybe loadquery info is outdated */81rc = dladdr_dont_reload(addr, info);82if (rc == 0) {83rc = dladdr_dont_reload(addr0, info);84}85}86}87return rc;88}
89