bool vogl_trace_file_reader::init_loose_file_blob_manager(const char *pTrace_filename, const char *pLoose_file_path)
{
    VOGL_FUNC_TRACER

    dynamic_string loose_file_path(".");

    if ((pLoose_file_path) && vogl_strlen(pLoose_file_path))
        loose_file_path = pLoose_file_path;
    else if ((pTrace_filename) && (vogl_strlen(pTrace_filename)))
    {
        dynamic_string fname;
        if (!file_utils::split_path(pTrace_filename, loose_file_path, fname))
        {
            console::error("%s: Failed splitting trace filename \"%s\", assuming \".\" as the loose file path\n", VOGL_FUNCTION_INFO_CSTR, pTrace_filename);
            loose_file_path = ".";
        }
    }

    if (!m_loose_file_blob_manager.init(cBMFReadable, loose_file_path.get_ptr()))
    {
        close();
        return false;
    }

    return true;
}
Example #2
0
 uint32_t ktx_texture::add_key_value(const char *pKey, const void *pVal, uint32_t val_size)
 {
     const uint32_t idx = m_key_values.size();
     m_key_values.resize(idx + 1);
     uint8_vec &v = m_key_values.back();
     v.append(reinterpret_cast<const uint8_t *>(pKey), vogl_strlen(pKey) + 1);
     v.append(static_cast<const uint8_t *>(pVal), val_size);
     return idx;
 }
Example #3
0
    const uint8_vec *ktx_texture::find_key(const char *pKey) const
    {
        const uint32_t n = vogl_strlen(pKey) + 1;
        for (uint32_t i = 0; i < m_key_values.size(); i++)
        {
            const uint8_vec &v = m_key_values[i];
            if ((v.size() >= n) && (!memcmp(&v[0], pKey, n)))
                return &v;
        }

        return NULL;
    }
Example #4
0
    bool ktx_texture::get_key_value_data(const char *pKey, uint8_vec &data) const
    {
        const uint8_vec *p = find_key(pKey);
        if (!p)
        {
            data.resize(0);
            return false;
        }

        const uint32_t ofs = vogl_strlen(pKey) + 1;
        const uint8_t *pValue = p->get_ptr() + ofs;
        const uint32_t n = p->size() - ofs;

        data.resize(n);
        if (n)
            memcpy(data.get_ptr(), pValue, n);
        return true;
    }
Example #5
0
    bool ktx_texture::get_key_value_as_string(const char *pKey, dynamic_string &str) const
    {
        const uint8_vec *p = find_key(pKey);
        if (!p)
        {
            str.clear();
            return false;
        }

        const uint32_t ofs = vogl_strlen(pKey) + 1;
        const uint8_t *pValue = p->get_ptr() + ofs;
        const uint32_t n = p->size() - ofs;

        uint32_t i;
        for (i = 0; i < n; i++)
            if (!pValue[i])
                break;

        str.set_from_buf(pValue, i);
        return true;
    }
Example #6
0
 bool data_stream::puts(const char *p)
 {
     uint len = vogl_strlen(p);
     return write(p, len * sizeof(char)) == len * sizeof(char);
 }
