Why does objdump not show .bss, .shstratab, .symtab and .strtab sections? - c

I'm currently doing my own objdump implementation in C.
For my -s option, I have to show the full contents of the sections of an ELF file.
I'm doing it well, but I'm showing more sections than the "real" objdump.
In fact, it does not output the .bss, .shstrtab, .symtab and .strtab sections.
I'm looking around the sh_flags value on the Shdr struct but I can't find any logic...
Why does objdump -s <ELF file> not show these sections ?

Why objdump -s does not shows these sections ?
Objdump is based on libbfd, which abstracts away many complexities of ELF, and was written when objects tended to only have three sections.
As such, objdump is quite deficient. In addition to not showing you (some) existing sections, it may also "synthesize" sections that don't exist at all, and do other weird tricks. This is more of a libbfd fault -- its abstraction layer simply doesn't tell objdump about the "missing" sections.
TL;DR: don't use objdump. Use readelf instead.

Try using sh_size and sh_type, instead of sh_flags.
Quoting from the ELF specification
sh_size This member gives the section’s size in bytes. Unless the
section type is SHT_NOBITS, the section occupies sh_size bytes in the
file. A section of type SHT_NOBITS may have a non-zero size, but it
occupies no space in the file

Related

Linker (ld) ELF Questions

I have an issue with an ELF file generated by the GNU linker ld.
The result is that the data section (.data) gets corrupted when the executable is loaded into memory. The corruption to the .data section occurs when the loader performs the relocation on the .eh_frame section using the relocation data (.rela.eh_frame).
What happens is that this relocation causes seven writes that are beyond the .eh_frame section and over-write the correct contents of the .data section which is adjacent to the top of the .eh_frame section.
After some investigation, I believe the loader is behaving correctly, but the ELF file it has been given contains an error.
But I could be wrong and wanted to check what I've found so far.
Using readelf on the ELF file, it can be seen that seven of the entries in the .rela.eh_frame section contain offsets that are outside (above) the range given by readelf for the .eh_frame section. ie The seven offsets in .rela.eh_frame are greater than the length given for .eh_frame. When these seven offsets are applied in the relocation, they corrupt the .data section.
So my questions are:
(1) Is my deduction that relocation offsets should not be greater than the length of the section to which they apply? And therefore the ELF file that has been generated is in error?
(2) What are people's opinions on the best way of proceeding to diagnose the cause of the incorrect ELF file? Are there any options to ld that will help, or any options that will remove/fix the .eh_frame and it's relocation counterpart .rela.eh_frame?
(3) How would I discover what linker script is being used when the ELF file is generated?
(4) Is there a specific forum where I might find a whole pile of linker experts who would be able to help. I appreciate this is a highly technical question and that many people may not have a clue what I'm talking about!
Thanks for any help!
The .eh_frame section is not supposed to have any run-time relocations. All offsets are fixed when the link editor is run (because the object layout is completely known at this point) and the ET_EXEC or ET_DYN object is created. Only ET_REL objects have relocations in that section, and those are never seen by the dynamic linker. So something odd most be going on.
You can ask such questions on the binutils list or the libc-help list (if you use the GNU toolchain).
EDIT It seems that you are using a toolchain configured for ZCX exceptions with a target which expects SJLJ exceptions. AdaCore has some documentation about his:
GNAT User's Guide Supplement for Cross Platforms 19.0w documentation » VxWorks Topics
Zero Cost Exceptions on PowerPC Targets
It doesn't quite say how t switch to the SJLJ-based VxWorks 5 toolchain. It is definitely not a matter of using the correct linker script. The choice of exception handling style affects code generation, too.

GRUB Multiboot header not found

After reading this this question and it's primary answer, I ran readelf on my kernel, and noticed my .text section was at 0x00101000 and not 0x00100000. I also noticed a section above that read .not.gnu.build-i that was in the place the .text section is supposed to be. Is there a way I could make my .text section be in the correct place? I have already used align 4 to set it to 1M.
The issue is that LD (or LD via GCC) is automatically placing a notes section (if one was generated) in the first 4k. If linking the final kernel with GCC pass it the -Wl,--build-id=none option. If you are using LD directly to link the final binary then you can pass it --build-id=none .
If writing a multiboot ELF object the existence of this extra section can force the mulitboot header beyond the 8k position in the file. This is accounting for the fact that ELF headers usually take a minimum of the first 4k of the file. Add in the 4k for .note.gnu.build-id and .multiboot section is now beyond 8k mark of the physical file. This will cause a multiboot loader like GRUB to think your ELF executable doesn't have a multiboot header since it only looks through the first 8k of the file.
Your linker script (given that it is the same as in the other question) is the problem: By telling it to 4k-align the sections and putting multiboot in a separate section, you allocate 4k for it, so .text starts at an offset of 1M + 4k, which causes your problem. Change it to the following:
SECTIONS
{
. = 1M;
.text ALIGN(4K) :
{
*(.multiboot)
*(.text)
}
[snip]

ELF second load segment address of .data + .bss

In this case, is right that address of:
.data start at 0x08048054 up to 0x08048054+0x0000e
.bss start at 0x08048054+0x0000e up to 0x0804805+0x00016
or am I missing something? please clarify it for me.
EDIT
I used this command to get the information as in the image:
readelf -l filename
Ok, so where do I begin... Yes both .data and .bss are in that region in memory. The problem is that there is no way to figure out what order they are in.
We can assume that the default order is followed and make an educated guess but I don't like that.
Through the lengthy comment thread under the question you mentioned something interesting, that wasn't evident in your question.
the executable isn't dynamically linked as file command says: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped in this case, there's no a linker script, isn't? – The Mask
In this case the library contains the symbol table with all of the symbol offsets. This table includes section information. It will be processed by the linker when you compile your application. At that point it is your linker script that controls the order in which the .data and .bss sections are out put in.
If it is the default linker script, look it up. If it is custom, you should have access to it and can read it. If unsure elaborate here and we'll try and help :)
I myself have asked a question that is unrelated but offers example code of a linker script and some C code. In that linker script the .bss segment came after the .data segment.
You are looking at the program header information, whereas the section headers are probably what you need. There may be many sections contained within a program header and you cannot precisely infer the sizes and alignment requirements of the various sections.
To see the section headers, use:
readelf -S

Negative effects to ld: warning: section `.bss' type changed to PROGBITS

I am sorry if this is too general of a question, but I haven't been able to find answers anywhere. I am wondering if there is any negative effects of the bss section changed to PROGBITS. I have been getting this warning when I have been compiling programs under GCC 4.8.1. Thanks in advance for any help.
When the BSS section is changed to PROGBITS, the effect is that there are more NUL bytes (zeroes) in the output file. When .bss is NOBITS (what it should be), the linker puts information in the output file that tell the operating system to wipe a section of memory to all zeroes when the program is loaded. If it's PROGBITS, then this information only tells the operating system to load the memory area from the file, and that section of the file is filled with zeroes. So the only negative effect is that the output file is bigger.

Predefined ELF Code Sections

What are the predefined code sections that can be referenced in an ELF linker command file? In addition to any others that may be available, I am specifically wondering about these:
.text
.rodata
.sdata
.sbss
.bss
.data
Finding documentation has proven most difficult. If anyone can also tell me what the acronym ELF stands for in this context, that would be a plus. Thanks.
Not sure what you mean about not finding documentation. Wikipedia has a large collection of links about the Executable and Linkable Format. One of the links there describes the ELF sections you are interested in (plus lots of other stuff). Another link here describes additional ELF special sections (.sbss/.sdata).

Resources