28 # include <imagehlp.h>
35 # include "utils/dlfcn.h"
43 # include <sys/stat.h>
49 # if HAVE_SGIDEFS_H // irix n32, 64
52 # include <obj_list.h>
55 # if HAVE_MACH_O_DYLD_H // darwin
56 # include <mach-o/dyld.h>
57 # include <mach-o/getsect.h>
68 extern ElfW(Dyn) _DYNAMIC [];
74 #ifndef SHLIB_UNSUPPORTED
75 # define SHLIB_UNSUPPORTED \
76 throw SharedLibraryError ("", "unsupported operation")
82 const std::string& cause)
83 : m_message (
"Shared library operation")
85 if (! context.empty ())
110 enumModules (LPSTR
name, ULONG base_address, PVOID context)
112 IMAGEHLP_MODULE moduleinfo;
116 memset (&moduleinfo, 0,
sizeof (moduleinfo));
117 moduleinfo.SizeOfStruct =
sizeof (moduleinfo);
121 if (SymGetModuleInfo (GetCurrentProcess (), base_address, &moduleinfo))
123 info.m_filename = moduleinfo.LoadedImageName;
124 info.m_text_start = moduleinfo.BaseOfImage;
125 info.m_text_end = moduleinfo.BaseOfImage + moduleinfo.ImageSize;
126 info.m_data_start = 0;
128 info.m_bss_start = 0;
134 info.m_text_start = base_address;
136 info.m_data_start = 0;
138 info.m_bss_start = 0;
150 const char *pathvar =
PATH;
151 const char *
path = pathvar ?
getenv (pathvar) : 0;
166 const char *pathvar =
PATH;
168 setenv(pathvar,
path.c_str(),1);
181 return name +
".dll";
183 return "lib" +
name +
".sl";
185 return "lib" +
name +
".so";
208 #if HAVE_DLOPEN || HAVE_LOAD
215 void *handle = ::dlopen (0, RTLD_LAZY);
218 const char *
msg = ::dlerror ();
219 msg =
msg ?
msg :
"dynamic linker error message lost!";
243 assert(!
name.empty ());
247 #if HAVE_DLOPEN || HAVE_LOAD
249 # define RTLD_GLOBAL 0
252 if (! (handle = ::dlopen (
name.c_str (), RTLD_LAZY | RTLD_GLOBAL)))
254 const char *
msg = ::dlerror ();
255 msg =
msg ?
msg :
"dynamic linker error message lost!";
260 if (! (handle = ::shl_load (
name.c_str (), BIND_DEFERRED, 0L)))
264 if (! (handle = ::LoadLibrary (
name.c_str ())))
289 #if HAVE_SHL_LOAD // hp-ux
300 info.m_bss_start = 0;
306 #elif HAVE_LINK_H // bsd/svr4/elf
307 # if !HAVE_LINK_MAP_L_MAP_START
308 # define l_map_start l_addr
309 # define l_map_end l_addr
311 # if !HAVE_PROGRAM_INVOCATION_NAME
312 static const char *program_invocation_name =
"(unknown program name)";
314 # if HAVE_R_DEBUG // linux/glibc
315 link_map *
p = _r_debug.r_map;
346 for (
ElfW(Dyn) *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
347 if (dyn->d_tag == DT_DEBUG && dyn->d_un.d_ptr)
349 p = (link_map *) *((
unsigned long *) dyn->d_un.d_ptr + 1);
362 memset (exe, 0,
sizeof (exe));
363 if (::
stat (
"/proc/self/exe", &sbuf) == 0)
364 ::readlink (
"/proc/self/exe", exe,
sizeof (exe)-1);
366 STDC::strncpy (exe, program_invocation_name,
sizeof (exe)-1);
369 for ( ;
p;
p =
p->l_next)
390 info.m_filename = (
p->l_name &&
p->l_name[0] ?
p->l_name : exe);
391 info.m_text_start =
p->l_addr ?
p->l_addr :
p->l_map_start;
392 info.m_text_end =
p->l_addr ?
p->l_addr :
p->l_map_end;
393 info.m_data_start = 0;
395 info.m_bss_start = 0;
401 #elif HAVE_SGIDEFS_H // irix
421 extern ElfW(Obj_Info) *__rld_obj_head;
422 ElfW(Obj_Info) *
p = __rld_obj_head;
424 for ( ;
p;
p = (
ElfW(Obj_Info) *)
p->oi_next)
428 # if defined _MIPS_SIM_ABI32 && _MIPS_SIM == _MIPS_SIM_ABI32
429 info.m_filename = (
const char *)
p->o_path;
430 info.m_text_start =
p->o_praw;
431 info.m_text_end =
p->o_praw;
432 # elif (defined _MIPS_SIM_NABI32 && _MIPS_SIM == _MIPS_SIM_NABI32) \
433 || (defined _MIPS_SIM_ABI64 && _MIPS_SIM == _MIPS_SIM_ABI64)
434 info.m_filename = (
const char *)
p->oi_pathname;
435 info.m_text_start =
p->oi_ehdr;
436 info.m_text_end =
p->oi_ehdr;
438 # error "Unsupported ABI: not o32, n32 or 64"
440 info.m_data_start = 0;
442 info.m_bss_start = 0;
448 #elif HAVE_LOADER_H && HAVE_LDR_NEXT_MODULE_DECL // tru64
449 ldr_process_t
proc = ldr_my_process ();
450 ldr_module_t
mod = LDR_NULL_MODULE;
451 int ret = ldr_next_module (
proc, &
mod);
453 for (; ret == 0 &&
mod != LDR_NULL_MODULE; ret = ldr_next_module (
proc, &
mod))
455 ldr_module_info_t
info;
470 for (
int i = 0;
i <
info.lmi_nregion; ++
i)
472 ldr_region_info_t rinfo;
476 if (ldr_inq_region(
proc,
mod,
i, &rinfo,
sizeof(rinfo), &
size) < 0)
479 low = (
unsigned long) rinfo.lri_mapaddr;
480 high = ((
unsigned long) rinfo.lri_mapaddr) + rinfo.lri_size;
482 if (!strcmp(rinfo.lri_name,
".text")) {
485 }
else if (!strcmp(rinfo.lri_name,
".data")) {
488 }
else if (!strcmp(rinfo.lri_name,
".bss")) {
500 #elif HAVE_LOAD && HAVE_LOAD_DECL // aix
506 while (
error == -1 && errno == ENOMEM)
508 delete [] (ld_info *)
buffer;
520 const char *
path =
ld->ldinfo_filename;
521 const char *member =
path + strlen (
path) + 1;
533 info.m_text_start = (
unsigned long)
ld->ldinfo_textorg;
534 info.m_text_end =
info.m_text_start +
ld->ldinfo_textsize;
535 info.m_data_start = (
unsigned long)
ld->ldinfo_dataorg;
536 info.m_data_end =
info.m_data_start +
ld->ldinfo_datasize;
537 info.m_bss_start = 0;
548 delete [] (ld_info *)
buffer;
550 #elif HAVE_MACH_O_DYLD_H // darwin
551 unsigned long images = _dyld_image_count ();
552 for (
unsigned long i = 0;
i < images; ++
i)
554 const mach_header *hdr = _dyld_get_image_header (
i);
555 unsigned long slide = _dyld_get_image_vmaddr_slide (
i);
560 info.m_filename = _dyld_get_image_name (
i);
562 sect = getsectdatafromheader (hdr, SEG_TEXT, SECT_TEXT, &
size);
563 info.m_text_start = sect ? (
unsigned long) sect + slide : 0;
564 info.m_text_end = sect ? (
unsigned long) sect + slide +
size : 0;
565 sect = getsectdatafromheader (hdr, SEG_DATA, SECT_DATA, &
size);
566 info.m_data_start = sect ? (
unsigned long) sect + slide : 0;
567 info.m_data_end = sect ? (
unsigned long) sect + slide +
size : 0;
568 sect = getsectdatafromheader (hdr, SEG_DATA, SECT_BSS, &
size);
569 info.m_bss_start = sect ? (
unsigned long) sect + slide : 0;
570 info.m_bss_end = sect ? (
unsigned long) sect + slide +
size : 0;
575 #elif defined _WIN32 // windows
576 if (! SymInitialize (GetCurrentProcess (), NULL,
TRUE)
577 || ! SymEnumerateModules (GetCurrentProcess (), &enumModules, (
void *) &
handler)
578 || ! SymCleanup (GetCurrentProcess ()))
606 #if HAVE_DLOPEN || HAVE_LOAD
611 ::FreeLibrary ((HINSTANCE)
m_handle);
642 assert (!
name.empty ());
647 #if HAVE_DLOPEN || HAVE_LOAD
649 const char *
error = 0;
650 symbol = ::dlsym (
m_handle, mangled.c_str ());
651 if (! symbol && (
error = ::dlerror ()) != 0)
656 if (::shl_findsym (&handle, mangled.c_str (), TYPE_DATA, &symbol) != 0)
658 assert (handle == (shl_t)
m_handle);
661 if (! (symbol = (
Data)::GetProcAddress((HINSTANCE)
m_handle, mangled.c_str())))
680 assert (!
name.empty ());
685 #if HAVE_DLOPEN || HAVE_LOAD
687 const char *
error = 0;
689 sym.data = ::dlsym (
m_handle, mangled.c_str ());
690 if (! sym.data && (
error = ::dlerror ()) != 0)
696 if (::shl_findsym (&handle, mangled.c_str (), TYPE_PROCEDURE, &symbol) != 0)
698 assert (handle == (shl_t)
m_handle);