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