This is an archive of the discontinued LLVM Phabricator instance.

Add AArch64 backend support for pagerando
Needs ReviewPublic

Authored by rinon on Sep 7 2017, 12:24 PM.

Details

Reviewers
javed.absar
Summary

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.

Diff Detail

Event Timeline

rinon created this revision.Sep 7 2017, 12:24 PM
rinon updated this revision to Diff 114745.Sep 11 2017, 6:29 PM
  • Fix style nits
rinon updated this revision to Diff 118518.Oct 10 2017, 5:49 PM
  • Rebase
  • Handle function aliases when checking for pagerando targets

Function aliases should be treated as functions to determine if the target is in
a pagerando bin.

rinon updated this revision to Diff 123119.Nov 15 2017, 5:55 PM

Fix external symbol references from pagerando code.

Calls to external symbols from pagerando code need to go through the GOT, so we
force this in getPOT().

rinon edited the summary of this revision. (Show Details)Jan 22 2018, 7:13 PM
rinon updated this revision to Diff 140719.Apr 2 2018, 5:44 PM
  • Don't tailcall from non-pagerando to pagerando functions
  • Rebase
hintonda removed a subscriber: hintonda.Apr 4 2018, 4:38 PM
rinon updated this revision to Diff 156646.Jul 20 2018, 5:02 PM

Rebase

  • Update AArch64 tests
  • Fix OpFlags checks for new packed OpFlags
  • Correctly handle null Callee in FastISel
rinon updated this revision to Diff 167017.Sep 25 2018, 3:37 PM
  • Fix AArch64 TargetFlags to accomodate MO_COFFSTUB along with pagerando flags
  • Rebase