linux-next/arch/sparc/kernel/vmlinux.lds.S
Rong Xu 0043ecea23 vmlinux.lds.h: Adjust symbol ordering in text output section
When the -ffunction-sections compiler option is enabled, each function
is placed in a separate section named .text.function_name rather than
putting all functions in a single .text section.

However, using -function-sections can cause problems with the
linker script. The comments included in include/asm-generic/vmlinux.lds.h
note these issues.:
  “TEXT_MAIN here will match .text.fixup and .text.unlikely if dead
   code elimination is enabled, so these sections should be converted
   to use ".." first.”

It is unclear whether there is a straightforward method for converting
a suffix to "..".

This patch modifies the order of subsections within the text output
section. Specifically, it changes current order:
  .text.hot, .text, .text_unlikely, .text.unknown, .text.asan
to the new order:
  .text.asan, .text.unknown, .text_unlikely, .text.hot, .text

Here is the rationale behind the new layout:

The majority of the code resides in three sections: .text.hot, .text,
and .text.unlikely, with .text.unknown containing a negligible amount.
.text.asan is only generated in ASAN builds.

The primary goal is to group code segments based on their execution
frequency (hotness).

First, we want to place .text.hot adjacent to .text. Since we cannot put
.text.hot after .text (Due to constraints with -ffunction-sections,
placing .text.hot after .text is problematic), we need to put
.text.hot before .text.

Then it comes to .text.unlikely, we cannot put it after .text (same
-ffunction-sections issue) . Therefore, we position .text.unlikely
before .text.hot.

.text.unknown and .tex.asan follow the same logic.

This revised ordering effectively reverses the original arrangement (for
.text.unlikely, .text.unknown, and .tex.asan), maintaining a similar level
of affinity between sections.

It also places .text.hot section at the beginning of a page to better
utilize the TLB entry.

Note that the limitation arises because the linker script employs glob
patterns instead of regular expressions for string matching. While there
is a method to maintain the current order using complex patterns, this
significantly complicates the pattern and increases the likelihood of
errors.

This patch also changes vmlinux.lds.S for the sparc64 architecture to
accommodate specific symbol placement requirements.

Co-developed-by: Han Shen <shenhan@google.com>
Signed-off-by: Han Shen <shenhan@google.com>
Signed-off-by: Rong Xu <xur@google.com>
Suggested-by: Sriraman Tallam <tmsriram@google.com>
Suggested-by: Krzysztof Pszeniczny <kpszeniczny@google.com>
Tested-by: Yonghong Song <yonghong.song@linux.dev>
Tested-by: Yabin Cui <yabinc@google.com>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2024-11-27 09:38:27 +09:00

