|
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,22 @@ static struct rela *toc_rela(const struct rela *rela) |
214 | 216 | (unsigned int)rela->addend); |
215 | 217 | } |
216 | 218 |
|
| 219 | +#ifdef __aarch64__ |
| 220 | +static int kpatch_is_mapping_symbol(struct symbol *sym) |
| 221 | +{ |
| 222 | + if (sym->name && sym->name[0] == '$' |
| 223 | + && sym->type == STT_NOTYPE \ |
| 224 | + && sym->bind == STB_LOCAL) |
| 225 | + return 1; |
| 226 | + return 0; |
| 227 | +} |
| 228 | +#else |
| 229 | +static int kpatch_is_mapping_symbol(struct symbol *sym) |
| 230 | +{ |
| 231 | + return 0; |
| 232 | +} |
| 233 | +#endif |
| 234 | + |
217 | 235 | /* |
218 | 236 | * When compiling with -ffunction-sections and -fdata-sections, almost every |
219 | 237 | * symbol gets its own dedicated section. We call such symbols "bundled" |
@@ -563,6 +581,13 @@ static void kpatch_compare_correlated_section(struct section *sec) |
563 | 581 | goto out; |
564 | 582 | } |
565 | 583 |
|
| 584 | + /* As above but for aarch64 */ |
| 585 | + if (!strcmp(sec->name, ".rela__patchable_function_entries") || |
| 586 | + !strcmp(sec->name, "__patchable_function_entries")) { |
| 587 | + sec->status = SAME; |
| 588 | + goto out; |
| 589 | + } |
| 590 | + |
566 | 591 | if (sec1->sh.sh_size != sec2->sh.sh_size || |
567 | 592 | sec1->data->d_size != sec2->data->d_size) { |
568 | 593 | sec->status = CHANGED; |
@@ -1027,6 +1052,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist_orig, |
1027 | 1052 | !strncmp(sym_orig->name, ".LC", 3)) |
1028 | 1053 | continue; |
1029 | 1054 |
|
| 1055 | + if (kpatch_is_mapping_symbol(sym_orig)) |
| 1056 | + continue; |
| 1057 | + |
1030 | 1058 | /* group section symbols must have correlated sections */ |
1031 | 1059 | if (sym_orig->sec && |
1032 | 1060 | sym_orig->sec->sh.sh_type == SHT_GROUP && |
@@ -1536,7 +1564,7 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) |
1536 | 1564 | continue; |
1537 | 1565 | } |
1538 | 1566 |
|
1539 | | -#ifdef __powerpc64__ |
| 1567 | +#if defined(__powerpc64__) || defined(__aarch64__) |
1540 | 1568 | add_off = 0; |
1541 | 1569 | #else |
1542 | 1570 | if (rela->type == R_X86_64_PC32 || |
@@ -1568,7 +1596,11 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) |
1568 | 1596 | end = sym->sym.st_value + sym->sym.st_size; |
1569 | 1597 |
|
1570 | 1598 | if (!is_text_section(sym->sec) && |
| 1599 | +#ifdef __x86_64__ |
1571 | 1600 | rela->type == R_X86_64_32S && |
| 1601 | +#elif defined(__aarch64__) |
| 1602 | + rela->type == R_AARCH64_ABS64 && |
| 1603 | +#endif |
1572 | 1604 | rela->addend == (long)sym->sec->sh.sh_size && |
1573 | 1605 | end == (long)sym->sec->sh.sh_size) { |
1574 | 1606 |
|
@@ -2073,35 +2105,36 @@ static int parainstructions_group_size(struct kpatch_elf *kelf, int offset) |
2073 | 2105 | return size; |
2074 | 2106 | } |
2075 | 2107 |
|
2076 | | -static int altinstructions_group_size(struct kpatch_elf *kelf, int offset) |
| 2108 | +static int smp_locks_group_size(struct kpatch_elf *kelf, int offset) |
| 2109 | +{ |
| 2110 | + return 4; |
| 2111 | +} |
| 2112 | + |
| 2113 | +static int static_call_sites_group_size(struct kpatch_elf *kelf, int offset) |
2077 | 2114 | { |
2078 | 2115 | static int size = 0; |
2079 | 2116 | char *str; |
2080 | 2117 |
|
2081 | 2118 | if (!size) { |
2082 | | - str = getenv("ALT_STRUCT_SIZE"); |
| 2119 | + str = getenv("STATIC_CALL_STRUCT_SIZE"); |
2083 | 2120 | if (!str) |
2084 | | - ERROR("ALT_STRUCT_SIZE not set"); |
| 2121 | + ERROR("STATIC_CALL_STRUCT_SIZE not set"); |
2085 | 2122 | size = atoi(str); |
2086 | 2123 | } |
2087 | 2124 |
|
2088 | 2125 | return size; |
2089 | 2126 | } |
2090 | | - |
2091 | | -static int smp_locks_group_size(struct kpatch_elf *kelf, int offset) |
2092 | | -{ |
2093 | | - return 4; |
2094 | | -} |
2095 | | - |
2096 | | -static int static_call_sites_group_size(struct kpatch_elf *kelf, int offset) |
| 2127 | +#endif |
| 2128 | +#if defined(__x86_64__) || defined(__aarch64__) |
| 2129 | +static int altinstructions_group_size(struct kpatch_elf *kelf, int offset) |
2097 | 2130 | { |
2098 | 2131 | static int size = 0; |
2099 | 2132 | char *str; |
2100 | 2133 |
|
2101 | 2134 | if (!size) { |
2102 | | - str = getenv("STATIC_CALL_STRUCT_SIZE"); |
| 2135 | + str = getenv("ALT_STRUCT_SIZE"); |
2103 | 2136 | if (!str) |
2104 | | - ERROR("STATIC_CALL_STRUCT_SIZE not set"); |
| 2137 | + ERROR("ALT_STRUCT_SIZE not set"); |
2105 | 2138 | size = atoi(str); |
2106 | 2139 | } |
2107 | 2140 |
|
@@ -2215,15 +2248,17 @@ static struct special_section special_sections[] = { |
2215 | 2248 | .name = ".parainstructions", |
2216 | 2249 | .group_size = parainstructions_group_size, |
2217 | 2250 | }, |
2218 | | - { |
2219 | | - .name = ".altinstructions", |
2220 | | - .group_size = altinstructions_group_size, |
2221 | | - }, |
2222 | 2251 | { |
2223 | 2252 | .name = ".static_call_sites", |
2224 | 2253 | .group_size = static_call_sites_group_size, |
2225 | 2254 | }, |
2226 | 2255 | #endif |
| 2256 | +#if defined(__x86_64__) || defined(__aarch64__) |
| 2257 | + { |
| 2258 | + .name = ".altinstructions", |
| 2259 | + .group_size = altinstructions_group_size, |
| 2260 | + }, |
| 2261 | +#endif |
2227 | 2262 | #ifdef __powerpc64__ |
2228 | 2263 | { |
2229 | 2264 | .name = "__ftr_fixup", |
|
0 commit comments