From 98fbb766d618386eb2d7638b23365890bfde1491 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Thu, 3 Dec 2020 10:22:18 +0300 Subject: [PATCH] compel/handle-elf: override unexpected precalculated addresses We've seen addresses in parasite.built-in.o precalculated by linker but in some unexpected manner: readelf -WS criu/pie/parasite.built-in.o Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 1] .text PROGBITS 0000000000000000 000040 00400a 00 AX 0 0 16 [87] .data PROGBITS 0000000000000000 005000 000068 00 WA 0 0 4096 [88] .rodata PROGBITS 0000000000000080 005080 001016 00 A 0 0 32 (Notes: All other sections does not have SHF_ALLOC or are of size 0, so I skip them. Need to add "-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1" to CFLAGS to reproduce.) Section 88 has address 0x80 in elf file but in our "consequent" addresses precalculation algorithm it should be at 0x5080: addr(.text) == 0x0 addr(.data) == 0x400a + (0x1000 - 0x400a % 0x1000) + 0x68 == 0x5068 addr(.rodata) == 0x5068 + (0x20 - 0x5068 % 0x20) == 0x5080 Probably the linker advises us to move 4096 aligned section to the beginning to save some space, but it's just a guess. So probably we should be ready to "non-consequent" alignments precalculated and just override them. https://github.com/checkpoint-restore/criu/issues/1301 Signed-off-by: Pavel Tikhomirov --- compel/src/lib/handle-elf.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compel/src/lib/handle-elf.c b/compel/src/lib/handle-elf.c index e505f2c43..2d643ce43 100644 --- a/compel/src/lib/handle-elf.c +++ b/compel/src/lib/handle-elf.c @@ -212,13 +212,11 @@ int __handle_elf(void *mem, size_t size) if (sh->sh_addralign > 0 && k % sh->sh_addralign != 0) { k += sh->sh_addralign - k % sh->sh_addralign; } - if (sh->sh_addr && sh->sh_addr != k) { - pr_err("Unexpected precalculated address of section (section %s addr 0x%lx expected 0x%lx)\n", - &secstrings[sh->sh_name], - (unsigned long) sh->sh_addr, - (unsigned long) k); - goto err; - } + if (sh->sh_addr && sh->sh_addr != k) + pr_info("Overriding unexpected precalculated address of section (section %s addr 0x%lx expected 0x%lx)\n", + &secstrings[sh->sh_name], + (unsigned long) sh->sh_addr, + (unsigned long) k); sh->sh_addr = k; k += sh->sh_size; }