brintos

brintos / linux-shallow public Read only

0
0
Text · 7.7 KiB · c768de6 Raw
236 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _ASM_GENERIC_SECTIONS_H_3#define _ASM_GENERIC_SECTIONS_H_4 5/* References to section boundaries */6 7#include <linux/compiler.h>8#include <linux/types.h>9 10/*11 * Usage guidelines:12 * _text, _data: architecture specific, don't use them in arch-independent code13 * [_stext, _etext]: contains .text.* sections, may also contain .rodata.*14 *                   and/or .init.* sections15 * [_sdata, _edata]: contains .data.* sections, may also contain .rodata.*16 *                   and/or .init.* sections.17 * [__start_rodata, __end_rodata]: contains .rodata.* sections18 * [__start_ro_after_init, __end_ro_after_init]:19 *		     contains .data..ro_after_init section20 * [__init_begin, __init_end]: contains .init.* sections, but .init.text.*21 *                   may be out of this range on some architectures.22 * [_sinittext, _einittext]: contains .init.text.* sections23 * [__bss_start, __bss_stop]: contains BSS sections24 *25 * Following global variables are optional and may be unavailable on some26 * architectures and/or kernel configurations.27 *	_text, _data28 *	__kprobes_text_start, __kprobes_text_end29 *	__entry_text_start, __entry_text_end30 *	__ctors_start, __ctors_end31 *	__irqentry_text_start, __irqentry_text_end32 *	__softirqentry_text_start, __softirqentry_text_end33 *	__start_opd, __end_opd34 */35extern char _text[], _stext[], _etext[];36extern char _data[], _sdata[], _edata[];37extern char __bss_start[], __bss_stop[];38extern char __init_begin[], __init_end[];39extern char _sinittext[], _einittext[];40extern char __start_ro_after_init[], __end_ro_after_init[];41extern char _end[];42extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];43extern char __kprobes_text_start[], __kprobes_text_end[];44extern char __entry_text_start[], __entry_text_end[];45extern char __start_rodata[], __end_rodata[];46extern char __irqentry_text_start[], __irqentry_text_end[];47extern char __softirqentry_text_start[], __softirqentry_text_end[];48extern char __start_once[], __end_once[];49 50/* Start and end of .ctors section - used for constructor calls. */51extern char __ctors_start[], __ctors_end[];52 53/* Start and end of .opd section - used for function descriptors. */54extern char __start_opd[], __end_opd[];55 56/* Start and end of instrumentation protected text section */57extern char __noinstr_text_start[], __noinstr_text_end[];58 59extern __visible const void __nosave_begin, __nosave_end;60 61/* Function descriptor handling (if any).  Override in asm/sections.h */62#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS63void *dereference_function_descriptor(void *ptr);64void *dereference_kernel_function_descriptor(void *ptr);65#else66#define dereference_function_descriptor(p) ((void *)(p))67#define dereference_kernel_function_descriptor(p) ((void *)(p))68 69/* An address is simply the address of the function. */70typedef struct {71	unsigned long addr;72} func_desc_t;73#endif74 75static inline bool have_function_descriptors(void)76{77	return IS_ENABLED(CONFIG_HAVE_FUNCTION_DESCRIPTORS);78}79 80/**81 * memory_contains - checks if an object is contained within a memory region82 * @begin: virtual address of the beginning of the memory region83 * @end: virtual address of the end of the memory region84 * @virt: virtual address of the memory object85 * @size: size of the memory object86 *87 * Returns: true if the object specified by @virt and @size is entirely88 * contained within the memory region defined by @begin and @end, false89 * otherwise.90 */91static inline bool memory_contains(void *begin, void *end, void *virt,92				   size_t size)93{94	return virt >= begin && virt + size <= end;95}96 97/**98 * memory_intersects - checks if the region occupied by an object intersects99 *                     with another memory region100 * @begin: virtual address of the beginning of the memory region101 * @end: virtual address of the end of the memory region102 * @virt: virtual address of the memory object103 * @size: size of the memory object104 *105 * Returns: true if an object's memory region, specified by @virt and @size,106 * intersects with the region specified by @begin and @end, false otherwise.107 */108static inline bool memory_intersects(void *begin, void *end, void *virt,109				     size_t size)110{111	void *vend = virt + size;112 113	if (virt < end && vend > begin)114		return true;115 116	return false;117}118 119/**120 * init_section_contains - checks if an object is contained within the init121 *                         section122 * @virt: virtual address of the memory object123 * @size: size of the memory object124 *125 * Returns: true if the object specified by @virt and @size is entirely126 * contained within the init section, false otherwise.127 */128static inline bool init_section_contains(void *virt, size_t size)129{130	return memory_contains(__init_begin, __init_end, virt, size);131}132 133/**134 * init_section_intersects - checks if the region occupied by an object135 *                           intersects with the init section136 * @virt: virtual address of the memory object137 * @size: size of the memory object138 *139 * Returns: true if an object's memory region, specified by @virt and @size,140 * intersects with the init section, false otherwise.141 */142static inline bool init_section_intersects(void *virt, size_t size)143{144	return memory_intersects(__init_begin, __init_end, virt, size);145}146 147/**148 * is_kernel_core_data - checks if the pointer address is located in the149 *			 .data or .bss section150 *151 * @addr: address to check152 *153 * Returns: true if the address is located in .data or .bss, false otherwise.154 * Note: On some archs it may return true for core RODATA, and false155 *       for others. But will always be true for core RW data.156 */157static inline bool is_kernel_core_data(unsigned long addr)158{159	if (addr >= (unsigned long)_sdata && addr < (unsigned long)_edata)160		return true;161 162	if (addr >= (unsigned long)__bss_start &&163	    addr < (unsigned long)__bss_stop)164		return true;165 166	return false;167}168 169/**170 * is_kernel_rodata - checks if the pointer address is located in the171 *                    .rodata section172 *173 * @addr: address to check174 *175 * Returns: true if the address is located in .rodata, false otherwise.176 */177static inline bool is_kernel_rodata(unsigned long addr)178{179	return addr >= (unsigned long)__start_rodata &&180	       addr < (unsigned long)__end_rodata;181}182 183static inline bool is_kernel_ro_after_init(unsigned long addr)184{185	return addr >= (unsigned long)__start_ro_after_init &&186	       addr < (unsigned long)__end_ro_after_init;187}188/**189 * is_kernel_inittext - checks if the pointer address is located in the190 *                      .init.text section191 *192 * @addr: address to check193 *194 * Returns: true if the address is located in .init.text, false otherwise.195 */196static inline bool is_kernel_inittext(unsigned long addr)197{198	return addr >= (unsigned long)_sinittext &&199	       addr < (unsigned long)_einittext;200}201 202/**203 * __is_kernel_text - checks if the pointer address is located in the204 *                    .text section205 *206 * @addr: address to check207 *208 * Returns: true if the address is located in .text, false otherwise.209 * Note: an internal helper, only check the range of _stext to _etext.210 */211static inline bool __is_kernel_text(unsigned long addr)212{213	return addr >= (unsigned long)_stext &&214	       addr < (unsigned long)_etext;215}216 217/**218 * __is_kernel - checks if the pointer address is located in the kernel range219 *220 * @addr: address to check221 *222 * Returns: true if the address is located in the kernel range, false otherwise.223 * Note: an internal helper, check the range of _stext to _end,224 *       and range from __init_begin to __init_end, which can be outside225 *       of the _stext to _end range.226 */227static inline bool __is_kernel(unsigned long addr)228{229	return ((addr >= (unsigned long)_stext &&230	         addr < (unsigned long)_end) ||231		(addr >= (unsigned long)__init_begin &&232		 addr < (unsigned long)__init_end));233}234 235#endif /* _ASM_GENERIC_SECTIONS_H_ */236