Exemplo n.º 1
0
void
ruby_init_loadpath_safe(int safe_level)
{
    VALUE load_path;
    extern const char ruby_initial_load_paths[];
    const char *paths = ruby_initial_load_paths;
#if defined LOAD_RELATIVE
# if defined HAVE_DLADDR || (defined __CYGWIN__ && defined CCP_WIN_A_TO_POSIX)
#   define VARIABLE_LIBPATH 1
# else
#   define VARIABLE_LIBPATH 0
# endif
# if VARIABLE_LIBPATH
    char *libpath;
    VALUE sopath;
# else
    char libpath[MAXPATHLEN + 1];
    size_t baselen;
# endif
    char *p;

#if defined _WIN32 || defined __CYGWIN__
# if VARIABLE_LIBPATH
    sopath = rb_str_tmp_new(MAXPATHLEN);
    libpath = RSTRING_PTR(sopath);
    GetModuleFileName(libruby, libpath, MAXPATHLEN);
# else
    GetModuleFileName(libruby, libpath, sizeof libpath);
# endif
#elif defined(__EMX__)
    _execname(libpath, sizeof(libpath) - 1);
#elif defined(HAVE_DLADDR)
    Dl_info dli;
    if (dladdr(expand_include_path, &dli)) {
	VALUE fname = rb_str_new_cstr(dli.dli_fname);
	sopath = rb_file_absolute_path(fname, Qnil);
	rb_str_resize(fname, 0);
    }
    else {
	sopath = rb_str_new(0, 0);
    }
    libpath = RSTRING_PTR(sopath);
#endif

#if !VARIABLE_LIBPATH
    libpath[sizeof(libpath) - 1] = '\0';
#endif
#if defined DOSISH
    translit_char(libpath, '\\', '/');
#elif defined __CYGWIN__
    {
# if VARIABLE_LIBPATH
	const int win_to_posix = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
	size_t newsize = cygwin_conv_path(win_to_posix, libpath, 0, 0);
	if (newsize > 0) {
	    VALUE rubylib = rb_str_tmp_new(newsize);
	    p = RSTRING_PTR(rubylib);
	    if (cygwin_conv_path(win_to_posix, libpath, p, newsize) == 0) {
		rb_str_resize(sopath, 0);
		sopath = rubylib;
		libpath = p;
	    }
	}
# else
	char rubylib[FILENAME_MAX];
	cygwin_conv_to_posix_path(libpath, rubylib);
	strncpy(libpath, rubylib, sizeof(libpath));
# endif
    }
#endif
    p = strrchr(libpath, '/');
    if (p) {
	*p = 0;
	if (p - libpath > 3 && !(STRCASECMP(p - 4, "/bin") && strcmp(p - 4, "/lib"))) {
	    p -= 4;
	    *p = 0;
	}
    }
#if !VARIABLE_LIBPATH
    else {
	strlcpy(libpath, ".", sizeof(libpath));
	p = libpath + 1;
    }

    baselen = p - libpath;

#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)
#else
    rb_str_set_len(sopath, p - libpath);

#define BASEPATH() rb_str_dup(sopath)
#endif

#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), path, len)
#else
#define RUBY_RELATIVE(path, len) rubylib_mangled_path(path, len)
#endif
#define incpush(path) rb_ary_push(load_path, (path))
    load_path = GET_VM()->load_path;

    if (safe_level == 0) {
	ruby_push_include(getenv("RUBYLIB"), identical_path);
    }

    while (*paths) {
	size_t len = strlen(paths);
	incpush(RUBY_RELATIVE(paths, len));
	paths += len + 1;
    }
}
Exemplo n.º 2
0
jint
AWT_OnLoad(JavaVM *vm, void *reserved)
{
    Dl_info dlinfo;
    char buf[MAXPATHLEN];
    int32_t len;
    char *p, *tk = 0;
    JNI_OnLoad_type *JNI_OnLoad_ptr;
    struct utsname name;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(vm, JNI_VERSION_1_2);
    void *v;
    char *envvar;
    jstring fmanager = NULL;
    jstring fmProp = NULL;

    if (awtHandle != NULL) {
        /* Avoid several loading attempts */
        return JNI_VERSION_1_2;
    }

    jvm = vm;

    /* Get address of this library and the directory containing it. */
    dladdr((void *)JNI_OnLoad, &dlinfo);
    realpath((char *)dlinfo.dli_fname, buf);
    len = strlen(buf);
    p = strrchr(buf, '/');

    /*
     * 1. Set the "sun.font.fontmanager" system property,
     * 2. Choose the library image name.
     */

    fmProp = (*env)->NewStringUTF(env, "sun.font.fontmanager");
    /* Check if toolkit is specified in env variable */
#ifdef MACOSX
    envvar = getenv("AWT_TOOLKIT");
    if (envvar && strstr(envvar, "XToolkit")) {
#endif
        fmanager = (*env)->NewStringUTF(env, "sun.awt.X11FontManager");
        tk = "/xawt/libmawt";
#ifdef MACOSX
    } else {
        fmanager = (*env)->NewStringUTF(env, "sun.font.CFontManager");
        tk = "/lwawt/liblwawt";
    }
#endif
    if (fmanager && fmProp) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty",
                                   "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
                                   fmProp, fmanager);
    }

    /* Calculate library name to load */
#ifndef MACOSX
    if (AWTIsHeadless()) {
        strcpy(p, "/headless/libmawt");
    } else if (tk) {
#endif
        strcpy(p, tk);
#ifndef MACOSX
    }
#endif

#ifdef MACOSX
    strcat(p, ".dylib");
#else
    strcat(p, ".so");
#endif

    if (tk) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load",
                                   "(Ljava/lang/String;)V",
                                   JNU_NewStringPlatform(env, buf));
            awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
    }

    return JNI_VERSION_1_2;
}
Exemplo n.º 3
0
void test_dl(int step) {
    Dl_info di;
    dladdr(free, &di);
    printf("di.dli_fname %s\n", di.dli_fname);
    printf("di.dli_sname %s\n", di.dli_sname);
}
bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t n, size_t required, dynamic_link_handle *handle ) {
    // Get library handle in case it is already loaded into the current process
#if _WIN32||_WIN64
    dynamic_link_handle library_handle = GetModuleHandle( library );
#else
    dynamic_link_handle library_handle = dlopen( NULL, RTLD_LAZY );
#endif /* _WIN32||_WIN64 */

    // Get descriptors from the library
    if ( library_handle && dynamic_link( library_handle, descriptors, n, required ) ) {
#if !__TBB_DYNAMIC_LOAD_ENABLED && !__TBB_TASK_CPP_DIRECTLY_INCLUDED
        return true;
#else
        // The library have been loaded by another module and contains requested symbols.
        // But after we obtained the library's handle it can be unloaded by another thread
        // invalidating our handle copy. Therefore we need to pin the library in memory.
#if _WIN32||_WIN64
        char library_full_name[ MAX_PATH+1 ];
        // Get library's name from earlier found handle
        if ( GetModuleFileName( library_handle, library_full_name, MAX_PATH+1 ) ) {
            // Pin the library
            library_handle = LoadLibrary( library_full_name );
            if ( library_handle == NULL ) {
                int err = GetLastError();
                DYNAMIC_LINK_WARNING( dl_lib_not_found, library_full_name, err );
            } // if
        } // if
#else /* !WIN */
        Dl_info info;
        // Get library's name from earlier found symbol
        if ( dladdr( (void*)*descriptors[0].handler, &info ) ) {
            // Pin the library
            library_handle = dlopen( info.dli_fname, RTLD_LAZY );
            if ( library_handle == NULL ) {
                char const * err = dlerror();
                DYNAMIC_LINK_WARNING( dl_lib_not_found, info.dli_fname, err );
            } // if
        } // if
#endif /* !WIN */
        else {
            // The library have been unloaded by another thread
            library_handle = 0;
        }
        if ( library_handle ) {
            // If original library was unloaded before we pinned it
            // and then another module loaded in its place, the earlier
            // found symbols would become invalid. So revalidate them.
            if ( !dynamic_link( library_handle, descriptors, n, required ) ) {
                // Wrong library.
                dynamic_unlink(library_handle);
                library_handle = 0;
            }
        }
        if ( !library_handle ) {
            // Failed to pin the library, so clear the descriptors too.
            for( size_t i=0; i<n; ++i )
                *descriptors[i].handler = 0;
        }
#endif /* __TBB_DYNAMIC_LOAD_ENABLED */
    } else {
        library_handle = 0;
    }

#if __TBB_DYNAMIC_LOAD_ENABLED || __TBB_TASK_CPP_DIRECTLY_INCLUDED
    if ( !library_handle ) {
#if _WIN32||_WIN64
        // Prevent Windows from displaying silly message boxes if it fails to load library
        // (e.g. because of MS runtime problems - one of those crazy manifest related ones)
#if _XBOX
        library_handle = LoadLibrary (library);
#else
        library_handle = NULL;
        // Construct absolute path to the library to avoid security issue.
        size_t const len = MAX_PATH + 1;
        char path[ len ];
        size_t rc = abs_path( library, path, len );
        if ( 0 < rc && rc < len ) {
            UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
            library_handle = LoadLibrary (path);
            SetErrorMode (prev_mode);
            if ( library_handle == NULL ) {
                int err = GetLastError();
                DYNAMIC_LINK_WARNING( dl_lib_not_found, path, err );
            } // if
        } // if
#endif /* !_XBOX */
#else /* !WIN */
        library_handle = dlopen( library, RTLD_LAZY );
        if ( library_handle == NULL ) {
            char const * err = dlerror();
            DYNAMIC_LINK_WARNING( dl_lib_not_found, library, err );
        } // if
#endif /* !WIN */
        if( library_handle ) {
            if( !dynamic_link( library_handle, descriptors, n, required ) ) {
                // The loaded library does not contain all the expected entry points
                dynamic_unlink( library_handle );
                library_handle = NULL;
            }
        }
    }
#endif /* __TBB_DYNAMIC_LOAD_ENABLED */

    if ( library_handle ) {
        if ( handle )
            *handle = library_handle;
#if __TBB_BUILD
        else
            handles.add_handle( library_handle );
#endif /* __TBB_BUILD */
        return true;
    }
    return false;
}
Exemplo n.º 5
0
  void LLVMState::show_machine_code(void* buffer, size_t size) {

#if defined(IS_X86) || defined(IS_X8664)
#ifndef RBX_WINDOWS
    ud_t ud;

    ud_init(&ud);
#ifdef IS_64BIT_ARCH
    ud_set_mode(&ud, 64);
#else
    ud_set_mode(&ud, 32);
#endif
    ud_set_syntax(&ud, UD_SYN_ATT);
    ud_set_input_buffer(&ud, reinterpret_cast<uint8_t*>(buffer), size);

    while(ud_disassemble(&ud)) {
      void* address = reinterpret_cast<void*>(
          reinterpret_cast<uintptr_t>(buffer) + ud_insn_off(&ud));

      llvm::outs() << format("%10p", address) << "  ";
      llvm::outs() << format("%-24s", ud_insn_asm(&ud));
      if(ud.operand[0].type == UD_OP_JIMM) {
        const void* addr = (const void*)((uintptr_t)buffer + ud.pc + (int)ud.operand[0].lval.udword);
        llvm::outs() << " ; " << addr;
        if(ud.mnemonic == UD_Icall) {
          Dl_info info;
          if(dladdr((void*)addr, &info)) {
            int status = 0;
            char* cpp_name = abi::__cxa_demangle(info.dli_sname, 0, 0, &status);
            if(status >= 0) {
              // Chop off the arg info from the signature output
              char *paren = strstr(cpp_name, "(");
              *paren = 0;
              llvm::outs() << " " << cpp_name;
              free(cpp_name);
            } else {
              llvm::outs() << " " << info.dli_sname;
            }
          }
        }
      }

      for(uint8_t i = 0; i < 2; i++) {
        if(ud.operand[i].type == UD_OP_IMM) {
          Dl_info info;
          if(dladdr((void*)ud.operand[i].lval.uqword, &info)) {
            llvm::outs() << " ; " << info.dli_sname;
            break; // only do one
          }
        }
      }

      llvm::outs() << "\n";
    }
#endif  // !RBX_WINDOWS

#else
    JITDisassembler disassembler(buffer, size);
    std::string output = disassembler.print_machine_code();
    std::cout << output;
#endif // !IS_X86

  }
