b19c9dea3e
The arm kernel stack unwinder has apparently never been able to unwind when the path of execution leads through a kernel module. There was code that tried to handle modules by looking for the unwind data in them, but it did so by trying to find symbols which have never existed in arm kernel modules. That caused the unwind code to panic, and because part of panic handling calls into the unwind code, that just created a recursion loop. Locating the unwind data in a loaded module requires accessing the Elf section headers to find the SHT_ARM_EXIDX section. For preloaded modules those headers are present in a metadata blob. For dynamically loaded modules, the headers are present only while the loading is in progress; the memory is freed once the module is ready to use. For that reason, there is new code in kern/link_elf.c, wrapped in #ifdef __arm__, to extract the unwind info while the headers are loaded. The values are saved into new fields in the linker_file structure which are also conditional on __arm__. In arm/unwind.c there is new code to locally cache the per-module info needed to find the unwind tables. The local cache is crafted for lockless read access, because the unwind code often needs to run in context where sleeping is not allowed. A large comment block describes the local cache list, so I won't repeat it all here.
69 lines
1.8 KiB
C
69 lines
1.8 KiB
C
/*-
|
|
* Copyright (c) 2000, 2001 Ben Harris
|
|
* Copyright (c) 1996 Scott K. Stevens
|
|
*
|
|
* Mach Operating System
|
|
* Copyright (c) 1991,1990 Carnegie Mellon University
|
|
* All Rights Reserved.
|
|
*
|
|
* Permission to use, copy, modify and distribute this software and its
|
|
* documentation is hereby granted, provided that both the copyright
|
|
* notice and this permission notice appear in all copies of the
|
|
* software, derivative works or modified versions, and any portions
|
|
* thereof, and that both notices appear in supporting documentation.
|
|
*
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
|
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
|
*
|
|
* Carnegie Mellon requests users of this software to return to
|
|
*
|
|
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
|
* School of Computer Science
|
|
* Carnegie Mellon University
|
|
* Pittsburgh PA 15213-3890
|
|
*
|
|
* any improvements or extensions that they make and grant Carnegie the
|
|
* rights to redistribute these changes.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
#ifndef _MACHINE_STACK_H_
|
|
#define _MACHINE_STACK_H_
|
|
|
|
#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
|
|
|
|
#define FR_SCP (0)
|
|
#define FR_RLV (-1)
|
|
#define FR_RSP (-2)
|
|
#define FR_RFP (-3)
|
|
|
|
/* The state of the unwind process */
|
|
struct unwind_state {
|
|
uint32_t registers[16];
|
|
uint32_t start_pc;
|
|
uint32_t *insn;
|
|
u_int entries;
|
|
u_int byte;
|
|
uint16_t update_mask;
|
|
};
|
|
|
|
/* The register names */
|
|
#define FP 11
|
|
#define SP 13
|
|
#define LR 14
|
|
#define PC 15
|
|
|
|
#ifdef _KERNEL
|
|
|
|
int unwind_stack_one(struct unwind_state *, int);
|
|
|
|
struct linker_file;
|
|
void unwind_module_loaded(struct linker_file *);
|
|
void unwind_module_unloaded(struct linker_file *);
|
|
|
|
#endif
|
|
|
|
#endif /* !_MACHINE_STACK_H_ */
|