Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 2c044806b0fef214ba05b8638843d093c08ab2c3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<head>
    <title>TCF Agent Porting Guide</title>
</head>

<body lang='EN-US'>

    <h1>TCF Agent Porting Guide</h1>

    <p>
        Copyright (c) 2009 Wind River Systems, Inc. Made available under the EPL v1.0
    </p>
    <p>
        Direct comments, questions to the <a href="https://dev.eclipse.org/mailman/listinfo/tcf-dev">tcf-dev@eclipse.org</a> mailing list
    </p>

    <h2>Table of Contents</h2>
    <ul>
        <li>
            <a href='#Introduction'>Introduction</a>
        </li>
        <li>
            <a href='#Customizing'>Customizing and Porting TCF Agent</a>
        </li>
        <li>
            <a href='#NewOS'>Porting TCF Agent to a New OS Platform</a>
        </li>
        <li>
            <a href='#NewCPU'>Porting TCF Agent to a New CPU Type</a>
        </li>
        <li>
            <a href='#NewExeFile'>Adding Support For a New Executable File Format</a>
        </li>
        <li>
            <a href='#NewDebugData'>Adding Support For a New Debug Data Format</a>
        </li>
        <li>
            <a href='#NewTransport'>Adding Support For a New Communication Trasport</a>
        </li>
    </ul>

    <h2>
        <a name='Introduction'>Introduction</a>
    </h2>

    <p>
        TCF Agent is a lightweight reference implementation of TCF protocol that supports basic debugging and other TCF services.
        It is written in C and can be used for remote debugging of software written for Linux, Windows XP or VxWorks.
        See <a href='TCF Getting Started.html'>TCF Getting Started</a> for instructions on how to get the source code and build the agent.
    </p>


    <h2>
        <a name='Customizing'>Customizing and Porting TCF Agent</a>
    </h2>

    <p>
        It is important to know concurrency model used by the agent code before making any changes.
        Most of the agent code is event driven: it has a main loop that retrieves events from an event queue and executes them sequentially by calling event handlers by a single thread.
        Single threaded event driven design provides good level of concurrency (equivalent to cooperative multithreading), while greatly reduces need for synchronization -
        each event dispatch cycle can be viewed as fully synchronized atomic operation.
    </p>

    <p>
        Event driven code should avoid long running or potentially blocking operations in event handlers since they can stop all event processing for indefinite time.
        Such operations should use asynchronous APIs (like POSIX Asynchronous I/O), or should be performed by background threads.
        Treat background threads with extreme caution - agent data structures are not intended for multithreaded access.
        Background thread scope should be limited to a single module and it should not call agent public APIs.
        Instead they should communicate with the rest of the code by posting events.
    </p>

    <p>
        An event is essentially a function pointer (a call-back) that points to event handler, plus a data pointer.
        Call-backs are also used throughout the agent code to subscribe listeners for various state change notifications.
        Using events and call-backs, as a design principle, is also known as inversion of control.
        Note that, in general, inversion of control is not compatible with traditional multithreaded programming model that used mutexes to protect shared data from racing conditions.
    </p>

    <p>
        Most of TCF agent configuration is done at compile time.
        Conditional compilation statements in the source code assume that both the agent and inferior code will run on same OS platform and
        on same CPU type that were used to build the agent.
        Building an agent that can run on one machine while controlling execution of code on another machine might be possible, but not fully supported at this time.
    </p>

    <p>
        Header file <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a> contains macro definitions that control agent configuration.
        All C files in the agent code include <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a> before other header files.
        Individual services or features can be enabled or disabled by changing definitions in the file.
        Also, macro values can be overwritten by using -D option in C compiler command line.
        Agent <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/Makefile'>Makefile</a> contains additional logic that makes it even more convenient to build different agent configurations.
    </p>

    <p>
        It should be much easier to port the agent if you don't need all TCF services.
        For example, for RSE integration you only need File System, System Monitor and Processes services,
        so you can disable all other services by editing <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a>.
    </p>

    <p>
        It is better to create a separate directory with alternative versions of
        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/config.h'>config.h</a>,
        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/context.h'>context.h,</a>
        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/context.c'>context.c,</a>
        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/Makefile'>Makefile,</a>
        etc., instead of editing original files.
        The idea is that Makefile will search that directory first, and if a file not found there, it will search original agent sources.
        See <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/examples/org.eclipse.tm.tcf.examples.daytime.agent'>examples/org.eclipse.tm.tcf.examples.daytime.agent</a>
        for an example of a custom TCF agent.
        Of course, if changes are generic enough to be useful for other ports, then it is better to change code in the main directory.
    </p>

    <p>
        Please, consider contributing your changes of the source code back to eclipse.org.
    </p>

    <h2>
        <a name='NewOS'>Porting TCF Agent to a New OS Platform</a>
    </h2>

    <p>
        In order to improve portability, instead of using non-portable native OS calls, agent code uses POSIX APIs whenever possible.
        When a POSIX API is not available for particular platform, and it can be easily emulated, it is done in mdep.h/mdep.c files.
        For example, mdep.h/mdep.c contains emulation of POSIX Threads for Win32, since the API is not available with Microsoft C compiler.
        API emulation does not have to be complete, it only needs to implement functionality that is used by the agent.
    </p>

    <p>
        When it is not possible or not feasible to use portable POSIX APIs, the agent code contains conditional compilation statements that
        use well known macros like WIN32, __CYGWIN__, __MINGW32__, etc. Such places might require editing when porting to a new OS.
    </p>

    <h2>
        <a name='NewCPU'>Porting TCF Agent to a New CPU Type</a>
    </h2>

    <p>
                Searching TCF agent source code for __i386__ is a good way to find all places where the source code depends on CPU type.
        </p>

        <p>
                There are several files in the code that might need changes in order to support a new CPU type:
        </p>

    <dl>
        <dt>
            <b>
                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/context.c'>context.c</a>
            </b>
        </dt>
        <dd>
            The module provides low level debugger functionality: attach/detach, suspend/resume, single step, memory read/write.
            It uses OS debug APIs to do its job. Most of the code does not depend on CPU type, however, single stepping is not always directly
            supported by OS, and its implementation needs to be reviewed and changed to support new CPU type.
        </dd>
        <dt>
            <b>
                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/dwarfexpr.c'>dwarfexpr.c</a>
            </b>
        </dt>
        <dd>
            The module implements evaluation of <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> expressions.
            The module is used only if the agent is built to support
            <a href='http://en.wikipedia.org/wiki/Executable_and_Linkable_Format'>ELF</a> executable file format and
            <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> debugging data format.
            No need to change the module if <a href='http://en.wikipedia.org/wiki/Executable_and_Linkable_Format'>ELF</a> or
            <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> support is not required.
            <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> expressions can have references to CPU registers.
            Register access code needs to be changed to support new CPU type.
            Note that different compilers can use different numbers to identify same registers of same CPU.
        </dd>
        <dt>
            <b>
                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/registers.c'>registers.c</a>
            </b>
        </dt>
        <dd>
            The module implements <a href='TCF Service - Registers.html'>Registers service</a>. The code has static variable "regs_index" that contains a table of CPU registers.
            The table holds names, offsets and sizes of CPU registers. Offset and size define location of register data in REG_SET structure,
            which represents snapshot of register values of an execution context. Definition of the variable needs to be changed to support new CPU type.
        </dd>
        <dt>
            <b>
                <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/stacktrace.c'>stacktrace.c</a>
            </b>
        </dt>
        <dd>
            The module implements <a href='TCF Service - Stack Trace.html'>Stack Trace service</a>.
            The module contains "trace_stack" function that creates stack trace by walking a stack of an executable context.
            Stack trace data format is defined by two struct declarations: StackTrace and StackFrame.
            The data structure is generic, however the code that created the data structure is CPU dependand.
            Alternative version of "trace_stack" function needs to be provided to support new CPU type.
        </dd>
    </dl>

    <h2>
        <a name='NewExeFile'>Adding Support For a New Executable File Format</a>
    </h2>

    <p>
        For source level debugging TCF agent needs to understand executable file format.
        Source level debugging is supported by providing two services: Symbols and Line Numbers.
        The services are optional, and if they are disabled no support for executable file format is needed.
        At this time the agent supports <a href='http://en.wikipedia.org/wiki/Executable_and_Linkable_Format'>ELF (Executable and Linking Format)</a>
        and <a href='http://en.wikipedia.org/wiki/Portable_Executable'>PE (Portable Executable)</a> files.
        ELF is very popular format in Unix-like and embedded systems, and PE is used in Windows operating systems.
    </p>

    <p>
        ELF supported in the agent is developed from scratch, has no external dependences, and is available in source form as part of the agent source code.
        The code might require changes to support a particular flavor of ELF.
        Probably the most tricky part of the code is interface to the system loader.
        The agent needs to know when an ELF file is loaded into or removed from target memory so it can update symbol tables and breakpoints.
        For that it plants an internal (not visible to clients) breakpoint (aka eventpoint) inside system loader code.
        The breakpoint allows agent to intercept control every time an ELF file is loaded or unloaded.
    </p>

    <p>
        PE support in the agent is implemented by using DBGHELP.DLL. This DLL is included in Windows operating system.
        However, older versions of the DLL might not provide all necessary functionality.
        To obtain the latest version of DBGHELP.DLL, go to <a href='http://www.microsoft.com/whdc/devtools/debugging/default.mspx'>
        http://www.microsoft.com/whdc/devtools/debugging/default.mspx</a> and download Debugging Tools for Windows.
    </p>

    <p>
        Support for a completely new file format would require to develop alternative versions of symbols_xxx.c and linenumbers_xxx.c files.
        See <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/symbols_elf.c'>symbols_elf.c</a>
        and <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/linenumbers_elf.c'>linenumbers_elf.c</a>
        as example implementation of the services.
    </p>

    <h2>
        <a name='NewDebugData'>Adding Support For a New Debug Data Format</a>
    </h2>

    <p>
        For source level debugging TCF agent needs to understand debug data format.
                Debug data is usually reside in a section of an executable file, so the file format should be supported, see <a href='#NewExeFile'>Adding Support For a New Executable File Format</a>.
                At this time the agent supports <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> and
                <a href='http://en.wikipedia.org/wiki/Portable_Executable'>PE (Portable Executable)</a> debug data formats.
                <a href='http://en.wikipedia.org/wiki/DWARF'>DWARF</a> support is implemented as part of the agent source code,
                and <a href='http://en.wikipedia.org/wiki/Portable_Executable'>PE</a> data is accessed using DBGHELP.DLL, which is included in Windows operating system.
    </p>

    <h2>
        <a name='NewTransport'>Adding Support For a New Communication Transport</a>
    </h2>

    <p>
        Current agent code uses TCP/IP as the transport protocol to open communication channels.
        The agent code can be easily modified to support other transport protocols, like UDP, USB, etc.
    </p>

        <p>
            Files <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/channel_tcp.h'>channel_tcp.h</a>
        and <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/channel_tcp.c'>channel_tcp.c</a> provide support for TCP/IP transport.
        To support another protocol one would need to develop similar code using TCP support as an example.
        </p>

        <p>
        Adding new transport would also require to modify functions channel_server() and channel_connect() in
        <a href='http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/agent/channel.c'>channel.c</a>.
        </p>
</body>
</HTML>

Back to the top