@@ -70,7 +70,6 @@ enum subsection {
7070enum loglevel loglevel = NORMAL ;
7171
7272bool KLP_ARCH ;
73- bool multi_pfe ;
7473
7574int jump_label_errors , static_call_errors ;
7675
@@ -3754,114 +3753,68 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
37543753 }
37553754}
37563755
3757- /*
3758- * Allocate the mcount/patchable_function_entry sections which must be done
3759- * before the patched object is torn down so that the section flags can be
3760- * copied.
3761- */
3762- static void kpatch_alloc_mcount_sections (struct kpatch_elf * kelf , struct kpatch_elf * kelfout )
3756+ static void kpatch_set_pfe_link (struct kpatch_elf * kelf )
37633757{
3764- int nr ;
3765- struct symbol * sym ;
3766- int text_idx = 0 ;
3758+ struct section * sec ;
3759+ struct rela * rela ;
37673760
3768- nr = 0 ;
3769- list_for_each_entry (sym , & kelfout -> symbols , list ) {
3770- if (sym -> type == STT_FUNC && sym -> status != SAME &&
3771- sym -> has_func_profiling ) {
3772- text_idx = sym -> sec -> index ;
3773- nr ++ ;
3761+ list_for_each_entry (sec , & kelf -> sections , list ) {
3762+ if (strcmp (sec -> name , "__patchable_function_entries" )) {
3763+ continue ;
37743764 }
3775- }
3776-
3777- /* create text/rela section pair */
3778- switch (kelf -> arch ) {
3779- case AARCH64 : {
3780- struct section * sec ;
3781- int entries = multi_pfe ? 1 : nr ;
3782- int copies = multi_pfe ? nr : 1 ;
3783- int flags = 0 , rflags = 0 ;
37843765
3785- /*
3786- * Depending on the compiler the __patchable_function_entries section
3787- * can be ordered or not, copy this flag to the section we created to
3788- * avoid:
3789- * ld: __patchable_function_entries has both ordered [...] and unordered [...] sections
3790- */
3791- sec = find_section_by_name (& kelf -> sections , "__patchable_function_entries" );
3792- if (sec ) {
3793- flags = (sec -> sh .sh_flags & (SHF_LINK_ORDER |SHF_WRITE ));
3794- if (sec -> rela )
3795- rflags = (sec -> rela -> sh .sh_flags & (SHF_LINK_ORDER |SHF_WRITE ));
3766+ if (!sec -> rela ) {
3767+ continue ;
37963768 }
3797-
3798- for (nr = 0 ; nr < copies ; nr ++ ) {
3799- sec = create_section_pair (kelfout ,
3800- "__patchable_function_entries" ,
3801- sizeof (void * ), entries );
3802-
3803- sec -> sh .sh_flags |= flags ;
3804- if (sec -> rela )
3805- sec -> rela -> sh .sh_flags |= rflags ;
3806- if (multi_pfe )
3807- sec -> sh .sh_link = 0 ;
3808- else
3809- sec -> sh .sh_link = text_idx ;
3769+ list_for_each_entry (rela , & sec -> rela -> relas , list ) {
3770+ rela -> sym -> sec -> pfe = sec ;
38103771 }
3811- break ;
3812- }
3813- case PPC64 :
3814- case X86_64 :
3815- case S390 :
3816- create_section_pair (kelfout , "__mcount_loc" , sizeof (void * ), nr );
3817- break ;
3818- default :
3819- ERROR ("unsupported arch\n" );
38203772 }
38213773}
38223774
38233775/*
3824- * Populate the mcount sections allocated by kpatch_alloc_mcount_sections()
3825- * previously.
38263776 * This function basically reimplements the functionality of the Linux
38273777 * recordmcount script, so that patched functions can be recognized by ftrace.
38283778 *
38293779 * TODO: Eventually we can modify recordmount so that it recognizes our bundled
38303780 * sections as valid and does this work for us.
38313781 */
3832- static void kpatch_populate_mcount_sections (struct kpatch_elf * kelf )
3782+ static void kpatch_create_mcount_sections (struct kpatch_elf * kelf )
38333783{
38343784 int nr , index ;
3835- struct section * sec , * relasec ;
3785+ struct section * relasec ;
38363786 struct symbol * sym ;
38373787 struct rela * rela , * mcount_rela ;
38383788 void * * funcs ;
3789+ bool pfe_per_function ;
38393790
3840- switch (kelf -> arch ) {
3791+ nr = 0 ;
3792+ list_for_each_entry (sym , & kelf -> symbols , list )
3793+ if (sym -> type == STT_FUNC && sym -> status != SAME &&
3794+ sym -> has_func_profiling )
3795+ nr ++ ;
3796+
3797+ switch (kelf -> arch ) {
38413798 case AARCH64 :
3842- if (multi_pfe )
3843- sec = NULL ;
3844- else
3845- sec = find_section_by_name (& kelf -> sections ,
3846- "__patchable_function_entries" );
3799+ /* For aarch64, we will create separate __patchable_function_entries sections for each symbols. */
3800+ pfe_per_function = true;
3801+ relasec = NULL ;
38473802 break ;
38483803 case PPC64 :
38493804 case X86_64 :
38503805 case S390 :
3851- sec = find_section_by_name (& kelf -> sections , "__mcount_loc" );
3806+ {
3807+ struct section * sec ;
3808+
3809+ /* create text/rela section pair */
3810+ sec = create_section_pair (kelf , "__mcount_loc" , sizeof (void * ), nr );
3811+ relasec = sec -> rela ;
38523812 break ;
3813+ }
38533814 default :
38543815 ERROR ("unsupported arch\n" );
38553816 }
38563817
3857- if (multi_pfe ) {
3858- relasec = NULL ;
3859- nr = 0 ;
3860- } else {
3861- relasec = sec -> rela ;
3862- nr = (int ) (sec -> data -> d_size / sizeof (void * ));
3863- }
3864-
38653818 /* populate sections */
38663819 index = 0 ;
38673820 list_for_each_entry (sym , & kelf -> symbols , list ) {
@@ -3878,6 +3831,7 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
38783831
38793832 switch (kelf -> arch ) {
38803833 case AARCH64 : {
3834+ struct section * sec ;
38813835 unsigned char * insn ;
38823836 int i ;
38833837
@@ -3902,6 +3856,14 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
39023856 ERROR ("%s: unexpected instruction in patch section of function\n" , sym -> name );
39033857 }
39043858
3859+ /* Allocate __patchable_function_entries for symbol */
3860+ sec = create_section_pair (kelf , "__patchable_function_entries" , sizeof (void * ), 1 );
3861+ sec -> sh .sh_flags |= SHF_WRITE | SHF_LINK_ORDER ;
3862+ /* We will reset this sh_link in the reindex function. */
3863+ sec -> sh .sh_link = 0 ;
3864+
3865+ relasec = sec -> rela ;
3866+ sym -> sec -> pfe = sec ;
39053867 break ;
39063868 }
39073869 case PPC64 : {
@@ -3972,18 +3934,6 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
39723934 ERROR ("unsupported arch" );
39733935 }
39743936
3975- if (multi_pfe ) {
3976- sec = find_nth_section_by_name (& kelf -> sections , nr , "__patchable_function_entries" );
3977- if (!sec )
3978- ERROR ("cannot retrieve pre-allocated __pfe #%d\n" , nr );
3979-
3980- relasec = sec -> rela ;
3981- sym -> sec -> pfe = sec ;
3982- sec -> sh .sh_link = sec -> index ;
3983-
3984- nr ++ ;
3985- }
3986-
39873937 /*
39883938 * 'rela' points to the mcount/fentry call.
39893939 *
@@ -3994,9 +3944,8 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
39943944 mcount_rela -> type = absolute_rela_type (kelf );
39953945 mcount_rela -> addend = insn_offset - sym -> sym .st_value ;
39963946
3997- if (multi_pfe ) {
3947+ if (pfe_per_function ) {
39983948 mcount_rela -> offset = 0 ;
3999- sec = NULL ;
40003949 } else {
40013950 mcount_rela -> offset = (unsigned int ) (index * sizeof (* funcs ));
40023951 }
@@ -4166,19 +4115,21 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
41664115 switch (kelf -> arch ) {
41674116 case AARCH64 : {
41684117 struct section * sec ;
4169-
41704118 list_for_each_entry (sec , & kelf -> sections , list ) {
4171- if (strcmp (sec -> name , "__patchable_function_entries" ))
4119+ if (strcmp (sec -> name , "__patchable_function_entries" )) {
41724120 continue ;
4173- if (multi_pfe && sym -> sec -> pfe != sec )
4121+ }
4122+ if (sym -> sec -> pfe != sec ) {
41744123 continue ;
4175- if (!sec -> rela )
4124+ }
4125+ if (!sec -> rela ) {
41764126 continue ;
4127+ }
41774128
41784129 list_for_each_entry (rela , & sec -> rela -> relas , list ) {
41794130 if (rela -> sym -> sec && sym -> sec == rela -> sym -> sec ) {
41804131 sym -> has_func_profiling = 1 ;
4181- goto next_symbol ;
4132+ goto next_symbol ;
41824133 }
41834134 }
41844135 }
@@ -4268,12 +4219,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
42684219 return 0 ;
42694220}
42704221
4271- static bool has_multi_pfe (struct kpatch_elf * kelf )
4272- {
4273- return !!find_nth_section_by_name (& kelf -> sections , 1 ,
4274- "__patchable_function_entries" );
4275- }
4276-
42774222static struct argp argp = { options , parse_opt , args_doc , NULL };
42784223
42794224int main (int argc , char * argv [])
@@ -4307,7 +4252,10 @@ int main(int argc, char *argv[])
43074252
43084253 kelf_orig = kpatch_elf_open (orig_obj );
43094254 kelf_patched = kpatch_elf_open (patched_obj );
4310- multi_pfe = has_multi_pfe (kelf_orig ) || has_multi_pfe (kelf_patched );
4255+
4256+ kpatch_set_pfe_link (kelf_orig );
4257+ kpatch_set_pfe_link (kelf_patched );
4258+
43114259 kpatch_find_func_profiling_calls (kelf_orig );
43124260 kpatch_find_func_profiling_calls (kelf_patched );
43134261
@@ -4369,9 +4317,6 @@ int main(int argc, char *argv[])
43694317 /* this is destructive to kelf_patched */
43704318 kpatch_migrate_included_elements (kelf_patched , & kelf_out );
43714319
4372- /* this must be done before kelf_patched is torn down */
4373- kpatch_alloc_mcount_sections (kelf_patched , kelf_out );
4374-
43754320 /*
43764321 * Teardown kelf_patched since we shouldn't access sections or symbols
43774322 * through it anymore. Don't free however, since our section and symbol
@@ -4390,7 +4335,7 @@ int main(int argc, char *argv[])
43904335 kpatch_create_callbacks_objname_rela (kelf_out , parent_name );
43914336 kpatch_build_strings_section_data (kelf_out );
43924337
4393- kpatch_populate_mcount_sections (kelf_out );
4338+ kpatch_create_mcount_sections (kelf_out );
43944339
43954340 /*
43964341 * At this point, the set of output sections and symbols is
0 commit comments