Populate the memory map structure
This commit is contained in:
@@ -21,7 +21,7 @@ typedef struct {
|
|||||||
} ModuleInfos;
|
} ModuleInfos;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct sc_array_memreg *memory_regions;
|
struct sc_array_memreg memory_regions;
|
||||||
} HiloadContext;
|
} HiloadContext;
|
||||||
|
|
||||||
static HiloadContext context = {0};
|
static HiloadContext context = {0};
|
||||||
@@ -267,7 +267,7 @@ int hi_init() {
|
|||||||
sc_log_set_level("DEBUG");
|
sc_log_set_level("DEBUG");
|
||||||
|
|
||||||
|
|
||||||
if (read_memory_maps_self(context.memory_regions) != HILOAD_OK) {
|
if (read_memory_maps_self(&context.memory_regions) != HILOAD_OK) {
|
||||||
sc_log_error("Could not populate program memory maps.\n");
|
sc_log_error("Could not populate program memory maps.\n");
|
||||||
return HILOAD_FAIL;
|
return HILOAD_FAIL;
|
||||||
}
|
}
|
||||||
|
|||||||
62
src/memory.c
62
src/memory.c
@@ -4,22 +4,68 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void hi_clear_memreg(struct sc_array_memreg *regions)
|
|
||||||
{
|
|
||||||
MemoryRegions *reg;
|
|
||||||
sc_array_foreach(regions, *reg) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) {
|
HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) {
|
||||||
str memory_str = str_null;
|
str memory_str = str_null;
|
||||||
|
|
||||||
|
sc_array_clear(regions);
|
||||||
|
sc_array_init(regions);
|
||||||
|
|
||||||
HiloadResult res = read_stream_to_str(&memory_str, "/proc/self/maps");
|
HiloadResult res = read_stream_to_str(&memory_str, "/proc/self/maps");
|
||||||
if (res == HILOAD_FAIL)
|
if (res == HILOAD_FAIL)
|
||||||
return HILOAD_FAIL;
|
return HILOAD_FAIL;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
MemoryRegions reg = {0};
|
||||||
|
char *strptr = (char *)str_ptr(memory_str);
|
||||||
|
char *line = strtok(strptr, "\n");
|
||||||
|
while (line) {
|
||||||
|
|
||||||
|
if (i >= HI_MEM_REG_MAX) {
|
||||||
|
sc_array_add(regions, reg);
|
||||||
|
memset(®, 0, sizeof(reg));
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char perm_str[5];
|
||||||
|
u32 dev_major;
|
||||||
|
u32 dev_minor;
|
||||||
|
char pathname[256];
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// Example from `cat /proc/self/maps`
|
||||||
|
// 7fa0b66ca000-7fa0b66cc000 rw-p 00033000 fe:02 28063911 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
|
||||||
|
int result = sscanf(line, "%lx-%lx %4s %lx %x:%x %lu %255s",
|
||||||
|
®.region_starts[i],
|
||||||
|
®.region_ends[i],
|
||||||
|
perm_str,
|
||||||
|
®.offsets[i],
|
||||||
|
&dev_major,
|
||||||
|
&dev_minor,
|
||||||
|
®.inodes[i],
|
||||||
|
pathname);
|
||||||
|
|
||||||
|
if (perm_str[0] == 'r') reg.permissions[i] |= HI_MEMORY_READ;
|
||||||
|
if (perm_str[1] == 'w') reg.permissions[i] |= HI_MEMORY_WRITE;
|
||||||
|
if (perm_str[2] == 'x') reg.permissions[i] |= HI_MEMORY_EXECUTE;
|
||||||
|
if (perm_str[3] == 'p') reg.permissions[i] |= HI_MEMORY_PRIVATE;
|
||||||
|
if (perm_str[3] == 's') reg.permissions[i] |= HI_MEMORY_SHARED;
|
||||||
|
|
||||||
|
// pathname could be empty, so we check for it
|
||||||
|
if (result >= 8) {
|
||||||
|
reg.pathnames[i] = strdup(pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
line = strtok(NULL, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
sc_array_add(regions, reg);
|
||||||
|
|
||||||
sc_log_debug("Memory Map\n-- /proc/self/maps:\n%s\n", str_ptr(memory_str));
|
sc_log_debug("Memory Map\n-- /proc/self/maps:\n%s\n", str_ptr(memory_str));
|
||||||
|
|
||||||
|
str_free(memory_str);
|
||||||
|
|
||||||
return HILOAD_OK;
|
return HILOAD_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/memory.h
24
src/memory.h
@@ -7,30 +7,30 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
enum MemoryPermissions {
|
typedef enum {
|
||||||
HI_MEMORY_READ = 1 << 0,
|
HI_MEMORY_READ = 1 << 0,
|
||||||
HI_MEMORY_WRITE = 1 << 1,
|
HI_MEMORY_WRITE = 1 << 1,
|
||||||
HI_MEMORY_EXECUTE = 1 << 2,
|
HI_MEMORY_EXECUTE = 1 << 2,
|
||||||
HI_MEMORY_SHARED = 1 << 3,
|
HI_MEMORY_SHARED = 1 << 3,
|
||||||
HI_MEMORY_PRIVATE = 1 << 4
|
HI_MEMORY_PRIVATE = 1 << 4
|
||||||
};
|
} MemoryPermissions;
|
||||||
|
|
||||||
#define HI_MEM_REG_MAX 256
|
#define HI_MEM_REG_MAX 256
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *region_starts[HI_MEM_REG_MAX];
|
uptr region_starts[HI_MEM_REG_MAX];
|
||||||
void *region_end[HI_MEM_REG_MAX];
|
uptr region_ends[HI_MEM_REG_MAX];
|
||||||
u32 region_flags[HI_MEM_REG_MAX]; // enum MemoryPermissions
|
uptr offsets[HI_MEM_REG_MAX];
|
||||||
u32 offset[HI_MEM_REG_MAX];
|
u64 inodes[HI_MEM_REG_MAX];
|
||||||
str pathname[HI_MEM_REG_MAX];
|
u32 permissions[HI_MEM_REG_MAX]; // enum MemoryPermissions
|
||||||
|
const char *pathnames[HI_MEM_REG_MAX];
|
||||||
} MemoryRegions;
|
} MemoryRegions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sc_array_def(MemoryRegions, memreg);
|
sc_array_def(MemoryRegions, memreg);
|
||||||
_Static_assert(sizeof(MemoryRegions) < 1024 * 11, "MemoryRegion size has increased. Fix this assert.");
|
_Static_assert(sizeof(MemoryRegions) < 1024 * 12, "MemoryRegion size has increased. Fix this assert.");
|
||||||
|
|
||||||
/* Needed to free the underlying pathnames before clear */
|
/* A pointer that can be used to place the memory regions into. Clears regions before use, but uses the same buffer. */
|
||||||
void hi_clear_memreg(struct sc_array_memreg *regions);
|
|
||||||
|
|
||||||
/* A pointer that can be used to place the memory regions into. If mr isn't cleared, the content will be cleared. */
|
|
||||||
HiloadResult read_memory_maps_self(struct sc_array_memreg *regions);
|
HiloadResult read_memory_maps_self(struct sc_array_memreg *regions);
|
||||||
|
|
||||||
#endif // MEMORY_H_
|
#endif // MEMORY_H_
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define TYPES_H_
|
#define TYPES_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
@@ -14,6 +15,9 @@ typedef int64_t i64;
|
|||||||
typedef float f32;
|
typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
|
||||||
|
typedef uintptr_t uptr;
|
||||||
|
typedef ptrdiff_t ptrdiff;
|
||||||
|
|
||||||
typedef enum { HILOAD_OK = 0, HILOAD_FAIL } HiloadResult;
|
typedef enum { HILOAD_OK = 0, HILOAD_FAIL } HiloadResult;
|
||||||
|
|
||||||
#endif // TYPES_H_
|
#endif // TYPES_H_
|
||||||
|
|||||||
Reference in New Issue
Block a user