## Using the MAKSYM Tool

MAKSYM is a command line tool that processes the log file generated when building a ROM image, and creates a text file that lists the address of every global and exported function in the ROM.

Reference: tools: MAKSYM outlines the syntax of the command.

If you know the address of the instruction which caused an exception, you can compare this address with the MAKSYM log to see which function this is in. You can narrow this down to the exact code within the function by using ABLD LISTING to get the assembler output from the compiler.

The following example MAKSYM log is taken from an EKA1 build; however, the principle is the same for EKA2.

From \Epoc32\Release\Misa\UREL\ekern.exe
50003040 0094 _E32Startup
500030d4 002c ImpDma::Init1(void)
50003100 0004 ImpDma::Init3(void)
50003104 0008 ImpDma::MaxBlockSize(void)

If, for example, the code address of the exception is at 0x500030dc, then you can see from the log that this is in the ImpDma::Init1() function, at offset 8 from the start of the function. This function is in the file ...\e32\ekern\epoc\arm\sa1100\ka_dma.cpp, so use ABLD LISTING to obtain the assembler:

> cd \e32

> abld listing misa urel ekern ka_dma

Notice that you must specify the component that the file is part of, in this case EKERN, and that you do not put the .cpp extension on the source file name. If you do not specify a source file ABLD will create an assembler listing for every file in component EKERN.

The listing file will be placed in the same directory as ka_dma.cpp, and will be called ka_dma.lis. If you look at this file you will see something like this:

7 Init1__6ImpDma:
8 @ args = 0, pretend = 0, frame = 0
9 @ frame_needed = 0, current_function_anonymous_args = 0
10 @ I don't think this function clobbers lr
11 0000 18209FE5 ldr r2, .L793
12 0004 0630A0E3 mov r3, #6
13 0008 003082E5 str r3, [r2, #0]
14 000c 10309FE5 ldr r3, .L793+4
15 0010 10009FE5 ldr r0, .L793+8
16 0014 000083E5 str r0, [r3, #0]
17 0018 1810A0E3 mov r1, #24
18 001c FEFFFFEA b FillZ__3MemPvi

Offset 8 is the first STR instruction. Comparing this with the C++ source:

void ImpDma::Init1()
//
// Phase 1 initialisation of the Dma channels
//
{
PP::DmaMaxChannels=KNumberOfDmaChannels;
PP::DmaChannelTable=(TDma **)(&DmaChannels[0]);
Mem::FillZ(PP::DmaChannelTable,sizeof(TDma *)*KNumberOfDmaChannels);
}

The first store is to PP::DmaMaxChannels, so clearly there is a problem writing this memory.