@@ -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
6977int exitStatus ;
7078size_t fileLength ;
79+ char line [HALF_READ_BUFFER_SIZE ];
80+ int lineNumber ;
81+ int mapFile ;
7182char readBuffer [HALF_READ_BUFFER_SIZE * 2 ];
7283size_t readBufferBytes ;
7384bool readBufferEndOfFile ;
7485size_t readBufferHead ;
7586size_t readBufferTail ;
87+ char symbolBuffer [HALF_READ_BUFFER_SIZE ];
7688int symbolEntries ;
7789SYMBOL_TYPE * symbolListHead ;
7890SYMBOL_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()
469745int 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