optee中的栈

optee中定义了三种stack

#define DECLARE_STACK(name, num_stacks, stack_size, linkage) \
linkage uint32_t name[num_stacks] \
        [ROUNDUP(stack_size + STACK_CANARY_SIZE + STACK_CHECK_EXTRA, \
             STACK_ALIGNMENT) / sizeof(uint32_t)] \
        __attribute__((section(".nozi_stack." # name), \
                   aligned(STACK_ALIGNMENT)))

#define GET_STACK(stack) ((vaddr_t)(stack) + STACK_SIZE(stack))

DECLARE_STACK(stack_tmp, CFG_TEE_CORE_NB_CORE,
          STACK_TMP_SIZE + CFG_STACK_TMP_EXTRA, static);
DECLARE_STACK(stack_abt, CFG_TEE_CORE_NB_CORE, STACK_ABT_SIZE, static);
#ifndef CFG_WITH_PAGER
DECLARE_STACK(stack_thread, CFG_NUM_THREADS,
          STACK_THREAD_SIZE + CFG_STACK_THREAD_EXTRA, static);
#endif

这里的stack基本就是一个二维数组,且这些数组都会被放到一段特殊的段中".nozi_stack."。以stack_thread,其第二个参数CFG_NUM_THREADS表示为每个线程都有一个stack,
其大小是STACK_THREAD_SIZE,如果开启debug stack的话,会额外增加一个大小#define STACK_CHECK_EXTRA    1536
在这些栈被使用之前会通过init_canaries 来为这些栈的起始和结束的地址写一个特殊的字符,例如起始写的是*start_canary = START_CANARY_VALUE
static void init_canaries(void)
{
#ifdef CFG_WITH_STACK_CANARIES
    size_t n;
#define INIT_CANARY(name)                        \
    for (n = 0; n < ARRAY_SIZE(name); n++) {            \
        uint32_t *start_canary = &GET_START_CANARY(name, n);    \
        uint32_t *end_canary = &GET_END_CANARY(name, n);    \
                                    \
        *start_canary = START_CANARY_VALUE;            \
        *end_canary = END_CANARY_VALUE;                \
    }

    INIT_CANARY(stack_tmp);
    INIT_CANARY(stack_abt);
#if !defined(CFG_WITH_PAGER) && !defined(CFG_VIRTUALIZATION)
    INIT_CANARY(stack_thread);
#endif
#endif/*CFG_WITH_STACK_CANARIES*/
}

这主要是防止使用栈超过其初始的大小.例如就会调用下面的函数来检查栈
void thread_check_canaries(void)
{
#ifdef CFG_WITH_STACK_CANARIES
    uint32_t *canary = NULL;
    size_t n = 0;

    
#if !defined(CFG_WITH_PAGER) && !defined(CFG_VIRTUALIZATION)
    for (n = 0; n < ARRAY_SIZE(stack_thread); n++) {
        canary = &GET_START_CANARY(stack_thread, n);
        if (*canary != START_CANARY_VALUE)
            CANARY_DIED(stack_thread, start, n, canary);
        canary = &GET_END_CANARY(stack_thread, n);
        if (*canary != END_CANARY_VALUE)
            CANARY_DIED(stack_thread, end, n, canary);
    }
#endif
#endif/*CFG_WITH_STACK_CANARIES*/
}
具体哪些地方用栈呢?还是以stack_thread为例,当我们申请thread的时候就会从stack_thread拿到栈
static void init_thread_stacks(void)
{
    size_t n;

    /* Assign the thread stacks */
    for (n = 0; n < CFG_NUM_THREADS; n++) {
        if (!thread_init_stack(n, GET_STACK_BOTTOM(stack_thread, n)))
            panic("thread_init_stack failed");
    }
}
从GET_STACK_BOTTOM(stack_thread, n))可以看出这些栈是从bottom涨到up的,也就是说栈是从地址大的忘地址小的一次减小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值