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 4, 2024
1 parent a5b7365 commit dacb4af
Show file tree
Hide file tree
Showing 11 changed files with 556 additions and 158 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
43 changes: 24 additions & 19 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@
// currently there's quite a bit of redundancy to make things easier to think
// about

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 All @@ -48,8 +46,6 @@ extern void
__clear_cache(void *, void *);

// Number of instructions required by the transition function
#define COMP_TRANS_FN_INSTR_CNT 4

extern void *__capability sealed_redirect_cap;
extern void *__capability comp_return_caps[2];

Expand Down Expand Up @@ -145,6 +141,26 @@ 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;
};

/**
* 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,29 +182,18 @@ 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;
size_t max_manager_caps_count;
size_t active_manager_caps_count;

// Transition function (duplicated across compartments, but must be within
// to be within DDC bounds)
void *mng_trans_fn;
size_t mng_trans_fn_sz;

// Internal libraries and relocations
size_t libs_count;
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 dacb4af

Please sign in to comment.