Merge branch 'for-4.16-deprecate-printk-pf' into for-4.16
This commit is contained in:
commit
3ccdc5190f
|
@ -50,42 +50,31 @@ Symbols/Function Pointers
|
|||
|
||||
::
|
||||
|
||||
%pS versatile_init+0x0/0x110
|
||||
%ps versatile_init
|
||||
%pF versatile_init+0x0/0x110
|
||||
%pf versatile_init
|
||||
%pS versatile_init+0x0/0x110
|
||||
%pSR versatile_init+0x9/0x110
|
||||
(with __builtin_extract_return_addr() translation)
|
||||
%ps versatile_init
|
||||
%pB prev_fn_of_versatile_init+0x88/0x88
|
||||
|
||||
The ``F`` and ``f`` specifiers are for printing function pointers,
|
||||
for example, f->func, &gettimeofday. They have the same result as
|
||||
``S`` and ``s`` specifiers. But they do an extra conversion on
|
||||
ia64, ppc64 and parisc64 architectures where the function pointers
|
||||
are actually function descriptors.
|
||||
The ``S`` and ``s`` specifiers are used for printing a pointer in symbolic
|
||||
format. They result in the symbol name with (``S``) or without (``s``)
|
||||
offsets. If KALLSYMS are disabled then the symbol address is printed instead.
|
||||
|
||||
The ``S`` and ``s`` specifiers can be used for printing symbols
|
||||
from direct addresses, for example, __builtin_return_address(0),
|
||||
(void *)regs->ip. They result in the symbol name with (``S``) or
|
||||
without (``s``) offsets. If KALLSYMS are disabled then the symbol
|
||||
address is printed instead.
|
||||
Note, that the ``F`` and ``f`` specifiers are identical to ``S`` (``s``)
|
||||
and thus deprecated. We have ``F`` and ``f`` because on ia64, ppc64 and
|
||||
parisc64 function pointers are indirect and, in fact, are function
|
||||
descriptors, which require additional dereferencing before we can lookup
|
||||
the symbol. As of now, ``S`` and ``s`` perform dereferencing on those
|
||||
platforms (when needed), so ``F`` and ``f`` exist for compatibility
|
||||
reasons only.
|
||||
|
||||
The ``B`` specifier results in the symbol name with offsets and should be
|
||||
used when printing stack backtraces. The specifier takes into
|
||||
consideration the effect of compiler optimisations which may occur
|
||||
when tail-call``s are used and marked with the noreturn GCC attribute.
|
||||
|
||||
Examples::
|
||||
|
||||
printk("Going to call: %pF\n", gettimeofday);
|
||||
printk("Going to call: %pF\n", p->func);
|
||||
printk("%s: called from %pS\n", __func__, (void *)_RET_IP_);
|
||||
printk("%s: called from %pS\n", __func__,
|
||||
(void *)__builtin_return_address(0));
|
||||
printk("Faulted at %pS\n", (void *)regs->ip);
|
||||
printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack);
|
||||
|
||||
|
||||
Kernel Pointers
|
||||
===============
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
|
|||
extern char __start_unwind[], __end_unwind[];
|
||||
extern char __start_ivt_text[], __end_ivt_text[];
|
||||
|
||||
#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
|
||||
|
||||
#undef dereference_function_descriptor
|
||||
static inline void *dereference_function_descriptor(void *ptr)
|
||||
{
|
||||
|
@ -38,6 +40,12 @@ static inline void *dereference_function_descriptor(void *ptr)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
#undef dereference_kernel_function_descriptor
|
||||
static inline void *dereference_kernel_function_descriptor(void *ptr)
|
||||
{
|
||||
if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
|
||||
return ptr;
|
||||
return dereference_function_descriptor(ptr);
|
||||
}
|
||||
|
||||
#endif /* _ASM_IA64_SECTIONS_H */
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <asm/patch.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#define ARCH_MODULE_DEBUG 0
|
||||
|
||||
|
@ -918,3 +919,14 @@ module_arch_cleanup (struct module *mod)
|
|||
if (mod->arch.core_unw_table)
|
||||
unw_remove_unwind_table(mod->arch.core_unw_table);
|
||||
}
|
||||
|
||||
void *dereference_module_function_descriptor(struct module *mod, void *ptr)
|
||||
{
|
||||
Elf64_Shdr *opd = mod->arch.opd;
|
||||
|
||||
if (ptr < (void *)opd->sh_addr ||
|
||||
ptr >= (void *)(opd->sh_addr + opd->sh_size))
|
||||
return ptr;
|
||||
|
||||
return dereference_function_descriptor(ptr);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,9 @@ SECTIONS {
|
|||
RODATA
|
||||
|
||||
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
|
||||
__start_opd = .;
|
||||
*(.opd)
|
||||
__end_opd = .;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/unwinder.h>
|
||||
|
||||
extern char _etext, _stext;
|
||||
#include <asm/sections.h>
|
||||
|
||||
int kstack_depth_to_print = 0x180;
|
||||
int lwa_flag;
|
||||
|
|
|
@ -29,7 +29,9 @@ SECTIONS
|
|||
. = ALIGN(16);
|
||||
/* Linkage tables */
|
||||
.opd : {
|
||||
__start_opd = .;
|
||||
*(.opd)
|
||||
__end_opd = .;
|
||||
} PROVIDE (__gp = .);
|
||||
.plt : {
|
||||
*(.plt)
|
||||
|
|
|
@ -6,8 +6,14 @@
|
|||
#include <asm-generic/sections.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
|
||||
|
||||
#undef dereference_function_descriptor
|
||||
void *dereference_function_descriptor(void *);
|
||||
|
||||
#undef dereference_kernel_function_descriptor
|
||||
void *dereference_kernel_function_descriptor(void *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/unwind.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#if 0
|
||||
#define DEBUGP printk
|
||||
|
@ -954,3 +955,18 @@ void module_arch_cleanup(struct module *mod)
|
|||
{
|
||||
deregister_unwind_table(mod);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
void *dereference_module_function_descriptor(struct module *mod, void *ptr)
|
||||
{
|
||||
unsigned long start_opd = (Elf64_Addr)mod->core_layout.base +
|
||||
mod->arch.fdesc_offset;
|
||||
unsigned long end_opd = start_opd +
|
||||
mod->arch.fdesc_count * sizeof(Elf64_Fdesc);
|
||||
|
||||
if (ptr < (void *)start_opd || ptr >= (void *)end_opd)
|
||||
return ptr;
|
||||
|
||||
return dereference_function_descriptor(ptr);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -276,6 +276,15 @@ void *dereference_function_descriptor(void *ptr)
|
|||
ptr = p;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *dereference_kernel_function_descriptor(void *ptr)
|
||||
{
|
||||
if (ptr < (void *)__start_opd ||
|
||||
ptr >= (void *)__end_opd)
|
||||
return ptr;
|
||||
|
||||
return dereference_function_descriptor(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unsigned long brk_rnd(void)
|
||||
|
|
|
@ -100,7 +100,9 @@ SECTIONS
|
|||
. = ALIGN(16);
|
||||
/* Linkage tables */
|
||||
.opd : {
|
||||
__start_opd = .;
|
||||
*(.opd)
|
||||
__end_opd = .;
|
||||
} PROVIDE (__gp = .);
|
||||
.plt : {
|
||||
*(.plt)
|
||||
|
|
|
@ -45,6 +45,9 @@ struct mod_arch_specific {
|
|||
unsigned long tramp;
|
||||
#endif
|
||||
|
||||
/* For module function descriptor dereference */
|
||||
unsigned long start_opd;
|
||||
unsigned long end_opd;
|
||||
#else /* powerpc64 */
|
||||
/* Indices of PLT sections within module. */
|
||||
unsigned int core_plt_section;
|
||||
|
|
|
@ -66,6 +66,9 @@ static inline int overlaps_kvm_tmp(unsigned long start, unsigned long end)
|
|||
}
|
||||
|
||||
#ifdef PPC64_ELF_ABI_v1
|
||||
|
||||
#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
|
||||
|
||||
#undef dereference_function_descriptor
|
||||
static inline void *dereference_function_descriptor(void *ptr)
|
||||
{
|
||||
|
@ -76,6 +79,15 @@ static inline void *dereference_function_descriptor(void *ptr)
|
|||
ptr = p;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#undef dereference_kernel_function_descriptor
|
||||
static inline void *dereference_kernel_function_descriptor(void *ptr)
|
||||
{
|
||||
if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
|
||||
return ptr;
|
||||
|
||||
return dereference_function_descriptor(ptr);
|
||||
}
|
||||
#endif /* PPC64_ELF_ABI_v1 */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -93,6 +93,15 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *dereference_module_function_descriptor(struct module *mod, void *ptr)
|
||||
{
|
||||
if (ptr < (void *)mod->arch.start_opd ||
|
||||
ptr >= (void *)mod->arch.end_opd)
|
||||
return ptr;
|
||||
|
||||
return dereference_function_descriptor(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define STUB_MAGIC 0x73747562 /* stub */
|
||||
|
@ -344,6 +353,11 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
|
|||
else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
|
||||
dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
|
||||
sechdrs[i].sh_size);
|
||||
else if (!strcmp(secstrings + sechdrs[i].sh_name, ".opd")) {
|
||||
me->arch.start_opd = sechdrs[i].sh_addr;
|
||||
me->arch.end_opd = sechdrs[i].sh_addr +
|
||||
sechdrs[i].sh_size;
|
||||
}
|
||||
|
||||
/* We don't handle .init for the moment: rename to _init */
|
||||
while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
|
||||
|
|
|
@ -278,7 +278,9 @@ SECTIONS
|
|||
}
|
||||
|
||||
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
|
||||
__start_opd = .;
|
||||
*(.opd)
|
||||
__end_opd = .;
|
||||
}
|
||||
|
||||
. = ALIGN(256);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* __ctors_start, __ctors_end
|
||||
* __irqentry_text_start, __irqentry_text_end
|
||||
* __softirqentry_text_start, __softirqentry_text_end
|
||||
* __start_opd, __end_opd
|
||||
*/
|
||||
extern char _text[], _stext[], _etext[];
|
||||
extern char _data[], _sdata[], _edata[];
|
||||
|
@ -49,12 +50,15 @@ extern char __start_once[], __end_once[];
|
|||
/* Start and end of .ctors section - used for constructor calls. */
|
||||
extern char __ctors_start[], __ctors_end[];
|
||||
|
||||
/* Start and end of .opd section - used for function descriptors. */
|
||||
extern char __start_opd[], __end_opd[];
|
||||
|
||||
extern __visible const void __nosave_begin, __nosave_end;
|
||||
|
||||
/* function descriptor handling (if any). Override
|
||||
* in asm/sections.h */
|
||||
/* Function descriptor handling (if any). Override in asm/sections.h */
|
||||
#ifndef dereference_function_descriptor
|
||||
#define dereference_function_descriptor(p) (p)
|
||||
#define dereference_kernel_function_descriptor(p) (p)
|
||||
#endif
|
||||
|
||||
/* random extra sections (if any). Override
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/sections.h>
|
||||
|
||||
#define KSYM_NAME_LEN 128
|
||||
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
|
||||
|
@ -22,6 +26,56 @@
|
|||
|
||||
struct module;
|
||||
|
||||
static inline int is_kernel_inittext(unsigned long addr)
|
||||
{
|
||||
if (addr >= (unsigned long)_sinittext
|
||||
&& addr <= (unsigned long)_einittext)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_kernel_text(unsigned long addr)
|
||||
{
|
||||
if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
|
||||
arch_is_kernel_text(addr))
|
||||
return 1;
|
||||
return in_gate_area_no_mm(addr);
|
||||
}
|
||||
|
||||
static inline int is_kernel(unsigned long addr)
|
||||
{
|
||||
if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
|
||||
return 1;
|
||||
return in_gate_area_no_mm(addr);
|
||||
}
|
||||
|
||||
static inline int is_ksym_addr(unsigned long addr)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
|
||||
return is_kernel(addr);
|
||||
|
||||
return is_kernel_text(addr) || is_kernel_inittext(addr);
|
||||
}
|
||||
|
||||
static inline void *dereference_symbol_descriptor(void *ptr)
|
||||
{
|
||||
#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
|
||||
struct module *mod;
|
||||
|
||||
ptr = dereference_kernel_function_descriptor(ptr);
|
||||
if (is_ksym_addr((unsigned long)ptr))
|
||||
return ptr;
|
||||
|
||||
preempt_disable();
|
||||
mod = __module_address((unsigned long)ptr);
|
||||
preempt_enable();
|
||||
|
||||
if (mod)
|
||||
ptr = dereference_module_function_descriptor(mod, ptr);
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
/* Lookup the address for a symbol. Returns 0 if not found. */
|
||||
unsigned long kallsyms_lookup_name(const char *name);
|
||||
|
|
|
@ -606,6 +606,9 @@ int ref_module(struct module *a, struct module *b);
|
|||
__mod ? __mod->name : "kernel"; \
|
||||
})
|
||||
|
||||
/* Dereference module function descriptor */
|
||||
void *dereference_module_function_descriptor(struct module *mod, void *ptr);
|
||||
|
||||
/* For kallsyms to ask for address resolution. namebuf should be at
|
||||
* least KSYM_NAME_LEN long: a pointer to namebuf is returned if
|
||||
* found, otherwise NULL. */
|
||||
|
@ -760,6 +763,13 @@ static inline bool is_module_sig_enforced(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Dereference module function descriptor */
|
||||
static inline
|
||||
void *dereference_module_function_descriptor(struct module *mod, void *ptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* compression (see scripts/kallsyms.c for a more complete description)
|
||||
*/
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/fs.h>
|
||||
|
@ -20,15 +19,12 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/sched.h> /* for cond_resched */
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* These will be re-linked against their real values
|
||||
* during the second link stage.
|
||||
|
@ -52,37 +48,6 @@ extern const u16 kallsyms_token_index[] __weak;
|
|||
|
||||
extern const unsigned long kallsyms_markers[] __weak;
|
||||
|
||||
static inline int is_kernel_inittext(unsigned long addr)
|
||||
{
|
||||
if (addr >= (unsigned long)_sinittext
|
||||
&& addr <= (unsigned long)_einittext)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_kernel_text(unsigned long addr)
|
||||
{
|
||||
if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
|
||||
arch_is_kernel_text(addr))
|
||||
return 1;
|
||||
return in_gate_area_no_mm(addr);
|
||||
}
|
||||
|
||||
static inline int is_kernel(unsigned long addr)
|
||||
{
|
||||
if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
|
||||
return 1;
|
||||
return in_gate_area_no_mm(addr);
|
||||
}
|
||||
|
||||
static int is_ksym_addr(unsigned long addr)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
|
||||
return is_kernel(addr);
|
||||
|
||||
return is_kernel_text(addr) || is_kernel_inittext(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand a compressed symbol data into the resulting uncompressed string,
|
||||
* if uncompressed string is too long (>= maxlen), it will be truncated,
|
||||
|
|
|
@ -3938,6 +3938,12 @@ static const char *get_ksymbol(struct module *mod,
|
|||
return symname(kallsyms, best);
|
||||
}
|
||||
|
||||
void * __weak dereference_module_function_descriptor(struct module *mod,
|
||||
void *ptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* For kallsyms to ask for address resolution. NULL means not found. Careful
|
||||
* not to lock to avoid deadlock on oopses, simply disable preemption. */
|
||||
const char *module_address_lookup(unsigned long addr,
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "sched.h"
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include "sched.h"
|
||||
|
||||
unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
|
||||
static struct autogroup autogroup_default;
|
||||
static atomic_t autogroup_seq_nr;
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "../mm/internal.h" /* For the trace_print_flags arrays */
|
||||
|
||||
#include <asm/page.h> /* for PAGE_SIZE */
|
||||
#include <asm/sections.h> /* for dereference_function_descriptor() */
|
||||
#include <asm/byteorder.h> /* cpu_to_le16 */
|
||||
|
||||
#include <linux/string_helpers.h>
|
||||
|
@ -1723,10 +1722,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
|||
switch (*fmt) {
|
||||
case 'F':
|
||||
case 'f':
|
||||
ptr = dereference_function_descriptor(ptr);
|
||||
/* Fallthrough */
|
||||
case 'S':
|
||||
case 's':
|
||||
ptr = dereference_symbol_descriptor(ptr);
|
||||
/* Fallthrough */
|
||||
case 'B':
|
||||
return symbol_string(buf, end, ptr, spec, fmt);
|
||||
case 'R':
|
||||
|
|
|
@ -5753,18 +5753,25 @@ sub process {
|
|||
for (my $count = $linenr; $count <= $lc; $count++) {
|
||||
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
|
||||
$fmt =~ s/%%//g;
|
||||
if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) {
|
||||
if ($fmt =~ /(\%[\*\d\.]*p(?![\WSsBKRraEhMmIiUDdgVCbGNO]).)/) {
|
||||
$bad_extension = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($bad_extension ne "") {
|
||||
my $stat_real = raw_line($linenr, 0);
|
||||
my $ext_type = "Invalid";
|
||||
my $use = "";
|
||||
for (my $count = $linenr + 1; $count <= $lc; $count++) {
|
||||
$stat_real = $stat_real . "\n" . raw_line($count, 0);
|
||||
}
|
||||
if ($bad_extension =~ /p[Ff]/) {
|
||||
$ext_type = "Deprecated";
|
||||
$use = " - use %pS instead";
|
||||
$use =~ s/pS/ps/ if ($bad_extension =~ /pf/);
|
||||
}
|
||||
WARN("VSPRINTF_POINTER_EXTENSION",
|
||||
"Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
|
||||
"$ext_type vsprintf pointer extension '$bad_extension'$use\n" . "$here\n$stat_real\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue