more flexible 64-bit reachability: separate DR lib + heap, auto-magic client opnds
From bruen...@google.com on May 16, 2012 12:58:33
the lib vs heap portion was PR 286713
the current requirement that everything fit in the low 2GB was always meant to be a temporary solution. we've seen some apps with 2GB executables which if placed in the low 2GB can really limit the space for DR.
we've already made our native_exec hooks independent of low-2GB (but not hotp/gbop hooks IIRC: that was PR 250294)
some major usability features we gained from low-2GB include:
- the client can refer directly to vars in its lib via abs addr to &var
- co-locating everything in low 2GB makes code cache able to reach client lib via direct jmp/call
we want to keep those features while loosening restrictions elsewhere.
should identify all the components (DR lib, client libs, priv libs, DR heap, client heap, code cache, gencode) and relax reachability between as many as possible
issues:
- do we support code cache itself being larger than 2GB? => punt for later: for now sticking w/ direct-jmp-reachable to any location in the cache + stubs + DR gencode + client lib
- do we give up OPND_CREATE_ABSMEM(&var) and allow cache to float? => we use rip-rel to refer to &var
- instr address as stored target for return from lean procedure: can support 64-bit if put 8-byte immed in register first but that complicates instru b/c of spill => 2-instr mem write
issues listed under PR 253624:
- we need a way to get the DR shared library bounds before heap init ditto for the client lib bounds
- we need to implement os_heap_reserve_in_region()
here is the proposal we came up with, which includes a number of todo items that for now will all be considered part of this issue:
- reachability guaranteed:
- client lib reachable from code cache for jmp/call to routine
- client &var reachable but only via rip-rel ref
- client gencode/heap optionally reachable (=> flag) from code cache
- separate stubs reachable from code cache
- DR gencode reachable from code cache and from stubs
- no reachability guarantees:
- DR lib => extra overhead on selfmod s2ro counters and indirect jumps in fcache_{enter,return}
- DR heap
- private libs imported by client
- client gencode/heap if not specified
- client + cache + stubs + DR gencode are co-located but are NOT required to be low 2GB (but may want near app to reduce # of pc-rel manglings for app's refs?)
- add "bool reachable_from_cache" to dr_thread_alloc() and dr_global_alloc() and dr_nonheap_alloc() so client can choose whether its heap and gencode are also co-located w/ client lib + cache.
- opnd_create_abs_addr() => automagically turns into opnd_create_rel_addr() so client has portable (across 32-bit and 64-bit) code to refer to &var. document that the rare client who really does want to refer to absolute low addr can ignore the unreachable assert or use opnd_create_base_disp()
- mov/push w/ opnd_t as operand is automagically turned into a 2-instruction sequence that moves/pushes an 8-byte immed
- for 64-bit multi-shared-lib reachability, our private loader should take care to load all client + extension libs such that they can reach cache+stubs
this will solve:
- issue #719 (closed): DR can't satisfy reachability on Linux x64 for binaries built with -fPIE -pie
- conflicts in preferred base among multiple clients and/or extensions
- DR can't run large apps that occupy too much of low 2GB
xref:
- issue #719 (closed): DR can't satisfy reachability on Linux x64 for binaries built with -fPIE -pie
- [[file:~/notes/dr/64-bit.gpg::*PR%20253624%20Linux%20x64%20pc%20relative%20jump%20reachability][DONE PR 253624: {Linux} {x64} pc-relative jump reachability]]
- issue #326 (closed): handle zero %gs on 64-bit linux when msr and not gdt is used
- PR 215395: [x64] pc-relative jump reachability
- think about: jmp-to-stub, jmp-from-stub, and jmp-from-gen-routine
- if not reachable need to restore reg on other side or have security hole by jumping through memory
- hooks on native libs are primary concern => but isn't PR 245169 marked done?
- parent can best control where DR.dll is
- TODO PR 250294: [x64] general hook support on x64 for GBOP, hot patches, and probes
- DONE PR 245169: [x64] update native_exec_syscalls and Ki hooks for x64
- TODO issue #630 (closed): if dynamorio base conflicts w/ app or before-DR library base => fatal reachability problem
- DONE issue #592 (closed): 64-bit library bases for reachability: fixed by private loader?
- TODO: look at hooking tools for x64: xref PR 211760/7316
- PR 233721: [x64] rip-relative reachability for clients
- TODO PR 233721: more robust 64-bit client reachability
- TODO PR 286713: [x64] make DR library location independent of DR heap location /* For 64-bit linux we can't use a fixed base since our library * might be loaded anywhere. For now we just hope to find * enough free space at this random offset from it. * Probably the best long-term solution is to make our heap * and library not need to reach each other, which should only * require indirect jumps in fcache_{enter,return}. Selfmod * s2ro isn't perf-critical. Client library callees and data * should ideally be close to the heap though. * Xref PR 253624. */ xref -heap_in_lower_4GB
Original issue: http://code.google.com/p/dynamorio/issues/detail?id=774