Exemplo n.º 6
0
EAPI Eina_Prefix *
eina_prefix_new(const char *argv0, void *symbol, const char *envprefix,
                const char *sharedir, const char *magicsharefile,
                const char *pkg_bin, const char *pkg_lib,
                const char *pkg_data, const char *pkg_locale)
{
   Eina_Prefix *pfx;
   char *p, buf[4096], *tmp, *magic = NULL;
   struct stat st;
   const char *p1, *p2;
   const char *pkg_bin_p = NULL;
   const char *pkg_lib_p = NULL;
   const char *pkg_data_p = NULL;
   const char *pkg_locale_p = NULL;
   const char *bindir = "bin";
   const char *libdir = "lib";
   const char *datadir = "share";
   const char *localedir = "share";

   DBG("EINA PREFIX: argv0=%s, symbol=%p, magicsharefile=%s, envprefix=%s",
       argv0, symbol, magicsharefile, envprefix);
   pfx = calloc(1, sizeof(Eina_Prefix));
   if (!pfx) return NULL;

   /* if provided with a share dir use datadir/sharedir as the share dir */
   if (sharedir)
     {
        int len;

        len = snprintf(buf, sizeof(buf), "%s" DSEP_S "%s", datadir, sharedir);
        if (len > 0)
          {
#ifdef _WIN32
             /* on win32 convert / to \ for path here */
             for (p = buf + strlen(datadir) + strlen(DSEP_S); *p; p++)
               {
                  if (*p == '/') *p = DSEP_C;
               }
#endif
             tmp = alloca(len + 1);
             strcpy(tmp, buf);
             datadir = tmp;
          }
     }
   if (magicsharefile)
     {
        magic = alloca(strlen(magicsharefile));
        strcpy(magic, magicsharefile);
#ifdef _WIN32
        /* on win32 convert / to \ for path here */
        for (p = magic; *p; p++)
          {
             if (*p == '/') *p = DSEP_C;
          }
#endif
     }

   /* look at compile-time package bin/lib/datadir etc. and figure out the
    * bin, lib and data dirs from these, if possible. i.e.
    *   bin = /usr/local/bin
    *   lib = /usr/local/lib
    *   data = /usr/local/share/enlightenment
    * thus they all have a common prefix string of /usr/local/ and
    *   bindir = bin
    *   libdir = lib
    *   datadir = share/enlightenment
    * this addresses things like libdir is lib64 or lib32 or other such
    * junk distributions like to do so then:
    *   bin = /usr/local/bin
    *   lib = /usr/local/lib64
    *   data = /usr/local/share/enlightenment
    * then
    *   bindir = bin
    *   libdir = lib64
    *   datadir = share/enlightennment
    * in theory this should also work with debians new multiarch style like
    *   bindir = bin
    *   libdir = lib/i386-linux-gnu
    *     or
    *   libdir = lib/x86_64-linux-gnu
    * all with a common prefix that can be relocated
    */
   /* 1. check last common char in bin and lib strings */
   for (p1 = pkg_bin, p2 = pkg_lib; *p1 && *p2; p1++, p2++)
     {
        if (*p1 != *p2)
          {
             pkg_bin_p = p1;
             pkg_lib_p = p2;
             break;
          }
     }
   /* 1. check last common char in bin and data strings */
   for (p1 = pkg_bin, p2 = pkg_data; *p1 && *p2; p1++, p2++)
     {
        if (*p1 != *p2)
          {
             pkg_data_p = p2;
             break;
          }
     }
   /* 1. check last common char in bin and locale strings */
   for (p1 = pkg_bin, p2 = pkg_locale; *p1 && *p2; p1++, p2++)
     {
        if (*p1 != *p2)
          {
             pkg_locale_p = p2;
             break;
          }
     }
   /* 2. if all the common string offsets match we compiled with a common prefix */
   if (((pkg_bin_p - pkg_bin) == (pkg_lib_p - pkg_lib))
       && ((pkg_bin_p - pkg_bin) == (pkg_data_p - pkg_data))
       && ((pkg_bin_p - pkg_bin) == (pkg_locale_p - pkg_locale))
      )
     {
        bindir = pkg_bin_p;
        libdir = pkg_lib_p;
        datadir = pkg_data_p;
        localedir = pkg_locale_p;
        DBG("Prefix relative bindir = %s", bindir);
        DBG("Prefix relative libdir = %s", libdir);
        DBG("Prefix relative datadir = %s", datadir);
        DBG("Prefix relative localedir = %s", localedir);
     }
   /* 3. some galoot thought it awesome not to give us a common prefix at compile time
    * so fall back to the compile time directories. we are no longer relocatable */
   else
     {
        STRDUP_REP(pfx->prefix_path_bin, pkg_bin);
        STRDUP_REP(pfx->prefix_path_lib, pkg_lib);
        STRDUP_REP(pfx->prefix_path_data, pkg_data);
        STRDUP_REP(pfx->prefix_path_locale, pkg_locale);
        pfx->no_common_prefix = 1;
        DBG("Can't work out a common prefix - compiled in fallback");
     }

   /* if user provides env vars - then use that or also more specific sub
    * dirs for bin, lib, data and locale */
   if ((envprefix) &&
       (_get_env_vars(pfx, envprefix, bindir, libdir, datadir, localedir) > 0))
     {
        pfx->env_used = 1;
        return pfx;
     }

#ifdef HAVE_DLADDR
   DBG("Try dladdr on %p", symbol);
   if (symbol)
     {
        Dl_info info_dl;

        if (dladdr(symbol, &info_dl))
          {
             DBG("Dlinfo worked");
             if (info_dl.dli_fname)
               {
                  DBG("Dlinfo dli_fname = %s", info_dl.dli_fname);
# ifdef _WIN32
                  if (info_dl.dli_fname[0] && (info_dl.dli_fname[1] == ':'))
# else
                  if (info_dl.dli_fname[0] == DSEP_C)
# endif
                    {
                       INF("Dlsym gave full path = %s", info_dl.dli_fname);
                       STRDUP_REP(pfx->exe_path, info_dl.dli_fname);
                    }
               }
          }
     }
#endif
   /* no env var - examine process and possible argv0 */
   if ((argv0) && (!pfx->exe_path) && (symbol))
     {
#ifndef _WIN32
        if (!_try_proc(pfx, symbol))
          {
#endif
             if (!_try_argv(pfx, argv0))
               {
                  _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale,
                            envprefix);
                  return pfx;
               }
#ifndef _WIN32
          }
#endif
     }
   if (!pfx->exe_path)
     {
        WRN("Fallback - nothing found");
        _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale, envprefix);
        return pfx;
     }
   /* _exe_path is now a full absolute path TO this exe - figure out rest */
   /*   if
    * exe        = /blah/whatever/bin/exe
    *   or
    * exe        = /blah/whatever/lib/libexe.so
    *   then
    * prefix     = /blah/whatever
    * bin_dir    = /blah/whatever/bin
    * data_dir   = /blah/whatever/share/enlightenment
    * lib_dir    = /blah/whatever/lib
    */
   DBG("From exe %s figure out the rest", pfx->exe_path);
   p = strrchr(pfx->exe_path, DSEP_C);
   if (p)
     {
	p--;
	while (p >= pfx->exe_path)
	  {
	     if (*p == DSEP_C)
	       {
		  pfx->prefix_path = malloc(p - pfx->exe_path + 1);
		  if (pfx->prefix_path)
		    {
		       strncpy(pfx->prefix_path, pfx->exe_path,
                               p - pfx->exe_path);
		       pfx->prefix_path[p - pfx->exe_path] = 0;
                       DBG("Have prefix = %s", pfx->prefix_path);

		       /* bin */
		       snprintf(buf, sizeof(buf), "%s" DSEP_S "%s",
                                pfx->prefix_path, bindir);
                       STRDUP_REP(pfx->prefix_path_bin, buf);
                       DBG("Have bin = %s", pfx->prefix_path_bin);
		       /* lib */
		       snprintf(buf, sizeof(buf), "%s" DSEP_S "%s",
                                pfx->prefix_path, libdir);
                       STRDUP_REP(pfx->prefix_path_lib, buf);
                       DBG("Have lib = %s", pfx->prefix_path_lib);
		       /* locale */
		       snprintf(buf, sizeof(buf), "%s" DSEP_S "%s",
                                pfx->prefix_path, localedir);
                       STRDUP_REP(pfx->prefix_path_locale, buf);
                       DBG("Have locale = %s", pfx->prefix_path_locale);
		       /* check if magic file is there - then our guess is right */
                       if (magic)
                         {
                            DBG("Magic = %s", magic);
                            snprintf(buf, sizeof(buf),
                                     "%s" DSEP_S "%s" DSEP_S "%s",
                                     pfx->prefix_path, datadir, magic);
                            DBG("Check in %s", buf);
                         }
		       if ((!magic) || (stat(buf, &st) == 0))
			 {
                            if (buf[0])
                               DBG("Magic path %s stat passed", buf);
                            else
                               DBG("No magic file");
			    snprintf(buf, sizeof(buf), "%s" DSEP_S "%s",
                                     pfx->prefix_path, datadir);
                            STRDUP_REP(pfx->prefix_path_data, buf);
			 }
		       /* magic file not there. time to start hunting! */
		       else
                         {
                            WRN("Magic failed");
                            _fallback(pfx, pkg_bin, pkg_lib, pkg_data,
                                      pkg_locale, envprefix);
                         }
		    }
		  else
                    {
                       WRN("No Prefix path (alloc fail)");
                       _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale,
                                 envprefix);
                    }
                  return pfx;
	       }
	     p--;
	  }
     }
   WRN("Final fallback");
   _fallback(pfx, pkg_bin, pkg_lib, pkg_data, pkg_locale, envprefix);
   return pfx;
}
Exemplo n.º 7
0
/*
 * Sets $funamep to the name of the function $addr is contained within.
 * If $fnamep is not NULL sets it to the name of the DSO where function
 * is defined.  Returns 1 if everything is OK, 0 if the name was not
 * found, or -1 if it is not to be reported.
 */
