Skip to content

Commit 73839c5

Browse files
authored
Merge pull request #621 from LeeLeahy2/read-map-file
Read_Map_File: Parse more symbols
2 parents d7a228e + 566892f commit 73839c5

File tree

1 file changed

+285
-10
lines changed

1 file changed

+285
-10
lines changed

Firmware/Tools/Read_Map_File.c

Lines changed: 285 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,18 @@ typedef struct _SYMBOL_TYPE
5353
char * name;
5454
} SYMBOL_TYPE;
5555

56+
typedef struct _PARSE_TABLE_ENTRY
57+
{
58+
const char * string;
59+
size_t stringLength;
60+
void (* routine)(char * line);
61+
} PARSE_TABLE_ENTRY;
62+
5663
//----------------------------------------
5764
// Constants
5865
//----------------------------------------
5966

67+
#define C_PLUS_PLUS_HEADER "_Z"
6068
#define HALF_READ_BUFFER_SIZE 65536
6169
#define STDIN 0
6270

@@ -68,15 +76,26 @@ typedef struct _SYMBOL_TYPE
6876

6977
int exitStatus;
7078
size_t fileLength;
79+
char line[HALF_READ_BUFFER_SIZE];
80+
int lineNumber;
81+
int mapFile;
7182
char readBuffer[HALF_READ_BUFFER_SIZE * 2];
7283
size_t readBufferBytes;
7384
bool readBufferEndOfFile;
7485
size_t readBufferHead;
7586
size_t readBufferTail;
87+
char symbolBuffer[HALF_READ_BUFFER_SIZE];
7688
int symbolEntries;
7789
SYMBOL_TYPE * symbolListHead;
7890
SYMBOL_TYPE * symbolListTail;
7991

92+
//----------------------------------------
93+
// Macros
94+
//----------------------------------------
95+
96+
#define PARSE_ENTRY(string, routine) \
97+
{string, sizeof(string) - 1, routine}
98+
8099
//----------------------------------------
81100
// Support routines
82101
//----------------------------------------
@@ -149,7 +168,7 @@ char * skipOverText(char * buffer)
149168
// File read routines
150169
//----------------------------------------
151170

152-
int readFromFile(int mapFile)
171+
int readFromFile()
153172
{
154173
ssize_t bytesRead;
155174

@@ -176,7 +195,7 @@ int readFromFile(int mapFile)
176195
return exitStatus;
177196
}
178197

