intel: add PIC variants to recipes and encodings

This commit is contained in:
Pat Hickey
2017-12-12 13:54:11 -08:00
committed by Jakob Stoklund Olesen
parent 5834520bfe
commit 6d44debc18
2 changed files with 48 additions and 6 deletions

View File

@@ -2,7 +2,7 @@
Intel Encodings. Intel Encodings.
""" """
from __future__ import absolute_import from __future__ import absolute_import
from cdsl.predicates import IsUnsignedInt, Not from cdsl.predicates import IsUnsignedInt, Not, And
from base import instructions as base from base import instructions as base
from base.formats import UnaryImm from base.formats import UnaryImm
from .defs import I32, I64 from .defs import I32, I64
@@ -11,7 +11,7 @@ from . import settings as cfg
from . import instructions as x86 from . import instructions as x86
from .legalize import intel_expand from .legalize import intel_expand
from base.legalize import narrow, expand from base.legalize import narrow, expand
from base.settings import allones_funcaddrs from base.settings import allones_funcaddrs, is_pic
from .settings import use_sse41 from .settings import use_sse41
try: try:
@@ -281,25 +281,33 @@ enc_both(base.regspill.f64, r.frsp32, 0x66, 0x0f, 0xd6)
I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8), I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8),
isap=Not(allones_funcaddrs)) isap=Not(allones_funcaddrs))
I64.enc(base.func_addr.i64, *r.fnaddr8.rex(0xb8, w=1), I64.enc(base.func_addr.i64, *r.fnaddr8.rex(0xb8, w=1),
isap=Not(allones_funcaddrs)) isap=And(Not(allones_funcaddrs), Not(is_pic)))
I32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8), I32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8),
isap=allones_funcaddrs) isap=allones_funcaddrs)
I64.enc(base.func_addr.i64, *r.allones_fnaddr8.rex(0xb8, w=1), I64.enc(base.func_addr.i64, *r.allones_fnaddr8.rex(0xb8, w=1),
isap=allones_funcaddrs) isap=And(allones_funcaddrs, Not(is_pic)))
I64.enc(base.func_addr.i64, *r.got_fnaddr8.rex(0x8b, w=1),
isap=is_pic)
# #
# Global addresses. # Global addresses.
# #
I32.enc(base.globalsym_addr.i32, *r.gvaddr4(0xb8)) I32.enc(base.globalsym_addr.i32, *r.gvaddr4(0xb8))
I64.enc(base.globalsym_addr.i64, *r.gvaddr8.rex(0xb8, w=1)) I64.enc(base.globalsym_addr.i64, *r.gvaddr8.rex(0xb8, w=1),
isap=Not(is_pic))
I64.enc(base.globalsym_addr.i64, *r.got_gvaddr8.rex(0x8b, w=1),
isap=is_pic)
# #
# Call/return # Call/return
# #
I32.enc(base.call, *r.call_id(0xe8)) I32.enc(base.call, *r.call_id(0xe8))
I64.enc(base.call, *r.call_id(0xe8)) I64.enc(base.call, *r.call_id(0xe8), isap=Not(is_pic))
I64.enc(base.call, *r.call_plt_id(0xe8), isap=is_pic)
I32.enc(base.call_indirect.i32, *r.call_r(0xff, rrr=2)) I32.enc(base.call_indirect.i32, *r.call_r(0xff, rrr=2))
I64.enc(base.call_indirect.i64, *r.call_r.rex(0xff, rrr=2)) I64.enc(base.call_indirect.i64, *r.call_r.rex(0xff, rrr=2))

View File

@@ -558,6 +558,19 @@ allones_fnaddr8 = TailRecipe(
sink.put8(!0); sink.put8(!0);
''') ''')
got_fnaddr8 = TailRecipe(
'got_fnaddr8', FuncAddr, size=5, ins=(), outs=GPR,
# rex2 is a hack at the moment to get one that sets the `r` bit in rex
# rm for modrm_rm is 5 to get RIP-relative addressing
emit='''
PUT_OP(bits, rex2(0, out_reg0), sink);
modrm_rm(5, out_reg0, sink);
sink.reloc_external(Reloc::IntelGotPCRel4,
&func.dfg.ext_funcs[func_ref].name);
sink.put4(0);
''')
# XX+rd id with Abs4 globalsym relocation. # XX+rd id with Abs4 globalsym relocation.
gvaddr4 = TailRecipe( gvaddr4 = TailRecipe(
'gvaddr4', UnaryGlobalVar, size=4, ins=(), outs=GPR, 'gvaddr4', UnaryGlobalVar, size=4, ins=(), outs=GPR,
@@ -578,6 +591,18 @@ gvaddr8 = TailRecipe(
sink.put8(0); sink.put8(0);
''') ''')
# XX+rd iq with Abs8 globalsym relocation.
got_gvaddr8 = TailRecipe(
'got_gvaddr8', UnaryGlobalVar, size=5, ins=(), outs=GPR,
emit='''
PUT_OP(bits, rex2(0, out_reg0), sink);
modrm_rm(5, out_reg0, sink);
sink.reloc_external(Reloc::IntelGotPCRel4,
&func.global_vars[global_var].symbol_name());
sink.put4(0);
''')
# #
# Store recipes. # Store recipes.
# #
@@ -853,6 +878,15 @@ call_id = TailRecipe(
sink.put4(0); sink.put4(0);
''') ''')
call_plt_id = TailRecipe(
'call_plt_id', Call, size=4, ins=(), outs=(),
emit='''
PUT_OP(bits, BASE_REX, sink);
sink.reloc_external(Reloc::IntelPLTRel4,
&func.dfg.ext_funcs[func_ref].name);
sink.put4(0);
''')
call_r = TailRecipe( call_r = TailRecipe(
'call_r', IndirectCall, size=1, ins=GPR, outs=(), 'call_r', IndirectCall, size=1, ins=GPR, outs=(),
emit=''' emit='''