I am learning about ELF. The file class can be one of ELFCLASS32, ELFCLASS64 or ELFCLASSNONE.
However, I cannot find any example usage of ELFCLASSNONE.
What is it used for ? And when ? Is it actually used anywhere ?
Is it actually used anywhere ?
No.
(It's only used to detect invalid ELF files.)
Used where?
Anywhere validity of the ELF file is verified. Here is an example from the Linux kernel tools.
even there, ELFCLASSNONE is not used.
You don't know what parts of the ELF header readelf examined before it concluded that .bashrc is not an ELF file. It may have looked at ei_ident[EI_CLASS] and compared the value with ELFCLASSNONE (though likely it didn't).
If you make a copy of e.g. /bin/date, and write a 0 byte into 5th byte of the copy (EI_IDENT == 4) to corrupt it, then run readelf -h on that copy, you'll probably get an "invalid ELF class" or similar message.
Related
Reading the ELF specification, it seems that for an EXEC type ELF file, the section header table is listed as "optional". Under what circumstances would it be omitted?
Under what circumstances would it be omitted?
Section info is not needed at execution time, and traditionally is only kept for debugging (e.g. you can get a backtrace for a crash from an executable compiled without any debugging info).
You should be able to remove them with e.g. strip --strip-all, but that doesn't appear to work.
You could also binary-patch the the file -- e.g. zero out .e_shoff and .e_shnum in the ELF header.
Related answer.
I want to change where in the elf file execution starts. For example I have a basic hello world program in a elf file. The actual code is located at an offset of 0x1000 bytes into the file. I want to move that code to, lets say, a 0x900 offset and modify the file so that it starts executing at 0x900. I know this sounds kinda useless but it does serve a purpose.
First you compile/assemble (clang/as/...) your program into a hello.o ELF object file. At this point, you would normally let the compiler driver finish the job and emit an ELF executable.
You can instead use the linker (lld/ld/...) and specify the entry point with --entry 0x900. You can also do this with a linker script. Note that if you do this, you have to handle a bunch of stuff that the compiler driver normally handles for you. The warning from the Oracle linker manual says:
When you invoke the link-editor directly, you have to supply every
object file and library required to create the intended output. The
link-editor makes no assumptions about the object modules or libraries
that you meant to use in creating the output.
I am working on understanding some ground concepts in embedded Systems. My question is similar to understand hexedit of an elf .
In order to burn compiler output to ROM, the .out file is converted to HEX (say intel-hex). I wonder how the following informations are preserved in HEX format:
Section header
Symbol tables, debug symbols, linker symbols etc.
Elf header.
If these are preserved in HEX file, how they can be read from hex file?
A bit out question but how the microcontroller on boot knows where .data .bss etc. exists in HEX and to be coppied to RAM?
None of that is preserved. A HEX file only contains the raw program and data. https://en.wikipedia.org/wiki/Intel_HEX
The microcontroller does not know where .data and .bss are located - it doesn't even know that they exist. The start-up code which is executed before main() is called contains the start addresses of those sections - the addresses are hard-coded into the program. This start-up code will be in the HEX file like everything else.
The elements in points 1 to 3 are not included in the raw binary since they serve no purpose in the application; rather they are used by the linker and the debugger on the development host, and are unnecessary for program execution where all you need is the byte values and the address to write them to, which is more or less all the hex file contains (may also contain a start address record).
Systems that have dynamic linking or self-hosted debug capabilities (such as VxWorks for example) use the object file file.
With respect to point 5, the microcontroller does not need to know; the linker uses that information when resolving absolute and relative addresses in the object code. Once filly resolved (linked), the addresses are embedded in the code directly. Again where dynamic loading/linking is used the object file meta-data is required and such systems do not normally load a raw hex file or binary.
Problem scenario:
In simple words, do we have a Trace32 command to read symbols (and its contents) from ELF file that was loaded on to target ? We have this special case where application specific debug symbols of the ELF file are made as part of '.noload' section in ELF, which means the symbols/contents are present part of the ELF file (available when read using readelf -a xxxx.elf_file_name) but are not part of the final binary image generated i.e. the '.noload' section in ELF file is stripped away when generating xxx.bin which is flashed to target memory.
Debug symbols in '.noload' section are statically assigned values and these values do not change during runtime.
When I tried to read the debug symbols part of the '.noload' section (after compiling into binary and loading onto Trace32), I see 'MMU fail' flagged on trace32 popup window which means trace32 is trying to read symbol contents from memory but is not accessible, since symbols part of the '.noload' section was not loaded at all though they have addresses mapped.
Any inputs:
- I need help with a trace32 command that can directly read symbol content from ELF file than from target memory.
- Also not sure if I can use 'readelf ' in practice scripts ? Any help in this direction if we do not have any solution for above query ?
Use command
Data.LOAD.Elf myfile.elf [<optional address offset>] /NoCODE
The option /NoCODE instructs TRACE32 to only load the debgug symbols from your ELF but not to load any code to your target. You can than view the symbols with command sYmbol.Browse.
However if you use TRACE32 to load your application to your target, you don't have to create a binary from you ELF first. With TRACE32 you can also load the PROGBITS sections of your ELF directly to your target.
In this case you would simply use the Data.LOAD.Elf command without the /NoCODE option (after enabling flash programming).
Since you are using an MMU you might want to activate logical memory space IDs with command SYStem.Option.MMUSPACES ON. Then load your symbols with
Data.LOAD.Elf myfile.elf <space-ID>:<offset> /NoCODE
where 'space-ID' matches with the space-ID used by you MMU for the Task and 'offset' is usually zero.
If you are debugging your application on an embedded Linux than you should use the TRACE32 OS awareness for Linux and the Linux symbol auto-loader to load the symbols to the correct addresses for you.
I don't think there is any reason why you should use 'readelf' from within TRACE32. Anyway you can invoke any command line program with commands OS.Area or OS.Command.
I would like to add a new flag to an elf file. This flag should then be available
to the kernel in the process descriptor. My first idea was to use libelf, but unfortunately
there seems to be a bug with it on Ubuntu. Elfedit would have probably been a nice tool but I have not found a version for Linux, in particular Ubuntu.
So, I am wondering if anyone can suggest to me if there is any other useful tool out there
to add a custom flag to an elf file?
Many thanks for your help!
People who are able to modify the kernel to take advantage of the new flag probably wouldn't be asking how to add the flag to the ELF libraries.
So, how do you plan to have the kernel use this new flag? What is the purpose of the flag?
Since you are adding to the standard libelf, can't you fix the bug for Ubuntu and let them know that you've done so (make the fix available to them - though they'll probably need to relay it back up the chain).
Please look at ELFIO library. It contains WriteObj and Writer examples. By using the library, you will be able to create and/or modify ELF binary files.
(although old question but for reference I am writing answer based on my own experience)
I suggest to read elf file in memory struct, make changes to flags and load process memory with your in-memory struct. This method will need less efford as compare to bug correction. To start, check file elf.c for elf, program header, section headers struct. you can read file header in your struct which should have three struct members for elf, program, section. start read in your struct from elf header. then read program header on offset given in elf header (iteratively for all program headers). In same way you can read all sections through section headers.
encapsulating 3 headers struct in your own struct also give you oppertunity to have extra needed data in your other struct member.