Skip to content

Commit e0c09ea

Browse files
authored
Merge pull request #1451 from puranjaymohan/pfe_ordering_fix
create-diff-object: Fix ordering of __patchable_function_entries
2 parents e6b0cf0 + 9ea87f8 commit e0c09ea

3 files changed

Lines changed: 25 additions & 15 deletions

File tree

kpatch-build/create-diff-object.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,8 @@ static void kpatch_migrate_included_elements(struct kpatch_elf *kelf, struct kpa
19951995
ERROR("malloc");
19961996
memset(out, 0, sizeof(*out));
19971997
out->arch = kelf->arch;
1998+
out->has_pfe = kelf->has_pfe;
1999+
out->pfe_ordered = kelf->pfe_ordered;
19982000
INIT_LIST_HEAD(&out->sections);
19992001
INIT_LIST_HEAD(&out->symbols);
20002002
INIT_LIST_HEAD(&out->strings);
@@ -3732,7 +3734,7 @@ static void kpatch_set_pfe_link(struct kpatch_elf *kelf)
37323734
* TODO: Eventually we can modify recordmount so that it recognizes our bundled
37333735
* sections as valid and does this work for us.
37343736
*/
3735-
static void kpatch_create_ftrace_callsite_sections(struct kpatch_elf *kelf, bool has_pfe)
3737+
static void kpatch_create_ftrace_callsite_sections(struct kpatch_elf *kelf)
37363738
{
37373739
int nr, index;
37383740
struct section *sec = NULL;
@@ -3748,13 +3750,7 @@ static void kpatch_create_ftrace_callsite_sections(struct kpatch_elf *kelf, bool
37483750
sym->has_func_profiling)
37493751
nr++;
37503752

3751-
if (has_pfe)
3752-
/*
3753-
* Create separate __patchable_function_entries sections
3754-
* for each function in the following loop.
3755-
*/
3756-
kelf->has_pfe = true;
3757-
else
3753+
if (!kelf->has_pfe)
37583754
/*
37593755
* Create a single __mcount_loc section pair for all
37603756
* functions.
@@ -3861,7 +3857,14 @@ static void kpatch_create_ftrace_callsite_sections(struct kpatch_elf *kelf, bool
38613857
* - its lone rela is based on the section symbol
38623858
*/
38633859
sec = create_section_pair(kelf, "__patchable_function_entries", sizeof(void *), 1);
3864-
sec->sh.sh_flags |= SHF_WRITE | SHF_ALLOC | SHF_LINK_ORDER;
3860+
sec->sh.sh_flags |= SHF_WRITE | SHF_ALLOC;
3861+
/*
3862+
* Old linkers don't support mixing ordered and unordered sections, so set
3863+
* the SHF_LINK_ORDER flag only if it is set in the pfe section generated by
3864+
* the compiler.
3865+
*/
3866+
if (kelf->pfe_ordered)
3867+
sec->sh.sh_flags |= SHF_LINK_ORDER;
38653868
rela_sym = sym->sec->secsym;
38663869
rela_offset = 0;
38673870
rela_sym->pfe = sec;
@@ -4161,7 +4164,6 @@ int main(int argc, char *argv[])
41614164
struct section *relasec, *symtab;
41624165
char *orig_obj, *patched_obj, *parent_name;
41634166
char *parent_symtab, *mod_symvers, *patch_name, *output_obj;
4164-
bool has_pfe = false;
41654167

41664168
memset(&arguments, 0, sizeof(arguments));
41674169
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
@@ -4187,8 +4189,6 @@ int main(int argc, char *argv[])
41874189

41884190
kpatch_set_pfe_link(kelf_orig);
41894191
kpatch_set_pfe_link(kelf_patched);
4190-
if (kelf_patched->has_pfe)
4191-
has_pfe = true;
41924192

41934193
kpatch_find_func_profiling_calls(kelf_orig);
41944194
kpatch_find_func_profiling_calls(kelf_patched);
@@ -4269,7 +4269,7 @@ int main(int argc, char *argv[])
42694269
kpatch_create_callbacks_objname_rela(kelf_out, parent_name);
42704270
kpatch_build_strings_section_data(kelf_out);
42714271

4272-
kpatch_create_ftrace_callsite_sections(kelf_out, has_pfe);
4272+
kpatch_create_ftrace_callsite_sections(kelf_out);
42734273

42744274
/*
42754275
* At this point, the set of output sections and symbols is

kpatch-build/kpatch-elf.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ struct kpatch_elf *kpatch_elf_open(const char *name)
559559
int fd;
560560
struct kpatch_elf *kelf;
561561
struct section *relasec;
562+
struct section *pfesec;
562563
GElf_Ehdr ehdr;
563564

564565
fd = open(name, O_RDONLY);
@@ -614,9 +615,17 @@ struct kpatch_elf *kpatch_elf_open(const char *name)
614615
* These sections aren't used by ftrace on this arch, so do not
615616
* bother reading/writing them for x86_64.
616617
*/
617-
if (kelf->arch != X86_64)
618-
if (find_section_by_name(&kelf->sections, "__patchable_function_entries"))
618+
if (kelf->arch != X86_64) {
619+
pfesec = find_section_by_name(&kelf->sections, "__patchable_function_entries");
620+
if (pfesec) {
619621
kelf->has_pfe = true;
622+
/*
623+
* Check if the pfe section generated by the toolchain has the SHF_LINK_ORDER
624+
* flag set. This info is used while generating pfe sections in the diff object.
625+
*/
626+
kelf->pfe_ordered = !!(pfesec->sh.sh_flags & SHF_LINK_ORDER);
627+
}
628+
}
620629

621630
return kelf;
622631
}

kpatch-build/kpatch-elf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct kpatch_elf {
127127
Elf_Data *symtab_shndx;
128128
int fd;
129129
bool has_pfe;
130+
bool pfe_ordered;
130131
};
131132

132133
/*******************

0 commit comments

Comments
 (0)