mirror of https://github.com/dynup/kpatch
kpatch-build: clarify ppc64le comments
Clarify some of the comment wording in the new ppc64le code.
This commit is contained in:
parent
e3ccff0cab
commit
339938c0a9
|
@ -3,9 +3,9 @@ KPATCH_BUILD ?= /lib/modules/$(shell uname -r)/build
|
|||
KPATCH_MAKE = $(MAKE) -C $(KPATCH_BUILD) M=$(PWD)
|
||||
LDFLAGS += $(KPATCH_LDFLAGS)
|
||||
|
||||
# ppc64le kernel modules are expected to compiled with
|
||||
# -mcmodel=large flag. This enable 64-bit relocations,
|
||||
# instead of 32-bit offset from TOC pointer.
|
||||
# ppc64le kernel modules are expected to compile with the
|
||||
# -mcmodel=large flag. This enables 64-bit relocations
|
||||
# instead of a 32-bit offset from the TOC pointer.
|
||||
PROCESSOR = $(shell uname -p)
|
||||
ifeq ($(PROCESSOR), ppc64le)
|
||||
KBUILD_CFLAGS_MODULE += -mcmodel=large
|
||||
|
|
|
@ -184,10 +184,11 @@ static int rela_equal(struct rela *rela1, struct rela *rela2)
|
|||
* 00000000000000b4 000000b90000000a R_PPC64_REL24 0000000000000000 printk + 0
|
||||
* 00000000000000bc 000000a10000000a R_PPC64_REL24 0000000000000000 dump_stack + 0
|
||||
*
|
||||
* with -mcmodel=large on ppc64le, gcc might generate entries in .toc section for symbol
|
||||
* reference in relocation sections. There are chances of symbol referenced by toc + offset
|
||||
* may point to different symbols in original and patched .o. Compare the symbols by
|
||||
* reading its corresponding toc + offset rela from .toc section.
|
||||
* With -mcmodel=large on ppc64le, GCC might generate entries in the .toc
|
||||
* section for relocation symbol references. The .toc offsets may change
|
||||
* between the original and patched .o, so comparing ".toc + offset" isn't
|
||||
* right. Compare the .toc-based symbols by reading the corresponding relas
|
||||
* from the .toc section.
|
||||
*/
|
||||
if (!strcmp(rela1->sym->name, ".toc") &&
|
||||
!strcmp(rela2->sym->name, ".toc")) {
|
||||
|
@ -237,9 +238,8 @@ static void kpatch_compare_correlated_rela_section(struct section *sec)
|
|||
struct rela *rela1, *rela2 = NULL;
|
||||
|
||||
/*
|
||||
* Don't compare relocation entries for .toc section.
|
||||
* .toc and .rela.toc sections are included as standard
|
||||
* elements.
|
||||
* On ppc64le, don't compare the .rela.toc section. The .toc and
|
||||
* .rela.toc sections are included as standard elements.
|
||||
*/
|
||||
if (!strcmp(sec->name, ".rela.toc")) {
|
||||
sec->status = SAME;
|
||||
|
@ -1011,10 +1011,12 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
|||
|
||||
#ifdef __powerpc__
|
||||
/*
|
||||
* With -mcmodel=large, the relative relocation or
|
||||
* R_PPC64_REL24 type is limited to functions only.
|
||||
* rela->sym->sec should have been replaced with it's
|
||||
* section symbol already. If not bail out.
|
||||
* With -mcmodel=large, R_PPC64_REL24 is only used for
|
||||
* functions. Assuming the function is bundled in a
|
||||
* section, the section symbol should have been
|
||||
* replaced with a text symbol already. Otherwise,
|
||||
* bail out. If we hit this situation, more core is
|
||||
* needed here to calculate the value of 'add_off'.
|
||||
*/
|
||||
if (rela->type == R_PPC64_REL24)
|
||||
ERROR("Unexpected relocation type R_PPC64_REL24 for %s\n", rela->sym->name);
|
||||
|
@ -1220,9 +1222,9 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf)
|
|||
}
|
||||
|
||||
/*
|
||||
* rela.toc section holds reference to symbols,
|
||||
* referred by function section relocation
|
||||
* entries. Include all of the symbols.
|
||||
* On ppc64le, the .rela.toc section refers to symbols which
|
||||
* are needed for function symbol relocations. Include all the
|
||||
* symbols.
|
||||
*/
|
||||
if (!strcmp(sec->name, ".rela.toc"))
|
||||
{
|
||||
|
@ -2254,8 +2256,8 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|||
sym_objname = objname;
|
||||
|
||||
/*
|
||||
* function prologue generated by gcc6 on ppc64le has
|
||||
* the sequence:
|
||||
* On ppc64le, the function prologue generated by GCC 6
|
||||
* has the sequence:
|
||||
*
|
||||
* .globl my_func
|
||||
* .type my_func, @function
|
||||
|
@ -2264,12 +2266,10 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|||
* .reloc ., R_PPC64_ENTRY ; optional
|
||||
* ld r2,-8(r12)
|
||||
* add r2,r2,r12
|
||||
* .localentry my_func, .-my_func
|
||||
* .localentry my_func, .-my_func
|
||||
*
|
||||
* first entry past function global entry point is optional
|
||||
* and has the relocation type R_PPC64_ENTRY. We should *not*
|
||||
* skip this entry while building up the rela list, rather
|
||||
* skip it's lookup.
|
||||
* The R_PPC64_ENTRY is optional and its symbol might
|
||||
* have an empty name. Leave it as a normal rela.
|
||||
*/
|
||||
if (rela->type == R_PPC64_ENTRY)
|
||||
continue;
|
||||
|
@ -2291,17 +2291,19 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|||
*/
|
||||
#ifdef __powerpc__
|
||||
/*
|
||||
* An exported symbol, might be local to an object file
|
||||
* and any access to the function might be through localentry
|
||||
* (toc+offset) instead of global offset.
|
||||
* An exported symbol might be local to an
|
||||
* object file and any access to the function
|
||||
* might be through localentry (toc+offset)
|
||||
* instead of global offset.
|
||||
*
|
||||
* fs/proc/proc_sysctl::sysctl_head_grab:
|
||||
* 166: 0000000000000000 256 FUNC GLOBAL DEFAULT [<localentry>: 8] 42 unregister_sysctl_table
|
||||
* 167: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND .TOC.
|
||||
*
|
||||
* These type of function have the sym->type == STT_FUNC, treat them as local
|
||||
* symbol. This creates an entry under klp.relocations and relocation
|
||||
* is handled by livepatch.
|
||||
* These type of symbols have a type of
|
||||
* STT_FUNC. Treat them like local symbols.
|
||||
* They will be handled by the livepatch
|
||||
* relocation code.
|
||||
*/
|
||||
if (lookup_is_exported_symbol(table, rela->sym->name)) {
|
||||
if (rela->sym->type != STT_FUNC)
|
||||
|
|
|
@ -201,8 +201,10 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
|||
* 0000000000000058 0000003900000026 R_PPC64_ADDR64 0000000000000000 __per_cpu_offset + 0
|
||||
* [...]
|
||||
*
|
||||
* when more .o files are linked together, the .toc entries might get re-arranged. Capture new .toc rela
|
||||
* offset value, which will be used below to setting the rela->addend. */
|
||||
* On ppc64le, when .o files are linked together, the .toc
|
||||
* entries might get re-arranged. Capture the new .toc rela
|
||||
* offset value, which is used below to set the rela->addend.
|
||||
*/
|
||||
toc_offset = rela->addend;
|
||||
|
||||
base = rela->sym->sec;
|
||||
|
@ -245,10 +247,11 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
|||
rela->offset = krelas[index].offset;
|
||||
|
||||
/*
|
||||
* gcc6 adds offset for 0x8 for every local function entry in
|
||||
* .toc section, for avoiding setup of toc but when the previously
|
||||
* local function becomes global, toc is anyways setup. So remove
|
||||
* the wrong addend.
|
||||
* GCC 6+ adds 0x8 to the offset of every local function entry
|
||||
* in the .toc section, for avoiding the setup of the toc when
|
||||
* the function is called locally. But when the previously
|
||||
* local function becomes global, we don't want to skip the
|
||||
* .toc setup anymore.
|
||||
*/
|
||||
if (!strcmp(base->name, ".toc") &&
|
||||
rela->sym->type == STT_FUNC && rela->sym->bind == STB_LOCAL) {
|
||||
|
|
|
@ -160,12 +160,12 @@ gcc_version_check() {
|
|||
return 1
|
||||
fi
|
||||
|
||||
# On ppc64le, livepatch relies on gcc support for -mprofile-kernel flag.
|
||||
# Script with differnet checks is run during kernel build, to ensure that
|
||||
# the required gcc supports is available. This check is done during kernel
|
||||
# build by:
|
||||
# <linux-sources>/arch/powerpc/tools/gcc-check-mprofile-kernel.sh
|
||||
# Postpond the check until kernel build, instead of duplicating it here.
|
||||
# On ppc64le, livepatch needs the GCC -mprofile-kernel flag. A script
|
||||
# is run during the kernel build to ensure the flag is present:
|
||||
#
|
||||
# <linux>/arch/powerpc/tools/gcc-check-mprofile-kernel.sh
|
||||
#
|
||||
# Postpone the check to the kernel build instead of duplicating it here.
|
||||
if [[ $ARCH = "ppc64le" ]]; then
|
||||
return
|
||||
else
|
||||
|
|
|
@ -85,8 +85,7 @@ int is_debug_section(struct section *sec)
|
|||
(((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
|
||||
|
||||
/*
|
||||
* function prologue generated by gcc6 on ppc64le has
|
||||
* the sequence:
|
||||
* On ppc64le, the function prologue generated by GCC 6+ has the sequence:
|
||||
*
|
||||
* .globl my_func
|
||||
* .type my_func, @function
|
||||
|
@ -95,15 +94,12 @@ int is_debug_section(struct section *sec)
|
|||
* .reloc ., R_PPC64_ENTRY ; optional
|
||||
* ld r2,-8(r12)
|
||||
* add r2,r2,r12
|
||||
* .localentry my_func, .-my_func
|
||||
* .localentry my_func, .-my_func
|
||||
*
|
||||
* my_func is resolved by .TOC.-my_func to a 64-bit offset stored
|
||||
* above the global entry point. my_func st_value is set 0x8, for
|
||||
* calling into the .localentry of the function.
|
||||
*
|
||||
* Number of instructions between global and local entry point of a
|
||||
* function is mostly 8 instructions. i.e st_other == 3. The count of
|
||||
* instruction can be decoded only for local function symbols.
|
||||
* my_func is the global entry point, which, when called, sets up the TOC.
|
||||
* .localentry is the local entry point, for calls to the function from within
|
||||
* the object file. The local entry point is 8 bytes after the global entry
|
||||
* point.
|
||||
*/
|
||||
static int is_localentry_sym(struct symbol *sym)
|
||||
{
|
||||
|
@ -381,6 +377,7 @@ void kpatch_create_symbol_list(struct kpatch_elf *kelf)
|
|||
}
|
||||
|
||||
sym->sec->sym = sym;
|
||||
|
||||
} else if (sym->type == STT_SECTION) {
|
||||
sym->sec->secsym = sym;
|
||||
/* use the section name as the symbol name */
|
||||
|
|
|
@ -15,9 +15,11 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
|||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
obj=$2
|
||||
# skip copying the original .o files, when .tmp_mc_*.o
|
||||
# is passed from recordmcount.pl.
|
||||
|
||||
# skip copying the temporary .o files created by
|
||||
# recordmcount.pl
|
||||
[[ $obj = */.tmp_mc_*.o ]] && break;
|
||||
|
||||
[[ $obj = */.tmp_*.o ]] && obj=${obj/.tmp_/}
|
||||
case "$obj" in
|
||||
*.mod.o|\
|
||||
|
|
Loading…
Reference in New Issue