• Kees Cook's avatar
    arm64/efi: Move variable assignments after SECTIONS · 90776dd1
    Kees Cook authored
    It seems that LLVM's linker does not correctly handle variable assignments
    involving section positions that are updated during the SECTIONS
    parsing. Commit aa69fb62 ("arm64/efi: Mark __efistub_stext_offset as
    an absolute symbol explicitly") ran into this too, but found a different
    workaround.
    
    However, this was not enough, as other variables were also miscalculated
    which manifested as boot failures under UEFI where __efistub__end was
    not taking the correct _end value (they should be the same):
    
    $ ld.lld -EL -maarch64elf --no-undefined -X -shared \
    	-Bsymbolic -z notext -z norelro --no-apply-dynamic-relocs \
    	-o vmlinux.lld -T poc.lds --whole-archive vmlinux.o && \
      readelf -Ws vmlinux.lld | egrep '\b(__efistub_|)_end\b'
    368272: ffff000002218000     0 NOTYPE  LOCAL  HIDDEN    38 __efistub__end
    368322: ffff000012318000     0 NOTYPE  GLOBAL DEFAULT   38 _end
    
    $ aarch64-linux-gnu-ld.bfd -EL -maarch64elf --no-undefined -X -shared \
    	-Bsymbolic -z notext -z norelro --no-apply-dynamic-relocs \
    	-o vmlinux.bfd -T poc.lds --whole-archive vmlinux.o && \
      readelf -Ws vmlinux.bfd | egrep '\b(__efistub_|)_end\b'
    338124: ffff000012318000     0 NOTYPE  LOCAL  DEFAULT  ABS __efistub__end
    383812: ffff000012318000     0 NOTYPE  GLOBAL DEFAULT 15325 _end
    
    To work around this, all of the __efistub_-prefixed variable assignments
    need to be moved after the linker script's SECTIONS entry. As it turns
    out, this also solves the problem fixed in commit aa69fb62, so those
    changes are reverted here.
    
    Link: https://github.com/ClangBuiltLinux/linux/issues/634
    Link: https://bugs.llvm.org/show_bug.cgi?id=42990Acked-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
    Signed-off-by: default avatarKees Cook <keescook@chromium.org>
    Signed-off-by: default avatarWill Deacon <will@kernel.org>
    90776dd1
image-vars.h 1.55 KB