mirror of https://github.com/dynup/kpatch
kpatch-build: Support CONFIG_PRINTK_INDEX, part 2
For each printk() call site, CONFIG_PRINTK_INDEX makes a static local struct named `_entry`, and then adds a pointer to it in the `.printk_index` section. When regenerating the `.printk_index` section for the patch module, we only need to include those entries which are referenced by included functions. Luckily this is a common pattern already used by several other "special" sections. Add `.printk_index` to the special section handling logic. Fixes: #1206 Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
parent
6cf50a6fca
commit
56471ffc7c
|
@ -2004,6 +2004,21 @@ static int jump_table_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int printk_index_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
|
{
|
||||||
|
static int size = 0;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if (!size) {
|
||||||
|
str = getenv("PRINTK_INDEX_STRUCT_SIZE");
|
||||||
|
if (!str)
|
||||||
|
ERROR("PRINTK_INDEX_STRUCT_SIZE not set");
|
||||||
|
size = atoi(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
|
static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
{
|
{
|
||||||
|
@ -2149,6 +2164,10 @@ static struct special_section special_sections[] = {
|
||||||
.name = "__jump_table",
|
.name = "__jump_table",
|
||||||
.group_size = jump_table_group_size,
|
.group_size = jump_table_group_size,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = ".printk_index",
|
||||||
|
.group_size = printk_index_group_size,
|
||||||
|
},
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
{
|
{
|
||||||
.name = ".smp_locks",
|
.name = ".smp_locks",
|
||||||
|
|
|
@ -329,6 +329,7 @@ clang_version_check() {
|
||||||
find_special_section_data_ppc64le() {
|
find_special_section_data_ppc64le() {
|
||||||
|
|
||||||
[[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="-vskip_j=1"
|
[[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="-vskip_j=1"
|
||||||
|
[[ "$CONFIG_PRINTK_INDEX" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_i=1"
|
||||||
|
|
||||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||||
gawk --non-decimal-data '
|
gawk --non-decimal-data '
|
||||||
|
@ -339,21 +340,24 @@ find_special_section_data_ppc64le() {
|
||||||
b == 0 && /DW_AT_name.* bug_entry[[:space:]]*$/ {b = 1; next}
|
b == 0 && /DW_AT_name.* bug_entry[[:space:]]*$/ {b = 1; next}
|
||||||
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
||||||
j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next}
|
j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next}
|
||||||
|
i == 0 && /DW_AT_name.* pi_entry[[:space:]]*$/ {i = 1; next}
|
||||||
|
|
||||||
# Reset state unless this abbrev describes the struct size
|
# Reset state unless this abbrev describes the struct size
|
||||||
f == 1 && !/DW_AT_byte_size/ { f = 0; next }
|
f == 1 && !/DW_AT_byte_size/ { f = 0; next }
|
||||||
b == 1 && !/DW_AT_byte_size/ { b = 0; next }
|
b == 1 && !/DW_AT_byte_size/ { b = 0; next }
|
||||||
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
||||||
j == 1 && !/DW_AT_byte_size/ { j = 0; next }
|
j == 1 && !/DW_AT_byte_size/ { j = 0; next }
|
||||||
|
i == 1 && !/DW_AT_byte_size/ { i = 0; next }
|
||||||
|
|
||||||
# Now that we know the size, stop parsing for it
|
# Now that we know the size, stop parsing for it
|
||||||
f == 1 {printf("export FIXUP_STRUCT_SIZE=%d\n", $4); f = 2}
|
f == 1 {printf("export FIXUP_STRUCT_SIZE=%d\n", $4); f = 2}
|
||||||
b == 1 {printf("export BUG_STRUCT_SIZE=%d\n", $4); b = 2}
|
b == 1 {printf("export BUG_STRUCT_SIZE=%d\n", $4); b = 2}
|
||||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
||||||
j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2}
|
j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2}
|
||||||
|
i == 1 {printf("export PRINTK_INDEX_STRUCT_SIZE=%d\n", $4); i = 2}
|
||||||
|
|
||||||
# Bail out once we have everything
|
# Bail out once we have everything
|
||||||
f == 2 && b == 2 && e == 2 && (j == 2 || skip_j) {exit}')"
|
f == 2 && b == 2 && e == 2 && (j == 2 || skip_j) && (i == 2 || skip_i) {exit}')"
|
||||||
|
|
||||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||||
|
|
||||||
|
@ -361,6 +365,7 @@ find_special_section_data_ppc64le() {
|
||||||
[[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
|
[[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
|
||||||
[[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
|
[[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
|
||||||
[[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size"
|
[[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size"
|
||||||
|
[[ -z "$PRINTK_INDEX_STRUCT_SIZE" && "$CONFIG_PRINTK_INDEX" -ne 0 ]] && die "can't find special struct pi_entry size"
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -374,13 +379,14 @@ find_special_section_data() {
|
||||||
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
|
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
|
||||||
[[ "$CONFIG_UNWINDER_ORC" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_o=1"
|
[[ "$CONFIG_UNWINDER_ORC" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_o=1"
|
||||||
[[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1"
|
[[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1"
|
||||||
|
[[ "$CONFIG_PRINTK_INDEX" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_i=1"
|
||||||
! kernel_version_gte 5.10.0 && AWK_OPTIONS="$AWK_OPTIONS -vskip_s=1"
|
! kernel_version_gte 5.10.0 && AWK_OPTIONS="$AWK_OPTIONS -vskip_s=1"
|
||||||
|
|
||||||
# If $AWK_OPTIONS are blank gawk would treat "" as a blank script
|
# If $AWK_OPTIONS are blank gawk would treat "" as a blank script
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||||
gawk --non-decimal-data $AWK_OPTIONS '
|
gawk --non-decimal-data $AWK_OPTIONS '
|
||||||
BEGIN { a = b = p = e = o = j = s = 0 }
|
BEGIN { a = b = p = e = o = j = s = i = 0 }
|
||||||
|
|
||||||
# Set state if name matches
|
# Set state if name matches
|
||||||
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
||||||
|
@ -390,6 +396,7 @@ find_special_section_data() {
|
||||||
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next}
|
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next}
|
||||||
j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next}
|
j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next}
|
||||||
s == 0 && /DW_AT_name.* static_call_site[[:space:]]*$/ {s = 1; next}
|
s == 0 && /DW_AT_name.* static_call_site[[:space:]]*$/ {s = 1; next}
|
||||||
|
i == 0 && /DW_AT_name.* pi_entry[[:space:]]*$/ {i = 1; next}
|
||||||
|
|
||||||
# Reset state unless this abbrev describes the struct size
|
# Reset state unless this abbrev describes the struct size
|
||||||
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
||||||
|
@ -399,6 +406,7 @@ find_special_section_data() {
|
||||||
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
|
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
|
||||||
j == 1 && !/DW_AT_byte_size/ { j = 0; next }
|
j == 1 && !/DW_AT_byte_size/ { j = 0; next }
|
||||||
s == 1 && !/DW_AT_byte_size/ { s = 0; next }
|
s == 1 && !/DW_AT_byte_size/ { s = 0; next }
|
||||||
|
i == 1 && !/DW_AT_byte_size/ { i = 0; next }
|
||||||
|
|
||||||
# Now that we know the size, stop parsing for it
|
# Now that we know the size, stop parsing for it
|
||||||
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
||||||
|
@ -408,9 +416,10 @@ find_special_section_data() {
|
||||||
o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2}
|
o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2}
|
||||||
j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2}
|
j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2}
|
||||||
s == 1 {printf("export STATIC_CALL_STRUCT_SIZE=%d\n", $4); s = 2}
|
s == 1 {printf("export STATIC_CALL_STRUCT_SIZE=%d\n", $4); s = 2}
|
||||||
|
i == 1 {printf("export PRINTK_INDEX_STRUCT_SIZE=%d\n", $4); i = 2}
|
||||||
|
|
||||||
# Bail out once we have everything
|
# Bail out once we have everything
|
||||||
a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && (j == 2 || skip_j) && (s == 2 || skip_s) {exit}')"
|
a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && (j == 2 || skip_j) && (s == 2 || skip_s) && (i == 2 || skip_i) {exit}')"
|
||||||
|
|
||||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||||
|
|
||||||
|
@ -420,6 +429,7 @@ find_special_section_data() {
|
||||||
[[ -z "$PARA_STRUCT_SIZE" && "$CONFIG_PARAVIRT" -ne 0 ]] && die "can't find special struct paravirt_patch_site size"
|
[[ -z "$PARA_STRUCT_SIZE" && "$CONFIG_PARAVIRT" -ne 0 ]] && die "can't find special struct paravirt_patch_site size"
|
||||||
[[ -z "$ORC_STRUCT_SIZE" && "$CONFIG_UNWINDER_ORC" -ne 0 ]] && die "can't find special struct orc_entry size"
|
[[ -z "$ORC_STRUCT_SIZE" && "$CONFIG_UNWINDER_ORC" -ne 0 ]] && die "can't find special struct orc_entry size"
|
||||||
[[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size"
|
[[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size"
|
||||||
|
[[ -z "$PRINTK_INDEX_STRUCT_SIZE" && "$CONFIG_PRINTK_INDEX" -ne 0 ]] && die "can't find special struct pi_entry size"
|
||||||
[[ -z "$STATIC_CALL_STRUCT_SIZE" ]] && kernel_version_gte 5.10.0 && die "can't find special struct static_call_site size"
|
[[ -z "$STATIC_CALL_STRUCT_SIZE" ]] && kernel_version_gte 5.10.0 && die "can't find special struct static_call_site size"
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 375794c2e5c6898643fea44f7ce354dc6404a4cc
|
Subproject commit 32ab24dc590c955f50f794afc0ccc2d8d9a92aa2
|
Loading…
Reference in New Issue