6.1.1. Why dynamically-loaded code requires special hardware and software support

When a debugger is debugging a system it talks to the system largely in terms of addresses in the system’s (possibly virtual) memory space. To be useful to its user it must translate between these addresses and locations in the images loaded on the system. This allows it to present a symbolic or source level view of the code running on the system to the user.

In a simple statically linked and loaded system the system runs a single image. The user tells the debugger the name of this image, and the image describes the mapping between target addresses as image locations. The debugger needs no further information to debug the image.

Many systems, including Operating Systems (OS) such as WinCE, Linux, or Epoc32, load part or all of their software dynamically. This can have a number of effects:

To debug such a system the debugger must be able to ask the target system what images are loaded and where. At present ARMs debugger cannot ask such questions.

The problem is more difficult when using trace, because trace contains historical information. When analyzing a trace the debugger needs to know what images were loaded when the trace data was collected, rather than what images are loaded now. Additionally, even without a valid image, you can do some very basic, but sometimes useful interactive debugging, such as single-stepping instructions. The compression algorithm used for trace data means that the debugger cannot start to decode trace data unless the images that were loaded when it was generated are available.

In particular, you must remember that, for ALL embedded trace solutions to work, an image of the code being executed must be available to the trace decompression software of the debugger. This is because the instructions being executed are not broadcast, due to the data bandwidth that would be required, and so only the minimum of address information is traced. This means that, given a (compressed) address issued by the trace port, the tools must be able to know what instructions are at and around that point. This allows the target address of direct branches (B and BL instructions in the case of ARM) to be implied. Virtual memory and software paging, (effectively self-modifying code) for example, make this hard because the debugger probably does not know where the code ends up being executed from.

For a device with a full MMU, and an operating system that loads application and OS code into arbitrary locations in RAM, a way of telling the debugger what the code image for a particular trace sequence is required. The side-effect of this is that the closer to a physical address that can be supplied the better. For ARM720T the chosen solution is to broadcast the modified virtual address on the trace interface.

Copyright © 2000, 2001 ARM Limited. All rights reserved.ARM DDI 0158D