Skip to content

Commit

Permalink
Add TLS support
Browse files Browse the repository at this point in the history
Initial support for `_Thread_local` (and `_Thread_local static`)
variables.

Limitations:
* Supports a single TLS region, but amenable to
future extensions if we want to implement multi-threaded compartments;
* Handles only symbols of type `TLSDESC`.

Other changes:
* Remove some old `struct Compartment` member variables that are now
  unneeded;
* Add `print_comp` back;
* Fix a bug regarding calculating scratch memory size for compartments;
* Fixed a bug with setting relocation target addresses.
  • Loading branch information
0152la committed Jun 3, 2024
1 parent a5b7365 commit a3813d6
Show file tree
Hide file tree
Showing 10 changed files with 520 additions and 114 deletions.
1 change: 1 addition & 0 deletions include/comp_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <err.h>
#include <stddef.h>
#include <string.h>
#include <sys/mman.h>

#include "cheriintrin.h"

Expand Down
33 changes: 27 additions & 6 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
void
compartment_transition_out();
int64_t
comp_exec_in(
void *, void *__capability, void *, void *, size_t, void *__capability);
comp_exec_in(void *, void *__capability, void *, void *, size_t,
void *__capability, void *);
void
comp_exec_out();

Expand Down Expand Up @@ -145,6 +145,28 @@ struct LibDependency
// Symbols within this library that need eager relocation
size_t rela_maps_count;
struct LibRelaMapping *rela_maps;

// TLS-related variables
// TODO can there be more TLS sections?
void *tls_sec_addr;
size_t tls_sec_size;
size_t tls_data_size;
unsigned short tls_vars_count;
unsigned int tls_vars_idx_start;
};

/**
* Struct representing TLS information for a compartment. Since we currently
* enforce only single-threaded code, we basically only have pointers for
* regions allocated for TLS for each dynamic shared object
*/
struct TLSDesc
{
unsigned short region_count;
size_t region_size;
void *region_start;
unsigned short libs_count;
unsigned short *lib_idxs;
};

/**
Expand All @@ -166,16 +188,13 @@ struct Compartment
// Scratch memory
void *scratch_mem_base;
size_t scratch_mem_size;
size_t scratch_mem_alloc;

size_t scratch_mem_heap_size;
void *scratch_mem_stack_top;
size_t scratch_mem_stack_size;
void *stack_pointer;
struct MemAlloc *alloc_head;

// TODO double check / rework this process
void *manager_caps;
void *manager_caps; // seems unused
size_t max_manager_caps_count;
size_t active_manager_caps_count;

Expand All @@ -189,6 +208,8 @@ struct Compartment
struct LibDependency **libs;
size_t entry_point_count;
struct CompEntryPoint *entry_points;
void *tls_lookup_func;
struct TLSDesc *libs_tls_sects;

// Hardware info - maybe move
size_t page_size;
Expand Down
6 changes: 0 additions & 6 deletions include/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ extern void *__capability manager_ddc;
extern struct CompWithEntries **comps;
extern struct Compartment *loaded_comp;

/*******************************************************************************
* Utility Functions
******************************************************************************/

void print_full_cap(uintcap_t);

/*******************************************************************************
* Compartment
******************************************************************************/
Expand Down
31 changes: 29 additions & 2 deletions src/comp_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,33 @@
static void *malloc_ptr;
static size_t heap_mem_left;

#define NON_COMP_DEFAULT_SIZE 10 * 1024 // 10 MB

void *
malloc(size_t to_alloc)
{
if (!malloc_ptr)
{
void *__capability ddc = cheri_ddc_get();
malloc_ptr = (char *) cheri_address_get(ddc);
heap_mem_left = cheri_length_get(ddc) - cheri_offset_get(ddc);
if (cheri_base_get(ddc) == 0)
{
malloc_ptr = mmap(0, NON_COMP_DEFAULT_SIZE, PROT_WRITE | PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
heap_mem_left = NON_COMP_DEFAULT_SIZE;
if (malloc_ptr == MAP_FAILED)
{
err(1, "Failed `mmap`");
}
}
else
{
malloc_ptr = (char *) cheri_address_get(ddc);
// TODO move heap to the end of the compartment; currently, it's at
// the beginning of the memory scratch area
heap_mem_left = cheri_length_get(ddc) - cheri_offset_get(ddc);
}
}

if (to_alloc > heap_mem_left)
{
errx(1, "Insufficient heap space left.");
Expand Down Expand Up @@ -44,3 +62,12 @@ realloc(void *to_realloc, size_t new_size)

return malloc(new_size);
}

void
tls_lookup_stub()
{
// Get TLS index
// TODO works only for one TLS region
asm("ldr x0, [x0, #8]" : :);
return;
}
Loading

0 comments on commit a3813d6

Please sign in to comment.