Skip to content

Commit 05f2958

Browse files
authored
Merge pull request #1494 from sumanthkorikkar/remove-undefined-function-symbols
create-diff-object: Remove undefined function symbols
2 parents 7d45f6b + 6571f2a commit 05f2958

1 file changed

Lines changed: 73 additions & 1 deletion

File tree

kpatch-build/create-diff-object.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,23 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf)
18861886
DIFF_FATAL("%d unsupported section change(s)", errs);
18871887
}
18881888

1889+
/*
1890+
* Do not perform symbol inclusion initially from .rela__bug_table.
1891+
*
1892+
* WARN() is converted to a static call which emits relocations that point
1893+
* directly into __bug_table+off. If the usual "include every symbol referenced
1894+
* by this rela section" rule is applied here, it could end up dragging in the
1895+
* entire __bug_table via propagation.
1896+
*
1897+
* .rela__bug_table relocations are processed later in
1898+
* kpatch_regenerate_special_section(), which also adjusts relocations
1899+
* targetting __bug_table.
1900+
*/
1901+
static bool kpatch_skip_symbol_inclusion_from_relasec(struct section *relasec)
1902+
{
1903+
return !strcmp(relasec->name, ".rela__bug_table");
1904+
}
1905+
18891906
static void kpatch_include_symbol(struct symbol *sym);
18901907

18911908
static void kpatch_include_section(struct section *sec)
@@ -1906,6 +1923,8 @@ static void kpatch_include_section(struct section *sec)
19061923
if (!sec->rela)
19071924
return;
19081925
sec->rela->include = 1;
1926+
if (kpatch_skip_symbol_inclusion_from_relasec(sec->rela))
1927+
return;
19091928
list_for_each_entry(rela, &sec->rela->relas, list)
19101929
kpatch_include_symbol(rela->sym);
19111930
}
@@ -2801,14 +2820,52 @@ static void kpatch_update_ex_table_addend(struct kpatch_elf *kelf,
28012820
}
28022821
}
28032822

2823+
static bool is_reloc_to_bug_table(struct rela *rela)
2824+
{
2825+
return !strcmp(rela->sym->name, "__bug_table");
2826+
}
2827+
2828+
static void recalculate_bug_table_rela_addend(struct kpatch_elf *kelf,
2829+
long old_bug_offset,
2830+
long new_bug_offset)
2831+
{
2832+
long add_offset, old_target_offset;
2833+
struct section *relasec;
2834+
struct rela *rela;
2835+
2836+
list_for_each_entry(relasec, &kelf->sections, list) {
2837+
if (!is_rela_section(relasec) ||
2838+
!relasec->include ||
2839+
!strcmp(relasec->name, ".rela__bug_table"))
2840+
continue;
2841+
list_for_each_entry(rela, &relasec->relas, list) {
2842+
if (!is_reloc_to_bug_table(rela))
2843+
continue;
2844+
old_target_offset = rela_target_offset(kelf, relasec, rela);
2845+
if (old_target_offset == old_bug_offset) {
2846+
add_offset = rela_target_offset(kelf, relasec, rela) - rela->addend;
2847+
rela->addend = new_bug_offset - add_offset;
2848+
rela->rela.r_addend = rela->addend;
2849+
log_debug("%s: adjusting rela from %s+%lx to %s+%lx\n",
2850+
relasec->name,
2851+
rela->sym->name,
2852+
old_bug_offset - add_offset,
2853+
rela->sym->name,
2854+
new_bug_offset - add_offset);
2855+
}
2856+
}
2857+
}
2858+
2859+
}
2860+
28042861
static void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
28052862
struct lookup_table *lookup,
28062863
struct special_section *special,
28072864
struct section *relasec)
28082865
{
28092866
struct rela *rela, *safe;
28102867
char *src, *dest;
2811-
unsigned int group_size, src_offset, dest_offset;
2868+
unsigned int group_size, src_offset, dest_offset, new_offset;
28122869

28132870
LIST_HEAD(newrelas);
28142871

@@ -2862,6 +2919,21 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
28622919
list_del(&rela->list);
28632920
list_add_tail(&rela->list, &newrelas);
28642921

2922+
if (!strcmp(relasec->name, ".rela__bug_table")) {
2923+
new_offset = rela->offset - (src_offset - dest_offset);
2924+
/*
2925+
* When a bug table rela entry is
2926+
* reassigned to a new offset
2927+
* (rela->offset adjustment below),
2928+
* update the addends of all
2929+
* relocations targeting __bug_table so
2930+
* they continue to reference the
2931+
* updated bug entry.
2932+
*/
2933+
recalculate_bug_table_rela_addend(kelf, rela->offset,
2934+
new_offset);
2935+
}
2936+
28652937
rela->offset -= src_offset - dest_offset;
28662938
rela->rela.r_offset = rela->offset;
28672939

0 commit comments

Comments
 (0)