Visible to Intel only — GUID: cjl1679711185450
Ixiasoft
Visible to Intel only — GUID: cjl1679711185450
Ixiasoft
6.4.1. Loading Symbol Files in a Simulation
The command used to load a symbol file in a simulation is the following:
add-symbol-file symbolfile ["context-query"] [relocation-address][relative] ["section"] [segment]
The arguments provided are explained next:
Argument | Description |
---|---|
symbolfile | This is the debug symbol file. You can define the full path in the host machine where the file is located. If the full path is not provided, Intel® Simics® simulator uses Intel® Simics® Search Path and path markers (%simics%, %script%) to find the symbol file. |
context-query | This is the context in which the symbol file is used. This can be a process, a debug context, or a specific core. This value can be retrieved directly from the context-query-for-object command. If no context is specified, it uses the default ‘*’, which indicates that it applies to any context. |
relocation-address relative | This is the address the file/segment/section must be mapped to. The -relative flag specifies if the relocation address is relative to the load address in the binary. When not set, the address is the absolute address specified. |
section | This is the name of the section to relocate. See the list-sections command. |
segment | This is the number of the segment to relocate. See the list-segments command. |
The command returns an ID that can be used with remove-symbol-file to remove the mappings that were added. This command also displays the number of contexts that match this symbol file.
The following capture shows some examples about how the symbol file can be added. In the same capture is described what is being done as a comment.
#Intel Simics simulator CLI # Get the objects for which the default ‘*’ context-query applies simics> context-query-for-object object =agilex <autocomplete> agilex agilex.hps.core[2] agilex.hps.cpu_mem[1] agilex.hps.core[0] agilex.hps.core[3] agilex.hps.cpu_mem[2] agilex.hps.core[1] agilex.hps.cpu_mem[0] agilex.hps.cpu_mem[3] # Load a symbol file without any context. This applies to all contexts(9) simics> add-symbol-file "/home/simicsUser/TestSymFile/testSymFile" Context query * currently matches 9 contexts. Symbol file added with id '1'. # Load a symbol file that has context specific to a core. The symbol # file can be used only with this core. Note that only matches one context. simics> add-symbol-file context-query = "'hps.core[3]'" "/home/simicsUser/TestSymFile/testSymFile" Context query "hps.core[3]" currently matches 1 context. Symbol file added with id '2'. # Load a symbol file using a context defined by the context ID of core. Note # that also 1 single context matches this. simics> context-query-for-object object = agilex.hps.core[0] "ID=\"obj_00000162ee418b18\"" simics> add-symbol-file context-query = "ID='obj_00000162ee418b18'" "/home/simicsUser/TestSymFile/testSymFile" Context query ID="obj_00000162ee418b18" currently matches 1 context. Symbol file added with id '3'. # Load a symbol file using the ID returned by context-query-for-object simics> $cid = (context-query-for-object object = agilex.hps.core[2]) simics> add-symbol-file context-query = $cid "/home/simicsUser/TestSymFile/testSymFile" Context query ID="obj_00000187dfff8475" currently matches 1 context. Symbol file added with id '4'. # Load a symbol file using a debug session that was applied over a core simics> debug-context name = "dbg1" object = "agilex.hps.core[1]" dbg1 (the arm-cortex-a53 agilex.hps.core[1]) Now debugging the arm-cortex-a53 agilex.hps.core[1] ??() hint #0x1d simics> $cid = "ID="+dbg1->cid simics> echo $cid ID=obj_0000017912c563b5 simics> add-symbol-file context-query = $cid "/home/simicsUser/TestSymFile/testSymFile" Context query ID=obj_0000017912c563b5 currently matches 1 context. Symbol file added with id '5'. # Removing a symbols file using an ID and the name of the symbol file. # At this point the 5 IDs of symbol files were created. In this example # each instance of a symbol file adds 2 memory maps entries (see show- # memorymap command). simics> remove-symbol-file id=1 simics> remove-symbol-file id=2 simics> remove-symbol-file "/home/simicsUser/TestSymFile/testSymFile" Removed 6 Memory Map entries.
Intel® Simics® simulator provides some commands that allow you to obtain information about the symbol file. The following capture shows some examples of these commands:
Command | Description |
---|---|
list-segments | Lists the sections of the symbol file symbol-file. |
list-sections | Lists the sections of the symbol file symbol-file. |
show-memorymap | Shows all memory map entries that were setup when the symbol file was loaded. |
add-pathmap-entry | Adds a translation from a path in the debug information to a path on the host. This is used to make available to the debugger the source code that was used to create the symbol files (if the source code is in a single directory and the symbols file is also there, this command is not needed). |
For additional information about any command, you can use help <command> from Intel® Simics® simulator CLI.
The following capture shows an example of the use of some of the commands described above:
#Intel Simics simulator CLI simics> add-symbol-file "/home/simicsUser/TestSymFile/test" Context query * currently matches 9 contexts. Symbol file added with id '1'. simics> list-segments "/home/simicsUser/TestSymFile/test" Segments Sections --------------------------------------------------------- 0 <segment is empty> 1 .interp 2 .interp, .note.ABI-tag, .hash, .gnu.hash, .dynsym, …, .eh_frame 3 .init_array, .fini_array, .dynamic, .got, .got.plt, .data, .bss 4 .dynamic 5 .note.ABI-tag 6 .eh_frame_hdr 7 <segment is empty> 8 .init_array, .fini_array, .dynamic, .got simics> list-sections "/home/rolando/tasks/gdbLearn/arm/test" .interp, .note.ABI-tag, .hash, .gnu.hash, .dynsym, .dynstr, .gnu.version, .gnu.version_r, .rela.dyn, .rela.plt, .init, .plt, .text, .fini, .rodata, .eh_frame_hdr, .eh_frame, .init_array, .fini_array, .dynamic, .got, .got.plt, .data, .bss, .comment, .debug_aranges, .debug_info, .debug_abbrev, .debug_line, .debug_str, .debug_loc, .debug_ranges, .symtab, .strtab, .shstrtab simics> show-memorymap Contexts matching * =================== ID Address Size Flags Offset File 1 0x400000 0x86c rx 0x0 /home/rolando/tasks/gdbLearn/arm/test 1 0x410de8 0x258 rw 0xde8 /home/rolando/tasks/gdbLearn/arm/test
To support the debug process, Intel® Simics® simulator provides some additional commands that operate over debug context using the information provided by the symbol file. These commands are described next.
Command | Description |
---|---|
sym-value* | Gets the value of a symbol or a C expression. |
sym-write* | Writes a new value to a variable. |
sym-type* | Gets the type of a C expression. |
sym-address* | Gets the address of a C value expression. |
list* | Lists source code. |
stack-trace* | Shows the stack. |
bp.source_location.break | Adds a breakpoint on a particular location. |
bp.source_location.run-until | Runs until the specified location is reached. Equivalent to bp.source_location.break + run. |
bp.source_location.wait-for | Waits in the current script branch until the specified location is reached. Must be used inside a script branch. |
bp.source_location.trace | Enables tracing of the events that the specified location is reached. |
bp.source_line.break | Adds a breakpoint at a given source code line. |
For additional information about any command, you can use help <command> from Intel® Simics® simulator CLI.
An example that shows how some of these commands are executed is shown next. For this example, simple C application (testSymFile.c) source code has been created and compiled to create a symbol file (testSymFile). The source code includes the main() function and inside of this, some variables are being printed. The exitVar variable is initialized in 0 and is declared as volatile to control the value of this using the Intel® Simics® debugger. In the application, an initial debug message is printed and then, it gets into a loop and remains there if the exitVar variable remains with its initial value. If the value of this exitVar variable changes, some arithmetic operations are done with the variables defined and finally the value of the c variable is printed just after finishing the application.
# Source code snippet (testSymFile.c) #include <stdio.h> int main() { int x = 1000; int a; int b; int c; volatile int exitVar = 0; printf("=== My Debug example ===\n"); while(exitVar==0); a = x; b = x; c = a + b; printf("%d\n", c); return 0; }
The following is a capture of a debug session over the testSymFile application. The explanation of the example is embedded in the capture. An assumption about this debug example is that the application is ready to be executed in the target system.
# Intel Simics simulator CLI # Loading the symbol file from the host system file system simics> add-symbol-file "~/myTestDir/test" Context query * currently matches 9 contexts. Symbol file added with id '1'. # Set a breakpoint at the main() function of the application and the # sumulation is run. This can be done in a single step using run-until. simics> bp.source_location.break main Breakpoint 1: 0x1 (planted) simics> bp.list -------------------------------------------------------------------- ID Description Enabled Oneshot Ignore count Hit count -------------------------------------------------------------------- 1 execution of main true false 0 0 --------------------------------------------------------------------
# Intel Simics simulator CLI simics> run # At this time, the application must be run in the target system. So the # breakpoint triggers. simics> r Setting new inspection object: agilex.hps.core[3] [tcf] Breakpoint 1 on execution in context hps.core[3] # The application reached the main() function. This was executed on core3. simics> psel "agilex.hps.core[3]" # Crate a debug context with the current core selected. simics> (psel).debug dbg0 (the arm-cortex-a53 agilex.hps.core[3]) Now debugging the arm-cortex-a53 agilex.hps.core[3] main() at /home/rolando/tasks/gdbLearn/arm/test.c:6 6 int x = 1000; # List the current line in core3. simics> list 4 { 5 -> 6 int x = 1000; 7 int a; 8 int b; # Advance few line in the application code execution, list the code again # to observe the new location. Get the value of the exitVar variable. # Observe that the value is 0, so it means that the application remains # in the loop until a new value is set in the variable. Check that the type # of variable can be retrieved from the debugger. simics> next-line simics> next-line simics> next-line simics> list 10 volatile int exitVar = 0; 11 -> 12 printf("=== My Debug example ===\n"); 13 while(exitVar==0); 14 a = x; simics> sym-type exitVar volatile int simics> sym-value exitVar 0 # Run the simulation. The debug message is printed in the target # system console. Stop the simulation and list again to see where the code # is located now. This time, it must be inside of the while loop. (Note: # depending on how the application is run, it is possible that the OS # changes the core in which the application runs or by the time the # simulation is stopped the core is executing something different than what # is in the loop). simics> r simics> stop simics> list 11 12 printf("=== My Debug example ===\n"); -> 13 while(exitVar==0); 14 a = x; 15 b = x; # Update the value of exitVar to 1. Once it changes the application must # exit from the loop and the value of c variable is printed before # finishing the application. simics> sym-write exitVar 1 exitVar = 1 simics> r
After running this example, the output in the target system terminal must look like the following:
# Target Serial Console root@psgdevice:~# ./test === My Debug example === 2000
In the last example, you are using global scope debug commands (list, next-line, sym-write, etc.) that apply to the current debug context selected, but you can also use local scope commands using the dbg0 debug context (dbg0.list, dbg0.next-line, dbg0.sym-write, etc.).