ANDROID: android: Create debug_symbols driver

Introduce new API to expose symbols useful for debugging the GKI kernel.
Symbols exported from this driver would be difficult to maintain via the
traditional EXPORT_SYMBOL_GPL.

Bug: 160245776
Change-Id: I92053450bd74788889d1b7a569e291a35cd525ea
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
This commit is contained in:
Prasad Sodagudi
2020-10-28 18:26:21 -07:00
parent ba152773be
commit 3fcbb15c1a
4 changed files with 153 additions and 0 deletions

View File

@@ -54,6 +54,17 @@ config ANDROID_BINDER_IPC_SELFTEST
exhaustively with combinations of various buffer sizes and exhaustively with combinations of various buffer sizes and
alignments. 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 config ANDROID_VENDOR_HOOKS
bool "Android Vendor Hooks" bool "Android Vendor Hooks"
depends on TRACEPOINTS depends on TRACEPOINTS

View File

@@ -4,4 +4,5 @@ ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o
obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o
obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.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 obj-$(CONFIG_ANDROID_VENDOR_HOOKS) += vendor_hooks.o

View File

@@ -0,0 +1,99 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/android_debug_symbols.h>
#include <asm/stacktrace.h>
#include <asm/sections.h>
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");

View File

@@ -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 */