Get memory regions as string
This commit is contained in:
12
src/files.c
12
src/files.c
@@ -7,7 +7,17 @@
|
||||
HiloadResult read_file_to_str(str *s, const char *filename) {
|
||||
|
||||
int copied = str_from_file(s, filename);
|
||||
if (copied == 0) {
|
||||
if (copied != 0) {
|
||||
sc_log_error("Failed to read file: %s\n", filename);
|
||||
return HILOAD_FAIL;
|
||||
}
|
||||
return HILOAD_OK;
|
||||
}
|
||||
|
||||
HiloadResult read_stream_to_str(str *s, const char *filename) {
|
||||
int nread = 0;
|
||||
int copied = str_from_stream(s, filename, &nread);
|
||||
if (copied != 0) {
|
||||
sc_log_error("Failed to read file: %s\n", filename);
|
||||
return HILOAD_FAIL;
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
#include "types.h"
|
||||
|
||||
HiloadResult read_file_to_str(str *s, const char *);
|
||||
HiloadResult read_stream_to_str(str *s, const char *);
|
||||
|
||||
#endif // FILES_H_
|
||||
|
||||
10
src/memory.c
10
src/memory.c
@@ -1,14 +1,18 @@
|
||||
#include "memory.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include "files.h"
|
||||
#include "logger.h"
|
||||
#include "types.h"
|
||||
|
||||
static
|
||||
str read_memory_maps_self() {
|
||||
str memory_str = str_null;
|
||||
|
||||
HiloadResult res = read_file_to_str(&memory_str, "/proc/self/maps");
|
||||
sc_log_debug("Memory Map (/proc/self/maps):\n%s\n", str_ptr(memory_str));
|
||||
HiloadResult res = read_stream_to_str(&memory_str, "/proc/self/maps");
|
||||
if (res == HILOAD_FAIL)
|
||||
return str_null;
|
||||
|
||||
sc_log_debug("Memory Map\n-- /proc/self/maps:\n%s\n", str_ptr(memory_str));
|
||||
|
||||
return memory_str;
|
||||
}
|
||||
|
||||
17
src/memory.h
17
src/memory.h
@@ -13,16 +13,13 @@ enum MemoryPermissions {
|
||||
HI_MEMORY_PRIVATE = 1 << 4
|
||||
};
|
||||
|
||||
#define REGIONS_MAX 256
|
||||
typedef struct {
|
||||
void *region_start;
|
||||
void *redion_end;
|
||||
u32 region_flags; // enum MemoryPermissions
|
||||
u32 offset;
|
||||
str pathname;
|
||||
} MemoryRegion;
|
||||
|
||||
str read_memory_maps_self();
|
||||
|
||||
sc_array_def(MemoryRegion, memreg);
|
||||
void *region_starts[REGIONS_MAX];
|
||||
void *region_end[REGIONS_MAX];
|
||||
u32 region_flags[REGIONS_MAX]; // enum MemoryPermissions
|
||||
u32 offset[REGIONS_MAX];
|
||||
str pathname[REGIONS_MAX];
|
||||
} MemoryRegions;
|
||||
|
||||
#endif // MEMORY_H_
|
||||
|
||||
99
src/str.c
99
src/str.c
@@ -74,6 +74,14 @@ void str_free_auto(const str* const ps)
|
||||
___p; \
|
||||
})
|
||||
|
||||
#define REALLOC(p, n) \
|
||||
({ \
|
||||
void* const ___p = realloc((p), (n)); \
|
||||
if(!___p) return ENOMEM; \
|
||||
___p; \
|
||||
})
|
||||
|
||||
|
||||
// errno checker
|
||||
#define RETURN_ON_ERROR(expr) \
|
||||
while((expr) < 0) do { const int __err = errno; if(__err != EINTR) return __err; } while(0)
|
||||
@@ -231,6 +239,35 @@ int read_from_fd(const int fd, void* p, off_t* const psize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int read_from_fd_cont(const int fd, void* p, off_t* const psize)
|
||||
{
|
||||
const void* end = p + *psize;
|
||||
void *buf = p;
|
||||
ssize_t n;
|
||||
ssize_t nread = 0;
|
||||
|
||||
do
|
||||
{
|
||||
RETURN_ON_ERROR(n = read(fd, p, end - p));
|
||||
|
||||
p += n;
|
||||
nread += n;
|
||||
|
||||
// pre-emptively realloc, even though we could potentially be at the end
|
||||
if (p == end) {
|
||||
*psize *= 2;
|
||||
buf = REALLOC(buf, *psize);
|
||||
p = buf + nread;
|
||||
end = buf + *psize;
|
||||
}
|
||||
|
||||
} while(n > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int str_from_fd(const int fd, const off_t size, str* const dest)
|
||||
{
|
||||
@@ -275,6 +312,46 @@ int str_from_fd(const int fd, const off_t size, str* const dest)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int str_from_stream_cont(const int fd, str* const dest, int *nmax)
|
||||
{
|
||||
const size_t start_size = 8192;
|
||||
|
||||
char* buff = ALLOC(start_size + 1);
|
||||
off_t n = start_size;
|
||||
const int err = read_from_fd_cont(fd, buff, &n);
|
||||
|
||||
if(err != 0)
|
||||
{
|
||||
free(buff);
|
||||
return err;
|
||||
}
|
||||
|
||||
if(n == 0)
|
||||
{
|
||||
free(buff);
|
||||
str_clear(dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(n < start_size)
|
||||
{
|
||||
char* const p = realloc(buff, n + 1);
|
||||
|
||||
if(!p)
|
||||
{
|
||||
free(buff);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
buff = p;
|
||||
}
|
||||
|
||||
buff[n] = '\0';
|
||||
str_assign(dest, str_acquire_chars(buff, n));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int str_from_file(str* const dest, const char* const file_name)
|
||||
{
|
||||
int fd;
|
||||
@@ -291,6 +368,28 @@ int str_from_file(str* const dest, const char* const file_name)
|
||||
return err;
|
||||
}
|
||||
|
||||
int str_from_stream(str* const dest, const char* const file_name, int *nread)
|
||||
{
|
||||
int fd;
|
||||
|
||||
RETURN_ON_ERROR(fd = open(file_name, O_CLOEXEC | O_RDONLY));
|
||||
|
||||
int nmax = nread ? *nread : 0;
|
||||
|
||||
off_t chunk_size = 4096;
|
||||
int err = 0;
|
||||
if (nmax == 0)
|
||||
err = str_from_stream_cont(fd, dest, &nmax);
|
||||
else
|
||||
err = str_from_fd(fd, nmax, dest);
|
||||
|
||||
if (nread)
|
||||
*nread = nmax;
|
||||
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
// string composition -----------------------------------------------------------------------
|
||||
// append string
|
||||
static inline
|
||||
|
||||
@@ -216,6 +216,9 @@ str str_acquire(const char* const s);
|
||||
// string from file
|
||||
int str_from_file(str* const dest, const char* const file_name);
|
||||
|
||||
// read maximum nread bytes from file, write bytes read. 0 reads until EOS.
|
||||
int str_from_stream(str* const dest, const char* const file_name, int *nread);
|
||||
|
||||
// searching and sorting --------------------------------------------------------------------
|
||||
// string partitioning (substring search)
|
||||
bool str_partition(const str src, const str patt, str* const prefix, str* const suffix);
|
||||
|
||||
Reference in New Issue
Block a user