static int addr2name(char const **fnamep, char const **funamep,
	void const *addr)
{
	static struct dso_st *seen;
	Dl_info info;
	char const *fname;
	struct dso_st *dso;

	/* Find the file that defined the function of $addr. */
	if (fnamep)
		*fnamep = "[???]";
	if (!dladdr(addr, &info))
		/* We're in trouble, don't do anything. */
		return report_function(NULL) ? 0 : -1;
	if (!info.dli_fname)
		/* Should not happen either. */
		return report_function(NULL) ? 0 : -1;

	/* Check whether calls to this DSO is to be reported here
	 * to avoid opening it unnecessarily. */
	if (!(fname = report_dso(info.dli_fname)))
		return -1;
	if (fnamep)
		*fnamep = fname;

	if (info.dli_sname)
	{
		/* dladdr() managed to do the hard work for us. */
		*funamep = info.dli_sname;
		return report_function(*funamep) ? 1 : -1;
	} else if (info.dli_saddr)
		/* info.dli_addr may be more accurate than $addr. */
		addr = info.dli_saddr;

	/* It is up to us to find out the function name from info.dli_fname.
	 * First we need to get contextual information we cache in $seen. */
	for (dso = seen; ; dso = dso->next)
	{
		if (dso == NULL)
		{
			int hfile;
			off_t fsize;
			void const *file;
			struct dso_st newdso;

			/* Never saw this DSO before, let's meet.
			 * TODO I think .dli_fname becomes incorrect
			 * if the program chdir()ed elsewhere. */
			if (!getdso(&newdso, info.dli_fname,
					&hfile, &file, &fsize))
				return report_function(NULL) ? 0 : -1;
			*funamep = getsym(&newdso, info.dli_fbase, addr);

			/* Try to remember it. */
			if ((dso = malloc(sizeof(*dso))) != NULL)
			{
				memcpy(dso, &newdso, sizeof(*dso));
				dso->next = seen;
				seen = dso;
			} else
			{	/* Failed, clean up what getdso() did. */
				LOGIT("malloc(%zu): %m", sizeof(*dso));
				munmap((void *)file, fsize);
				close(hfile);
			}

			return report_function(*funamep)
				? *funamep != NULL : -1;
		} else if (dso->fname == info.dli_fname)
		{
			/* info.dli_fname pointers point to some program
			 * header and are the same for all invocations. */
			*funamep = getsym(dso, info.dli_fbase, addr);
			return report_function(*funamep)
				? *funamep != NULL : -1;
		} /* if */
	} /* for */
} /* addr2name */
Exemplo n.º 8
0
struct ast_vector_string *__ast_bt_get_symbols(void **addresses, size_t num_frames)
{
	struct ast_vector_string *return_strings;
	int stackfr;
	bfd *bfdobj;
	long allocsize;
	char msg[MSG_BUFF_LEN];
	static pthread_mutex_t bfd_mutex = PTHREAD_MUTEX_INITIALIZER;

	return_strings = malloc(sizeof(struct ast_vector_string));
	if (!return_strings) {
		return NULL;
	}
	if (AST_VECTOR_INIT(return_strings, num_frames)) {
		free(return_strings);
		return NULL;
	}

	for (stackfr = 0; stackfr < num_frames; stackfr++) {
		int symbolcount;
		struct bfd_data data = {
			.return_strings = return_strings,
			.msg = msg,
			.pc = (bfd_vma)(uintptr_t) addresses[stackfr],
			.found = 0,
			.dynamic = 0,
		};

		msg[0] = '\0';

		if (!dladdr((void *)(uintptr_t) data.pc, &data.dli)) {
			continue;
		}
		data.libname = strrchr(data.dli.dli_fname, '/');
		if (!data.libname) {
			data.libname = data.dli.dli_fname;
		} else {
			data.libname++;
		}

		pthread_mutex_lock(&bfd_mutex);
		/* Using do while(0) here makes it easier to escape and clean up */
		do {
			bfdobj = bfd_openr(data.dli.dli_fname, NULL);
			if (!bfdobj) {
				break;
			}

			/* bfd_check_format does more than check.  It HAS to be called */
			if (!bfd_check_format(bfdobj, bfd_object)) {
				break;
			}

			data.has_syms = !!(bfd_get_file_flags(bfdobj) & HAS_SYMS);
			data.dynamic = !!(bfd_get_file_flags(bfdobj) & DYNAMIC);

			if (!data.has_syms) {
				break;
			}

			allocsize = data.dynamic ?
				bfd_get_dynamic_symtab_upper_bound(bfdobj) : bfd_get_symtab_upper_bound(bfdobj);
			if (allocsize < 0) {
				break;
			}

			data.syms = malloc(allocsize);
			if (!data.syms) {
				break;
			}

			symbolcount = data.dynamic ?
				bfd_canonicalize_dynamic_symtab(bfdobj, data.syms) : bfd_canonicalize_symtab(bfdobj, data.syms);
			if (symbolcount < 0) {
				break;
			}

			bfd_map_over_sections(bfdobj, process_section, &data);
		} while(0);

		if (bfdobj) {
			bfd_close(bfdobj);
			free(data.syms);
			data.syms = NULL;
		}
		pthread_mutex_unlock(&bfd_mutex);

		/* Default output, if we cannot find the information within BFD */
		if (!data.found) {
			snprintf(msg, sizeof(msg), "%s %s()",
				data.libname,
				S_OR(data.dli.dli_sname, "<unknown>"));
			AST_VECTOR_APPEND(return_strings, strdup(msg));
		}
	}

	return return_strings;
}

#else
struct ast_vector_string *__ast_bt_get_symbols(void **addresses, size_t num_frames)
{
	char **strings;
	struct ast_vector_string *return_strings;
	int i;

	return_strings = malloc(sizeof(struct ast_vector_string));
	if (!return_strings) {
		return NULL;
	}
	if (AST_VECTOR_INIT(return_strings, num_frames)) {
		free(return_strings);
		return NULL;
	}

	strings = backtrace_symbols(addresses, num_frames);
	if (strings) {
		for (i = 0; i < num_frames; i++) {
			AST_VECTOR_APPEND(return_strings, strdup(strings[i]));
		}
		free(strings);
	}

	return return_strings;
}
Exemplo n.º 9
0
int diag_backtrace(diag_output_t *o, diag_backtrace_param_t *p, diag_context_t *c)
{
    char frame[128];
    char addr_buf[20];
    char offset_buf[20];
    char name_buf[80];
    char *name;
    const char *module_path, *module;
    int count, cur, rc;
    unw_context_t ctx;
    unw_cursor_t csr;
    unw_word_t ip, offp;
#if DIAG_PLATFORM_LINUX || DIAG_PLATFORM_FREEBSD || DIAG_PLATFORM_MACOSX
    Dl_info info;
#endif

    if (p->backtrace_count && p->backtrace_count < DIAG_BT_LIMIT) {
        count = p->backtrace_count;
    }
    else {
        count = DIAG_BT_LIMIT;
    }
    
    rc = unw_getcontext(&ctx);
    if (!rc) {
        rc = unw_init_local(&csr, &ctx);
    }

    if (rc) {
        return DIAG_ERR_INIT;
    }

    cur = 0;
    while ((rc = unw_step(&csr)) > 0) {

        cur++;
        if (cur > count) {
            break;
        }

        unw_get_reg(&csr, UNW_REG_IP, &ip);

        if (!ip) {
            break;
        }

        add_int(addr_buf, addr_buf + sizeof addr_buf - 1, ip, 16);

        rc = unw_get_proc_name(&csr, name_buf, sizeof name_buf, &offp);
        if (rc && rc != UNW_ENOMEM) {
            name = NULL;
        }
        else {
            name = name_buf;
        }

        module = module_path = NULL;
#if DIAG_PLATFORM_LINUX || DIAG_PLATFORM_FREEBSD || DIAG_PLATFORM_MACOSX
        if (p->backtrace_fields
            & (DIAG_BTFIELDS_MODULE_PATH | DIAG_BTFIELDS_MODULE_NAME)) {
            if ((rc = dladdr((void *)ip, &info)) != 0) {
                module_path = info.dli_fname;
                module = strrchr(module_path, '/');
                if (module) {
                    module += 1;
                }
            }
        }
#endif

        add_int(offset_buf, offset_buf + sizeof offset_buf - 1,
                offp, 16);
        output_frame(frame, frame + sizeof frame - 1,
                     p->backtrace_fields,
                     module_path, module, name, offset_buf, addr_buf);

        if (o->output_mode == DIAG_CALL_FN) {
            o->output_fn(o->user_data, frame);
        }
        else {
            write(o->outfile, frame, strlen(frame));
            write(o->outfile, "\n", 1);
        }
    }

    return 0;
}
Exemplo n.º 10
0
void funk2_signal_segv_handler(int signum, siginfo_t* info, void* ptr) {
  int         i;
  int         f = 0;
  ucontext_t* ucontext = (ucontext_t*)ptr;
  Dl_info     dlinfo;
  void**      bp       = 0;
  void*       ip       = 0;
  
  status("funk2_signal_segv_handler: Segmentation Fault!");
  status("funk2_signal_segv_handler: info.si_signo = %d", signum);
  status("funk2_signal_segv_handler: info.si_errno = %d", info->si_errno);
  status("funk2_signal_segv_handler: info.si_code  = %d", info->si_code);
  status("funk2_signal_segv_handler: info.si_addr  = %p", info->si_addr);
  for(i = 0; i < NGREG; i++) {
    status("funk2_signal_segv_handler: reg[%02d]       = 0x" REGFORMAT, i, ucontext->uc_mcontext.gregs[i]);
  }
  
#ifndef SIGSEGV_NOSTACK
#  if defined(SIGSEGV_STACK_IA64) || defined(SIGSEGV_STACK_X86)
#    if defined(SIGSEGV_STACK_IA64)
  ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
  bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
#    elif defined(SIGSEGV_STACK_X86)
  ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
  bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
#    endif
  
  status("funk2_signal_segv_handler: Stack trace: bp=%p, ip=%p", bp, ip);
  while(bp) {
    const char*   symname   = "unknown_symbol";
    const char*   filename  = "unknown_filename";
    unsigned long dli_saddr = 0;
    if(dladdr(ip, &dlinfo)) {
      symname   = dlinfo.dli_sname;
      filename  = dlinfo.dli_fname;
      dli_saddr = (unsigned long)dlinfo.dli_saddr;
    }
    
#    ifndef NO_CPP_DEMANGLE
    int   status_value;
    char* tmp = __cxa_demangle(symname, NULL, 0, &status_value);
    
    if (status_value == 0 && tmp) {
      symname = tmp;
    }
#    endif
    
    status("funk2_signal_segv_handler: % 2d: %p <%s+%lu> (%s)",
	   ++f,
	   ip,
	   symname,
	   (unsigned long)ip - (unsigned long)dli_saddr,
	   filename);
    
#    ifndef NO_CPP_DEMANGLE
    if (tmp) {
      free(tmp);
    }
#    endif
    
    if(symname && !strcmp(symname, "main")) {
      break;
    }
    
    ip = bp[1];
    bp = (void**)bp[0];
  }
#  else
  status("funk2_signal_segv_handler: Stack trace (non-dedicated):");
  sz = backtrace(bt, 20);
  strings = backtrace_symbols(bt, sz);
  for(i = 0; i < sz; ++i)
    status("funk2_signal_segv_handler: %s", strings[i]);
#  endif
  status("funk2_signal_segv_handler: End of stack trace.");
#else
  status("funk2_signal_segv_handler: Not printing stack strace.");
#endif
}
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
    size_t i;
#if defined(NGREG)
    ucontext_t *ucontext = (ucontext_t*)ptr;
#endif /* #if defined(NGREG) */

#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
    int f = 0;
    Dl_info dlinfo;
    void **bp = 0;
    void *ip = 0;
#endif
#if defined(HAVE_EXECINFO_H)
    void *bt[20];
    char **strings;
    size_t sz;
#endif /* #if defined(HAVE_EXECINFO_H) */

    openlog("memcached", LOG_PID, LOG_LOCAL0);

    syslog(LOG_ALERT, "Segmentation Fault!\n");
    syslog(LOG_ALERT, "info.si_signo = %d\n", signum);
    syslog(LOG_ALERT, "info.si_errno = %d\n", info->si_errno);
    syslog(LOG_ALERT, "info.si_code  = %d\n", info->si_code);
    syslog(LOG_ALERT, "info.si_addr  = %p\n", info->si_addr);
#if defined(NGREG)
    for(i = 0; i < NGREG; i++)
        syslog(LOG_ALERT, "reg[%02lu]       = 0x" REGFORMAT "\n", i, ucontext->uc_mcontext.gregs[i]);
#endif /* #if defined(NGREG) */

#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
# if defined(SIGSEGV_STACK_IA64)
    ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
    bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
# elif defined(SIGSEGV_STACK_X86)
    ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
    bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
