Skip to content

Commit a2e500d

Browse files
committed
create-diff-object: Add support for arm64 DYNAMIC_FTRACE_WITH_CALL_OPS
For arm64 this option uses -fpatchable-function-entry=M,2, so 2 NOPs are placed before the function entry point (in order to store a pointer to ftrace_ops). When calculating function padding, check for the presence of the two NOPs, and adjust the padding size by 8 if they are found.
1 parent 3fb4582 commit a2e500d

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

kpatch-build/create-diff-object.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,36 @@ static bool kpatch_is_mapping_symbol(struct kpatch_elf *kelf, struct symbol *sym
250250
return false;
251251
}
252252

253+
static unsigned int function_padding_size(struct kpatch_elf *kelf, struct symbol *sym)
254+
{
255+
unsigned int size = 0;
256+
257+
switch (kelf->arch) {
258+
case AARCH64:
259+
{
260+
uint32_t *insn = sym->sec->data->d_buf;
261+
unsigned int i;
262+
void *insn_end = sym->sec->data->d_buf + sym->sym.st_value;
263+
264+
/*
265+
* Check for exactly two NOPs (0xd503201f), used to store a
266+
* pointer to ftrace call ops when DYNAMIC_FTRACE_WITH_CALL_OPS
267+
* is enbled.
268+
*/
269+
for (i = 0; (void *)insn < insn_end && *insn == 0xd503201f; i++, insn++)
270+
;
271+
272+
if (i == 2)
273+
size = 8;
274+
break;
275+
}
276+
default:
277+
break;
278+
}
279+
280+
return size;
281+
}
282+
253283
/*
254284
* When compiling with -ffunction-sections and -fdata-sections, almost every
255285
* symbol gets its own dedicated section. We call such symbols "bundled"
@@ -266,6 +296,8 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf)
266296
expected_offset = 16;
267297
else if (is_gcc6_localentry_bundled_sym(kelf, sym))
268298
expected_offset = 8;
299+
else if (sym->type == STT_FUNC)
300+
expected_offset = function_padding_size(kelf, sym);
269301
else
270302
expected_offset = 0;
271303

0 commit comments

Comments
 (0)