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) {
|
HiloadResult read_file_to_str(str *s, const char *filename) {
|
||||||
|
|
||||||
int copied = str_from_file(s, 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);
|
sc_log_error("Failed to read file: %s\n", filename);
|
||||||
return HILOAD_FAIL;
|
return HILOAD_FAIL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
HiloadResult read_file_to_str(str *s, const char *);
|
HiloadResult read_file_to_str(str *s, const char *);
|
||||||
|
HiloadResult read_stream_to_str(str *s, const char *);
|
||||||
|
|
||||||
#endif // FILES_H_
|
#endif // FILES_H_
|
||||||
|
|||||||
14
src/memory.c
14
src/memory.c
@@ -1,14 +1,18 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
static
|
||||||
str read_memory_maps_self() {
|
str read_memory_maps_self() {
|
||||||
str memory_str = str_null;
|
str memory_str = str_null;
|
||||||
|
|
||||||
HiloadResult res = read_file_to_str(&memory_str, "/proc/self/maps");
|
HiloadResult res = read_stream_to_str(&memory_str, "/proc/self/maps");
|
||||||
sc_log_debug("Memory Map (/proc/self/maps):\n%s\n", str_ptr(memory_str));
|
if (res == HILOAD_FAIL)
|
||||||
|
return str_null;
|
||||||
|
|
||||||
return memory_str;
|
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
|
HI_MEMORY_PRIVATE = 1 << 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define REGIONS_MAX 256
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *region_start;
|
void *region_starts[REGIONS_MAX];
|
||||||
void *redion_end;
|
void *region_end[REGIONS_MAX];
|
||||||
u32 region_flags; // enum MemoryPermissions
|
u32 region_flags[REGIONS_MAX]; // enum MemoryPermissions
|
||||||
u32 offset;
|
u32 offset[REGIONS_MAX];
|
||||||
str pathname;
|
str pathname[REGIONS_MAX];
|
||||||
} MemoryRegion;
|
} MemoryRegions;
|
||||||
|
|
||||||
str read_memory_maps_self();
|
|
||||||
|
|
||||||
sc_array_def(MemoryRegion, memreg);
|
|
||||||
|
|
||||||
#endif // MEMORY_H_
|
#endif // MEMORY_H_
|
||||||
|
|||||||
99
src/str.c
99
src/str.c
@@ -74,6 +74,14 @@ void str_free_auto(const str* const ps)
|
|||||||
___p; \
|
___p; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define REALLOC(p, n) \
|
||||||
|
({ \
|
||||||
|
void* const ___p = realloc((p), (n)); \
|
||||||
|
if(!___p) return ENOMEM; \
|
||||||
|
___p; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// errno checker
|
// errno checker
|
||||||
#define RETURN_ON_ERROR(expr) \
|
#define RETURN_ON_ERROR(expr) \
|
||||||
while((expr) < 0) do { const int __err = errno; if(__err != EINTR) return __err; } while(0)
|
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;
|
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
|
static
|
||||||
int str_from_fd(const int fd, const off_t size, str* const dest)
|
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;
|
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 str_from_file(str* const dest, const char* const file_name)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@@ -291,6 +368,28 @@ int str_from_file(str* const dest, const char* const file_name)
|
|||||||
return err;
|
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 -----------------------------------------------------------------------
|
// string composition -----------------------------------------------------------------------
|
||||||
// append string
|
// append string
|
||||||
static inline
|
static inline
|
||||||
|
|||||||
@@ -216,6 +216,9 @@ str str_acquire(const char* const s);
|
|||||||
// string from file
|
// string from file
|
||||||
int str_from_file(str* const dest, const char* const file_name);
|
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 --------------------------------------------------------------------
|
// searching and sorting --------------------------------------------------------------------
|
||||||
// string partitioning (substring search)
|
// string partitioning (substring search)
|
||||||
bool str_partition(const str src, const str patt, str* const prefix, str* const suffix);
|
bool str_partition(const str src, const str patt, str* const prefix, str* const suffix);
|
||||||
|
|||||||
Reference in New Issue
Block a user