[llvm-bugs] [Bug 43214] New: relr and overlapping segments not generally converging in AArch64 in thunk creation loop

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Sep 3 15:49:57 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=43214

            Bug ID: 43214
           Summary: relr and overlapping segments not generally converging
                    in AArch64 in thunk creation loop
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: jakehehrlich at google.com
                CC: llvm-bugs at lists.llvm.org, peter.smith at linaro.org

We recently found a bug in lld that infrequently occurs in the Fuchsia AArch64
build. We've only seen it occur once in the wild but after debugging what was
going on we figured out what the cause of the issue was. The issue involves
relr, https://reviews.llvm.org/D64930, and the thunk creation loop for AArch64.
The bug presents as an infinite loop in recent versions and as a lack of
convergence in slightly older versions  (which is behavior you need to know
about to bisect to D64930). The behavior changed to an infinite loop in
https://reviews.llvm.org/D66279

What's happening is that the size of relr is ping ponging between two different
sizes
here(https://github.com/llvm-mirror/lld/blob/master/ELF/Writer.cpp#L1564). This
causes `changed` to always be true by the end of this loop and consequently we
never exit the loop (the error never triggers because at the start changed is
false). This ping ponging occurs because the size of the relro segment is
*very* close to being paged aligned. When relr are is small the relro segment
winds up ending at address 0x9ffe8. Because of the overlapping segments change
above this causes the data segment to start at address 0xafff0. On the next
iteration of the loop when relr is updated it has to include this address jump
this causes relr to grow by 8 bytes which in turn causes the relro segment to
end at 0xefff8. This causes the data segment to wind up at 0xa0000 which is
0xfff0 bytes earilier. On the next iteration of the loop relr goes back to its
original state because there is no address jump required because 0xa0000 comes
right after 0xefff0. Being back in the same state

I haven't thought of a good solution to the general problem. Perhaps when
overlapping segments are enabled we should always bump the virtual address?
This is only suboptimal in 1 in 4000 cases which is quite rare. Another option
would be to add logic to make relr always take up the maximum space that it
occupies. This would ensure that relr is always within 8-bytes of its optimal
size. I don't have a solution that doesn't require some sub-optimal behavior to
occur so far.

Another possible direction: It isn't clear to me that the thunks for doing long
jumps on arm need to be added in a relaxation loop that updates structures
outside of a code segment. If the read only segment becomes larger that will
push all code together so relative jumps wouldn't change. This would let us
insert thunks inside of a loop and then to assign addresses and update all the
structures finally at the end. Given that this wasn't done however I assume I
might be misunderstanding something.

Using `-z seperate-code` fixes the issue but I haven't groked what that flag
does exactly but it seems to bring us closer to the old non-overlapping
behavior. I'm not sure if it just changes things in this case because the
boundary in question gets pushed to a different spot or if it's fundamentally
solving the problem here. In Fuchsia we want to use this flag anyway to ensure
that we never have any garbage in our executable pages and the disk/memory
trade off for us is such that we always prefer alignment bumps to wasted pages
in memory.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190903/051c05ac/attachment.html>


More information about the llvm-bugs mailing list