# endif

    syslog(LOG_ALERT, "Stack trace:\n");
    while(ip) {
        if(!dladdr(ip, &dlinfo))
            break;

        const char *symname = dlinfo.dli_sname;
#ifndef NO_CPP_DEMANGLE
        int status;
        char *tmp = __cxa_demangle(symname, NULL, 0, &status);

        if(status == 0 && tmp)
            symname = tmp;
#endif

        syslog(LOG_ALERT, "% 2d: %p <%s+%u> (%s)\n",
                ++f,
                ip,
                symname,
                (unsigned)(ip - dlinfo.dli_saddr),
                dlinfo.dli_fname);

#ifndef NO_CPP_DEMANGLE
        if(tmp)
            free(tmp);
#endif

        if (bp == NULL) {
          break;
        }

        if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
            break;

        ip = bp[1];
        bp = (void**)bp[0];
    }
#endif
    syslog(LOG_ALERT, "End of stack trace\n");
    closelog();

#if defined(HAVE_EXECINFO_H)
    openlog("memcached", LOG_PID, LOG_LOCAL0);
    syslog(LOG_ALERT, "Stack trace (non-dedicated):\n");
    sz = backtrace(bt, 20);
    strings = backtrace_symbols(bt, sz);

    for(i = 0; i < sz; ++i)
        syslog(LOG_ALERT, "%s\n", strings[i]);

    syslog(LOG_ALERT, "End of stack trace (non-dedicated)\n");
    closelog();
#endif /* #if defined(HAVE_EXECINFO_H) */

    (void) i;                           /* consume i so we don't get a compiler warning. */

    exit (-1);
}
void runSuccess1() {
    Dl_info info;
    dladdr(NULL, &info);
}
void runSuccess() {
    Dl_info info;
    dladdr(anystring(), &info);
}
void runFailure() {
    Dl_info info;
    dladdr(anystring(), NULL);
}
Exemplo n.º 15
0
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
    static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};

    size_t i;
    const char *si_code_str;
    ucontext_t *ucontext = (ucontext_t*)ptr;

#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
    int f = 0;
    Dl_info dlinfo;
    void **bp = 0;
    void *ip = 0;
#else
    void *bt[20];
    char **strings;
    size_t sz;
#endif

    if (signum == SIGSEGV)
    {
        jack_error("Segmentation Fault!");
    }
    else if (signum == SIGABRT)
    {
        jack_error("Abort!");
    }
    else if (signum == SIGILL)
    {
        jack_error("Illegal instruction!");
    }
    else if (signum == SIGFPE)
    {
        jack_error("Floating point exception!");
    }
    else
    {
        jack_error("Unknown bad signal catched!");
    }

    if (info->si_code >= 0 && info->si_code < 3) 
        si_code_str = si_codes[info->si_code];
    else
        si_code_str = "unknown";

    jack_error("info.si_signo = %d", signum);
    jack_error("info.si_errno = %d", info->si_errno);
    jack_error("info.si_code  = %d (%s)", info->si_code, si_code_str);
    jack_error("info.si_addr  = %p", info->si_addr);
#if !defined(__alpha__) && !defined(__ia64__) && !defined(__FreeBSD_kernel__) && !defined(__arm__) && !defined(__hppa__) && !defined(__sh__)
    for(i = 0; i < NGREG; i++)
        jack_error("reg[%02d]       = 0x" REGFORMAT, i, 
#if defined(__powerpc__)
                ucontext->uc_mcontext.uc_regs[i]
#elif defined(__sparc__) && defined(__arch64__)
                ucontext->uc_mcontext.mc_gregs[i]
#else
                ucontext->uc_mcontext.gregs[i]
#endif
                );
#endif /* alpha, ia64, kFreeBSD, arm, hppa */

#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
# if defined(SIGSEGV_STACK_IA64)
    ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
    bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
# elif defined(SIGSEGV_STACK_X86)
    ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
    bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
# endif

    jack_error("Stack trace:");
    while(bp && ip) {
        if(!dladdr(ip, &dlinfo))
            break;

        const char *symname = dlinfo.dli_sname;
#ifndef NO_CPP_DEMANGLE
        int status;
        char *tmp = __cxa_demangle(symname, NULL, 0, &status);

        if(status == 0 && tmp)
            symname = tmp;
#endif

        jack_error("% 2d: %p <%s+%u> (%s)",
                ++f,
                ip,
                symname,
                (unsigned)(ip - dlinfo.dli_saddr),
                dlinfo.dli_fname);

#ifndef NO_CPP_DEMANGLE
        if(tmp)
            free(tmp);
#endif

        if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
            break;

        ip = bp[1];
        bp = (void**)bp[0];
    }
#else
    jack_error("Stack trace (non-dedicated):");
    sz = backtrace(bt, 20);
    strings = backtrace_symbols(bt, sz);

    for(i = 0; i < sz; ++i)
        jack_error("%s", strings[i]);
#endif
    jack_error("End of stack trace");
    exit (-1);
}
Exemplo n.º 16
0
cv::String CameraWrapperConnector::getPathLibFolder()
{
    if (!pathLibFolder.empty())
        return pathLibFolder;

    Dl_info dl_info;
    if(0 != dladdr((void *)nextFrame, &dl_info))
    {
        LOGD("Library name: %s", dl_info.dli_fname);
        LOGD("Library base address: %p", dl_info.dli_fbase);

        const char* libName=dl_info.dli_fname;
        while( ((*libName)=='/') || ((*libName)=='.') )
        libName++;

        char lineBuf[2048];
        FILE* file = fopen("/proc/self/smaps", "rt");

        if(file)
        {
            while (fgets(lineBuf, sizeof lineBuf, file) != NULL)
            {
                //verify that line ends with library name
                int lineLength = strlen(lineBuf);
                int libNameLength = strlen(libName);

                //trim end
                for(int i = lineLength - 1; i >= 0 && isspace(lineBuf[i]); --i)
                {
                    lineBuf[i] = 0;
                    --lineLength;
                }

                if (0 != strncmp(lineBuf + lineLength - libNameLength, libName, libNameLength))
                {
                //the line does not contain the library name
                    continue;
                }

                //extract path from smaps line
                char* pathBegin = strchr(lineBuf, '/');
                if (0 == pathBegin)
                {
                    LOGE("Strange error: could not find path beginning in lin \"%s\"", lineBuf);
                    continue;
                }

                char* pathEnd = strrchr(pathBegin, '/');
                pathEnd[1] = 0;

                LOGD("Libraries folder found: %s", pathBegin);

                fclose(file);
                return pathBegin;
            }
            fclose(file);
            LOGE("Could not find library path");
        }
        else
        {
            LOGE("Could not read /proc/self/smaps");
        }
    }
    else
    {
        LOGE("Could not get library name and base address");
    }

    return cv::String();
}
Exemplo n.º 17
0
NPError OSCALL NP_Initialize(NPNetscapeFuncs *browser) {
  const char *home;
  char logfile[PATH_MAX];
  const char* dir;
  Dl_info library;
  struct attendant__initializer initializer;

  say("NP_Initialize");

  /* Copy the browser NPAPI functions into our library. */
  npn_get_url = browser->geturl;
  npn_post_url = browser->posturl;
  npn_request_read = browser->requestread;
  npn_new_stream = browser->newstream;
  npn_write = browser->write;
  npn_destroy_stream = browser->destroystream;
  npn_status = browser->status;
  npn_user_agent = browser->uagent;
  npn_mem_alloc = browser->memalloc;
  npn_mem_free = browser->memfree;
  npn_mem_flush = browser->memflush;
  npn_reload_plugins = browser->reloadplugins;
  npn_get_java_env = browser->getJavaEnv;
  npn_get_java_peer = browser->getJavaPeer;
  npn_get_url_notify = browser->geturlnotify;
  npn_post_url_notify = browser->posturlnotify;
  npn_get_value = browser->getvalue;
  npn_set_value = browser->setvalue;
  npn_invalidate_rect = browser->invalidaterect;
  npn_invalidate_region = browser->invalidateregion;
  npn_force_redraw = browser->forceredraw;
  npn_get_string_identifier = browser->getstringidentifier;
  npn_get_string_identifiers = browser->getstringidentifiers;
  npn_get_int_identifier = browser->getintidentifier;
  npn_identifier_is_string = browser->identifierisstring;
  npn_utf8_from_indentifier = browser->utf8fromidentifier;
  npn_int_from_identifier = browser->intfromidentifier;
  npn_create_object = browser->createobject;
  npn_retain_object = browser->retainobject;
  npn_release_object = browser->releaseobject;
  npn_invoke = browser->invoke;
  npn_invoke_default = browser->invokeDefault;
  npn_evaluate = browser->evaluate;
  npn_get_property = browser->getproperty;
  npn_set_property = browser->setproperty;
  npn_remove_property = browser->removeproperty;
  npn_has_property = browser->hasproperty;
  npn_has_method = browser->hasmethod;
  npn_release_variant_value = browser->releasevariantvalue;
  npn_set_exception = browser->setexception;
  npn_push_popups_enabled_state = browser->pushpopupsenabledstate;
  npn_pop_popups_enabled_state = browser->poppopupsenabledstate;
  npn_enumerate = browser->enumerate;
  npn_plugin_thread_async_call = browser->pluginthreadasynccall;
  npn_construct = browser->construct;
  npn_get_value_for_url = browser->getvalueforurl;
  npn_set_value_for_url = browser->setvalueforurl;
  npn_get_authentication_info = browser->getauthenticationinfo;
  npn_schedule_timer = browser->scheduletimer;
  npn_unschedule_timer = browser->unscheduletimer;
  npn_pop_up_context_menu = browser->popupcontextmenu;
  npn_convert_point = browser->convertpoint;
  npn_handle_event = browser->handleevent;
  npn_unfocus_instance = browser->unfocusinstance;
  npn_url_redirect_response = browser->urlredirectresponse;

  /* Create our mutex and signaling device. */
  (void) pthread_mutex_init(&plugin.mutex, NULL);
  (void) pthread_cond_init(&plugin.cond, NULL);

  dladdr(NP_Initialize, &library);
  dir = library.dli_fname + strlen(library.dli_fname);
  while (*dir != '/') {
    dir--;
  }
  strncat(plugin.node, library.dli_fname, dir - library.dli_fname);
  strcat(plugin.node, "/node");

  chmod(plugin.node, 0755);

  memset(&initializer, 0, sizeof(struct attendant__initializer));
  strncat(initializer.relay, library.dli_fname, dir - library.dli_fname);
  strcat(initializer.relay, "/relay");
  chmod(initializer.relay, 0755);

  strncat(plugin.monitor, library.dli_fname, dir - library.dli_fname);
  strcat(plugin.monitor, "/monitor.js");

  initializer.starter = starter;
  initializer.connector = connector;
  initializer.canary = 31;

  attendant.initialize(&initializer);

  starter(0, -1);

  say("node: %s", plugin.node);
  say("relay: %s", initializer.relay);

  plugin.curl = curl_easy_init();

  return NPERR_NO_ERROR;
}
Exemplo n.º 18
0
int
test (FILE *out, int a)
{
  fputs ("in modstatic2.c (test)\n", out);

  void *handle = dlopen ("modstatic2-nonexistent.so", RTLD_LAZY);
  if (handle == NULL)
    fprintf (out, "nonexistent: %s\n", dlerror ());
  else
    exit (1);

  handle = dlopen ("modstatic2.so", RTLD_LAZY);
  if (handle == NULL)
    {
      fprintf (out, "%s\n", dlerror ());
      exit (1);
    }

  int (*test2) (FILE *, int);
  test2 = dlsym (handle, "test");
  if (test2 == NULL)
    {
      fprintf (out, "%s\n", dlerror ());
      exit (1);
    }
  if (test2 != test)
    {
      fprintf (out, "test %p != test2 %p\n", test, test2);
      exit (1);
    }

  Dl_info info;
  int res = dladdr (test2, &info);
  if (res == 0)
    {
      fputs ("dladdr returned 0\n", out);
      exit (1);
    }
  else
    {
      if (strstr (info.dli_fname, "modstatic2.so") == NULL
	  || strcmp (info.dli_sname, "test") != 0)
	{
	  fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
	  exit (1);
	}
      if (info.dli_saddr != (void *) test2)
	{
	  fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
	  exit (1);
	}
    }

  ElfW(Sym) *sym;
  void *symp;
  res = dladdr1 (test2, &info, &symp, RTLD_DL_SYMENT);
  if (res == 0)
    {
      fputs ("dladdr1 returned 0\n", out);
      exit (1);
    }
  else
    {
      if (strstr (info.dli_fname, "modstatic2.so") == NULL
	  || strcmp (info.dli_sname, "test") != 0)
	{
	  fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
	  exit (1);
	}
      if (info.dli_saddr != (void *) test2)
	{
	  fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test2);
	  exit (1);
	}
      sym = symp;
      if (sym == NULL)
	{
	  fputs ("sym == NULL\n", out);
	  exit (1);
	}
      if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
	  || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
	{
	  fprintf (out, "bind %d visibility %d\n",
		   (int) ELF32_ST_BIND (sym->st_info),
		   (int) ELF32_ST_VISIBILITY (sym->st_other));
	  exit (1);
	}
    }

  Lmid_t lmid;
  res = dlinfo (handle, RTLD_DI_LMID, &lmid);
  if (res != 0)
    {
      fprintf (out, "dlinfo returned %d %s\n", res, dlerror ());
      exit (1);
    }
  else if (lmid != LM_ID_BASE)
    {
      fprintf (out, "lmid %d != %d\n", (int) lmid, (int) LM_ID_BASE);
      exit (1);
    }

  void *handle2 = dlopen (LIBDL_SO, RTLD_LAZY);
  if (handle2 == NULL)
    {
      fprintf (out, "libdl.so: %s\n", dlerror ());
      exit (1);
    }

