Extend lowering to support POT-indirect address computation.
All calls between different bins (executable segments) must be lowered using
page offset table (POT) indirect address computation when pagerando is
enabled. This patch adds support to AArch64IselLowering to support this
indirection. The AArch64PagerandoOptimizer pass then optimizes intra-bin calls
back to direct calls, since references within the same bin are guaranteeed to
have a fixed PC-relative offset.
For example, the direct call to foo:
BL <ga:@foo>
will be selected as the following, assuming foo is placed in a randomly located
bin:
%vreg1 = LOADpot %X20, <ga:@foo> %vreg2 = MOVaddrBIN %vreg1, <ga:@foo> BLR %vreg2
LOADpot is a pseudo-instruction that is lowered to a load of the POT entry for
the bin containing foo, and MOVaddrBIN is a pseudo-instruction that is lowered
to add the immediate relative offset of foo inside its bin to the base address
of the bin.
Inside pagerando bins, global addresses not in the GOT are computed with
approximately the following instruction sequence:
%vreg1 = LOADpot %X20, 0 %vreg2 = MOVaddrEXT <es:_GLOBAL_OFFSET_TABLE_> %vreg3 = MOVaddr <ga:@global> %vreg4 = SUBSXrr %vreg3, %vreg2 %vreg5 = ADDXrr %vreg1, %vreg4
This sequence computes the relative offset of the global from the GOT and adds
this static value to the dynamic GOT address loaded from the first POT
slot. After this sequence, %vreg5 contains the dynamic address of @global. The
subtraction in this sequence avoids the need for a new static relocation,
however if we can create a new GOT-relative relocation this sequence becomes
much simpler.
Global addresses found in the GOT are loaded in the conventional way, once the
GOT address is loaded from the first POT entry.
This patch set (D37580, D37581, D37582, D37583, D37584, D37585, D37586, D37587)
is a first draft of the pagerando implementation described in
http://lists.llvm.org/pipermail/llvm-dev/2017-June/113794.html.