kpatch-build: add support for static calls

Add the new .static_call_sites special section.

Fixes #1165.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
Josh Poimboeuf 2021-03-19 17:40:07 -05:00
parent 6321c9ab5e
commit 7be75549ba
3 changed files with 27 additions and 3 deletions

View File

@ -2036,6 +2036,21 @@ static int smp_locks_group_size(struct kpatch_elf *kelf, int offset)
{
return 4;
}
static int static_call_sites_group_size(struct kpatch_elf *kelf, int offset)
{
static int size = 0;
char *str;
if (!size) {
str = getenv("STATIC_CALL_STRUCT_SIZE");
if (!str)
ERROR("STATIC_CALL_STRUCT_SIZE not set");
size = atoi(str);
}
return size;
}
#endif
#ifdef __powerpc64__
static int fixup_entry_group_size(struct kpatch_elf *kelf, int offset)
@ -2144,6 +2159,10 @@ static struct special_section special_sections[] = {
.name = ".altinstructions",
.group_size = altinstructions_group_size,
},
{
.name = ".static_call_sites",
.group_size = static_call_sites_group_size,
},
#endif
#ifdef __powerpc64__
{

View File

@ -334,12 +334,13 @@ find_special_section_data() {
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=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"
! 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
# shellcheck disable=SC2086
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
gawk --non-decimal-data $AWK_OPTIONS '
BEGIN { a = b = p = e = o = j = 0 }
BEGIN { a = b = p = e = o = j = s = 0 }
# Set state if name matches
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
@ -348,6 +349,7 @@ find_special_section_data() {
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 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}
# Reset state unless this abbrev describes the struct size
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
@ -356,6 +358,7 @@ find_special_section_data() {
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
j == 1 && !/DW_AT_byte_size/ { j = 0; next }
s == 1 && !/DW_AT_byte_size/ { s = 0; next }
# Now that we know the size, stop parsing for it
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
@ -364,9 +367,10 @@ find_special_section_data() {
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 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}
s == 1 {printf("export STATIC_CALL_STRUCT_SIZE=%d\n", $4); s = 2}
# Bail out once we have everything
a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && (j == 2 || skip_j) {exit}')"
a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && (j == 2 || skip_j) && (s == 2 || skip_s) {exit}')"
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
@ -376,6 +380,7 @@ find_special_section_data() {
[[ -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 "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size"
[[ -z "$STATIC_CALL_STRUCT_SIZE" ]] && kernel_version_gte 5.10.0 && die "can't find special struct static_call_site size"
return
}

@ -1 +1 @@
Subproject commit 4d0e838358397d50e186e1abca0eaeff730385df
Subproject commit 66295e60b42889710565a6001c9882d9942a0c28