#ifdef DO_VERSIONING
  if (dlvsym (handle2, "_dlfcn_hook", "GLIBC_PRIVATE") == NULL)
    {
      fprintf (out, "dlvsym: %s\n", dlerror ());
      exit (1);
    }
#endif

  void *(*dlsymfn) (void *, const char *);
  dlsymfn = dlsym (handle2, "dlsym");
  if (dlsymfn == NULL)
    {
      fprintf (out, "dlsym \"dlsym\": %s\n", dlerror ());
      exit (1);
    }
  void *test3 = dlsymfn (handle, "test");
  if (test3 == NULL)
    {
      fprintf (out, "%s\n", dlerror ());
      exit (1);
    }
  else if (test3 != (void *) test2)
    {
      fprintf (out, "test2 %p != test3 %p\n", test2, test3);
      exit (1);
    }

  dlclose (handle2);
  dlclose (handle);

  handle = dlmopen (LM_ID_BASE, "modstatic2.so", RTLD_LAZY);
  if (handle == NULL)
    {
      fprintf (out, "%s\n", dlerror ());
      exit (1);
    }
  dlclose (handle);

  handle = dlmopen (LM_ID_NEWLM, "modstatic2.so", RTLD_LAZY);
  if (handle == NULL)
    fprintf (out, "LM_ID_NEWLM: %s\n", dlerror ());
  else
    {
      fputs ("LM_ID_NEWLM unexpectedly succeeded\n", out);
      exit (1);
    }

  handle = dlopen ("modstatic.so", RTLD_LAZY);
  if (handle == NULL)
    {
      fprintf (out, "%s\n", dlerror ());
      exit (1);
    }

  int (*test4) (int);
  test4 = dlsym (handle, "test");
  if (test4 == NULL)
    {
      fprintf (out, "%s\n", dlerror ());
      exit (1);
    }

  res = test4 (16);
  if (res != 16 + 16)
    {
      fprintf (out, "modstatic.so (test) returned %d\n", res);
      exit (1);
    }

  res = dladdr1 (test4, &info, &symp, RTLD_DL_SYMENT);
  if (res == 0)
    {
      fputs ("dladdr1 returned 0\n", out);
      exit (1);
    }
  else
    {
      if (strstr (info.dli_fname, "modstatic.so") == NULL
	  || strcmp (info.dli_sname, "test") != 0)
	{
	  fprintf (out, "fname %s sname %s\n", info.dli_fname, info.dli_sname);
	  exit (1);
	}
      if (info.dli_saddr != (void *) test4)
	{
	  fprintf (out, "saddr %p != test %p\n", info.dli_saddr, test4);
	  exit (1);
	}
      sym = symp;
      if (sym == NULL)
	{
	  fputs ("sym == NULL\n", out);
	  exit (1);
	}
      if (ELF32_ST_BIND (sym->st_info) != STB_GLOBAL
	  || ELF32_ST_VISIBILITY (sym->st_other) != STV_DEFAULT)
	{
	  fprintf (out, "bind %d visibility %d\n",
		   (int) ELF32_ST_BIND (sym->st_info),
		   (int) ELF32_ST_VISIBILITY (sym->st_other));
	  exit (1);
	}
    }

  dlclose (handle);

  fputs ("leaving modstatic2.c (test)\n", out);
  return a + a;
}
void print_VTable(void *dlhndl, vtable_info *vtable)
{
    union classvtable_mem *vtablep;
    unsigned long vtbaseoffset;
    const char *vttypeinfo;
    fptr *vtvirtfuncs;
    void* vfuncp;
    Dl_info dlainfo;
    int i, j;
    int offset;
    int step;
    char* demngl;
    int size;
    int space;
    
    demngl = demangle(vtable->name);
    demngl[0] = toupper(demngl[0]);
    printf("%s\n", demngl);
    free(demngl);
    
    vtablep = dlsym(dlhndl, vtable->name);
    
    vtbaseoffset = vtablep->cat1.baseoffset;
    vttypeinfo = vtablep->cat1.typeinfo;
    vtvirtfuncs = vtablep->cat1.virtfuncs;
    
    size = vtable->size/sizeof(ptrdiff_t);
    
    printf("%s: %d entries\n", vtable->name, size);
    
    step = sizeof(ptrdiff_t);
    
    offset = 0;
    if (vtbaseoffset!=0)
    {
        printf("%d     %luu\n", offset, vtbaseoffset);
    }
    else
    {
        printf("%d     (int (*)(...)) 0\n", offset);
    }
    
    offset += step;
    if (dladdr(vttypeinfo, &dlainfo))
    {
        demngl = demangle(dlainfo.dli_sname);
        if(opt_mangled==1 && opt_demangled==1)
        {
            printf("%d     (int (*)(...)) (& %s) [%s]\n", offset, demngl, dlainfo.dli_sname);
        }
        else if(opt_demangled==1)
        {
            printf("%d     (int (*)(...)) (& %s)\n", offset, demngl);
        }
        else
        { // show mangled name by default
            printf("%d     (int (*)(...)) (& %s)\n", offset, dlainfo.dli_sname);
        }
        free(demngl);
    }
    else
    {
        if (vtbaseoffset!=0)
            printf("%d     0u\n", offset);
        else
            printf("%d     (int (*)(...)) 0\n", offset);
    }
    
    for (i = 0; i <= size - 3; i++)
    {
        offset += step;
        vfuncp = fptr2ptrp(&vtvirtfuncs[i]);
        memset(&dlainfo, 0, sizeof(dlainfo));
        
        space = 5 - integer_len(offset);
        
        if (dladdr(vfuncp, &dlainfo))
        {
            printf("%d", offset);
            for (j = 0; j<=space; j++)
            {
                printf(" ");
            }
            if (dlainfo.dli_sname==NULL)
            {
                printf("(int (*)(...)) %p\n", (void*) (vfuncp-dlainfo.dli_fbase));
            }
            else if (strstr(dlainfo.dli_sname, "__cxa_pure"))
            {
                printf("(int (*)(...)) %s\n", dlainfo.dli_sname);
            }
            else if (strstr(dlainfo.dli_sname, "_ZTI"))
            {
                demngl = demangle(dlainfo.dli_sname);
                if(opt_mangled==1 && opt_demangled==1)
                {
                    printf("(int (*)(...)) (& %s) [%s]\n", demngl, dlainfo.dli_sname);
                }
                else if(opt_demangled==1)
                {
                    printf("(int (*)(...)) (& %s)\n", demngl);
                }
                else
                { // show mangled name by default
                    printf("(int (*)(...)) (& %s)\n", dlainfo.dli_sname);
                }
                free(demngl);
            }
            else
            {
                demngl = demangle(dlainfo.dli_sname);
                
                if(opt_mangled==1 && opt_demangled==1)
                {
                    printf("(int (*)(...)) %s [%s]\n", demngl, dlainfo.dli_sname);
                }
                else if(opt_demangled==1)
                {
                    printf("(int (*)(...)) %s\n", demngl);
                }
                else if(opt_mangled==1)
                {
                    printf("(int (*)(...)) %s\n", dlainfo.dli_sname);
                }
                else
                {
                    if(strstr(dlainfo.dli_sname, "_ZN") == NULL)
                    { // _ZThn, _ZTv, __cxa, etc.
                      // show mangled name by default
                        printf("(int (*)(...)) %s\n", dlainfo.dli_sname);
                    }
                    else
                    {
                        printf("(int (*)(...)) %s\n", demngl);
                    }
                }
                
                free(demngl);
            }
        }
        else
        {
            printf("%d", offset);
            for (j = 0; j<=space; j++) 
            {
                printf(" ");
            }
            if (vfuncp == NULL)
            {
                printf("0u\n");
            }
            else
            {
                if ((ptrdiff_t)vfuncp < 0)
                {
                    printf("(int (*)(...)) -%016p\n", (void*) -(ptrdiff_t)vfuncp);
                }
                else
                {
                    printf("(int (*)(...)) %016p\n", vfuncp);
                }
            }
        }
    }
    printf("\n\n");
}
Exemplo n.º 20
0
SAMPGDK_EXPORT void *SAMPGDK_CALL sampgdk_get_plugin_handle(void *symbol) {
	Dl_info info;
	dladdr(symbol, &info);
	return dlopen(info.dli_fname, RTLD_NOW);
}
Exemplo n.º 21
0
void hpi::initialize_get_interface(vm_calls_t *callbacks)
{
#define args callbacks
#define InitializeHPI hpi::initialize_get_interface

    // "$JDK/src/solaris/javavm/runtime/javai_md.c":32 (ver. 1.7 98/09/15)
    char buf[MAXPATHLEN];
    Dl_info dlinfo;
    void *hpi_handle;
    GetInterfaceFunc& getintf = _get_interface;
    jint (JNICALL * DLL_Initialize)(GetInterfaceFunc *, void *);

#if 1 //HotSpot change
    char *thread_type = strdup("native_threads");

    os::jvm_path(buf, sizeof buf);
#else //HotSpot change
    char *thread_type = getenv("_JVM_THREADS_TYPE");

    if (thread_type) {
	/* Set by .java_wrapper.  Remove for the sake of exec'd VMs. */
	thread_type = strdup(thread_type);
        putenv("_JVM_THREADS_TYPE=");
    } else {
	/* Default thread type for the invocation API. */
        thread_type = strdup("native_threads");
    }

    dladdr((void *)InitializeHPI, &dlinfo);
    strcpy(buf, (char *)dlinfo.dli_fname);
#endif //HotSpot change

#ifdef PRODUCT
    const char * hpi_lib = "/libhpi.so";
#else
    char * ptr = strrchr(buf, '/');
    assert(strstr(ptr, "/libjvm") == ptr, "invalid library name");
    const char * hpi_lib = strstr(ptr, "_g") ? "/libhpi_g.so" : "/libhpi.so";
#endif

    *(strrchr(buf, '/')) = '\0';	/* get rid of /libjvm.so */
    *(strrchr(buf, '/') + 1) = '\0';	/* get rid of hotspot    */
    strcat(buf, thread_type);
    strcat(buf, hpi_lib);
    /* we use RTLD_NOW because of bug 4032715 */
    if (TraceHPI)  tty->print("Loading HPI %s ", buf);
    hpi_handle = dlopen(buf, RTLD_NOW);
    if (hpi_handle == NULL) {
	if (TraceHPI) tty->print_cr("HPI dlopen failed: %s", dlerror());
	goto bail;
    }
    DLL_Initialize = CAST_TO_FN_PTR(jint (JNICALL *)(GetInterfaceFunc *, void *),  
                                    dlsym(hpi_handle, "DLL_Initialize"));
    if (TraceHPI && DLL_Initialize == NULL) tty->print_cr("HPI dlsym of DLL_Initialize failed: %s", dlerror());
    if (DLL_Initialize == NULL ||
        (*DLL_Initialize)(&getintf, args) < 0) {
	if (TraceHPI) tty->print_cr("HPI DLL_Initialize failed");
        goto bail;
    }
    if (TraceHPI)  tty->print_cr("HPI loaded successfully");
bail:
    free(thread_type);

#undef args
#undef InitializeHPI
}
Exemplo n.º 22
0
/**
 * Prints a stack backtrace for the current thread to the specified ostream.
 *
 * Does not malloc, does not throw.
 *
 * The format of the backtrace is:
 *
 * ----- BEGIN BACKTRACE -----
 * JSON backtrace
 * Human-readable backtrace
 * -----  END BACKTRACE  -----
 *
 * The JSON backtrace will be a JSON object with a "backtrace" field, and optionally others.
 * The "backtrace" field is an array, whose elements are frame objects.  A frame object has a
 * "b" field, which is the base-address of the library or executable containing the symbol, and
 * an "o" field, which is the offset into said library or executable of the symbol.
 *
 * The JSON backtrace may optionally contain additional information useful to a backtrace
 * analysis tool.  For example, on Linux it contains a subobject named "somap", describing
 * the objects referenced in the "b" fields of the "backtrace" list.
 *
 * @param os    ostream& to receive printed stack backtrace
 */
