@@ -70,7 +70,6 @@ enum subsection {
70
70
enum loglevel loglevel = NORMAL ;
71
71
72
72
bool KLP_ARCH ;
73
- bool multi_pfe ;
74
73
75
74
int jump_label_errors , static_call_errors ;
76
75
@@ -3754,114 +3753,68 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
3754
3753
}
3755
3754
}
3756
3755
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 )
3763
3757
{
3764
- int nr ;
3765
- struct symbol * sym ;
3766
- int text_idx = 0 ;
3758
+ struct section * sec ;
3759
+ struct rela * rela ;
3767
3760
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 ;
3774
3764
}
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 ;
3784
3765
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 ;
3796
3768
}
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 ;
3810
3771
}
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" );
3820
3772
}
3821
3773
}
3822
3774
3823
3775
/*
3824
- * Populate the mcount sections allocated by kpatch_alloc_mcount_sections()
3825
- * previously.
3826
3776
* This function basically reimplements the functionality of the Linux
3827
3777
* recordmcount script, so that patched functions can be recognized by ftrace.
3828
3778
*
3829
3779
* TODO: Eventually we can modify recordmount so that it recognizes our bundled
3830
3780
* sections as valid and does this work for us.
3831
3781
*/
3832
- static void kpatch_populate_mcount_sections (struct kpatch_elf * kelf )
3782
+ static void kpatch_create_mcount_sections (struct kpatch_elf * kelf )
3833
3783
{
3834
3784
int nr , index ;
3835
- struct section * sec , * relasec ;
3785
+ struct section * relasec ;
3836
3786
struct symbol * sym ;
3837
3787
struct rela * rela , * mcount_rela ;
3838
3788
void * * funcs ;
3789
+ bool pfe_per_function ;
3839
3790
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 ) {
3841
3798
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 ;
3847
3802
break ;
3848
3803
case PPC64 :
3849
3804
case X86_64 :
3850
3805
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 ;
3852
3812
break ;
3813
+ }
3853
3814
default :
3854
3815
ERROR ("unsupported arch\n" );
3855
3816
}
3856
3817
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
-
3865
3818
/* populate sections */
3866
3819
index = 0 ;
3867
3820
list_for_each_entry (sym , & kelf -> symbols , list ) {
@@ -3878,6 +3831,7 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
3878
3831
3879
3832
switch (kelf -> arch ) {
3880
3833
case AARCH64 : {
3834
+ struct section * sec ;
3881
3835
unsigned char * insn ;
3882
3836
int i ;
3883
3837
@@ -3902,6 +3856,14 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
3902
3856
ERROR ("%s: unexpected instruction in patch section of function\n" , sym -> name );
3903
3857
}
3904
3858
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 ;
3905
3867
break ;
3906
3868
}
3907
3869
case PPC64 : {
@@ -3972,18 +3934,6 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
3972
3934
ERROR ("unsupported arch" );
3973
3935
}
3974
3936
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
-
3987
3937
/*
3988
3938
* 'rela' points to the mcount/fentry call.
3989
3939
*
@@ -3994,9 +3944,8 @@ static void kpatch_populate_mcount_sections(struct kpatch_elf *kelf)
3994
3944
mcount_rela -> type = absolute_rela_type (kelf );
3995
3945
mcount_rela -> addend = insn_offset - sym -> sym .st_value ;
3996
3946
3997
- if (multi_pfe ) {
3947
+ if (pfe_per_function ) {
3998
3948
mcount_rela -> offset = 0 ;
3999
- sec = NULL ;
4000
3949
} else {
4001
3950
mcount_rela -> offset = (unsigned int ) (index * sizeof (* funcs ));
4002
3951
}
@@ -4166,19 +4115,21 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
4166
4115
switch (kelf -> arch ) {
4167
4116
case AARCH64 : {
4168
4117
struct section * sec ;
4169
-
4170
4118
list_for_each_entry (sec , & kelf -> sections , list ) {
4171
- if (strcmp (sec -> name , "__patchable_function_entries" ))
4119
+ if (strcmp (sec -> name , "__patchable_function_entries" )) {
4172
4120
continue ;
4173
- if (multi_pfe && sym -> sec -> pfe != sec )
4121
+ }
4122
+ if (sym -> sec -> pfe != sec ) {
4174
4123
continue ;
4175
- if (!sec -> rela )
4124
+ }
4125
+ if (!sec -> rela ) {
4176
4126
continue ;
4127
+ }
4177
4128
4178
4129
list_for_each_entry (rela , & sec -> rela -> relas , list ) {
4179
4130
if (rela -> sym -> sec && sym -> sec == rela -> sym -> sec ) {
4180
4131
sym -> has_func_profiling = 1 ;
4181
- goto next_symbol ;
4132
+ goto next_symbol ;
4182
4133
}
4183
4134
}
4184
4135
}
@@ -4268,12 +4219,6 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
4268
4219
return 0 ;
4269
4220
}
4270
4221
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
-
4277
4222
static struct argp argp = { options , parse_opt , args_doc , NULL };
4278
4223
4279
4224
int main (int argc , char * argv [])
@@ -4307,7 +4252,10 @@ int main(int argc, char *argv[])
4307
4252
4308
4253
kelf_orig = kpatch_elf_open (orig_obj );
4309
4254
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
+
4311
4259
kpatch_find_func_profiling_calls (kelf_orig );
4312
4260
kpatch_find_func_profiling_calls (kelf_patched );
4313
4261
@@ -4369,9 +4317,6 @@ int main(int argc, char *argv[])
4369
4317
/* this is destructive to kelf_patched */
4370
4318
kpatch_migrate_included_elements (kelf_patched , & kelf_out );
4371
4319
4372
- /* this must be done before kelf_patched is torn down */
4373
- kpatch_alloc_mcount_sections (kelf_patched , kelf_out );
4374
-
4375
4320
/*
4376
4321
* Teardown kelf_patched since we shouldn't access sections or symbols
4377
4322
* through it anymore. Don't free however, since our section and symbol
@@ -4390,7 +4335,7 @@ int main(int argc, char *argv[])
4390
4335
kpatch_create_callbacks_objname_rela (kelf_out , parent_name );
4391
4336
kpatch_build_strings_section_data (kelf_out );
4392
4337
4393
- kpatch_populate_mcount_sections (kelf_out );
4338
+ kpatch_create_mcount_sections (kelf_out );
4394
4339
4395
4340
/*
4396
4341
* At this point, the set of output sections and symbols is
0 commit comments