How to print message to stdout from GNU ld script? - linker

I have quite large ld link script for embedded platform which is low on RAM and ROM. I want to know how much memory is left available after I have relocated all the code. Actually, I want to print out the value
of location counter . to stdout.
How can I do it? Is there some magic command like print(.)?

I have a post-link step in my projects that dumps the size of stuff so I can see how close I'm getting. Just add something along the lines of:
arm-none-eabi-size binary_image.axf
That will get you output like:
text data bss dec hex filename
204808 704 23188 228700 37d5c Foo.axf
On my cortex-m3 chip, this would be text+data = flash usage, data+bss = ram usage. dec/hex are useless values.
And as Olaf says, use a map file for more specific memory consumption. I have this added to my link step:
-Xlinker -Map=Foo.map

Another solution might be to add the following command to the linker:
-Xlinker --print-memory-usage
This gives me the following output:
Memory region Used Size Region Size %age Used
m_interrupts: 576 B 576 B 100.00%
m_text: 22988 B 32192 B 71.41%
m_data: 26552 B 32 KB 81.03%

Read the manual. There are no such commands - there cannot be.
Linker "scripts" are actually more like configuration/descriptor files. They are not "executed" like a script. There is also not a single . (how could be for different memory areas?).
You can, however, output a map which might exactly be what you need. Try option -M. If you have set up the memory regions in the linker script correctly, the linker will warn if some memory area overflows, which is actually what you want for automatic builds.
Update: You could grep/filter the map file if you want to insist seeing the section sizes on each build.

You can't print the value of a symbol while the script is being executed, but you can create a symbol and the look it up afterwards with nm. Like this:
value_of_dot = .;
Then
nm my_file.elf | grep value_of_dot
Edit: If you really want it printed to stdout you would have to modify the linker. E.g. for lld, add printfs in LinkerScript.cpp in LinkerScript::assignSymbol().
For your particular use-case of checking how much memory is used, it is probably better to use size, as escrafford suggested, or objdump -section-headers.

Related

Finding virtual memory address of variable on osx

Consider the following code in mono/domain.c:
static MonoDomain *mono_root_domain = NULL;
...
MonoDomain* mono_get_root_domain (void)
{
return mono_root_domain;
}
My task is to read the struct data pointed by the mono_root_domain pointer in runtime from another process. (Attaching, reading, locating dylibs, etc. from this other process is solved already)
Looking into the generated libmono dylib I can find the corresponding symbol:
This symbol points to the address of 0x2621A8 which in the local relocation section (__DATA, __bss):
This points to the address of 0x1A7690 (__TEXT, __symbol_stub):
The target is
so 0x1A7DF8 (__TEXT, __stub_helper):
At this point I am completely lost of how to retrieve the actual pointer to the MonoDomain struct. Any help is appreciated.
For security reasons and to prevent buffer overflow attacks and other exploits, you can't know that, because of a security measure called PIE or ASLR (address space layout randomization). However, this can be disabled for debugging purposes. LLDB and GDB do/did it in order to debug executables. The way this can be done with a CLI app is as follows:
Copy or download this python script from GitHub
https://github.com/thlorenz/chromium-build/blob/master/mac/change_mach_o_flags.py
Save the python script, for example, next to your executable
If so, open Terminal and cd to where your executable is
enter chmod +x ./change_mach_o_flags.py to make the script executable
enter ./change_mach_o_flags.py --no-pie ./YourExecutable
Now the addresses of your executable should not be randomized anymore. Because of that, to calculate the addresses of your static / global variables is possible. To do that, do the following in Terminal (I am assuming you are using a 64-bit machine):
otool -v -l ./YourExecutable | open -f(this will generate a file text with the commands inside your executable of how to layout DATA, TEXT, etc. in memory)
Look for the section you are interested in. Look at the addr field. If it contains let's say 0x0000000100001020 then the variable will be placed exactly there with ASLR disabled.
I am not sure if this works with dylibs but you can try it. Now I ran out of time, but I can try at home and see if this is doable with dylibs.

Is it possible to pass command line arguments to GNU LD to create a section, define size and place it in a specific memory?

I want to create a section in RAM, allocate a specific size and place it an an address? Is it possible to do all these operations without passing a linker script "file" or w/o modifying the existing linker script ?
.myspace :
{
. = 0x10000;
. = . + STACK_SIZE;
} > ram
Is it possible to do all the operation done by linker script in command line with GNU LD/GCC ?
Seems like a way outdated answer, but anyway.
It's not possible to reserve the section size via ld command line options, but if the next section starts at the end of your special section, you can try something like this:
ld --section-start=.myspace=0x10000 -Ttext=0x11000 ...

How to read, understand, analyze, and debug a Linux kernel panic?

