Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3ccdc519
Commit
3ccdc519
authored
Jan 22, 2018
by
Petr Mladek
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-4.16-deprecate-printk-pf' into for-4.16
parents
6fd78a1a
1df7338a
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
191 additions
and
71 deletions
+191
-71
Documentation/printk-formats.txt
Documentation/printk-formats.txt
+12
-23
arch/ia64/include/asm/sections.h
arch/ia64/include/asm/sections.h
+9
-1
arch/ia64/kernel/module.c
arch/ia64/kernel/module.c
+12
-0
arch/ia64/kernel/vmlinux.lds.S
arch/ia64/kernel/vmlinux.lds.S
+2
-0
arch/openrisc/kernel/traps.c
arch/openrisc/kernel/traps.c
+1
-2
arch/parisc/boot/compressed/vmlinux.lds.S
arch/parisc/boot/compressed/vmlinux.lds.S
+2
-0
arch/parisc/include/asm/sections.h
arch/parisc/include/asm/sections.h
+6
-0
arch/parisc/kernel/module.c
arch/parisc/kernel/module.c
+16
-0
arch/parisc/kernel/process.c
arch/parisc/kernel/process.c
+9
-0
arch/parisc/kernel/vmlinux.lds.S
arch/parisc/kernel/vmlinux.lds.S
+2
-0
arch/powerpc/include/asm/module.h
arch/powerpc/include/asm/module.h
+3
-0
arch/powerpc/include/asm/sections.h
arch/powerpc/include/asm/sections.h
+12
-0
arch/powerpc/kernel/module_64.c
arch/powerpc/kernel/module_64.c
+14
-0
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/kernel/vmlinux.lds.S
+2
-0
include/asm-generic/sections.h
include/asm-generic/sections.h
+6
-2
include/linux/kallsyms.h
include/linux/kallsyms.h
+54
-0
include/linux/module.h
include/linux/module.h
+10
-0
kernel/kallsyms.c
kernel/kallsyms.c
+0
-35
kernel/module.c
kernel/module.c
+6
-0
kernel/sched/autogroup.c
kernel/sched/autogroup.c
+2
-3
lib/vsprintf.c
lib/vsprintf.c
+2
-3
scripts/checkpatch.pl
scripts/checkpatch.pl
+9
-2
No files found.
Documentation/printk-formats.txt
View file @
3ccdc519
...
...
@@ -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
===============
...
...
arch/ia64/include/asm/sections.h
View file @
3ccdc519
...
...
@@ -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 */
arch/ia64/kernel/module.c
View file @
3ccdc519
...
...
@@ -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
);
}
arch/ia64/kernel/vmlinux.lds.S
View file @
3ccdc519
...
...
@@ -108,7 +108,9 @@ SECTIONS {
RODATA
.
opd
:
AT
(
ADDR
(
.
opd
)
-
LOAD_OFFSET
)
{
__start_opd
=
.
;
*(.
opd
)
__end_opd
=
.
;
}
/
*
...
...
arch/openrisc/kernel/traps.c
View file @
3ccdc519
...
...
@@ -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
;
...
...
arch/parisc/boot/compressed/vmlinux.lds.S
View file @
3ccdc519
...
...
@@ -29,7 +29,9 @@ SECTIONS
.
=
ALIGN
(
16
)
;
/
*
Linkage
tables
*/
.
opd
:
{
__start_opd
=
.
;
*(.
opd
)
__end_opd
=
.
;
}
PROVIDE
(
__gp
=
.
)
;
.
plt
:
{
*(.
plt
)
...
...
arch/parisc/include/asm/sections.h
View file @
3ccdc519
...
...
@@ -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
arch/parisc/kernel/module.c
View file @
3ccdc519
...
...
@@ -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
arch/parisc/kernel/process.c
View file @
3ccdc519
...
...
@@ -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
)
...
...
arch/parisc/kernel/vmlinux.lds.S
View file @
3ccdc519
...
...
@@ -100,7 +100,9 @@ SECTIONS
.
=
ALIGN
(
16
)
;
/
*
Linkage
tables
*/
.
opd
:
{
__start_opd
=
.
;
*(.
opd
)
__end_opd
=
.
;
}
PROVIDE
(
__gp
=
.
)
;
.
plt
:
{
*(.
plt
)
...
...
arch/powerpc/include/asm/module.h
View file @
3ccdc519
...
...
@@ -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
;
...
...
arch/powerpc/include/asm/sections.h
View file @
3ccdc519
...
...
@@ -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
...
...
arch/powerpc/kernel/module_64.c
View file @
3ccdc519
...
...
@@ -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"
)))
...
...
arch/powerpc/kernel/vmlinux.lds.S
View file @
3ccdc519
...
...
@@ -278,7 +278,9 @@ SECTIONS
}
.
opd
:
AT
(
ADDR
(
.
opd
)
-
LOAD_OFFSET
)
{
__start_opd
=
.
;
*(.
opd
)
__end_opd
=
.
;
}
.
=
ALIGN
(
256
)
;
...
...
include/asm-generic/sections.h
View file @
3ccdc519
...
...
@@ -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
...
...
include/linux/kallsyms.h
View file @
3ccdc519
...
...
@@ -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
);
...
...
include/linux/module.h
View file @
3ccdc519
...
...
@@ -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
...
...
kernel/kallsyms.c
View file @
3ccdc519
...
...
@@ -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,
...
...
kernel/module.c
View file @
3ccdc519
...
...
@@ -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
,
...
...
kernel/sched/autogroup.c
View file @
3ccdc519
// 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
;
...
...
lib/vsprintf.c
View file @
3ccdc519
...
...
@@ -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'
:
...
...
scripts/checkpatch.pl
View file @
3ccdc519
...
...
@@ -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(?![\W
Ff
SsBKRraEhMmIiUDdgVCbGNO]).)/
)
{
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
");
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment