gdb\bfd: get child variable address or size or offset - gdb

I'm using gdb and libbfd to retrieve global variables information from an elf file and show it.
I can get the following data from libbfd: Global Variable name, address and size.
I retrieve the type of the variables and its children using gdb and gdb\MI (ptype, whatis, -var-create & -var-list-children).
How can I get the address\size\offset from parent of all the children?
e.g
type = struct {\n"
unsigned char count;\n"
unsigned char time;\n
}\n
If a variable A of this type is in address 0x000100, I want to show that A.count is in 0x000100 with size 0x1 and A.time is in 0x000101 with size 0x1.
EDIT:
I've read that gdb can read the DWARF info, but I can't figure out how can I get this information from gdb.

Here's what I did eventually.
To get the size, I used:
p sizeof(A.time)
and to get the address I used:
p /a &A.time
NOTE: This only applies for variable of a size bigger then 1 byte.
To be able to get bitfields size and offset in bits, I had to recompile GDB according to the suggestion offered in nabble: Address of bitfield element bug?

Related

How to find a variable in a hex editor

My goal is to be able to change the value of a calibration variable externally (using a hexadecimal editor). I have used the Arduino IDE to develop my code.
The variable, defined as a float, is called corrector and is definded as a global variable before the setup(): float corrector;
In the setup() I first define it's value: corrector = 1.0f;
Afterwards, I print the hex address where the variable is located :
Serial.print("\tAddress: "); Serial.println((unsigned int)(&corrector), HEX);
The address I get is 309, and when I look at this address at the hex editor what I find is a 30, which means a 0 (wrong because I gave the value of 1 to the variable).
I would appreciate if someone could tell me if I am doing well or not.
Thank you.
A float value of "1.0f" is represented as four bytes 3f800000 (possibly in reversed order if your platform is little-endian) Since this is a global variable without initializer, its address is very probably the runtime address, not the address in the binary.
If you change the definition like this:
float corrector = 1.0f;
You should be able to find those bytes in your binary at the place where the corrector symbol is in your symbol table.

clarification about gdb function format

What does this kind of gdb output mean
#0 0x0000000000401782 in std::__fill_n_a<long long __vector(4)*, unsigned long, long long __vector(4)> (__first=0x604010, __n=1, __value=...)
What exactly does __value=... mean?
From this documentation link:
The value of parameter data in frame 1 has been replaced by ….
By default, GDB prints the value of a parameter only if it is a scalar
(integer, pointer, enumeration, etc). See command set print frame-arguments
in Print Settings for more details on how to configure the way function
parameter values are printed.
You want: set print frame-arguments all

How to make GDB use a RAM dump file?

We have an embedded board with ColdFire CPU which runs µC-OS/II. When the embebbed program crashes, the CPU dumps (or copies) the entire RAM in the embedded flash. Then, we have a procedure to retrieve the RAM content (which was dumped into the flash) into a simple .bin file.
When we want to debug, we use GDB (m68k-elf-gdb.exe) combined with the .elf file. For example :
$ gdb our_elf_file
(gdb) print some_var
Cannot access memory at address 0x30617890
(gdb) ptype some_var
type = unsigned int
(gdb)
This allows us to know the address of the variable. Then, we perform a simple offset operation with the previous given address and read the RAM dump at a specific location.
For example, if we want to read some_var located at 0x30617890, we know that the dump represent the RAM content starting from 0x20000000. After that, we read 4 bytes of the .bin file at the offset (0x30617890 - 0x20000000).
(Sometimes we also use objdump (m68k-elf-objdump.exe) for other purposes).
I am completely new to this kind of stuff so maybe my question is stupid, but, is there some way to tell gdb where the RAM content is ?

Can a gdb backtrace somehow omit the argument values?

I'm working on some modifications to DynamoRIO, which uses byte* for pointers into the code cache. When I'm debugging in gdb, the backtrace command thinks every byte* is null terminated, so it prints this massive spew of byte values all over the backtrace. I need a way to either:
Turn off the display of arguments in the backtrace, or
Change the way gdb prints a byte* (preferably just the pointer value as a hex number)
Use "set print frame-arguments none" to turn off display of arguments in backtraces. See GDB Manual: Print Settings.
You can also write a pretty printer in Python and register it with GDB to change how byte * are displayed.

How do I print a UChar* var as a string from inside of gdb?

I've been doing some work on an unfamiliar codebase that uses UChar* as strings. Uchars are defined as follows (at least according to gdb)
(gdb) ptype UChar
type = short unsigned int
However, when I try to print these in gdb, I just get the address. I can also index into the pointer and retrieve the values of each character.
Is there any way to print a variable of type UChar* from within gdb and get back a meaningful string?
Also, this is on OS X, if that makes any difference.
Just define this command in your .gdbinit and type uc varname (uc will likely work as a short form for the ucharprint command you define)
define ucharprint
echo "
set $c = (unsigned short*)$arg0
while ( *$c )
if ( *$c > 0x7f )
printf "[%x]", *$c
else
printf "%c", *$c
end
set $c++
end
echo "\n
end
You don't need to worry about endianness since each unsigned short in your UTF-16 UChar type holds a code point (or half surrogate) as a native binary integer.
You first need to figure out what a UChar actually represents. It is likely UTF-16 or UCS-2 (but BE or LE?). Once you determine this, you want to provide (you can probably use existing code, such as iconv) a debug method to convert to UTF-8. See http://www.skynet.ie/~caolan/TechTexts/GdbUnicodePrinting.html for details.
print is the same as x;
x/1s 0x1234 -- will print out that location in memory as a string, if you keep hitting carrage return, it will print the next line... etc...
If you want to monitor something continually, use display/ with the same format specifier as x (print). "display/1s 0x1234" then every time you break via a breakpoint or a single step, you will see the information you configured print out .. updated etc...
if it is an ascii string, you might try to tell gdb to reinterpret:
(gdb) print (char*) theUcharPtr