Consider the following Linux kernel dump stack trace; e.g., you can trigger a panic from the kernel source code by calling panic("debugging a Linux kernel panic");:
[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)
In unwind_backtrace+0x0/0xf8 what does +0x0/0xf8 stand for?
How can I see the C code of unwind_backtrace+0x0/0xf8?
How to interpret the panic's content?
It's just an ordinary backtrace, those functions are called in reverse order (first one called was called by the previous one and so on):
unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150
The bdi_register+0xec/0x150 is the symbol + the offset/length there's more information about that in Understanding a Kernel Oops and how you can debug a kernel oops. Also there's this excellent tutorial on Debugging the Kernel
Note: as suggested below by Eugene, you may want to try addr2line first, it still needs an image with debugging symbols though, for example
addr2line -e vmlinux_with_debug_info 0019594c(+offset)
Here are two alternatives for addr2line. Assuming you have the proper target's toolchain, you can do one of the following:
Use objdump:
locate your vmlinux or the .ko file under the kernel root directory, then disassemble the object file :
objdump -dS vmlinux > /tmp/kernel.s
Open the generated assembly file, /tmp/kernel.s. with a text editor such as vim. Go to
unwind_backtrace+0x0/0xf8, i.e. search for the address of unwind_backtrace + the offset. Finally, you have located the problematic part in your source code.
Use gdb:
IMO, an even more elegant option is to use the one and only gdb. Assuming you have the suitable toolchain on your host machine:
Run gdb <path-to-vmlinux>.
Execute in gdb's prompt: list *(unwind_backtrace+0x10).
For additional information, you may checkout the following resources:
Kernel Debugging Tricks.
Debugging The Linux Kernel Using Gdb
In unwind_backtrace+0x0/0xf8 what the +0x0/0xf8 stands for?
The first number (+0x0) is the offset from the beginning of the function (unwind_backtrace in this case). The second number (0xf8) is the total length of the function. Given these two pieces of information, if you already have a hunch about where the fault occurred this might be enough to confirm your suspicion (you can tell (roughly) how far along in the function you were).
To get the exact source line of the corresponding instruction (generally better than hunches), use addr2line or the other methods in other answers.

Tool to analyze size of ELF sections and symbol

I need a way to analyze output file of my GCC compiler for ARM. I am compiling for bare metal and I am quite concerned with size. I can use arm-none-eabi-objdump provided by the cross-compiler but parsing the output is not something I would be eager to do if there exists a tool for this task. Do you know of such a tool existing? My search turned out no results.
One more thing, every function in my own code is in its own section.
You can use nm and size to get the size of functions and ELF sections.
To get the size of the functions (and objects with static storage duration):
$ nm --print-size --size-sort --radix=d tst.o
The second column shows the size in decimal of function and objects.
To get the size of the sections:
$ size -A -d tst.o
The second column shows the size in decimal of the sections.
The readelf utility is handy for displaying a variety of section information, including section sizes, e.g.:
arm-none-eabi-readelf -e foo.o
If you're interested in the run-time memory footprint, you can ignore the sections that do not have the 'A' (allocate) flag set.
When re-visiting this question 10 years later one must mention the little Python-based wrapper for readelf and nm that is elf-size-analyze:
puncover uses objdump and a few other gcc tools to generate html pages you can easily browse to figure out where your code and data space is going.
It's a much nicer frontend than the text output of the gcc tools.

dumping C structure sizes from ELF object file

How can you extract the sizes of all C structures from an ELF object file with debugging symbols?
Individual struct sizes can be obtained from GDB using "print sizeof(some_struct)", but what I need is to get a listing of all structures.
I've looked at "nm" and "objdump", but I don't see options to do what I'm looking for. Is there a way to do this with standard Unix tools, or do I need to extract the debug symbol section from the ELF file and process it myself? I'm hoping it's not the latter.
Thanks in advance for any advice.
Ray
pahole shows this and other details about structs. Its git repo is at http://www.kernel.org/git/?p=linux/kernel/git/acme/pahole.git;a=summary.
You will have to dig in .debug_info section, objdump will dump it for you if you run it with --dwarf parameter.
You will see your structures there as *DW_TAG_structure_type* and *DW_AT_byte_size* attribute is equivalent to sizeof. Standard Unix tool should be enough to format this data into more readable list.
Install package dwarves, then you have the command "pahole".
Use the "pahole" command against a elf object file, you can get all the structure information, or you can use the "-C" parameter to specific a structure name, for example:
$ pahole vmlinux -C task_struct
Unless someone else known something, I think you will have to process the output of nm .
However, nm only gives you the start of each struct and knows nothing about its end so even that may not work unless each strut is immediately followed by some other symbol. Watch out for this issue!

Resources