Commit 8d2e6fdc authored by Joakim Bech's avatar Joakim Bech
Browse files

Add examples for the libarchcap macros


Signed-off-by: Joakim Bech's avatarJoakim Bech <joakim.bech@linaro.org>
parent e60627b0
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "archcap.h"
#include <hello_morello.h>
#define EXAMPLE_HEADER printf("\n[%s]\n", __func__)
/*
* Demonstrates usage of the function archcap_address_diff().
*
* Take two pointers and compare the difference between them. Provenance is
* kept since we're using the type uintptr_t.
*/
void example_archcap_address_diff(void)
{
/* Some dummy address */
char *s = "dummy";
void *start = s;
void *end = s + 4;
size_t diff = 0;
EXAMPLE_HEADER;
printf("start: 0x%" PRIxPTR "\n", (uintptr_t)start);
printf("end: 0x%" PRIxPTR "\n", (uintptr_t)end);
diff = archcap_address_diff((uintptr_t)end, (uintptr_t)start);
printf("diff (end-start): %zu\n", diff);
}
/*
* Demonstrates usage of the function archcap_address_get().
*
* FIXME: android_readme.rst says: "Gets address from pointer". Wouldn't it be
* more correct to say "Get pointer address from capability?"
*/
void example_archcap_address_get(void)
{
uintptr_t a = 0;
uintptr_t cap_ptraddr = archcap_address_get(&a);
EXAMPLE_HEADER;
printf("&a: 0x%" PRIxPTR "\n", (uintptr_t)&a);
printf("cap_ptraddr: 0x%" PRIxPTR "\n", cap_ptraddr);
}
/*
* Demonstrates usage of the function archcap_address_add().
*
* Here we're converting the pointer to a type (uintptr_t) that will propagate
* provenance before adding the values. The function will return the added
* value and provenance will be kept when casting it back to the pointer.
*/
void example_archcap_address_add(void)
{
/* Some dummy address */
char *s = "dummy";
uintptr_t offset = 2;
uintptr_t tmp;
void *s_offs = NULL;
EXAMPLE_HEADER;
printf("s: 0x%" PRIxPTR "\n", (uintptr_t)s);
tmp = archcap_address_add((uintptr_t)s, offset);
s_offs = (void *)tmp;
printf("s_offs (s+2): 0x%" PRIxPTR "\n", (uintptr_t)s_offs);
}
/*
* Demonstrates usage of the function archcap_address_get_bits().
*
* This will get an address where the bit mask has been applied. In this
* example, we clear the last bits of an address/value.
*/
void example_archcap_address_get_bits(void)
{
uintptr_t a = 0;
uintptr_t bitmask = 0xffff;
void *addr = &a;
uintptr_t addr_bits = archcap_address_get_bits(addr, ~bitmask);
EXAMPLE_HEADER;
printf("addr: 0x%" PRIxPTR "\n", (uintptr_t)addr);
printf("addr_bits (last 16 bits set to zero): 0x%" PRIxPTR "\n", addr_bits);
}
/*
* Demonstrates usage of the function archcap_address_get_bits().
*
* This is essentially the same as example_archcap_address_get_bits(), but here
* we're allocating memory that we later try to abuse to trigger CHERI runtime
* warnings/errors.
*/
void example_archcap_address_get_bits2(void)
{
#ifdef ENABLE_CHERI_VIOLATIONS
/* This mask generates return code 133 */
uintptr_t bitmask = 0xf;
/* This mask generates return code 139 */
/* uintptr_t bitmask = 0xff; */
void *addr = malloc(256);
uintptr_t addr_bits = archcap_address_get_bits(addr, ~bitmask);
EXAMPLE_HEADER;
printf("addr: 0x%" PRIxPTR "\n", (uintptr_t)addr);
printf("addr_bits (last 8 bits set to zero): 0x%" PRIxPTR "\n", addr_bits);
/*
* FIXME: Shouldn't this trigger a CHERI run-time error? Error 139?
* I.e., we're setting an address that should (?) be out of bounds for
* the original pointer?
*/
addr = (uintptr_t *)addr_bits;
printf("addr: 0x%" PRIxPTR "\n", (uintptr_t)addr);
free(addr);
#endif
}
#if 0
/*
* Demonstrates usage of the function archcap_nonderef_cast().
*
* Shows how to construct a capability that is not supposed to be dereferenced.
*/
void example_archcap_nonderef_cast(void)
{
int s = 0;
int *p = &s;
EXAMPLE_HEADER;
#if 0
printf("s: 0x%" PRIxPTR "\n", (uintptr_t)s);
printf("s[0]: 0x%" PRIxPTR "\n", (uintptr_t)*s);
#endif
p = archcap_nonderef_cast_for_type(void, s);
printf("*p: 0x%zu\n", (size_t)*p);
}
#endif
/*
* Demonstrates usage of the function archcap_address_align_up().
*/
void example_archcap_address_align_up(void)
{
size_t t = 0xff4fff;
EXAMPLE_HEADER;
printf("t: 0x%zx\n", t);
t = archcap_address_align_up((uintptr_t)t, 4096);
printf("t (aligned up): 0x%zx\n", t);
}
/*
* Demonstrates usage of the function archcap_address_align_down().
*/
void example_archcap_address_align_down(void)
{
size_t t = 0xff5001;
EXAMPLE_HEADER;
printf("t: 0x%zx\n", t);
t = archcap_address_align_down((uintptr_t)t, 4096);
printf("t (aligned down): 0x%zx\n", t);
}
/*
* Demonstrates usage of the function archcap_address_align_sub().
*
* This will simply just subtract a number from the address of the capability.
*/
void example_archcap_address_sub(void)
{
uintptr_t c = 0;
void *a = &c;
EXAMPLE_HEADER;
printf("c: 0x%" PRIxPTR "\n", (uintptr_t)&c);
c = archcap_address_sub((uintptr_t)a, 1);
printf("c-1: 0x%" PRIxPTR "\n", c);
}
/*
* Demonstrates usage of the function archcap_address_clear_bits().
*
* This example clears that last 16 bits
*/
void example_archcap_address_clear_bits(void)
{
uintptr_t a = 0;
void *addr = &a;
EXAMPLE_HEADER;
printf("addr: 0x%" PRIxPTR "\n", (uintptr_t)addr);
a = (uintptr_t)archcap_address_clear_bits(addr, 0xff);
printf("addr (last 8 bits set to zero): 0x%" PRIxPTR "\n", a);
}
/*
* Demonstrates usage of the function archcap_address_and().
*/
void example_archcap_address_and(void)
{
uintptr_t bits_a = 0xff0;
uintptr_t bits_b = 0xf0f;
uintptr_t res;
EXAMPLE_HEADER;
printf("bits_a: 0x%" PRIxPTR "\n", bits_a);
printf("bits_b: 0x%" PRIxPTR "\n", bits_b);
res = (uintptr_t)archcap_address_and(bits_a, bits_b);
printf("res (bits_a & bits_b): 0x%" PRIxPTR "\n", res);
}
#if 0
/*
* Demonstrates usage of the function archcap_address_set().
*
* FIXME: What's the purpose with the set function, when should it be used in
* reality?
*/
void example_archcap_address_set(void)
{
size_t a = 0;
void *p = &a;
EXAMPLE_HEADER;
}
#endif
/*
* Demonstrates usage of the function archcap_address_or().
*/
void example_archcap_address_or(void)
{
uintptr_t bits_a = 0xff0;
uintptr_t bits_b = 0xf0f;
uintptr_t res;
EXAMPLE_HEADER;
printf("bits_a: 0x%" PRIxPTR "\n", bits_a);
printf("bits_b: 0x%" PRIxPTR "\n", bits_b);
res = (uintptr_t)archcap_address_or(bits_a, bits_b);
printf("res (bits_a | bits_b): 0x%" PRIxPTR "\n", res);
}
int main()
{
printf("Hello world - Morello - Pure-capability\n");
example_archcap_address_diff();
example_archcap_address_get();
example_archcap_address_add();
example_archcap_address_get_bits();
example_archcap_address_get_bits2();
#if 0
example_archcap_nonderef_cast();
#endif
example_archcap_address_align_up();
example_archcap_address_align_down();
example_archcap_address_sub();
example_archcap_address_clear_bits();
example_archcap_address_and();
#if 0
example_archcap_address_set();
#endif
example_archcap_address_or();
return 0;
}
#ifdef _HELLO_MORELLO_H
#define _HELLO_MORELLO_H
#endif
#ifndef _HELLO_MORELLO_H
#define _HELLO_MORELLO_H
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment