2024-07-06 06:13:20 +00:00
|
|
|
#ifndef COSMOPOLITAN_MAPS_H_
|
|
|
|
#define COSMOPOLITAN_MAPS_H_
|
2024-06-21 03:46:42 +00:00
|
|
|
#include "libc/intrin/atomic.h"
|
2024-07-06 06:13:20 +00:00
|
|
|
#include "libc/intrin/tree.h"
|
|
|
|
#include "libc/runtime/runtime.h"
|
2024-06-21 03:46:42 +00:00
|
|
|
#include "libc/thread/tls2.internal.h"
|
|
|
|
COSMOPOLITAN_C_START_
|
|
|
|
|
2024-07-24 08:05:00 +00:00
|
|
|
#define MAPS_RETRY ((void *)-1)
|
|
|
|
|
2024-07-06 06:13:20 +00:00
|
|
|
#define MAP_TREE_CONTAINER(e) TREE_CONTAINER(struct Map, tree, e)
|
2024-06-21 03:46:42 +00:00
|
|
|
|
|
|
|
struct Map {
|
2024-06-29 12:10:15 +00:00
|
|
|
char *addr; /* granule aligned */
|
|
|
|
size_t size; /* must be nonzero */
|
2024-07-06 06:13:20 +00:00
|
|
|
int64_t off; /* ignore for anon */
|
2024-06-29 12:10:15 +00:00
|
|
|
int prot; /* memory protects */
|
|
|
|
int flags; /* memory map flag */
|
|
|
|
bool iscow; /* windows nt only */
|
|
|
|
bool readonlyfile; /* windows nt only */
|
2024-07-07 19:24:25 +00:00
|
|
|
unsigned visited; /* checks and fork */
|
2024-07-04 17:52:16 +00:00
|
|
|
intptr_t hand; /* windows nt only */
|
2024-07-06 06:13:20 +00:00
|
|
|
union {
|
|
|
|
struct Tree tree;
|
2024-07-23 10:16:17 +00:00
|
|
|
struct Map *freed;
|
2024-07-06 06:13:20 +00:00
|
|
|
};
|
2024-06-21 03:46:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Maps {
|
2024-07-06 06:13:20 +00:00
|
|
|
struct Tree *maps;
|
2024-07-26 07:44:45 +00:00
|
|
|
_Atomic(uint64_t) lock;
|
2024-07-23 10:16:17 +00:00
|
|
|
_Atomic(struct Map *) freed;
|
2024-06-24 13:53:49 +00:00
|
|
|
size_t count;
|
|
|
|
size_t pages;
|
2024-07-20 09:20:03 +00:00
|
|
|
_Atomic(char *) pick;
|
2024-07-04 17:52:16 +00:00
|
|
|
struct Map stack;
|
|
|
|
struct Map guard;
|
2024-06-21 03:46:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct AddrSize {
|
|
|
|
char *addr;
|
|
|
|
size_t size;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern struct Maps __maps;
|
|
|
|
|
|
|
|
void __maps_init(void);
|
2024-07-04 17:52:16 +00:00
|
|
|
bool __maps_lock(void);
|
2024-06-24 13:53:49 +00:00
|
|
|
void __maps_check(void);
|
2024-06-21 03:46:42 +00:00
|
|
|
void __maps_unlock(void);
|
2024-07-20 09:20:03 +00:00
|
|
|
void *__maps_randaddr(void);
|
|
|
|
void *__maps_pickaddr(size_t);
|
2024-07-04 09:50:20 +00:00
|
|
|
void __maps_add(struct Map *);
|
2024-06-21 03:46:42 +00:00
|
|
|
void __maps_free(struct Map *);
|
2024-07-06 06:13:20 +00:00
|
|
|
struct Map *__maps_alloc(void);
|
|
|
|
struct Map *__maps_floor(const char *);
|
2024-07-04 17:52:16 +00:00
|
|
|
void __maps_stack(char *, int, int, size_t, int, intptr_t);
|
2024-07-06 06:13:20 +00:00
|
|
|
int __maps_compare(const struct Tree *, const struct Tree *);
|
2024-06-21 03:46:42 +00:00
|
|
|
struct AddrSize __get_main_stack(void);
|
|
|
|
|
2024-07-06 06:13:20 +00:00
|
|
|
forceinline optimizespeed int __maps_search(const void *key,
|
|
|
|
const struct Tree *node) {
|
|
|
|
const char *addr = (const char *)key;
|
|
|
|
const struct Map *map = (const struct Map *)MAP_TREE_CONTAINER(node);
|
2024-07-07 19:24:25 +00:00
|
|
|
return (addr > map->addr) - (addr < map->addr);
|
2024-07-06 06:13:20 +00:00
|
|
|
}
|
|
|
|
|
2024-07-19 02:19:51 +00:00
|
|
|
static inline struct Map *__maps_next(struct Map *map) {
|
2024-07-06 06:13:20 +00:00
|
|
|
struct Tree *node;
|
|
|
|
if ((node = tree_next(&map->tree)))
|
|
|
|
return MAP_TREE_CONTAINER(node);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-07-19 02:19:51 +00:00
|
|
|
static inline struct Map *__maps_first(void) {
|
2024-07-06 06:13:20 +00:00
|
|
|
struct Tree *node;
|
|
|
|
if ((node = tree_first(__maps.maps)))
|
|
|
|
return MAP_TREE_CONTAINER(node);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-06-21 03:46:42 +00:00
|
|
|
COSMOPOLITAN_C_END_
|
2024-07-06 06:13:20 +00:00
|
|
|
#endif /* COSMOPOLITAN_MAPS_H_ */
|