Support more than one RW PT_LOAD (LLD's default layout )
LLD enables -z relro by default. Since https://reviews.llvm.org/D58892 , LLD switches to R RX RW(relro) RW(non-relro).
bcov currently crashes when patching an LLD linked executable due to:
DCHECK(regions[ElfModule::Impl::kDataRegionIdx].size() >
regions[ElfModule::Impl::kRelRoRegionIdx].size());
A larger issue is that kDataRegionIdx and its friends assume a particular layout of program headers. It'd be nice to not assume a particular layout.
I'd recommend testing the following 4 layouts for good platform portability:
-fuse-ld=bfd -z noseparate-code(traditional layout)-fuse-ld=bfd -z separate-code(default on Linux x86 since binutils 2.31 2018-02-27 commit "ld: Add --enable-separate-code" made -z separate-code the default on Linux.")-fuse-ld=lld -z noseparate-code(default since LLD 10.0.0 https://reviews.llvm.org/D67482)-fuse-ld=lld -z separate-code(older LLD layout)
Many binutils packages default to -z relro now. It'd be good to test -z norelro as well.
Thanks for reporting this!
The function build_loadable_segments tries to identify the (rough) layout of the sections .text, .data, and .got without resorting to section headers. I was aiming for more generality here by relying on the program headers only. Note that these sections are typically not stripped, but it would still be nicer to do without them. However, this goal has caused this function to be fragile. I will come back to this later.
The recent commit should fix this issue, at least partially. In an ELF module, we still expect only one data segment (PT_LOAD RW) and one code segment (PT_LOAD RX). However, loading segments is more robust now as the layout does not depend on compile-time constants anymore. Also, we no longer assume that the GNU_RELRO segment is located at the start of the data segment. Unlike ld, LLD seems to place GNU_RELRO somewhere inside the data segment.