198 lines
3.7 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0 */
/* ld script for sparc32/sparc64 kernel */
#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
#include <asm/thread_info.h>
#ifdef CONFIG_SPARC32
#define INITIAL_ADDRESS 0x10000 + SIZEOF_HEADERS
#define TEXTSTART 0xf0004000
#define SMP_CACHE_BYTES_SHIFT 5
#else
#define SMP_CACHE_BYTES_SHIFT 6
#define INITIAL_ADDRESS 0x4000
#define TEXTSTART 0x0000000000404000
#endif
#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT)
#ifdef CONFIG_SPARC32
OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
OUTPUT_ARCH(sparc)
ENTRY(_start)
jiffies = jiffies_64 + 4;
#else
/* sparc64 */
OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc")
OUTPUT_ARCH(sparc:v9a)
ENTRY(_start)
jiffies = jiffies_64;
#endif
#ifdef CONFIG_SPARC64
ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large")
#endif
SECTIONS
{
#ifdef CONFIG_SPARC64
swapper_pg_dir = 0x0000000000402000;
#endif
. = INITIAL_ADDRESS;
.text TEXTSTART :
{
_text = .;
HEAD_TEXT
ALIGN_FUNCTION();
#ifdef CONFIG_SPARC64
/* Match text section symbols in head_64.S first */
*head_64.o(.text)
#endif
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
*(.gnu.warning)
} = 0
_etext = .;
RO_DATA(PAGE_SIZE)
/* Start of data section */
_sdata = .;
.data1 : {
*(.data1)
}
RW_DATA(SMP_CACHE_BYTES, 0, THREAD_SIZE)
/* End of data section */
_edata = .;
.fixup : {
__start___fixup = .;
*(.fixup)
__stop___fixup = .;
}
EXCEPTION_TABLE(16)
. = ALIGN(PAGE_SIZE);
__init_begin = ALIGN(PAGE_SIZE);
INIT_TEXT_SECTION(PAGE_SIZE)
__init_text_end = .;
INIT_DATA_SECTION(16)
. = ALIGN(4);
.tsb_ldquad_phys_patch : {
__tsb_ldquad_phys_patch = .;
*(.tsb_ldquad_phys_patch)
__tsb_ldquad_phys_patch_end = .;
}
.tsb_phys_patch : {
__tsb_phys_patch = .;
*(.tsb_phys_patch)
__tsb_phys_patch_end = .;
}
.cpuid_patch : {
__cpuid_patch = .;
*(.cpuid_patch)
__cpuid_patch_end = .;
}
.sun4v_1insn_patch : {
__sun4v_1insn_patch = .;
*(.sun4v_1insn_patch)
__sun4v_1insn_patch_end = .;
}
.sun4v_2insn_patch : {
__sun4v_2insn_patch = .;
*(.sun4v_2insn_patch)
__sun4v_2insn_patch_end = .;
}
.leon_1insn_patch : {
__leon_1insn_patch = .;
*(.leon_1insn_patch)
__leon_1insn_patch_end = .;
}
.swapper_tsb_phys_patch : {
__swapper_tsb_phys_patch = .;
*(.swapper_tsb_phys_patch)
__swapper_tsb_phys_patch_end = .;
}
.swapper_4m_tsb_phys_patch : {
__swapper_4m_tsb_phys_patch = .;
*(.swapper_4m_tsb_phys_patch)
__swapper_4m_tsb_phys_patch_end = .;
}
.popc_3insn_patch : {
__popc_3insn_patch = .;
*(.popc_3insn_patch)
__popc_3insn_patch_end = .;
}
.popc_6insn_patch : {
__popc_6insn_patch = .;
*(.popc_6insn_patch)
__popc_6insn_patch_end = .;
}
.pause_3insn_patch : {
__pause_3insn_patch = .;
*(.pause_3insn_patch)
__pause_3insn_patch_end = .;
}
.sun_m7_1insn_patch : {
__sun_m7_1insn_patch = .;
*(.sun_m7_1insn_patch)
__sun_m7_1insn_patch_end = .;
}
.sun_m7_2insn_patch : {
__sun_m7_2insn_patch = .;
*(.sun_m7_2insn_patch)
__sun_m7_2insn_patch_end = .;
}
.get_tick_patch : {
__get_tick_patch = .;
*(.get_tick_patch)
__get_tick_patch_end = .;
}
.pud_huge_patch : {
__pud_huge_patch = .;
*(.pud_huge_patch)
__pud_huge_patch_end = .;
}
.fast_win_ctrl_1insn_patch : {
__fast_win_ctrl_1insn_patch = .;
*(.fast_win_ctrl_1insn_patch)
__fast_win_ctrl_1insn_patch_end = .;
}
PERCPU_SECTION(SMP_CACHE_BYTES)
. = ALIGN(PAGE_SIZE);
.exit.text : {
EXIT_TEXT
}
.exit.data : {
EXIT_DATA
}
. = ALIGN(PAGE_SIZE);
__init_end = .;
BSS_SECTION(0, 0, 0)
_end = . ;
STABS_DEBUG
DWARF_DEBUG
ELF_DETAILS
DISCARDS
}