diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index 32fb9e5b6195..a99ff854a2ed 100644 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -54,6 +54,17 @@ config ANDROID_BINDER_IPC_SELFTEST exhaustively with combinations of various buffer sizes and alignments. +config ANDROID_DEBUG_SYMBOLS + bool "Android Debug Symbols" + help + Enables export of debug symbols that are useful for offline debugging + of a kernel. These symbols would be used in vendor modules to find + addresses of the core kernel symbols for vendor extensions. + + This driver is statically compiled into kernel and maintains all the + required symbol addresses for vendor modules and provides necessary + interface vendor modules. + config ANDROID_VENDOR_HOOKS bool "Android Vendor Hooks" depends on TRACEPOINTS diff --git a/drivers/android/Makefile b/drivers/android/Makefile index d488047415a0..925d18eb29ff 100644 --- a/drivers/android/Makefile +++ b/drivers/android/Makefile @@ -4,4 +4,5 @@ ccflags-y += -I$(src) # needed for trace events obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +obj-$(CONFIG_ANDROID_DEBUG_SYMBOLS) += debug_symbols.o obj-$(CONFIG_ANDROID_VENDOR_HOOKS) += vendor_hooks.o diff --git a/drivers/android/debug_symbols.c b/drivers/android/debug_symbols.c new file mode 100644 index 000000000000..0a8c20cc775c --- /dev/null +++ b/drivers/android/debug_symbols.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +struct ads_entry { + char *name; + void *addr; +}; + +#define _ADS_ENTRY(index, symbol) \ + [index] = { .name = #symbol, .addr = (void *)symbol } +#define ADS_ENTRY(index, symbol) _ADS_ENTRY(index, symbol) + +#define _ADS_PER_CPU_ENTRY(index, symbol) \ + [index] = { .name = #symbol, .addr = (void *)&symbol } +#define ADS_PER_CPU_ENTRY(index, symbol) _ADS_PER_CPU_ENTRY(index, symbol) + +/* + * This module maintains static array of symbol and address information. + * Add all required core kernel symbols and their addresses into ads_entries[] array, + * so that vendor modules can query and to find address of non-exported symbol. + */ +static const struct ads_entry ads_entries[ADS_END] = { + ADS_ENTRY(ADS_SDATA, _sdata), + ADS_ENTRY(ADS_BSS_END, __bss_stop), + ADS_ENTRY(ADS_PER_CPU_START, __per_cpu_start), + ADS_ENTRY(ADS_PER_CPU_END, __per_cpu_end), + ADS_ENTRY(ADS_START_RO_AFTER_INIT, __start_ro_after_init), + ADS_ENTRY(ADS_END_RO_AFTER_INIT, __end_ro_after_init), + ADS_ENTRY(ADS_LINUX_BANNER, linux_banner), +}; + +/* + * ads_per_cpu_entries array contains all the per_cpu variable address information. + */ +static const struct ads_entry ads_per_cpu_entries[ADS_DEBUG_PER_CPU_END] = { +#ifdef CONFIG_ARM64 + ADS_PER_CPU_ENTRY(ADS_IRQ_STACK_PTR, irq_stack_ptr), +#endif +#ifdef CONFIG_X86 + ADS_PER_CPU_ENTRY(ADS_IRQ_STACK_PTR, hardirq_stack_ptr), +#endif +}; + +/* + * android_debug_symbol - Provide address inforamtion of debug symbol. + * @symbol: Index of debug symbol array. + * + * Return address of core kernel symbol on success and a negative errno will be + * returned in error cases. + * + */ +void *android_debug_symbol(enum android_debug_symbol symbol) +{ + if (symbol >= ADS_END) + return ERR_PTR(-EINVAL); + + return ads_entries[symbol].addr; +} +EXPORT_SYMBOL_GPL(android_debug_symbol); + +/* + * android_debug_per_cpu_symbol - Provide address inforamtion of per cpu debug symbol. + * @symbol: Index of per cpu debug symbol array. + * + * Return address of core kernel symbol on success and a negative errno will be + * returned in error cases. + * + */ +void *android_debug_per_cpu_symbol(enum android_debug_per_cpu_symbol symbol) +{ + if (symbol >= ADS_DEBUG_PER_CPU_END) + return ERR_PTR(-EINVAL); + + return ads_per_cpu_entries[symbol].addr; +} +EXPORT_SYMBOL_GPL(android_debug_per_cpu_symbol); + +static int __init debug_symbol_init(void) +{ + return 0; +} +module_init(debug_symbol_init); + +static void __exit debug_symbol_exit(void) +{ } +module_exit(debug_symbol_exit); + +MODULE_DESCRIPTION("Debug Symbol Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/android_debug_symbols.h b/include/linux/android_debug_symbols.h new file mode 100644 index 000000000000..5d669b2f82f6 --- /dev/null +++ b/include/linux/android_debug_symbols.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _ANDROID_DEBUG_SYMBOLS_H +#define _ANDROID_DEBUG_SYMBOLS_H + +enum android_debug_symbol { + ADS_SDATA = 0, + ADS_BSS_END, + ADS_PER_CPU_START, + ADS_PER_CPU_END, + ADS_START_RO_AFTER_INIT, + ADS_END_RO_AFTER_INIT, + ADS_LINUX_BANNER, + ADS_END +}; + +enum android_debug_per_cpu_symbol { + ADS_IRQ_STACK_PTR = 0, + ADS_DEBUG_PER_CPU_END +}; + +#ifdef CONFIG_ANDROID_DEBUG_SYMBOLS + +void *android_debug_symbol(enum android_debug_symbol symbol); +void *android_debug_per_cpu_symbol(enum android_debug_per_cpu_symbol symbol); + +#else /* !CONFIG_ANDROID_DEBUG_SYMBOLS */ + +static inline void *android_debug_symbol(enum android_debug_symbol symbol) +{ + return NULL; +} +static inline void *android_debug_per_cpu_symbol(enum android_debug_per_cpu_symbol symbol) +{ + return NULL; +} +#endif /* CONFIG_ANDROID_DEBUG_SYMBOLS */ + +#endif /* _ANDROID_DEBUG_SYMBOLS_H */