void printStackTrace(std::ostream& os) {
    static const char unknownFileName[] = "???";
    void* addresses[maxBackTraceFrames];
    Dl_info dlinfoForFrames[maxBackTraceFrames];

    ////////////////////////////////////////////////////////////
    // Get the backtrace addresses.
    ////////////////////////////////////////////////////////////

    const int addressCount = backtrace(addresses, maxBackTraceFrames);
    if (addressCount == 0) {
        const int err = errno;
        os << "Unable to collect backtrace addresses (errno: " <<
           err << ' ' << strerror(err) << ')' << std::endl;
        return;
    }

    ////////////////////////////////////////////////////////////
    // Collect symbol information for each backtrace address.
    ////////////////////////////////////////////////////////////

    os << std::hex << std::uppercase << '\n';
    for (int i = 0; i < addressCount; ++i) {
        Dl_info& dlinfo(dlinfoForFrames[i]);
        if (!dladdr(addresses[i], &dlinfo)) {
            dlinfo.dli_fname = unknownFileName;
            dlinfo.dli_fbase = NULL;
            dlinfo.dli_sname = NULL;
            dlinfo.dli_saddr = NULL;
        }
        os << ' ' << addresses[i];
    }

    os << "\n----- BEGIN BACKTRACE -----\n";

    ////////////////////////////////////////////////////////////
    // Display the JSON backtrace
    ////////////////////////////////////////////////////////////

    os << "{\"backtrace\":[";
    for (int i = 0; i < addressCount; ++i) {
        const Dl_info& dlinfo = dlinfoForFrames[i];
        const uintptr_t fileOffset = uintptr_t(addresses[i]) - uintptr_t(dlinfo.dli_fbase);
        if (i)
            os << ',';
        os << "{\"b\":\"" << uintptr_t(dlinfo.dli_fbase) <<
           "\",\"o\":\"" << fileOffset << "\"}";
    }
    os << ']';

    if (soMapJson)
        os << ",\"processInfo\":" << *soMapJson;
    os << "}\n";

    ////////////////////////////////////////////////////////////
    // Display the human-readable trace
    ////////////////////////////////////////////////////////////
    for (int i = 0; i < addressCount; ++i) {
        Dl_info& dlinfo(dlinfoForFrames[i]);
        os << ' ';
        if (dlinfo.dli_fbase) {
            os << getBaseName(dlinfo.dli_fname) << '(';
            if (dlinfo.dli_sname) {
                const uintptr_t offset = uintptr_t(addresses[i]) - uintptr_t(dlinfo.dli_saddr);
                os << dlinfo.dli_sname << "+0x" << offset;
            }
            else {
                const uintptr_t offset = uintptr_t(addresses[i]) - uintptr_t(dlinfo.dli_fbase);
                os << "+0x" << offset;
            }
            os << ')';
        }
        else {
            os << unknownFileName;
        }
        os << " [" << addresses[i] << ']' << std::endl;
    }

    os << std::dec << std::nouppercase;
    os << "-----  END BACKTRACE  -----" << std::endl;
}
Exemplo n.º 23
0
std::string GetModuleFile(std::string moduleName)
{
	std::string moduleFilePath = "";
	// this will only be used if moduleFilePath stays empty
	const char* error = NULL;

#if defined(linux) || defined(__APPLE__)
#ifdef __APPLE__
	#define SHARED_LIBRARY_EXTENSION "dylib"
#else
	#define SHARED_LIBRARY_EXTENSION "so"
#endif
	void* moduleAddress = NULL;

	// find an address in the module we are looking for
	if (moduleName.empty()) {
		// look for current module
		moduleAddress = (void*) GetModuleFile;
	} else {
		// look for specified module

		// add extension if it is not in the file name
		// it could also be "libXZY.so-1.2.3"
		// -> does not have to be the end, my friend
		if (moduleName.find("."SHARED_LIBRARY_EXTENSION) == std::string::npos) {
			moduleName = moduleName + "."SHARED_LIBRARY_EXTENSION;
		}

		// will not not try to load, but return the libs address
		// if it is already loaded, NULL otherwise
		moduleAddress = dlopen(moduleName.c_str(), RTLD_LAZY | RTLD_NOLOAD);

		if (moduleAddress == NULL) {
			// if not found, try with "lib" prefix
			moduleName = "lib" + moduleName;
			moduleAddress = dlopen(moduleName.c_str(), RTLD_LAZY | RTLD_NOLOAD);
		}
	}

	if (moduleAddress != NULL) {
		// fetch info about the module containing the address we just evaluated
		Dl_info moduleInfo;
		const int ret = dladdr(moduleAddress, &moduleInfo);
		if ((ret != 0) && (moduleInfo.dli_fname != NULL)) {
			moduleFilePath = moduleInfo.dli_fname;
			// required on APPLE; does not hurt elsewhere
			moduleFilePath = GetRealPath(moduleFilePath);
		} else {
			error = dlerror();
			if (error == NULL) {
				error = "Unknown";
			}
		}
	} else {
		error = "Not loaded";
	}

#elif WIN32
	HMODULE hModule = NULL;
	if (moduleName.empty()) {
		hModule = GetCurrentModule();
	} else {
		// If this fails, we get a NULL handle
		hModule = GetModuleHandle(moduleName.c_str());
	}

	if (hModule != NULL) {
		// fetch module file name
		TCHAR moduleFile[MAX_PATH+1];
		const int ret = ::GetModuleFileName(hModule, moduleFile, sizeof(moduleFile));

		if ((ret != 0) && (ret != sizeof(moduleFile))) {
			moduleFilePath = std::string(moduleFile);
		} else {
			error = + "Unknown";
		}
	} else {
		error = "Not found";
	}
#else
	#warning implement this (or use linux version)
#endif

	if (moduleFilePath.empty()) {
		if (moduleName.empty()) {
			moduleName = "<current>";
		}
		LOG_L(L_WARNING, "Failed to get file path of the module \"%s\", reason: %s", moduleName.c_str(), error);
	}

	return moduleFilePath;
}
Exemplo n.º 24
0
void
ruby_init_loadpath_safe(int safe_level)
{
    VALUE load_path;
    ID id_initial_load_path_mark;
    extern const char ruby_initial_load_paths[];
    const char *paths = ruby_initial_load_paths;
#if defined LOAD_RELATIVE
# if defined HAVE_DLADDR || defined HAVE_CYGWIN_CONV_PATH
#   define VARIABLE_LIBPATH 1
# else
#   define VARIABLE_LIBPATH 0
# endif
# if VARIABLE_LIBPATH
    char *libpath;
    VALUE sopath;
# else
    char libpath[MAXPATHLEN + 1];
# endif
    size_t baselen;
    char *p;

#if defined _WIN32 || defined __CYGWIN__
# if VARIABLE_LIBPATH
    sopath = rb_str_new(0, MAXPATHLEN);
    libpath = RSTRING_PTR(sopath);
    GetModuleFileName(libruby, libpath, MAXPATHLEN);
# else
    GetModuleFileName(libruby, libpath, sizeof libpath);
# endif
#elif defined(__EMX__)
    _execname(libpath, sizeof(libpath) - 1);
#elif defined(HAVE_DLADDR)
    Dl_info dli;
    if (dladdr((void *)(VALUE)expand_include_path, &dli)) {
	char fbuf[MAXPATHLEN];
	char *f = dln_find_file_r(dli.dli_fname, getenv(PATH_ENV), fbuf, sizeof(fbuf));
	VALUE fname = rb_str_new_cstr(f ? f : dli.dli_fname);
	rb_str_freeze(fname);
	sopath = rb_realpath_internal(Qnil, fname, 1);
    }
    else {
	sopath = rb_str_new(0, 0);
    }
    libpath = RSTRING_PTR(sopath);
#endif

#if !VARIABLE_LIBPATH
    libpath[sizeof(libpath) - 1] = '\0';
#endif
#if defined DOSISH
    translit_char(libpath, '\\', '/');
#elif defined __CYGWIN__
    {
# if VARIABLE_LIBPATH
	const int win_to_posix = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
	size_t newsize = cygwin_conv_path(win_to_posix, libpath, 0, 0);
	if (newsize > 0) {
	    VALUE rubylib = rb_str_new(0, newsize);
	    p = RSTRING_PTR(rubylib);
	    if (cygwin_conv_path(win_to_posix, libpath, p, newsize) == 0) {
		rb_str_resize(sopath, 0);
		sopath = rubylib;
		libpath = p;
	    }
	}
# else
	char rubylib[FILENAME_MAX];
	cygwin_conv_to_posix_path(libpath, rubylib);
	strncpy(libpath, rubylib, sizeof(libpath));
# endif
    }
#endif
    p = strrchr(libpath, '/');
    if (p) {
	static const char bindir[] = "/bin";
#ifdef LIBDIR_BASENAME
	static const char libdir[] = "/"LIBDIR_BASENAME;
#else
	static const char libdir[] = "/lib";
#endif
	const ptrdiff_t bindir_len = (ptrdiff_t)sizeof(bindir) - 1;
	const ptrdiff_t libdir_len = (ptrdiff_t)sizeof(libdir) - 1;
	*p = 0;
	if (p - libpath >= bindir_len && !STRCASECMP(p - bindir_len, bindir)) {
	    p -= bindir_len;
	    *p = 0;
	}
	else if (p - libpath >= libdir_len && !STRCASECMP(p - libdir_len, libdir)) {
	    p -= libdir_len;
	    *p = 0;
	}
    }
#if !VARIABLE_LIBPATH
    else {
	strlcpy(libpath, ".", sizeof(libpath));
	p = libpath + 1;
    }
    baselen = p - libpath;
#define PREFIX_PATH() rb_str_new(libpath, baselen)
#else
    baselen = p - libpath;
    rb_str_resize(sopath, baselen);
    libpath = RSTRING_PTR(sopath);
#define PREFIX_PATH() sopath
#endif

#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)

#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), (path), (len))
#else
    static const char exec_prefix[] = RUBY_EXEC_PREFIX;
#define RUBY_RELATIVE(path, len) rubylib_mangled_path((path), (len))
#define PREFIX_PATH() RUBY_RELATIVE(exec_prefix, sizeof(exec_prefix)-1)
#endif
    load_path = GET_VM()->load_path;

    if (safe_level == 0) {
#ifdef MANGLED_PATH
	rubylib_mangled_path("", 0);
#endif
	ruby_push_include(getenv("RUBYLIB"), identical_path);
    }

    id_initial_load_path_mark = rb_intern_const("@gem_prelude_index");
    while (*paths) {
	size_t len = strlen(paths);
	VALUE path = RUBY_RELATIVE(paths, len);
	rb_ivar_set(path, id_initial_load_path_mark, path);
	rb_ary_push(load_path, path);
	paths += len + 1;
    }

    rb_const_set(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"), rb_obj_freeze(PREFIX_PATH()));
}
Exemplo n.º 25
0
bool CSignatureFunction::getLibraryInfo(const void *libPtr, DynLibInfo &lib)
{
	uintptr_t baseAddr;

	if (libPtr == NULL)
	{
		return false;
	}

#ifdef _WIN32


	MEMORY_BASIC_INFORMATION info;
	IMAGE_DOS_HEADER *dos;
	IMAGE_NT_HEADERS *pe;
	IMAGE_FILE_HEADER *file;
	IMAGE_OPTIONAL_HEADER *opt;

	if (!VirtualQuery(libPtr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
	{
		return false;
	}

	baseAddr = reinterpret_cast<uintptr_t>(info.AllocationBase);

	// All this is for our insane sanity checks :o 
	dos = reinterpret_cast<IMAGE_DOS_HEADER *>(baseAddr);
	pe = reinterpret_cast<IMAGE_NT_HEADERS *>(baseAddr + dos->e_lfanew);
	file = &pe->FileHeader;
	opt = &pe->OptionalHeader;

	// Check PE magic and signature 
	if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
	{
		return false;
	}

	// Check architecture, which is 32-bit/x86 right now
		// Should change this for 64-bit if Valve gets their act together
	
	if (file->Machine != IMAGE_FILE_MACHINE_I386)
	{
		return false;
	}

	//For our purposes, this must be a dynamic library 
	if ((file->Characteristics & IMAGE_FILE_DLL) == 0)
	{
		return false;
	}

	//Finally, we can do this
	lib.memorySize = opt->SizeOfImage;

#else
	Dl_info info;
	Elf32_Ehdr *file;
	Elf32_Phdr *phdr;
	uint16_t phdrCount;

	if (!dladdr(libPtr, &info))
	{
		return false;
	}

	if (!info.dli_fbase || !info.dli_fname)
	{
		return false;
	}

	// This is for our insane sanity checks :o 
	baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
	file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);

	// Check ELF magic 
	if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
	{
		return false;
	}

	// Check ELF version 
	if (file->e_ident[EI_VERSION] != EV_CURRENT)
	{
		return false;
	}

	// Check ELF architecture, which is 32-bit/x86 right now
		// Should change this for 64-bit if Valve gets their act together
		
	if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
	{
		return false;
	}

	// For our purposes, this must be a dynamic library/shared object 
	if (file->e_type != ET_DYN)
	{
		return false;
	}

	phdrCount = file->e_phnum;
	phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);

	for (uint16_t i = 0; i < phdrCount; i++)
	{
		Elf32_Phdr &hdr = phdr[i];

		// We only really care about the segment with executable code 
		if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
		{
			// From glibc, elf/dl-load.c:
			// c->mapend = ((ph->p_vaddr + ph->p_filesz + GLRO(dl_pagesize) - 1) 
			//             & ~(GLRO(dl_pagesize) - 1));
			//
			// In glibc, the segment file size is aligned up to the nearest page size and
			// added to the virtual address of the segment. We just want the size here.
			
			lib.memorySize = PAGE_ALIGN_UP(hdr.p_filesz);
			break;
		}
	}
#endif

	lib.baseAddress = reinterpret_cast<void *>(baseAddr);

	return true;
}
static int Init()
{
	FILE *fp;
	char *p, buf[512];

	Dl_info info;
	if (dladdr((void *)Init, &info) != 0)
	{
		strncpy(buf, info.dli_fname, sizeof(buf) - 8);
		buf[sizeof(buf) - 8] = '\0';
		strcat(buf, ".conf");
	}
	else
		strcpy(buf, DEFAULT_CONF_NAME);

	fp = fopen(buf, "r");
	if (fp == NULL)
		return -1;

	BOOL bHost, bPort, bBonDriver, bChannelLock, bConnectTimeOut, bUseMagicPacket;
	BOOL bTargetHost, bTargetPort, bTargetMac;
	BOOL bPacketFifoSize, bTsFifoSize, bTsPacketBufSize;
	bHost = bPort = bBonDriver = bChannelLock = bConnectTimeOut = bUseMagicPacket = FALSE;
	bTargetHost = bTargetPort = bTargetMac = FALSE;
	bPacketFifoSize = bTsFifoSize = bTsPacketBufSize = FALSE;
	while (fgets(buf, sizeof(buf), fp))
	{
		if (buf[0] == ';')
			continue;
		p = buf + strlen(buf) - 1;
		while (*p == '\r' || *p == '\n')
			*p-- = '\0';
		if (!bHost && (strncmp(buf, "ADDRESS=", 8) == 0))
		{
			p = &buf[8];
			while (*p == ' ' || *p == '\t')
				p++;
			strncpy(g_Host, p, sizeof(g_Host) - 1);
			g_Host[sizeof(g_Host) - 1] = '\0';
			bHost = TRUE;
		}
		else if (!bPort && (strncmp(buf, "PORT=", 5) == 0))
		{
			p = &buf[5];
			while (*p == ' ' || *p == '\t')
				p++;
			g_Port = atoi(p);
			bPort = TRUE;
		}
		else if (!bBonDriver && (strncmp(buf, "BONDRIVER=", 10) == 0))
		{
			p = &buf[10];
			while (*p == ' ' || *p == '\t')
				p++;
			strncpy(g_BonDriver, p, sizeof(g_BonDriver) - 1);
			g_BonDriver[sizeof(g_BonDriver) - 1] = '\0';
			bBonDriver = TRUE;
		}
		else if (!bChannelLock && (strncmp(buf, "CHANNEL_LOCK=", 13) == 0))
		{
			p = &buf[13];
			while (*p == ' ' || *p == '\t')
				p++;
			g_ChannelLock = atoi(p);
			bChannelLock = TRUE;
		}
		else if (!bConnectTimeOut && (strncmp(buf, "CONNECT_TIMEOUT=", 16) == 0))
		{
			p = &buf[16];
			while (*p == ' ' || *p == '\t')
				p++;
			g_ConnectTimeOut = atoi(p);
			bConnectTimeOut = TRUE;
		}
		else if (!bUseMagicPacket && (strncmp(buf, "USE_MAGICPACKET=", 16) == 0))
		{
			p = &buf[16];
			while (*p == ' ' || *p == '\t')
				p++;
			g_UseMagicPacket = atoi(p);
			bUseMagicPacket = TRUE;
		}
		else if (!bTargetHost && (strncmp(buf, "TARGET_ADDRESS=", 15) == 0))
		{
			p = &buf[15];
			while (*p == ' ' || *p == '\t')
				p++;
			strncpy(g_TargetHost, p, sizeof(g_TargetHost) - 1);
			g_TargetHost[sizeof(g_TargetHost) - 1] = '\0';
			bTargetHost = TRUE;
		}
		else if (!bTargetPort && (strncmp(buf, "TARGET_PORT=", 12) == 0))
		{
			p = &buf[12];
			while (*p == ' ' || *p == '\t')
				p++;
			g_TargetPort = atoi(p);
			bTargetPort = TRUE;
		}
		else if (!bTargetMac && (strncmp(buf, "TARGET_MACADDRESS=", 18) == 0))
		{
			p = &buf[18];
			while (*p == ' ' || *p == '\t')
				p++;
			char mac[32];
			memset(mac, 0, sizeof(mac));
			strncpy(mac, p, sizeof(mac) - 1);
			BOOL bErr = FALSE;
			for (int i = 0; i < 6 && !bErr; i++)
			{
				BYTE b = 0;
				p = &mac[i * 3];
				for (int j = 0; j < 2 && !bErr; j++)
				{
					if ('0' <= *p && *p <= '9')
						b = b * 0x10 + (*p - '0');
					else if ('A' <= *p && *p <= 'F')
						b = b * 0x10 + (*p - 'A' + 10);
					else if ('a' <= *p && *p <= 'f')
						b = b * 0x10 + (*p - 'a' + 10);
					else
						bErr = TRUE;
					p++;
				}
				g_TargetMac[i] = b;
			}
			if (!bErr)
				bTargetMac = TRUE;
		}
		else if (!bPacketFifoSize && (strncmp(buf, "PACKET_FIFO_SIZE=", 17) == 0))
		{
			p = &buf[17];
			while (*p == ' ' || *p == '\t')
				p++;
			g_PacketFifoSize = atoi(p);
			bPacketFifoSize = TRUE;
		}
		else if (!bTsFifoSize && (strncmp(buf, "TS_FIFO_SIZE=", 13) == 0))
		{
			p = &buf[13];
			while (*p == ' ' || *p == '\t')
				p++;
			g_TsFifoSize = atoi(p);
			bTsFifoSize = TRUE;
		}
		else if (!bTsPacketBufSize && (strncmp(buf, "TSPACKET_BUFSIZE=", 17) == 0))
		{
			p = &buf[17];
			while (*p == ' ' || *p == '\t')
				p++;
			g_TsPacketBufSize = atoi(p);
			bTsPacketBufSize = TRUE;
		}
	}
	fclose(fp);

	if (!bHost || !bPort || !bBonDriver)
		return -2;

	if (g_UseMagicPacket)
	{
		if (!bTargetMac)
			return -3;
		if (!bTargetHost)
			strcpy(g_TargetHost, g_Host);
		if (!bTargetPort)
			g_TargetPort = g_Port;
	}

	return 0;
}
Exemplo n.º 27
0
/**
 * Perform specify operation on the address.
 *
 * @param addr		the address we're querying
 * @param op		the operation to perform
 *
 * @return NULL on failure, an address whose interpretation is op-specific
 * otherwise.
 */
static const void *
dl_util_query(const void *addr, enum dl_addr_op op)
{
	if G_UNLIKELY(!dl_util_inited)
		dl_util_init();

#ifdef HAS_DLADDR
	{
		static Dl_info info;
		static const void *last_addr;
		int stid = thread_small_id();

		/*
		 * Cache results for a given address.  This will help our stack
		 * pretty-printing code which is going to gather the various
		 * items at different times instead of doing one dladdr() call.
		 * For a given stack item, we may therefore face various calls
		 * for the same address.
		 *
		 * The rationale is that we may want to use different routines on
		 * another platform without dladdr() some days and therefore we wish
		 * to hide the existence of dladdr() and rather provide higher-level
		 * services like dl_util_get_base().
		 */

		if (addr != last_addr) {
			signal_handler_t old_sigsegv;
			int ret;

			ZERO(&info);

			/*
			 * Protect against segmentation faults in dladdr().
			 *
			 * We use signal_catch() instead of signal_set() because we
			 * don't need extra information about the fault context.
			 */

			old_sigsegv = signal_catch(SIGSEGV, dl_util_got_signal);

			if (Sigsetjmp(dl_util_env[stid], TRUE)) {
				last_addr = NULL;
				return NULL;
			}

			ret = dladdr(deconstify_pointer(addr), &info);
			signal_set(SIGSEGV, old_sigsegv);

			if (0 == ret) {
				last_addr = NULL;
				return NULL;
			}
			last_addr = addr;
		}

		switch (op) {
		case DL_ADDR_GET_BASE:
			return info.dli_fbase;
		case DL_ADDR_GET_NAME:
			return info.dli_sname;
		case DL_ADDR_GET_PATH:
			return info.dli_fname;
		case DL_ADDR_GET_START:
			return info.dli_saddr;
		}
	}

	g_assert_not_reached();
#else	/* !HAS_DLADDR */
	(void) addr;
	(void) op;

	return NULL;
#endif	/* HAS_DLADDR */
}
Exemplo n.º 28
0
SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
{
	if (m_IgnoreLevel)
	{
		m_IgnoreLevel--;
		return SMCResult_Continue;
	}

	if (m_CustomLevel)
	{
		m_CustomLevel--;
		m_CustomHandler->ReadSMC_LeavingSection(states);
		return SMCResult_Continue;
	}

	switch (m_ParseState)
	{
		case PSTATE_GAMES:
		{
			m_ParseState = PSTATE_NONE;
			break;
		}
		case PSTATE_GAMEDEFS:
		{
			m_ParseState = PSTATE_GAMES;
			break;
		}
		case PSTATE_GAMEDEFS_CLASSES:
		{
			m_MatchedClasses = false;
			m_ParseState = PSTATE_GAMEDEFS;
			break;
		}
		case PSTATE_GAMEDEFS_CLASSES_CLASS:
		{
			m_ParseState = PSTATE_GAMEDEFS_CLASSES;
			m_Class[0] = '\0';
			break;
		}
		case PSTATE_GAMEDEFS_CUSTOM:
		{
			m_ParseState = PSTATE_GAMEDEFS;
			m_CustomHandler->ReadSMC_ParseEnd(false, false);
			break;
		}
		case PSTATE_GAMEDEFS_KEYS:
		{
			m_ParseState = m_MatchedClasses ? PSTATE_GAMEDEFS_CLASSES_CLASS : PSTATE_GAMEDEFS;
			break;
		}
		case PSTATE_GAMEDEFS_OFFSETS:
		{
			m_ParseState = m_MatchedClasses ? PSTATE_GAMEDEFS_CLASSES_CLASS : PSTATE_GAMEDEFS;
			break;
		}
		case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
		{
			m_ParseState = PSTATE_GAMEDEFS_OFFSETS;
			break;
		}
		case PSTATE_GAMEDEFS_SUPPORTED:
		{
			if (!m_ShouldBeReadingDefault)
			{
				m_IgnoreLevel = 1;
				m_ParseState = PSTATE_GAMES;
			}
			else
			{
				m_ParseState = PSTATE_GAMEDEFS;
			}
			break;
		}
		case PSTATE_GAMEDEFS_SIGNATURES:
		{
			m_ParseState = m_MatchedClasses ? PSTATE_GAMEDEFS_CLASSES_CLASS : PSTATE_GAMEDEFS;
			break;
		}
		case PSTATE_GAMEDEFS_SIGNATURES_SIG:
		{
			if (TempSig.library[0] == '\0')
			{
				strncopy(TempSig.library, "server", sizeof(TempSig.library));
			}

			void *addressInBase = nullptr;

			if (strcmp(TempSig.library, "server") == 0)
			{
				addressInBase = reinterpret_cast<void*>(MDLL_Spawn);
			}
			else if (strcmp(TempSig.library, "engine") == 0)
			{
				addressInBase = reinterpret_cast<void*>(gpGlobals);
			}

			void *finalAddress = nullptr;

			if (!addressInBase)
			{
				AMXXLOG_Error("Unrecognized library \"%s\" (gameconf \"%s\")", TempSig.library, m_CurrentPath);
			}
			else if (TempSig.signature[0])
			{
				if (TempSig.signature[0] == '@')
				{
#if defined PLATFORM_WINDOWS
					MEMORY_BASIC_INFORMATION mem;

					if (VirtualQuery(addressInBase, &mem, sizeof(mem)))
					{
						finalAddress = g_MemUtils.ResolveSymbol(mem.AllocationBase, &TempSig.signature[1]);
					}
					else
					{
						AMXXLOG_Error("Unable to find library \"%s\" in memory (gameconf \"%s\")", TempSig.library, m_File);
					}

#elif defined PLATFORM_POSIX
					Dl_info info;

					if (dladdr(addressInBase, &info) != 0)
					{
						void *handle = dlopen(info.dli_fname, RTLD_NOW);

						if (handle)
						{
							finalAddress = g_MemUtils.ResolveSymbol(handle, &TempSig.signature[1]);
							dlclose(handle);
						}
						else
						{
							AMXXLOG_Error("Unable to load library \"%s\" (gameconf \"%s\")", TempSig.library, m_File);
						}
					}
					else
					{
						AMXXLOG_Error("Unable to find library \"%s\" in memory (gameconf \"%s\")", TempSig.library, m_File);
					}
#endif
				}

				if (!finalAddress)
				{
					finalAddress = g_MemUtils.DecodeAndFindPattern(addressInBase, TempSig.signature);
				}

				m_Sigs.replace(m_Offset, finalAddress);
			}

			m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
			break;
		}
		case PSTATE_GAMEDEFS_ADDRESSES:
		{
			m_ParseState = m_MatchedClasses ? PSTATE_GAMEDEFS_CLASSES_CLASS : PSTATE_GAMEDEFS;
			break;
		}
		case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS:
		{
			m_ParseState = PSTATE_GAMEDEFS_ADDRESSES;

			if (m_Address[0] != '\0' && m_AddressSignature[0] != '\0')
			{
				AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead);
				m_Addresses.replace(m_Address, addrConf);
			}

			break;
		}
		case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ:
		{
			m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS;
			break;
		}
	}

	return SMCResult_Continue;
}
Exemplo n.º 29
0
bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
{
	uintptr_t baseAddr;

	if (libPtr == NULL)
	{
		return false;
	}

#ifdef PLATFORM_WINDOWS

	MEMORY_BASIC_INFORMATION info;
	IMAGE_DOS_HEADER *dos;
	IMAGE_NT_HEADERS *pe;
	IMAGE_FILE_HEADER *file;
	IMAGE_OPTIONAL_HEADER *opt;

	if (!VirtualQuery(libPtr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
	{
		return false;
	}

	baseAddr = reinterpret_cast<uintptr_t>(info.AllocationBase);

	/* All this is for our insane sanity checks :o */
	dos = reinterpret_cast<IMAGE_DOS_HEADER *>(baseAddr);
	pe = reinterpret_cast<IMAGE_NT_HEADERS *>(baseAddr + dos->e_lfanew);
	file = &pe->FileHeader;
	opt = &pe->OptionalHeader;

	/* Check PE magic and signature */
	if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
	{
		return false;
	}

	/* Check architecture, which is 32-bit/x86 right now
	 * Should change this for 64-bit if Valve gets their act together
	 */
	if (file->Machine != IMAGE_FILE_MACHINE_I386)
	{
		return false;
	}

	/* For our purposes, this must be a dynamic library */
	if ((file->Characteristics & IMAGE_FILE_DLL) == 0)
	{
		return false;
	}

	/* Finally, we can do this */
	lib.memorySize = opt->SizeOfImage;

#elif defined PLATFORM_LINUX

	Dl_info info;
	Elf32_Ehdr *file;
	Elf32_Phdr *phdr;
	uint16_t phdrCount;

	if (!dladdr(libPtr, &info))
	{
		return false;
	}

	if (!info.dli_fbase || !info.dli_fname)
	{
		return false;
	}

	/* This is for our insane sanity checks :o */
	baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
	file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);

	/* Check ELF magic */
	if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
	{
		return false;
	}

	/* Check ELF version */
	if (file->e_ident[EI_VERSION] != EV_CURRENT)
	{
		return false;
	}

	/* Check ELF architecture, which is 32-bit/x86 right now
	 * Should change this for 64-bit if Valve gets their act together
	 */
	if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
	{
		return false;
	}

	/* For our purposes, this must be a dynamic library/shared object */
	if (file->e_type != ET_DYN)
	{
		return false;
	}

	phdrCount = file->e_phnum;
	phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);

	for (uint16_t i = 0; i < phdrCount; i++)
	{
		Elf32_Phdr &hdr = phdr[i];

		/* We only really care about the segment with executable code */
		if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
		{
			/* From glibc, elf/dl-load.c:
			 * c->mapend = ((ph->p_vaddr + ph->p_filesz + GLRO(dl_pagesize) - 1) 
			 *             & ~(GLRO(dl_pagesize) - 1));
			 *
			 * In glibc, the segment file size is aligned up to the nearest page size and
			 * added to the virtual address of the segment. We just want the size here.
			 */
			lib.memorySize = PAGE_ALIGN_UP(hdr.p_filesz);
			break;
		}
	}

#elif defined PLATFORM_APPLE

	Dl_info info;
	struct mach_header *file;
	struct segment_command *seg;
	uint32_t cmd_count;

	if (!dladdr(libPtr, &info))
	{
		return false;
	}

	if (!info.dli_fbase || !info.dli_fname)
	{
		return false;
	}

	/* This is for our insane sanity checks :o */
	baseAddr = (uintptr_t)info.dli_fbase;
	file = (struct mach_header *)baseAddr;

	/* Check Mach-O magic */
	if (file->magic != MH_MAGIC)
	{
		return false;
	}

	/* Check architecture (32-bit/x86) */
	if (file->cputype != CPU_TYPE_I386 || file->cpusubtype != CPU_SUBTYPE_I386_ALL)
	{
		return false;
	}

	/* For our purposes, this must be a dynamic library */
	if (file->filetype != MH_DYLIB)
	{
		return false;
	}

	cmd_count = file->ncmds;
	seg = (struct segment_command *)(baseAddr + sizeof(struct mach_header));
	
	/* Add up memory sizes of mapped segments */
	for (uint32_t i = 0; i < cmd_count; i++)
	{		
		if (seg->cmd == LC_SEGMENT)
		{
			lib.memorySize += seg->vmsize;
		}
		
		seg = (struct segment_command *)((uintptr_t)seg + seg->cmdsize);
	}

#endif

	lib.baseAddress = reinterpret_cast<void *>(baseAddr);

	return true;
}
Exemplo n.º 30
0
void
xorg_backtrace(void)
{
    unw_cursor_t cursor;
    unw_context_t context;
    unw_word_t off;
    unw_proc_info_t pip;
    int ret, i = 0;
    char procname[256];
    const char *filename;
    Dl_info dlinfo;

    pip.unwind_info = NULL;
    ret = unw_getcontext(&context);
    if (ret) {
        ErrorFSigSafe("unw_getcontext failed: %s [%d]\n", unw_strerror(ret),
                      ret);
        return;
    }

    ret = unw_init_local(&cursor, &context);
    if (ret) {
        ErrorFSigSafe("unw_init_local failed: %s [%d]\n", unw_strerror(ret),
                      ret);
        return;
    }

    ErrorFSigSafe("\n");
    ErrorFSigSafe("Backtrace:\n");
    ret = unw_step(&cursor);
    while (ret > 0) {
        ret = unw_get_proc_info(&cursor, &pip);
        if (ret) {
            ErrorFSigSafe("unw_get_proc_info failed: %s [%d]\n",
                          unw_strerror(ret), ret);
            break;
        }

        ret = unw_get_proc_name(&cursor, procname, 256, &off);
        if (ret && ret != -UNW_ENOMEM) {
            if (ret != -UNW_EUNSPEC)
                ErrorFSigSafe("unw_get_proc_name failed: %s [%d]\n",
                              unw_strerror(ret), ret);
            procname[0] = '?';
            procname[1] = 0;
        }

        if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
                *dlinfo.dli_fname)
            filename = dlinfo.dli_fname;
        else
            filename = "?";

        ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
                      ret == -UNW_ENOMEM ? "..." : "", (int)off,
                      (void *)(pip.start_ip + off));

        ret = unw_step(&cursor);
        if (ret < 0)
            ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);
    }
    ErrorFSigSafe("\n");
}