Example #1
0
  std::string Environment::system_prefix() {
    if(!system_prefix_.empty()) return system_prefix_;

    // 1. Check if our configure prefix is overridden by the environment.
    const char* path = getenv("RBX_PREFIX_PATH");
    if(path && verify_paths(path)) {
      system_prefix_ = path;
      return path;
    }

    // 2. Check if our configure prefix is valid.
    path = RBX_PREFIX_PATH;
    if(verify_paths(path)) {
      system_prefix_ = path;
      return path;
    }

    // 3. Check if we can derive paths from the executable name.
    // TODO: For Windows, substitute '/' for '\\'
    std::string name = executable_name();
    size_t exe = name.rfind('/');

    if(exe != std::string::npos) {
      std::string prefix = name.substr(0, exe - strlen(RBX_BIN_PATH));
      if(verify_paths(prefix)) {
        system_prefix_ = prefix;
        return prefix;
      }
    }

    throw MissingRuntime("FATAL ERROR: unable to find Rubinius runtime directories.");
  }
Example #2
0
TEST(dlfcn, dladdr) {
    dlerror(); // Clear any pending errors.
    void* self = dlopen(NULL, RTLD_NOW);
    ASSERT_TRUE(self != NULL);
    ASSERT_TRUE(dlerror() == NULL);

    void* sym = dlsym(self, "DlSymTestFunction");
    ASSERT_TRUE(sym != NULL);

    // Deliberately ask dladdr for an address inside a symbol, rather than the symbol base address.
    void* addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(sym) + 2);

    Dl_info info;
    int rc = dladdr(addr, &info);
    ASSERT_NE(rc, 0); // Zero on error, non-zero on success.

    // Get the name of this executable.
    char executable_path[PATH_MAX];
    rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
    ASSERT_NE(rc, -1);
    executable_path[rc] = '\0';
    std::string executable_name(basename(executable_path));

    // The filename should be that of this executable.
    // Note that we don't know whether or not we have the full path, so we want an "ends_with" test.
    std::string dli_fname(info.dli_fname);
    dli_fname = basename(&dli_fname[0]);
    ASSERT_EQ(dli_fname, executable_name);

    // The symbol name should be the symbol we looked up.
    ASSERT_STREQ(info.dli_sname, "DlSymTestFunction");

    // The address should be the exact address of the symbol.
    ASSERT_EQ(info.dli_saddr, sym);

    // Look in /proc/pid/maps to find out what address we were loaded at.
    // TODO: factor /proc/pid/maps parsing out into a class and reuse all over bionic.
    void* base_address = NULL;
    char path[PATH_MAX];
    snprintf(path, sizeof(path), "/proc/%d/maps", getpid());
    char line[BUFSIZ];
    FILE* fp = fopen(path, "r");
    ASSERT_TRUE(fp != NULL);
    while (fgets(line, sizeof(line), fp) != NULL) {
        uintptr_t start = strtoul(line, 0, 16);
        line[strlen(line) - 1] = '\0'; // Chomp the '\n'.
        char* path = strchr(line, '/');
        if (path != NULL && strcmp(executable_path, path) == 0) {
            base_address = reinterpret_cast<void*>(start);
            break;
        }
    }
    fclose(fp);

    // The base address should be the address we were loaded at.
    ASSERT_EQ(info.dli_fbase, base_address);

    ASSERT_EQ(0, dlclose(self));
}
Example #3
0
bstring
resolve_path(STATE, bstring path)
{
  char *absolute_path = malloc(PATH_MAX);
	bstring h = executable_name(state->binary);
	struct bstrList *x = bsplit(h, '/');
	bdestroy(h);
	bstring slash = bfromcstr("/");
	x->qty--;
	h = bjoin(x, slash);
	x->qty++;
	bstrListDestroy(x);
	bconcat(h, slash);
	bconcat(h, path);
	bdestroy(slash);

  realpath(bdata(h), absolute_path);
  bstring bpath = bfromcstr(absolute_path);
  bdestroy(h);
  free(absolute_path);
  return bpath;
}
Example #4
0
  std::string Environment::system_prefix() {
    if(!system_prefix_.empty()) return system_prefix_;

    std::string failure_reason;

    // 1. Check if our configure prefix is overridden by the environment.
    const char* path = getenv("RBX_PREFIX_PATH");
    if(path && verify_paths(path, failure_reason)) {
      system_prefix_ = path;
      return path;
    }

    // 2. Check if our configure prefix is valid.
    path = RBX_PREFIX_PATH;
    if(verify_paths(path, failure_reason)) {
      system_prefix_ = path;
      return path;
    }

    // 3. Check if we can derive paths from the executable name.
    // TODO: For Windows, substitute '/' for '\\'
    std::string name = executable_name();
    size_t exe = name.rfind('/');

    if(exe != std::string::npos) {
      std::string prefix = name.substr(0, exe - strlen(RBX_BIN_PATH));
      if(verify_paths(prefix, failure_reason)) {
        system_prefix_ = prefix;
        return prefix;
      }
    }

    std::string error("Unable to find Rubinius runtime directories: ");
    error.append(failure_reason);

    missing_core(error.c_str());
  }