Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_GENERIC_SECTIONS_H_
0003 #define _ASM_GENERIC_SECTIONS_H_
0004 
0005 /* References to section boundaries */
0006 
0007 #include <linux/compiler.h>
0008 #include <linux/types.h>
0009 
0010 /*
0011  * Usage guidelines:
0012  * _text, _data: architecture specific, don't use them in arch-independent code
0013  * [_stext, _etext]: contains .text.* sections, may also contain .rodata.*
0014  *                   and/or .init.* sections
0015  * [_sdata, _edata]: contains .data.* sections, may also contain .rodata.*
0016  *                   and/or .init.* sections.
0017  * [__start_rodata, __end_rodata]: contains .rodata.* sections
0018  * [__start_ro_after_init, __end_ro_after_init]:
0019  *           contains .data..ro_after_init section
0020  * [__init_begin, __init_end]: contains .init.* sections, but .init.text.*
0021  *                   may be out of this range on some architectures.
0022  * [_sinittext, _einittext]: contains .init.text.* sections
0023  * [__bss_start, __bss_stop]: contains BSS sections
0024  *
0025  * Following global variables are optional and may be unavailable on some
0026  * architectures and/or kernel configurations.
0027  *  _text, _data
0028  *  __kprobes_text_start, __kprobes_text_end
0029  *  __entry_text_start, __entry_text_end
0030  *  __ctors_start, __ctors_end
0031  *  __irqentry_text_start, __irqentry_text_end
0032  *  __softirqentry_text_start, __softirqentry_text_end
0033  *  __start_opd, __end_opd
0034  */
0035 extern char _text[], _stext[], _etext[];
0036 extern char _data[], _sdata[], _edata[];
0037 extern char __bss_start[], __bss_stop[];
0038 extern char __init_begin[], __init_end[];
0039 extern char _sinittext[], _einittext[];
0040 extern char __start_ro_after_init[], __end_ro_after_init[];
0041 extern char _end[];
0042 extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
0043 extern char __kprobes_text_start[], __kprobes_text_end[];
0044 extern char __entry_text_start[], __entry_text_end[];
0045 extern char __start_rodata[], __end_rodata[];
0046 extern char __irqentry_text_start[], __irqentry_text_end[];
0047 extern char __softirqentry_text_start[], __softirqentry_text_end[];
0048 extern char __start_once[], __end_once[];
0049 
0050 /* Start and end of .ctors section - used for constructor calls. */
0051 extern char __ctors_start[], __ctors_end[];
0052 
0053 /* Start and end of .opd section - used for function descriptors. */
0054 extern char __start_opd[], __end_opd[];
0055 
0056 /* Start and end of instrumentation protected text section */
0057 extern char __noinstr_text_start[], __noinstr_text_end[];
0058 
0059 extern __visible const void __nosave_begin, __nosave_end;
0060 
0061 /* Function descriptor handling (if any).  Override in asm/sections.h */
0062 #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
0063 void *dereference_function_descriptor(void *ptr);
0064 void *dereference_kernel_function_descriptor(void *ptr);
0065 #else
0066 #define dereference_function_descriptor(p) ((void *)(p))
0067 #define dereference_kernel_function_descriptor(p) ((void *)(p))
0068 
0069 /* An address is simply the address of the function. */
0070 typedef struct {
0071     unsigned long addr;
0072 } func_desc_t;
0073 #endif
0074 
0075 static inline bool have_function_descriptors(void)
0076 {
0077     return IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS);
0078 }
0079 
0080 /**
0081  * memory_contains - checks if an object is contained within a memory region
0082  * @begin: virtual address of the beginning of the memory region
0083  * @end: virtual address of the end of the memory region
0084  * @virt: virtual address of the memory object
0085  * @size: size of the memory object
0086  *
0087  * Returns: true if the object specified by @virt and @size is entirely
0088  * contained within the memory region defined by @begin and @end, false
0089  * otherwise.
0090  */
0091 static inline bool memory_contains(void *begin, void *end, void *virt,
0092                    size_t size)
0093 {
0094     return virt >= begin && virt + size <= end;
0095 }
0096 
0097 /**
0098  * memory_intersects - checks if the region occupied by an object intersects
0099  *                     with another memory region
0100  * @begin: virtual address of the beginning of the memory region
0101  * @end: virtual address of the end of the memory region
0102  * @virt: virtual address of the memory object
0103  * @size: size of the memory object
0104  *
0105  * Returns: true if an object's memory region, specified by @virt and @size,
0106  * intersects with the region specified by @begin and @end, false otherwise.
0107  */
0108 static inline bool memory_intersects(void *begin, void *end, void *virt,
0109                      size_t size)
0110 {
0111     void *vend = virt + size;
0112 
0113     if (virt < end && vend > begin)
0114         return true;
0115 
0116     return false;
0117 }
0118 
0119 /**
0120  * init_section_contains - checks if an object is contained within the init
0121  *                         section
0122  * @virt: virtual address of the memory object
0123  * @size: size of the memory object
0124  *
0125  * Returns: true if the object specified by @virt and @size is entirely
0126  * contained within the init section, false otherwise.
0127  */
0128 static inline bool init_section_contains(void *virt, size_t size)
0129 {
0130     return memory_contains(__init_begin, __init_end, virt, size);
0131 }
0132 
0133 /**
0134  * init_section_intersects - checks if the region occupied by an object
0135  *                           intersects with the init section
0136  * @virt: virtual address of the memory object
0137  * @size: size of the memory object
0138  *
0139  * Returns: true if an object's memory region, specified by @virt and @size,
0140  * intersects with the init section, false otherwise.
0141  */
0142 static inline bool init_section_intersects(void *virt, size_t size)
0143 {
0144     return memory_intersects(__init_begin, __init_end, virt, size);
0145 }
0146 
0147 /**
0148  * is_kernel_core_data - checks if the pointer address is located in the
0149  *           .data or .bss section
0150  *
0151  * @addr: address to check
0152  *
0153  * Returns: true if the address is located in .data or .bss, false otherwise.
0154  * Note: On some archs it may return true for core RODATA, and false
0155  *       for others. But will always be true for core RW data.
0156  */
0157 static inline bool is_kernel_core_data(unsigned long addr)
0158 {
0159     if (addr >= (unsigned long)_sdata && addr < (unsigned long)_edata)
0160         return true;
0161 
0162     if (addr >= (unsigned long)__bss_start &&
0163         addr < (unsigned long)__bss_stop)
0164         return true;
0165 
0166     return false;
0167 }
0168 
0169 /**
0170  * is_kernel_rodata - checks if the pointer address is located in the
0171  *                    .rodata section
0172  *
0173  * @addr: address to check
0174  *
0175  * Returns: true if the address is located in .rodata, false otherwise.
0176  */
0177 static inline bool is_kernel_rodata(unsigned long addr)
0178 {
0179     return addr >= (unsigned long)__start_rodata &&
0180            addr < (unsigned long)__end_rodata;
0181 }
0182 
0183 /**
0184  * is_kernel_inittext - checks if the pointer address is located in the
0185  *                      .init.text section
0186  *
0187  * @addr: address to check
0188  *
0189  * Returns: true if the address is located in .init.text, false otherwise.
0190  */
0191 static inline bool is_kernel_inittext(unsigned long addr)
0192 {
0193     return addr >= (unsigned long)_sinittext &&
0194            addr < (unsigned long)_einittext;
0195 }
0196 
0197 /**
0198  * __is_kernel_text - checks if the pointer address is located in the
0199  *                    .text section
0200  *
0201  * @addr: address to check
0202  *
0203  * Returns: true if the address is located in .text, false otherwise.
0204  * Note: an internal helper, only check the range of _stext to _etext.
0205  */
0206 static inline bool __is_kernel_text(unsigned long addr)
0207 {
0208     return addr >= (unsigned long)_stext &&
0209            addr < (unsigned long)_etext;
0210 }
0211 
0212 /**
0213  * __is_kernel - checks if the pointer address is located in the kernel range
0214  *
0215  * @addr: address to check
0216  *
0217  * Returns: true if the address is located in the kernel range, false otherwise.
0218  * Note: an internal helper, check the range of _stext to _end,
0219  *       and range from __init_begin to __init_end, which can be outside
0220  *       of the _stext to _end range.
0221  */
0222 static inline bool __is_kernel(unsigned long addr)
0223 {
0224     return ((addr >= (unsigned long)_stext &&
0225              addr < (unsigned long)_end) ||
0226         (addr >= (unsigned long)__init_begin &&
0227          addr < (unsigned long)__init_end));
0228 }
0229 
0230 #endif /* _ASM_GENERIC_SECTIONS_H_ */