The AMD64/EM64T Port of Dyninst and Paradyn

Download Report

Transcript The AMD64/EM64T Port of Dyninst and Paradyn

The AMD64/EM64T Port of
Dyninst and Paradyn
Greg Quinn
[email protected]
Ray Chen
[email protected]
March 17, 2005
AMD64/EM64T – Dyninst & Paradyn
Goals
• 64-bit Dyninst library and Paradyn daemon
that handle both 32-bit and 64-bit
mutatees
• Leverage as much existing functionality as
possible
-2-
AMD64/EM64T – Dyninst & Paradyn
Talk Outline
• 32-Bit Compatibility
• 64-Bit Mode
– Architectural Overview
– Issues for Dyninst
• Current status and timeline for the port
-3-
AMD64/EM64T – Dyninst & Paradyn
32-Bit Compatibility
March 17, 2005
AMD64/EM64T – Dyninst & Paradyn
Problematic Porting
• Conceptually simple
–
–
–
–
ISA extension
Hardware compatibility
Pre-existing code base
Nightly regression tests
-5-
AMD64/EM64T – Dyninst & Paradyn
System Structures
• What’s wrong with this code?
struct link_map {
/* Base address shared object is loaded at.*/
ElfW(Addr) l_addr;
/* Absolute file name object was found in.*/
char *l_name;
/* Dynamic section of the shared object.*/
ElfW(Dyn) *l_ld;
/* Chain of loaded objects. */
struct link_map *l_next, *l_prev;
};
-6-
AMD64/EM64T – Dyninst & Paradyn
System Structures
#define ElfW(type) \
Elf ## __ELF_NATIVE_CLASS ## type
• Compile-time decisions unacceptable
• Structure size depends on target platform
– X86: sizeof( ElfW(Addr) ) == 4
– X86_64: sizeof( ElfW(Addr) ) == 8
• Similar problem with pointer data types
-7-
AMD64/EM64T – Dyninst & Paradyn
System Structures
• No backwards compatible structure
– Must create and maintain our own
struct link_map_dyn32 {
Elf32_Addr l_addr;
uint32_t l_name;
uint32_t l_ld;
uint32_t l_next, l_prev;
};
• Multiple structures affected
– link_map, r_debug, libelf routines
-8-
AMD64/EM64T – Dyninst & Paradyn
System Structures
• Class based solution
– Hierarchy with 32-bit and 64-bit siblings
– Virtual functions instead of control structures
• Multiple benefits
– No code duplication
– Less source clutter
– Minor function call overhead
-9-
AMD64/EM64T – Dyninst & Paradyn
What Works?
• Operation on 32-bit binaries at 95%
– Passes most nightly regression tests
• Tests 1-12, attach, relocate
– Save the World not fully tested
• Existing x86 shared library issue
-10-
AMD64/EM64T – Dyninst & Paradyn
64-Bit Mode
Architectural Overview
March 17, 2005
AMD64/EM64T – Dyninst & Paradyn
Registers
EAX
EBX
ECX
EDX
EBP
ESP
EDI
ESI
• 32-bit Mode:
– Eight 32-bit registers
-12-
AMD64/EM64T – Dyninst & Paradyn
Registers
RAX
RBX
RCX
RDX
RBP
RSP
RDI
RSI
• 32-bit Mode:
– Eight 32-bit registers
• 64-bit Mode:
– Registers extended to
64 bits
-13-
AMD64/EM64T – Dyninst & Paradyn
Registers
RAX
RBX
RCX
RDX
RBP
RSP
RDI
RSI
R8
R9
R10
R11
R12
R13
R14
R15
• 32-bit Mode:
– Eight 32-bit registers
• 64-bit Mode:
– Registers extended to
64 bits
– Eight additional
registers
-14-
AMD64/EM64T – Dyninst & Paradyn
Registers
• Encoded using REX prefix:
0100
WR X B
Determines
Width of
Operation (32/64)
Serve as High
Order Bits for
Register Numbers
-15-
AMD64/EM64T – Dyninst & Paradyn
Immediate Values
• Variable-length instructions allow for
register-sized immediates (8 bytes)
– MOV
RAX,
0x1234567890abcdef
• This is the only way to specify an 8-byte
value in an instruction
• Most importantly for Dyninst:
– there is no JMP w/ 8-byte displacement
-16-
AMD64/EM64T – Dyninst & Paradyn
Handling 64-Bit Mutatees
March 17, 2005
AMD64/EM64T – Dyninst & Paradyn
Instruction Parsing
• x86 instruction parser collects basic block
information and searches for
instrumentation points
• We can use the same parsing algorithm for
64-bit mutatees
– Architectural changes are abstracted away by
instruction decoding
– Bonus: support for stripped binaries
-18-
AMD64/EM64T – Dyninst & Paradyn
Executing Instrumentation
• Dyninst maintains a heap
of non-contiguous memory
areas in the mutatee
• Instrumentation points
jump to code in nearby
heap region
• Code for this already
exists (AIX, Solaris)
-19-
Mutatee Address Space
executable
library code
AMD64/EM64T – Dyninst & Paradyn
Executing Instrumentation
• Dyninst maintains a heap
of non-contiguous memory
areas in the mutatee
• Instrumentation points
jump to code in nearby
heap region
• Code for this already
exists (AIX, Solaris)
-20-
Mutatee Address Space
executable
dyninst heap region
library code
AMD64/EM64T – Dyninst & Paradyn
Executing Instrumentation
• Dyninst maintains a heap
of non-contiguous memory
areas in the mutatee
• Instrumentation points
jump to code in nearby
heap region
• Code for this already
exists (AIX, Solaris)
-21-
Mutatee Address Space
executable
dyninst heap region
>> 4GB spacing
library code
AMD64/EM64T – Dyninst & Paradyn
Executing Instrumentation
• Dyninst maintains a heap
of non-contiguous memory
areas in the mutatee
• Instrumentation points
jump to code in nearby
heap region
• Code for this already
exists (AIX, Solaris)
Mutatee Address Space
executable
dyninst heap region
>> 4GB spacing
library code
dyninst heap region
-22-
AMD64/EM64T – Dyninst & Paradyn
Code Generation
• Improved architecture allows for more
efficient code generation
– Stack no longer used for passing arguments
– More registers means stack no longer needed
for temporary values
-23-
AMD64/EM64T – Dyninst & Paradyn
Good Things™
• We have been able to leverage x86 port
extensively (code reuse)
• Some 32-bit headaches go away
– Non-standard optimizations in mutatee code
(_dl_open example)
• More registers allow for more efficient
instrumentation code
-24-
AMD64/EM64T – Dyninst & Paradyn
Status/Timeline
• Now working:
– 32-bit support
– Instruction decoding, parsing
• Left to do:
– Code generation
– Memory allocation
– Counter, timers, and sampling code for Paradyn
• Beta release: 2Q05
– Available for partners and friends
• Production release: 3Q05
-25-
AMD64/EM64T – Dyninst & Paradyn
Questions?
-26-
AMD64/EM64T – Dyninst & Paradyn