diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index edf56a357f..d385f882c6 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -300,9 +300,6 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) * and .shstrtab. For the non-relocate we allocate and copy these * via other means - and the .rel we can ignore as we only use it * once during loading. - * - * Also ignore sections with zero size. Those can be for example: - * data, or .bss. */ if ( livepatch_elf_ignore_section(elf->sec[i].sec) ) offset[i] = UINT_MAX; @@ -361,8 +358,17 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf) else if ( elf->sec[i].sec->sh_flags & SHF_WRITE ) { buf = rw_buf; - rw_buf_sec = i; - rw_buf_cnt++; + if ( elf->sec[i].sec->sh_size ) + { + /* + * Special handling of RW empty regions: do not account for + * them in order to decide whether a patch can safely be + * re-applied, but assign them a load address so symbol + * resolution and relocations work. + */ + rw_buf_sec = i; + rw_buf_cnt++; + } } else buf = ro_buf; diff --git a/xen/include/xen/livepatch_elf.h b/xen/include/xen/livepatch_elf.h index 9ad499ee8b..5b1ec469da 100644 --- a/xen/include/xen/livepatch_elf.h +++ b/xen/include/xen/livepatch_elf.h @@ -48,7 +48,7 @@ int livepatch_elf_perform_relocs(struct livepatch_elf *elf); static inline bool livepatch_elf_ignore_section(const Elf_Shdr *sec) { - return !(sec->sh_flags & SHF_ALLOC) || sec->sh_size == 0; + return !(sec->sh_flags & SHF_ALLOC); } #endif /* __XEN_LIVEPATCH_ELF_H__ */