mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-07 15:42:36 +00:00
The intel64 switch implementation doesn't actually use a switch handle per se, just the raw thread struct pointers which get stored into the handle field. This works fine for normally initialized threads, but when switching out of a dummy thread at initialization, nothing has initialized that field and the code was dumping registers into the bottom of memory through the resulting NULL pointer. Fix this by skipping the load of the field value and just using an offset instead to get the struct address, which is actually slightly faster anyway (a SUB immediate instruction vs. the load). Actually for extra credit we could even move the switch_handle field to the top of the thread struct and eliminate the instruction entirely, though if we did that it's probably worth adding some conditional code to make the switch_handle field disappear entirely. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
93 lines
2.1 KiB
C
93 lines
2.1 KiB
C
/*
|
|
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <device.h>
|
|
|
|
#ifndef ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_
|
|
#define ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_
|
|
|
|
#include <syscall_list.h>
|
|
|
|
/* All of this is build time magic, but LCOV gets confused. Disable coverage
|
|
* for this whole file.
|
|
*
|
|
* LCOV_EXCL_START
|
|
*/
|
|
|
|
/*
|
|
* The final link step uses the symbol _OffsetAbsSyms to force the linkage of
|
|
* offsets.o into the ELF image.
|
|
*/
|
|
|
|
GEN_ABS_SYM_BEGIN(_OffsetAbsSyms)
|
|
|
|
#ifndef CONFIG_SMP
|
|
GEN_OFFSET_SYM(_kernel_t, current);
|
|
GEN_OFFSET_SYM(_kernel_t, nested);
|
|
GEN_OFFSET_SYM(_kernel_t, irq_stack);
|
|
#endif
|
|
|
|
GEN_OFFSET_SYM(_cpu_t, current);
|
|
GEN_OFFSET_SYM(_cpu_t, nested);
|
|
GEN_OFFSET_SYM(_cpu_t, irq_stack);
|
|
|
|
#if defined(CONFIG_THREAD_MONITOR)
|
|
GEN_OFFSET_SYM(_kernel_t, threads);
|
|
#endif
|
|
|
|
#ifdef CONFIG_SYS_POWER_MANAGEMENT
|
|
GEN_OFFSET_SYM(_kernel_t, idle);
|
|
#endif
|
|
|
|
GEN_OFFSET_SYM(_kernel_t, ready_q);
|
|
|
|
#ifndef CONFIG_SMP
|
|
GEN_OFFSET_SYM(_ready_q_t, cache);
|
|
#endif
|
|
|
|
#ifdef CONFIG_FP_SHARING
|
|
GEN_OFFSET_SYM(_kernel_t, current_fp);
|
|
#endif
|
|
|
|
GEN_ABSOLUTE_SYM(_STRUCT_KERNEL_SIZE, sizeof(struct z_kernel));
|
|
|
|
GEN_OFFSET_SYM(_thread_base_t, user_options);
|
|
GEN_OFFSET_SYM(_thread_base_t, thread_state);
|
|
GEN_OFFSET_SYM(_thread_base_t, prio);
|
|
GEN_OFFSET_SYM(_thread_base_t, sched_locked);
|
|
GEN_OFFSET_SYM(_thread_base_t, preempt);
|
|
GEN_OFFSET_SYM(_thread_base_t, swap_data);
|
|
|
|
GEN_OFFSET_SYM(_thread_t, base);
|
|
GEN_OFFSET_SYM(_thread_t, callee_saved);
|
|
GEN_OFFSET_SYM(_thread_t, arch);
|
|
|
|
#ifdef CONFIG_USE_SWITCH
|
|
GEN_OFFSET_SYM(_thread_t, switch_handle);
|
|
#endif
|
|
|
|
#ifdef CONFIG_THREAD_STACK_INFO
|
|
GEN_OFFSET_SYM(_thread_stack_info_t, start);
|
|
GEN_OFFSET_SYM(_thread_stack_info_t, size);
|
|
|
|
GEN_OFFSET_SYM(_thread_t, stack_info);
|
|
#endif
|
|
|
|
#if defined(CONFIG_THREAD_MONITOR)
|
|
GEN_OFFSET_SYM(_thread_t, next_thread);
|
|
#endif
|
|
|
|
#ifdef CONFIG_THREAD_CUSTOM_DATA
|
|
GEN_OFFSET_SYM(_thread_t, custom_data);
|
|
#endif
|
|
|
|
GEN_ABSOLUTE_SYM(K_THREAD_SIZEOF, sizeof(struct k_thread));
|
|
|
|
/* size of the device structure. Used by linker scripts */
|
|
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_SIZEOF, sizeof(struct device));
|
|
|
|
/* LCOV_EXCL_STOP */
|
|
#endif /* ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_ */
|