Example #7
0
    // init_uuid() is slow (~40ms, maybe slower), and forces a disk flush on a file, so don't call it more than once.
    // I'm a paranoid nut so this hashes a bunch of shit. It's probably completely overkill for my needs - I should stop reading RFC's.
    static md5_hash init_uuid()
    {
        static uint64_t s_counter;

        // Get as much entropy as we can here

        const uint N = 2;
        void *p[N];
        memset(p, 0, sizeof(p));

        md5_hash_gen gen;
        timer_ticks tick_hist[N];
        for (uint i = 0; i < N; i++)
        {
            uint64_t start_rdtsc = utils::RDTSC();
            gen.update(start_rdtsc);

            gen.update(s_counter);
            gen.update((uint64_t) & s_counter);
            s_counter++;

            // Hash stack address of gen_uuid
            gen.update((uint64_t) & gen_uuid);

            // Hash the initial timer ticks, and time(NULL)
            gen.update(timer::get_init_ticks());
            gen.update((uint64_t)time(NULL));

            // Hash user ID, name, shell, home dir
            uid_t uid = geteuid();
            gen.update(uid);
            struct passwd *pw = getpwuid(uid);
            gen.update((uint64_t) & pw);
            if (pw)
            {
                gen.update(pw, sizeof(struct passwd));
                if (pw->pw_name)
                    gen.update(pw->pw_name, vogl_strlen(pw->pw_name));
                if (pw->pw_passwd)
                    gen.update(pw->pw_passwd, vogl_strlen(pw->pw_passwd));
                if (pw->pw_shell)
                    gen.update(pw->pw_shell, vogl_strlen(pw->pw_shell));
                if (pw->pw_dir)
                    gen.update(pw->pw_dir, vogl_strlen(pw->pw_dir));
                if (pw->pw_gecos)
                    gen.update(pw->pw_gecos, vogl_strlen(pw->pw_gecos));
            }

            uint8_vec buf;

            timer_ticks ticks = timer::get_ticks();
            gen.update(ticks);

            // This is obviously expensive (and questionable?), only do it once. But it helps us get some entropy from the disk subsystem.
            // This is also by far the slowest component of this function (~35ms out of ~40ms).
            if (!i)
            {
                uint64_t st = utils::RDTSC();
                timer tm;
                tm.start();

                const char *pFilename = "!_!_!_!_!_!_!_vogl_temp!_!_!_!_!_!_!_!_.txt";
                FILE *pFile = vogl_fopen(pFilename, "wb");
                gen.update_obj_bits(pFile);
                if (pFile)
                {
                    fwrite("X", 1, 1, pFile);
                    fflush(pFile);
                    fsync(fileno(pFile));
                    vogl_fclose(pFile);
                    remove(pFilename);
                }

                uint64_t t = utils::RDTSC() - st;
                gen.update(t);

                tm.stop();

                gen.update(tm.get_elapsed_ticks());
            }

            // Grab some bits from /dev/urandom (not /dev/random - it may block for a long time)
            {
                const uint N = 64;
                char buf[N];
                FILE *fp = vogl_fopen("/dev/urandom", "rb");
                gen.update_obj_bits(fp);
                if (fp)
                {
                    size_t n = fread(buf, 1, N, fp);
                    VOGL_NOTE_UNUSED(n);
                    vogl_fclose(fp);

                    gen.update(buf, sizeof(buf));
                }
            }

// It's fine if some/most/all of these files don't exist, the true/false results get fed into the hash too.
// TODO: Double check that all the files we should be able to read are actually getting read and hashed here.
#define HASH_FILE(filename)                                               \
    do                                                                    \
    {                                                                     \
        bool success = cfile_stream::read_file_into_array(filename, buf); \
        gen.update_obj_bits(success);                                     \
        gen.update(buf);                                                  \
    } while (0)
            HASH_FILE("/proc/sys/kernel/random/entropy_avail");
            HASH_FILE("/proc/self/statm");
            HASH_FILE("/proc/self/mounts");
            HASH_FILE("/proc/self/io");
            HASH_FILE("/proc/self/smaps");
            HASH_FILE("/proc/self/stack");
            HASH_FILE("/proc/self/status");
            HASH_FILE("/proc/self/maps");
            HASH_FILE("/proc/self/stat");
            HASH_FILE("/proc/self/stat");
            HASH_FILE("/proc/cpuinfo");
            HASH_FILE("/proc/meminfo");
            HASH_FILE("/proc/stat");
            HASH_FILE("/proc/misc");
            HASH_FILE("/proc/swaps");
            HASH_FILE("/proc/version");
            HASH_FILE("/proc/loadavg");
            HASH_FILE("/proc/interrupts");
            HASH_FILE("/proc/ioports");
            HASH_FILE("/proc/partitions");
            HASH_FILE("/proc/driver/rtc");
            HASH_FILE("/proc/self/net/wireless");
            HASH_FILE("/proc/self/net/netstat");
            HASH_FILE("/proc/self/net/netlink");
            HASH_FILE("/sys/class/net/eth0/address");
            HASH_FILE("/sys/class/net/eth1/address");
            HASH_FILE("/sys/class/net/wlan0/address");
#undef HASH_FILE

            gen.update(utils::RDTSC());

            // Hash thread, process ID's, etc.
            pid_t tid = (pid_t)syscall(SYS_gettid);
            gen.update_obj_bits(tid);

            pid_t pid = getpid();
            gen.update_obj_bits(pid);

            pid = getppid();
            gen.update_obj_bits(pid);
            gen.update((uint64_t) & pid);

            ticks -= timer::get_ticks();
            tick_hist[i] = ticks;
            gen.update(ticks);

            ticks = timer::get_ticks();

            // Get some entropy from the stack.
            char purposely_uninitialized_buf[256];
            gen.update(purposely_uninitialized_buf, sizeof(purposely_uninitialized_buf));

            // Get some entropy from the heap.
            p[i] = vogl_malloc(65536 * (i + 1));
            gen.update_obj_bits(p[i]);
            if (p[i])
            {
                for (uint j = 0; j < 16; j++)
                    gen.update_obj_bits(reinterpret_cast<const uint64_t *>(p)[j]);
            }

            struct timeval tv;
            gettimeofday(&tv, NULL);
            gen.update_obj_bits(tv);

            // Hash the current environment
            uint e = 0;
            while (environ[e])
            {
                gen.update(environ[e], vogl_strlen(environ[e]));
                ++e;
            }

            uint64_t s = utils::RDTSC();

            // Try to get some entropy from the scheduler.
            vogl_sleep(2);

            gen.update(utils::RDTSC() - s);

            ticks -= timer::get_ticks();
            gen.update(ticks);

            gen.update(utils::RDTSC() - start_rdtsc);
        }

        for (uint i = 1; i < N; i++)
        {
            uint64_t t = tick_hist[i] - tick_hist[i - 1];
            gen.update(t);
        }

        for (uint i = 0; i < N; i++)
            vogl_free(p[i]);

        return gen.finalize();
    }