@@ -173,6 +173,8 @@ static bool is_gcc6_localentry_bundled_sym(struct kpatch_elf *kelf,
173173 struct symbol * sym )
174174{
175175 switch (kelf -> arch ) {
176+ case AARCH64 :
177+ return false;
176178 case PPC64 :
177179 return ((PPC64_LOCAL_ENTRY_OFFSET (sym -> sym .st_other ) != 0 ) &&
178180 sym -> sym .st_value == 8 );
@@ -228,6 +230,31 @@ static struct rela *toc_rela(const struct rela *rela)
228230 (unsigned int )rela -> addend );
229231}
230232
233+ /*
234+ * Mapping symbols are used to mark and label the transitions between code and
235+ * data in elf files. They begin with a "$" dollar symbol. Don't correlate them
236+ * as they often all have the same name either "$x" to mark the start of code
237+ * or "$d" to mark the start of data.
238+ */
239+ static bool kpatch_is_mapping_symbol (struct kpatch_elf * kelf , struct symbol * sym )
240+ {
241+ switch (kelf -> arch ) {
242+ case AARCH64 :
243+ if (sym -> name && sym -> name [0 ] == '$'
244+ && sym -> type == STT_NOTYPE \
245+ && sym -> bind == STB_LOCAL )
246+ return true;
247+ case X86_64 :
248+ case PPC64 :
249+ case S390 :
250+ return false;
251+ default :
252+ ERROR ("unsupported arch" );
253+ }
254+
255+ return false;
256+ }
257+
231258/*
232259 * When compiling with -ffunction-sections and -fdata-sections, almost every
233260 * symbol gets its own dedicated section. We call such symbols "bundled"
@@ -706,6 +733,12 @@ static bool insn_is_load_immediate(struct kpatch_elf *kelf, void *addr)
706733
707734 break ;
708735
736+ case AARCH64 :
737+ /* Verify mov w2 <line number> */
738+ if ((insn [0 ] & 0b11111 ) == 0x2 && insn [3 ] == 0x52 )
739+ return true;
740+ break ;
741+
709742 default :
710743 ERROR ("unsupported arch" );
711744 }
@@ -746,6 +779,7 @@ static bool kpatch_line_macro_change_only(struct kpatch_elf *kelf,
746779 void * data1 , * data2 , * insn1 , * insn2 ;
747780 struct rela * r , * rela ;
748781 bool found , found_any = false;
782+ bool warn_printk_only = (kelf -> arch == AARCH64 );
749783
750784 if (sec -> status != CHANGED ||
751785 is_rela_section (sec ) ||
@@ -809,8 +843,15 @@ static bool kpatch_line_macro_change_only(struct kpatch_elf *kelf,
809843 !strncmp (rela -> sym -> name , "__func__." , 9 ))
810844 continue ;
811845
846+ if (!strcmp (rela -> sym -> name , "__warn_printk" )) {
847+ found = true;
848+ break ;
849+ }
850+
851+ if (warn_printk_only )
852+ return false;
853+
812854 if (!strncmp (rela -> sym -> name , "warn_slowpath_" , 14 ) ||
813- !strcmp (rela -> sym -> name , "__warn_printk" ) ||
814855 !strcmp (rela -> sym -> name , "__might_sleep" ) ||
815856 !strcmp (rela -> sym -> name , "___might_sleep" ) ||
816857 !strcmp (rela -> sym -> name , "__might_fault" ) ||
@@ -1075,15 +1116,15 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig,
10751116 }
10761117}
10771118
1078- static void kpatch_correlate_symbols (struct list_head * symlist_orig ,
1079- struct list_head * symlist_patched )
1119+ static void kpatch_correlate_symbols (struct kpatch_elf * kelf_orig ,
1120+ struct kpatch_elf * kelf_patched )
10801121{
10811122 struct symbol * sym_orig , * sym_patched ;
10821123
1083- list_for_each_entry (sym_orig , symlist_orig , list ) {
1124+ list_for_each_entry (sym_orig , & kelf_orig -> symbols , list ) {
10841125 if (sym_orig -> twin )
10851126 continue ;
1086- list_for_each_entry (sym_patched , symlist_patched , list ) {
1127+ list_for_each_entry (sym_patched , & kelf_patched -> symbols , list ) {
10871128 if (kpatch_mangled_strcmp (sym_orig -> name , sym_patched -> name ) ||
10881129 sym_orig -> type != sym_patched -> type || sym_patched -> twin )
10891130 continue ;
@@ -1103,6 +1144,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist_orig,
11031144 !strncmp (sym_orig -> name , ".LC" , 3 ))
11041145 continue ;
11051146
1147+ if (kpatch_is_mapping_symbol (kelf_orig , sym_orig ))
1148+ continue ;
1149+
11061150 /* group section symbols must have correlated sections */
11071151 if (sym_orig -> sec &&
11081152 sym_orig -> sec -> sh .sh_type == SHT_GROUP &&
@@ -1508,7 +1552,7 @@ static void kpatch_correlate_elfs(struct kpatch_elf *kelf_orig,
15081552 struct kpatch_elf * kelf_patched )
15091553{
15101554 kpatch_correlate_sections (& kelf_orig -> sections , & kelf_patched -> sections );
1511- kpatch_correlate_symbols (& kelf_orig -> symbols , & kelf_patched -> symbols );
1555+ kpatch_correlate_symbols (kelf_orig , kelf_patched );
15121556}
15131557
15141558static void kpatch_compare_correlated_elements (struct kpatch_elf * kelf )
@@ -1624,7 +1668,8 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
16241668
16251669 if (is_text_section (relasec -> base ) &&
16261670 !is_text_section (sym -> sec ) &&
1627- rela -> type == R_X86_64_32S &&
1671+ (rela -> type == R_X86_64_32S ||
1672+ rela -> type == R_AARCH64_ABS64 ) &&
16281673 rela -> addend == (long )sym -> sec -> sh .sh_size &&
16291674 end == (long )sym -> sec -> sh .sh_size ) {
16301675
@@ -2493,28 +2538,28 @@ static bool static_call_sites_group_filter(struct lookup_table *lookup,
24932538static struct special_section special_sections [] = {
24942539 {
24952540 .name = "__bug_table" ,
2496- .arch = X86_64 | PPC64 | S390 ,
2541+ .arch = AARCH64 | X86_64 | PPC64 | S390 ,
24972542 .group_size = bug_table_group_size ,
24982543 },
24992544 {
25002545 .name = ".fixup" ,
2501- .arch = X86_64 | PPC64 | S390 ,
2546+ .arch = AARCH64 | X86_64 | PPC64 | S390 ,
25022547 .group_size = fixup_group_size ,
25032548 },
25042549 {
25052550 .name = "__ex_table" , /* must come after .fixup */
2506- .arch = X86_64 | PPC64 | S390 ,
2551+ .arch = AARCH64 | X86_64 | PPC64 | S390 ,
25072552 .group_size = ex_table_group_size ,
25082553 },
25092554 {
25102555 .name = "__jump_table" ,
2511- .arch = X86_64 | PPC64 | S390 ,
2556+ .arch = AARCH64 | X86_64 | PPC64 | S390 ,
25122557 .group_size = jump_table_group_size ,
25132558 .group_filter = jump_table_group_filter ,
25142559 },
25152560 {
25162561 .name = ".printk_index" ,
2517- .arch = X86_64 | PPC64 | S390 ,
2562+ .arch = AARCH64 | X86_64 | PPC64 | S390 ,
25182563 .group_size = printk_index_group_size ,
25192564 },
25202565 {
@@ -2529,7 +2574,7 @@ static struct special_section special_sections[] = {
25292574 },
25302575 {
25312576 .name = ".altinstructions" ,
2532- .arch = X86_64 | S390 ,
2577+ .arch = AARCH64 | X86_64 | S390 ,
25332578 .group_size = altinstructions_group_size ,
25342579 },
25352580 {
0 commit comments