arch/arm64/kernel/module-plts.c
Source file repositories/reference/linux-study-clean/arch/arm64/kernel/module-plts.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kernel/module-plts.c- Extension
.c- Size
- 11112 bytes
- Lines
- 378
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/elf.hlinux/ftrace.hlinux/kernel.hlinux/module.hlinux/moduleloader.hlinux/sort.h
Detected Declarations
function Copyrightfunction get_plt_entryfunction plt_entries_equalfunction module_emit_plt_entryfunction module_emit_veneer_for_adrpfunction cmp_relafunction duplicate_relfunction count_pltsfunction branch_rela_needs_pltfunction partition_branch_plt_relasfunction module_frob_arch_sections
Annotated Snippet
switch (ELF64_R_TYPE(rela[i].r_info)) {
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
/*
* We only have to consider branch targets that resolve
* to symbols that are defined in a different section.
* This is not simply a heuristic, it is a fundamental
* limitation, since there is no guaranteed way to emit
* PLT entries sufficiently close to the branch if the
* section size exceeds the range of a branch
* instruction. So ignore relocations against defined
* symbols if they live in the same section as the
* relocation target.
*/
s = syms + ELF64_R_SYM(rela[i].r_info);
if (s->st_shndx == dstidx)
break;
/*
* Jump relocations with non-zero addends against
* undefined symbols are supported by the ELF spec, but
* do not occur in practice (e.g., 'jump n bytes past
* the entry point of undefined function symbol f').
* So we need to support them, but there is no need to
* take them into consideration when trying to optimize
* this code. So let's only check for duplicates when
* the addend is zero: this allows us to record the PLT
* entry address in the symbol table itself, rather than
* having to search the list for duplicates each time we
* emit one.
*/
if (rela[i].r_addend != 0 || !duplicate_rel(rela, i))
ret++;
break;
case R_AARCH64_ADR_PREL_PG_HI21_NC:
case R_AARCH64_ADR_PREL_PG_HI21:
if (!cpus_have_final_cap(ARM64_WORKAROUND_843419))
break;
/*
* Determine the minimal safe alignment for this ADRP
* instruction: the section alignment at which it is
* guaranteed not to appear at a vulnerable offset.
*
* This comes down to finding the least significant zero
* bit in bits [11:3] of the section offset, and
* increasing the section's alignment so that the
* resulting address of this instruction is guaranteed
* to equal the offset in that particular bit (as well
* as all less significant bits). This ensures that the
* address modulo 4 KB != 0xfff8 or 0xfffc (which would
* have all ones in bits [11:3])
*/
min_align = 2ULL << ffz(rela[i].r_offset | 0x7);
/*
* Allocate veneer space for each ADRP that may appear
* at a vulnerable offset nonetheless. At relocation
* time, some of these will remain unused since some
* ADRP instructions can be patched to ADR instructions
* instead.
*/
if (min_align > SZ_4K)
ret++;
else
dstsec->sh_addralign = max(dstsec->sh_addralign,
min_align);
break;
}
}
if (cpus_have_final_cap(ARM64_WORKAROUND_843419)) {
/*
* Add some slack so we can skip PLT slots that may trigger
* the erratum due to the placement of the ADRP instruction.
*/
ret += DIV_ROUND_UP(ret, (SZ_4K / sizeof(struct plt_entry)));
}
return ret;
}
static bool branch_rela_needs_plt(Elf64_Sym *syms, Elf64_Rela *rela,
Elf64_Word dstidx)
{
Elf64_Sym *s = syms + ELF64_R_SYM(rela->r_info);
if (s->st_shndx == dstidx)
return false;
Annotation
- Immediate include surface: `linux/elf.h`, `linux/ftrace.h`, `linux/kernel.h`, `linux/module.h`, `linux/moduleloader.h`, `linux/sort.h`.
- Detected declarations: `function Copyright`, `function get_plt_entry`, `function plt_entries_equal`, `function module_emit_plt_entry`, `function module_emit_veneer_for_adrp`, `function cmp_rela`, `function duplicate_rel`, `function count_plts`, `function branch_rela_needs_plt`, `function partition_branch_plt_relas`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.