179-
ssize_t readLineFromFile(int mapFile, char * buffer, size_t maxLineLength)
198+
ssize_t readLineFromFile(char * buffer, size_t maxLineLength)
180199
{
181200
char * bufferEnd;
182201
char * bufferStart;
@@ -192,7 +211,7 @@ ssize_t readLineFromFile(int mapFile, char * buffer, size_t maxLineLength)
192211
if ((!readBufferEndOfFile)
193212
&& (readBufferBytes <= HALF_READ_BUFFER_SIZE))
194213
{
195-
status = readFromFile(mapFile);
214+
status = readFromFile();
196215
if (status)
197216
return -1;
198217
}
@@ -228,13 +247,267 @@ ssize_t readLineFromFile(int mapFile, char * buffer, size_t maxLineLength)
228247
// Map file parsing routines
229248
//----------------------------------------
230249

231-
int parseMapFile(int mapFile)
250+
void symbolAdd(const char * symbol, uint64_t baseAddress, uint64_t length)
251+
{
252+
SYMBOL_TYPE * entry;
253+
254+
entry = malloc(sizeof(SYMBOL_TYPE) + 7 + strlen(symbol) + 1);
255+
if (entry)
256+
{
257+
// Build the symbol entry
258+
entry->nextSymbol = nullptr;
259+
entry->address = baseAddress;
260+
entry->length = length;
261+
entry->name = &((char *)entry)[sizeof(SYMBOL_TYPE)];
262+
strcpy(entry->name, symbol);
263+
264+
// Add the symbol to the list
265+
if (!symbolListHead)
266+
{
267+
// This is the first entry in the list
268+
symbolListHead = entry;
269+
symbolListTail = entry;
270+
}
271+
else
272+
{
273+
// Add this entry of the end of the list
274+
symbolListTail->nextSymbol = entry;
275+
symbolListTail = entry;
276+
}
277+
symbolEntries += 1;
278+
// printf("0x%08lx-0x%08lx: %s\n",
279+
// baseAddress, baseAddress + length - 1, symbol);
280+
}
281+
}
282+
283+
char * symbolGetName(char * buffer)
284+
{
285+
int c;
286+
size_t headerLength;
287+
char * symbolName;
288+
289+
// Determine if this is a c symbol
290+
headerLength = sizeof(C_PLUS_PLUS_HEADER) - 1;
291+
c = strncmp(buffer, C_PLUS_PLUS_HEADER, headerLength);
292+
293+
// Remove the c++ header from the symbol
294+
if (!c)
295+
{
296+
buffer += headerLength;
297+
if (*buffer == 'N')
298+
buffer++;
299+
if (*buffer == 'K')
300+
buffer++;
301+
302+
// Remove the value
303+
while ((*buffer >= '0') && (*buffer <= '9'))
304+
buffer++;
305+
}
306+
307+
// Get the symbol name
308+
symbolName = &symbolBuffer[0];
309+
while (*buffer && (*buffer != ' ') && (*buffer != '\t'))
310+
*symbolName++ = *buffer++;
311+
*symbolName = 0;
312+
313+
// Remove the last character of a c++ symbol
314+
if ((!c) && (symbolBuffer[0]))
315+
*--symbolName = 0;
316+
317+
// Return the next position in the buffer
318+
return buffer;
319+
}
320+
321+
void parseIram1(char * buffer)
322+
{
323+
uint64_t baseAddress;
324+
uint64_t length;
325+
326+
/* There are 4 different forms of iram1 lines:
327+
328+
.iram1.30 0x0000000040084f00 0x5c /home/.../libheap.a(heap_caps.c.obj)
329+
0x0000000040084f00 heap_caps_malloc_prefer
330+
331+
.iram1.4 0x00000000400851b0 0x21 /home/.../libesp_hw_support.a(cpu_util.c.obj)
332+
0x00000000400851b0 esp_cpu_reset
333+
*fill* 0x00000000400851d1 0x3
334+
335+
.iram1.34 0x0000000040084f5c 0x36 /home/.../libheap.a(heap_caps.c.obj)
336+
0x3e (size before relaxing)
337+
0x0000000040084f5c heap_caps_free
338+
339+
.iram1.5 0x00000000400851d4 0x31 /home/.../libesp_hw_support.a(cpu_util.c.obj)
340+
0x35 (size before relaxing)
341+
0x00000000400851d4 esp_cpu_set_watchpoint
342+
*fill* 0x0000000040085205 0x3
343+
*/
344+
345+
do
346+
{
347+
// Skip the rest of the iram1 stuff
348+
buffer = skipOverText(buffer);
349+
350+
// Remove the white space
351+
buffer = removeWhiteSpace(buffer);
352+
353+
// Get the symbol address
354+
if (sscanf(buffer, "0x%016lx", &baseAddress) != 1)
355+
break;
356+
357+
// Validate the symbol address
358+
if (baseAddress < 0x40000000)
359+
break;
360+
361+
// Get the symbol length
362+
buffer = skipOverText(buffer);
363+
buffer = removeWhiteSpace(buffer);
364+
if (sscanf(buffer, "0x%lx", &length) != 1)
365+
break;
366+
367+
// Read a line from the map file
368+
if (readLineFromFile(line, sizeof(line)) <= 0)
369+
break;
370+
lineNumber += 1;
371+
buffer = &line[16];
372+
373+
// Locate the symbol value
374+
buffer += 16;
375+
if (*buffer != '0')
376+
{
377+
// Read a line from the map file
378+
if (readLineFromFile(line, sizeof(line)) <= 0)
379+
break;
380+
lineNumber += 1;
381+
buffer = &line[16];
382+
}
383+
384+
// Get the symbol name
385+
buffer = skipOverText(buffer);
386+
buffer = removeWhiteSpace(buffer);
387+
buffer = symbolGetName(buffer);
388+
symbolAdd(symbolBuffer, baseAddress, length);
389+
} while (0);
390+
}
391+
392+
void parseTextLine(char * buffer)
232393
{
233394
uint64_t baseAddress;
234-
char * buffer;
235395
uint64_t length;
236-
static char line[HALF_READ_BUFFER_SIZE];
396+
size_t lineOffset;
397+
int offset;
398+
char * symbol;
399+
int value;
400+
401+
/* There are 6 different forms of iram1 lines:
402+
.text.i2cRead 0x0000000040132094 0xfc /tmp/.../core.a(esp32-hal-i2c.c.o)
403+
0x107 (size before relaxing)
404+
0x0000000040132094 i2cRead
405+
406+
.text.i2cRead 0x0000000040132094 0xff /tmp/.../core.a(esp32-hal-i2c.c.o)
407+
0x107 (size before relaxing)
408+
0x0000000040132094 i2cRead
409+
*fill* 0x0000000040132193 0x1
410+
411+
.text._Z21createMessageListBaseR6String
412+
0x00000000400dc990 0x150 /tmp/.../RTK_Surveyor.ino.cpp.o
413+
0x00000000400dc990 _Z21createMessageListBaseR6String
414+
415+
.text._Z17ntripClientUpdatev
416+
0x00000000400dfe24 0x462 /tmp/.../RTK_Surveyor.ino.cpp.o
417+
0x00000000400dfe24 _Z17ntripClientUpdatev
418+
*fill* 0x00000000400e0286 0x2
419+
420+
.text._Z12printUnknownh
421+
0x00000000400e1058 0x18 /tmp/.../RTK_Surveyor.ino.cpp.o
422+
0x20 (size before relaxing)
423+
0x00000000400e1058 _Z12printUnknownh
424+
425+
.text._Z12printUnknowni
426+
0x00000000400e1070 0x13 /tmp/.../RTK_Surveyor.ino.cpp.o
427+
0x1a (size before relaxing)
428+
0x00000000400e1070 _Z12printUnknowni
429+
*fill* 0x00000000400e1083 0x1
430+
*/
431+
432+
do
433+
{
434+
// Get the symbol name
435+
buffer = symbolGetName(buffer);
436+
437+
// Remove the white space
438+
buffer = removeWhiteSpace(buffer);
439+
440+
// Read the symbol address and length from next line if necessary
441+
if (!*buffer)
442+
{
443+
// Read a line from the map file
444+
if (readLineFromFile(line, sizeof(line)) <= 0)
445+
break;
446+
lineNumber += 1;
447+
buffer = line;
448+
}
449+
450+
// Remove the white space
451+
buffer = removeWhiteSpace(buffer);
452+
453+
// Get the symbol address
454+
if (sscanf(buffer, "0x%016lx", &baseAddress) != 1)
455+
break;
456+
457+
// Remove the white space
458+
buffer = skipOverText(buffer);
459+
buffer = removeWhiteSpace(buffer);
460+
461+
// Get the symbol length
462+
if (sscanf(buffer, "0x%lx", &length) == 1)
463+
{
464+
// Routines are in flash which starts at 0x40000000
465+
if (baseAddress >= 0x40000000)
466+
symbolAdd(symbolBuffer, baseAddress, length);
467+
}
468+
} while (0);
469+
}
470+
471+
// Define the search text and routine to process the line when found
472+
const PARSE_TABLE_ENTRY parseTable[] =
473+
{
474+
PARSE_ENTRY(" .iram1.", parseIram1),
475+
PARSE_ENTRY(" .text.", parseTextLine),
476+
};
477+
const int parseTableEntries = sizeof(parseTable) / sizeof(parseTable[0]);
478+
479+
// Parse the map file to locate the symbols and their addresses and lengths
480+
int parseMapFile()
481+
{
482+
const PARSE_TABLE_ENTRY * entry;
483+
int index;
237484
ssize_t lineLength;
485+
486+
do
487+
{
488+
// Read a line from the map file
489+
lineLength = readLineFromFile(line, sizeof(line));
490+
if (lineLength <= 0)
491+
break;
492+
lineNumber += 1;
493+
494+
// Locate the matching text in the map file
495+
for (index = 0; index < parseTableEntries; index++)
496+
{
497+
// Locate the routine names
498+
entry = &parseTable[index];
499+
if (strncmp(line, entry->string, entry->stringLength) == 0)
500+
{
501+
parseTable[index].routine(&line[entry->stringLength]);
502+
break;
503+
}
504+
}
505+
} while (readBufferBytes);
506+
507+
/*
508+
uint64_t baseAddress;
509+
char * buffer;
510+
uint64_t length;
238511
static size_t lineNumber;
239512
size_t lineOffset;
240513
int offset;
@@ -245,10 +518,11 @@ int parseMapFile(int mapFile)
245518
int value;
246519
247520
textLength = strlen(text);
521+
248522
do
249523
{
250524
// Read a line from the map file
251-
lineLength = readLineFromFile(mapFile, line, sizeof(line));
525+
lineLength = readLineFromFile(line, sizeof(line));
252526
if (lineLength <= 0)
253527
break;
254528
lineNumber += 1;
@@ -284,7 +558,7 @@ int parseMapFile(int mapFile)
284558
if (!*buffer)
285559
{
286560
// Read a line from the map file
287-
lineLength = readLineFromFile(mapFile, line, sizeof(line));
561+
lineLength = readLineFromFile(line, sizeof(line));
288562
if (lineLength <= 0)
289563
break;
290564
lineNumber += 1;
@@ -341,6 +615,8 @@ int parseMapFile(int mapFile)
341615
}
342616
}
343617
} while (readBufferBytes);
618+
*/
619+
344620
return exitStatus;
345621
}
346622

@@ -469,7 +745,6 @@ int processBacktrace()
469745
int main(int argc, char ** argv)
470746
{
471747
char * filename;
472-
int mapFile;
473748
int status;
474749

475750
do
@@ -493,7 +768,7 @@ int main(int argc, char ** argv)
493768
}
494769

495770
// Parse the map file
496-
status = parseMapFile(mapFile);
771+
status = parseMapFile();
497772
} while (0);
498773

499774
if (!status)

0 commit comments

Comments
 (0)