29 # include <imagehlp.h>
36 # include "utils/dlfcn.h"
44 # include <sys/stat.h>
50 # if HAVE_SGIDEFS_H // irix n32, 64
53 # include <obj_list.h>
56 # if HAVE_MACH_O_DYLD_H // darwin
57 # include <mach-o/dyld.h>
58 # include <mach-o/getsect.h>
69 extern ElfW(Dyn) _DYNAMIC [];
76 #ifndef SHLIB_UNSUPPORTED
77 # define SHLIB_UNSUPPORTED \
78 throw SharedLibraryError ("", "unsupported operation")
84 const std::string& cause)
85 : m_message (
"Shared library operation")
87 if (! context.empty ())
112 enumModules (LPSTR
name, ULONG base_address, PVOID context)
114 IMAGEHLP_MODULE moduleinfo;
118 memset (&moduleinfo, 0,
sizeof (moduleinfo));
119 moduleinfo.SizeOfStruct =
sizeof (moduleinfo);
123 if (SymGetModuleInfo (GetCurrentProcess (), base_address, &moduleinfo))
125 info.m_filename = moduleinfo.LoadedImageName;
126 info.m_text_start = moduleinfo.BaseOfImage;
127 info.m_text_end = moduleinfo.BaseOfImage + moduleinfo.ImageSize;
128 info.m_data_start = 0;
130 info.m_bss_start = 0;
136 info.m_text_start = base_address;
138 info.m_data_start = 0;
140 info.m_bss_start = 0;
158 const char *pathvar =
PATH;
159 const char *
path = pathvar ?
getenv (pathvar) : 0;
174 const char *pathvar =
PATH;
176 const int path_size = strlen(pathvar) + 1 +
path.length () + 1;
178 snprintf (
var, path_size,
"%s=%s", pathvar,
path.c_str ());
180 #if HAVE_COPYING_PUTENV
195 return name +
".dll";
197 return "lib" +
name +
".sl";
199 return "lib" +
name +
".so";
222 #if HAVE_DLOPEN || HAVE_LOAD
229 void *handle = ::dlopen (0, RTLD_LAZY);
232 const char *
msg = ::dlerror ();
233 msg =
msg ?
msg :
"dynamic linker error message lost!";
257 assert(!
name.empty ());
261 #if HAVE_DLOPEN || HAVE_LOAD
263 # define RTLD_GLOBAL 0
266 if (! (handle = ::dlopen (
name.c_str (), RTLD_LAZY | RTLD_GLOBAL)))
268 const char *
msg = ::dlerror ();
269 msg =
msg ?
msg :
"dynamic linker error message lost!";
274 if (! (handle = ::shl_load (
name.c_str (), BIND_DEFERRED, 0L)))
278 if (! (handle = ::LoadLibrary (
name.c_str ())))
303 #if HAVE_SHL_LOAD // hp-ux
314 info.m_bss_start = 0;
320 #elif HAVE_LINK_H // bsd/svr4/elf
321 # if !HAVE_LINK_MAP_L_MAP_START
322 # define l_map_start l_addr
323 # define l_map_end l_addr
325 # if !HAVE_PROGRAM_INVOCATION_NAME
326 static const char *program_invocation_name =
"(unknown program name)";
328 # if HAVE_R_DEBUG // linux/glibc
329 link_map *
p = _r_debug.r_map;
360 for (
ElfW(Dyn) *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)
361 if (dyn->d_tag == DT_DEBUG && dyn->d_un.d_ptr)
363 p = (link_map *) *((
unsigned long *) dyn->d_un.d_ptr + 1);
376 memset (exe, 0,
sizeof (exe));
377 if (::
stat (
"/proc/self/exe", &sbuf) == 0)
378 ::readlink (
"/proc/self/exe", exe,
sizeof (exe)-1);
380 STDC::strncpy (exe, program_invocation_name,
sizeof (exe)-1);
383 for ( ;
p;
p =
p->l_next)
404 info.m_filename = (
p->l_name &&
p->l_name[0] ?
p->l_name : exe);
405 info.m_text_start =
p->l_addr ?
p->l_addr :
p->l_map_start;
406 info.m_text_end =
p->l_addr ?
p->l_addr :
p->l_map_end;
407 info.m_data_start = 0;
409 info.m_bss_start = 0;
415 #elif HAVE_SGIDEFS_H // irix
435 extern ElfW(Obj_Info) *__rld_obj_head;
436 ElfW(Obj_Info) *
p = __rld_obj_head;
438 for ( ;
p;
p = (
ElfW(Obj_Info) *)
p->oi_next)
442 # if defined _MIPS_SIM_ABI32 && _MIPS_SIM == _MIPS_SIM_ABI32
443 info.m_filename = (
const char *)
p->o_path;
444 info.m_text_start =
p->o_praw;
445 info.m_text_end =
p->o_praw;
446 # elif (defined _MIPS_SIM_NABI32 && _MIPS_SIM == _MIPS_SIM_NABI32) \
447 || (defined _MIPS_SIM_ABI64 && _MIPS_SIM == _MIPS_SIM_ABI64)
448 info.m_filename = (
const char *)
p->oi_pathname;
449 info.m_text_start =
p->oi_ehdr;
450 info.m_text_end =
p->oi_ehdr;
452 # error "Unsupported ABI: not o32, n32 or 64"
454 info.m_data_start = 0;
456 info.m_bss_start = 0;
462 #elif HAVE_LOADER_H && HAVE_LDR_NEXT_MODULE_DECL // tru64
463 ldr_process_t
proc = ldr_my_process ();
464 ldr_module_t
mod = LDR_NULL_MODULE;
465 int ret = ldr_next_module (
proc, &
mod);
467 for (; ret == 0 &&
mod != LDR_NULL_MODULE; ret = ldr_next_module (
proc, &
mod))
469 ldr_module_info_t
info;
484 for (
int i = 0;
i <
info.lmi_nregion; ++
i)
486 ldr_region_info_t rinfo;
490 if (ldr_inq_region(
proc,
mod,
i, &rinfo,
sizeof(rinfo), &
size) < 0)
493 low = (
unsigned long) rinfo.lri_mapaddr;
494 high = ((
unsigned long) rinfo.lri_mapaddr) + rinfo.lri_size;
496 if (!strcmp(rinfo.lri_name,
".text")) {
499 }
else if (!strcmp(rinfo.lri_name,
".data")) {
502 }
else if (!strcmp(rinfo.lri_name,
".bss")) {
514 #elif HAVE_LOAD && HAVE_LOAD_DECL // aix
520 while (
error == -1 && errno == ENOMEM)
522 delete [] (ld_info *)
buffer;
534 const char *
path =
ld->ldinfo_filename;
535 const char *member =
path + strlen (
path) + 1;
547 info.m_text_start = (
unsigned long)
ld->ldinfo_textorg;
548 info.m_text_end =
info.m_text_start +
ld->ldinfo_textsize;
549 info.m_data_start = (
unsigned long)
ld->ldinfo_dataorg;
550 info.m_data_end =
info.m_data_start +
ld->ldinfo_datasize;
551 info.m_bss_start = 0;
562 delete [] (ld_info *)
buffer;
564 #elif HAVE_MACH_O_DYLD_H // darwin
565 unsigned long images = _dyld_image_count ();
566 for (
unsigned long i = 0;
i < images; ++
i)
568 const mach_header *hdr = _dyld_get_image_header (
i);
569 unsigned long slide = _dyld_get_image_vmaddr_slide (
i);
574 info.m_filename = _dyld_get_image_name (
i);
576 sect = getsectdatafromheader (hdr, SEG_TEXT, SECT_TEXT, &
size);
577 info.m_text_start = sect ? (
unsigned long) sect + slide : 0;
578 info.m_text_end = sect ? (
unsigned long) sect + slide +
size : 0;
579 sect = getsectdatafromheader (hdr, SEG_DATA, SECT_DATA, &
size);
580 info.m_data_start = sect ? (
unsigned long) sect + slide : 0;
581 info.m_data_end = sect ? (
unsigned long) sect + slide +
size : 0;
582 sect = getsectdatafromheader (hdr, SEG_DATA, SECT_BSS, &
size);
583 info.m_bss_start = sect ? (
unsigned long) sect + slide : 0;
584 info.m_bss_end = sect ? (
unsigned long) sect + slide +
size : 0;
589 #elif defined _WIN32 // windows
590 if (! SymInitialize (GetCurrentProcess (), NULL,
TRUE)
591 || ! SymEnumerateModules (GetCurrentProcess (), &enumModules, (
void *) &
handler)
592 || ! SymCleanup (GetCurrentProcess ()))
620 #if HAVE_DLOPEN || HAVE_LOAD
625 ::FreeLibrary ((HINSTANCE)
m_handle);
656 assert (!
name.empty ());
661 #if HAVE_DLOPEN || HAVE_LOAD
663 const char *
error = 0;
664 symbol = ::dlsym (
m_handle, mangled.c_str ());
665 if (! symbol && (
error = ::dlerror ()) != 0)
670 if (::shl_findsym (&handle, mangled.c_str (), TYPE_DATA, &symbol) != 0)
672 assert (handle == (shl_t)
m_handle);
675 if (! (symbol = (
Data)::GetProcAddress((HINSTANCE)
m_handle, mangled.c_str())))
694 assert (!
name.empty ());
699 #if HAVE_DLOPEN || HAVE_LOAD
701 const char *
error = 0;
703 sym.data = ::dlsym (
m_handle, mangled.c_str ());
704 if (! sym.data && (
error = ::dlerror ()) != 0)
710 if (::shl_findsym (&handle, mangled.c_str (), TYPE_PROCEDURE, &symbol) != 0)
712 assert (handle == (shl_t)
m_handle);