|
62 | 62 |
|
63 | 63 | #ifdef __powerpc64__
|
64 | 64 | #define ABSOLUTE_RELA_TYPE R_PPC64_ADDR64
|
65 |
| -#else |
| 65 | +#elif defined(__aarch64__) |
| 66 | +#define ABSOLUTE_RELA_TYPE R_AARCH64_ABS64 |
| 67 | +#elif defined(__x86_64__) |
66 | 68 | #define ABSOLUTE_RELA_TYPE R_X86_64_64
|
67 | 69 | #endif
|
68 | 70 |
|
@@ -214,6 +216,28 @@ static struct rela *toc_rela(const struct rela *rela)
|
214 | 216 | (unsigned int)rela->addend);
|
215 | 217 | }
|
216 | 218 |
|
| 219 | +#ifdef __aarch64__ |
| 220 | +/* |
| 221 | + * Mapping symbols are used to mark and label the transitions between code and |
| 222 | + * data in elf files. They begin with a "$" dollar symbol. Don't correlate them |
| 223 | + * as they often all have the same name either "$x" to mark the start of code |
| 224 | + * or "$d" to mark the start of data. |
| 225 | + */ |
| 226 | +static bool kpatch_is_mapping_symbol(struct symbol *sym) |
| 227 | +{ |
| 228 | + if (sym->name && sym->name[0] == '$' |
| 229 | + && sym->type == STT_NOTYPE \ |
| 230 | + && sym->bind == STB_LOCAL) |
| 231 | + return 1; |
| 232 | + return 0; |
| 233 | +} |
| 234 | +#else |
| 235 | +static int kpatch_is_mapping_symbol(struct symbol *sym) |
| 236 | +{ |
| 237 | + return 0; |
| 238 | +} |
| 239 | +#endif |
| 240 | + |
217 | 241 | /*
|
218 | 242 | * When compiling with -ffunction-sections and -fdata-sections, almost every
|
219 | 243 | * symbol gets its own dedicated section. We call such symbols "bundled"
|
@@ -564,6 +588,13 @@ static void kpatch_compare_correlated_section(struct section *sec)
|
564 | 588 | goto out;
|
565 | 589 | }
|
566 | 590 |
|
| 591 | + /* As above but for aarch64 */ |
| 592 | + if (!strcmp(sec->name, ".rela__patchable_function_entries") || |
| 593 | + !strcmp(sec->name, "__patchable_function_entries")) { |
| 594 | + sec->status = SAME; |
| 595 | + goto out; |
| 596 | + } |
| 597 | + |
567 | 598 | if (sec1->sh.sh_size != sec2->sh.sh_size ||
|
568 | 599 | sec1->data->d_size != sec2->data->d_size) {
|
569 | 600 | sec->status = CHANGED;
|
@@ -1030,6 +1061,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist_orig,
|
1030 | 1061 | !strncmp(sym_orig->name, ".LC", 3))
|
1031 | 1062 | continue;
|
1032 | 1063 |
|
| 1064 | + if (kpatch_is_mapping_symbol(sym_orig)) |
| 1065 | + continue; |
| 1066 | + |
1033 | 1067 | /* group section symbols must have correlated sections */
|
1034 | 1068 | if (sym_orig->sec &&
|
1035 | 1069 | sym_orig->sec->sh.sh_type == SHT_GROUP &&
|
@@ -1539,7 +1573,7 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
1539 | 1573 | continue;
|
1540 | 1574 | }
|
1541 | 1575 |
|
1542 |
| -#ifdef __powerpc64__ |
| 1576 | +#if defined(__powerpc64__) || defined(__aarch64__) |
1543 | 1577 | add_off = 0;
|
1544 | 1578 | #else
|
1545 | 1579 | if (rela->type == R_X86_64_PC32 ||
|
@@ -1571,7 +1605,8 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
1571 | 1605 | end = sym->sym.st_value + sym->sym.st_size;
|
1572 | 1606 |
|
1573 | 1607 | if (!is_text_section(sym->sec) &&
|
1574 |
| - rela->type == R_X86_64_32S && |
| 1608 | + (rela->type == R_X86_64_32S || |
| 1609 | + rela->type == R_AARCH64_ABS64) && |
1575 | 1610 | rela->addend == (long)sym->sec->sh.sh_size &&
|
1576 | 1611 | end == (long)sym->sec->sh.sh_size) {
|
1577 | 1612 |
|
@@ -2047,35 +2082,36 @@ static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
|
2047 | 2082 | return size;
|
2048 | 2083 | }
|
2049 | 2084 |
|
2050 |
| -static int altinstructions_group_size(struct kpatch_elf *kelf, int offset) |
| 2085 | +static int smp_locks_group_size(struct kpatch_elf *kelf, int offset) |
| 2086 | +{ |
| 2087 | + return 4; |
| 2088 | +} |
| 2089 | + |
| 2090 | +static int static_call_sites_group_size(struct kpatch_elf *kelf, int offset) |
2051 | 2091 | {
|
2052 | 2092 | static int size = 0;
|
2053 | 2093 | char *str;
|
2054 | 2094 |
|
2055 | 2095 | if (!size) {
|
2056 |
| - str = getenv("ALT_STRUCT_SIZE"); |
| 2096 | + str = getenv("STATIC_CALL_STRUCT_SIZE"); |
2057 | 2097 | if (!str)
|
2058 |
| - ERROR("ALT_STRUCT_SIZE not set"); |
| 2098 | + ERROR("STATIC_CALL_STRUCT_SIZE not set"); |
2059 | 2099 | size = atoi(str);
|
2060 | 2100 | }
|
2061 | 2101 |
|
2062 | 2102 | return size;
|
2063 | 2103 | }
|
2064 |
| - |
2065 |
| -static int smp_locks_group_size(struct kpatch_elf *kelf, int offset) |
2066 |
| -{ |
2067 |
| - return 4; |
2068 |
| -} |
2069 |
| - |
2070 |
| -static int static_call_sites_group_size(struct kpatch_elf *kelf, int offset) |
| 2104 | +#endif |
| 2105 | +#if defined(__x86_64__) || defined(__aarch64__) |
| 2106 | +static int altinstructions_group_size(struct kpatch_elf *kelf, int offset) |
2071 | 2107 | {
|
2072 | 2108 | static int size = 0;
|
2073 | 2109 | char *str;
|
2074 | 2110 |
|
2075 | 2111 | if (!size) {
|
2076 |
| - str = getenv("STATIC_CALL_STRUCT_SIZE"); |
| 2112 | + str = getenv("ALT_STRUCT_SIZE"); |
2077 | 2113 | if (!str)
|
2078 |
| - ERROR("STATIC_CALL_STRUCT_SIZE not set"); |
| 2114 | + ERROR("ALT_STRUCT_SIZE not set"); |
2079 | 2115 | size = atoi(str);
|
2080 | 2116 | }
|
2081 | 2117 |
|
@@ -2189,15 +2225,17 @@ static struct special_section special_sections[] = {
|
2189 | 2225 | .name = ".parainstructions",
|
2190 | 2226 | .group_size = parainstructions_group_size,
|
2191 | 2227 | },
|
2192 |
| - { |
2193 |
| - .name = ".altinstructions", |
2194 |
| - .group_size = altinstructions_group_size, |
2195 |
| - }, |
2196 | 2228 | {
|
2197 | 2229 | .name = ".static_call_sites",
|
2198 | 2230 | .group_size = static_call_sites_group_size,
|
2199 | 2231 | },
|
2200 | 2232 | #endif
|
| 2233 | +#if defined(__x86_64__) || defined(__aarch64__) |
| 2234 | + { |
| 2235 | + .name = ".altinstructions", |
| 2236 | + .group_size = altinstructions_group_size, |
| 2237 | + }, |
| 2238 | +#endif |
2201 | 2239 | #ifdef __powerpc64__
|
2202 | 2240 | {
|
2203 | 2241 | .name = "__ftr_fixup",
|
|
0 commit comments