How to get src file names from ELF file - elf

How can I get the names of object files(source files will even be better) other than library from a ELF file?

How can I get the names of object files(source files will even be better) other than library from a ELF file?
What kind of ELF file?
Object file names contained in archive library are visible with ar tv libfoo.a.
In a shared library (libfoo.so) names of object files are only rarely stored (some compilers do store the entire compile command line, and that could include the output object file name).
But source filenames are commonly stored in both archive and shared libraries (built with debugging), and are visible with readelf -Wl libfoo.so.
If the library was built without debug info, source filenames are not generally available, although you could possibly get some of them with strings libfoo.so if the library was built with assertions turned on.

Related

How to generate and export one big OBJECT .o library blob from CMake instead of STATIC .a library

I am generating a STATIC library on Linux with the name myLi using CMake, but apart from myLib.a I would like to generate one big blob of .o (OBJECT) file that contains everything in it (all the sources/object files), but I can't figure out how to do it with CMake (with makefile it's easy done). I have tried the following:
set(${SOURCE_FILES} src/file1.cpp src/file2.cpp .. )
add_library(myLib OBJECT ${SOURCE_FILES})
target_link_libraries(myLib PRIVATE ${LIBS_THAT_REQUIRED})
add_library(FinalLibrary STATIC $<TARGET_OBJECTS:myLib> ...)
I would expect to find myLib.o blob somewhere, but I can't figure out how I can generate it.
Any thoughts?
TL;DR: you can't, what you describe is not an object file, and your interest in producing such an artifact is probably misplaced.
How to generate and export one big OBJECT .o library blob from CMake instead of STATIC .a library
Object files are not among the targets that CMake provides for defining. They are of course produced incidentally in the process of building program and library targets, but they are not an end goal. You might be able to set them up as custom targets, but substantially no one does this.
And they do not do it because there is nothing anyone typically wants to do with an object file that you cannot do with a static library containing that object file, or containing multiple object files that jointly contain the same content. There are, however, one or two things that you can do with a library that you cannot do directly with an object file.
I would like to generate one big blob of .o (OBJECT) file that contains everything in it (all the sources/object files)
That's not what an object file is. An object file is the result of compiling one translation unit (roughly, one source file plus any headers / included files / whatever), and it does not contain source.
And I have no idea what you have in mind to do with such a thing. An archive of the unbuilt source is potentially interesting. One or more programs or libraries built from the source is potentially interesting. An installation package containing some or all of the above is potentially interesting. But the intermediate object files are not interesting, except as stepping stones on a path to one of the others, and none of the aggregates I just listed are object files.
I would expect to find myLib.o blob somewhere, but I can't figure out how I can generate it.
I have no idea why you would expect that unless the library were built from a single source file (which seems not to be the case for you). And if it were built from a single source file then I expect that you would have been able to find the corresponding object file. Which would not contain source, unless possibly in the form of debug information.
A static library is a container for object files. They are created by compiling some number of source files to object files, then putting those object files into the library. (From which they also can be extracted, at least with many common library formats.) There is no other intermediate involved in creating one.
To get a one big object file you need to compile a one big source file. C/C++ sources can be concatenated before the compilation and this is called a Unity build.

Processing assembler files in cmake

I'm trying to create a binary file in cmake which:
- depeneds on some .c source files
- also depeneds on an assembler .s file
Now I have added the .c files normally by setting a variable as a list which contains all .c files in a directory. All good so far.
Now I need to add that assembler file as well as part of my binary directory. I did some research in the mailing archieve of cmake and I saw that with assembler files it's a little different you can't just include them as you do with the c files. You have to sometime preprocess them and include their output as a dependecy to the final binary file. Or so I understood.
The way I tried to do it in my project is something like this:
get assembler file name and path using a get_filename_component command:
in an 'add_custom_command' preprocess the file like this:
COMMAND ${COMPILER_NAME} --preprocess=p ${ASSEMBLER_FILE_NAME} >
${OUT_S_FILE}
Where OUT_S_FILE will be added as a dependency to a target which will be then added as a dependency to the binary file so that it gets created before the binary is created. Now I do not understand the --preprocess=p argument I tried googleing it but to no avail I do not know if it's correct or what it actually does(I have seen it in an example which took care of some assembler files).
set a variable: "ASM_OUT_FILE" to path of the file processed above
create a custom target which depends on this "ASM_OUT_FILE"
Finally add this target as a dependency so it gets created before the binary is created.
I'm sorry I cannot provide more actually example for what I've done but it's work related :D.
The result is "no rule to make target for that assembler file" as if the file was not there but it is(I checked).
Please tell me if possible if there are other things I need to do or if I'm doing something wrong in handling this assembler file. Thank you for reading and I'm sorry if my erxplanation was not so clear!
Edit:
set_source_files_properties(assembly_file.s PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp")

Trace32 command to read symbol contents from ELF file

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.

distinguish shared objects from position independent executables

I'm looking for a fast way to check if a ELF binary is a shared object or a position independent executable. I think a can do that by checking the contained symbols / functions. I'm looking for a more efficient way of not having to read the complete file. I have to perform the check on different platforms, at least Android, Linux (32 and 64 bit).
I'm looking for a fast way to check if a ELF binary is a shared object or a position independend executable.
There is no way to check: a PIE executable is a shared object.
I think a can do that by checking the contained symbols / functions.
Symbols can be stripped, and once they are, you can't tell.
shared objects and executables they normally differ by the linked startup code
That's true: the PIE is normally linked with Scrt1.o, but a shared library is normally not. But there is nothing to prevent a shared library to be linked with Scrt1.o as well, and in a stripped binary even finding that startup code may be somewhat problematic.
If what you really want is to distinguish between a shared library and a PIE executable which you built yourself (rather than solving a general case of any shared library and any PIE), then checking for presence of PT_INTERP (readelf -l a.out | grep INTERP) is likely the easiest way to go: a PIE executable is guaranteed to have PT_INTERP, and shared libraries normally don't have it (libc.so.6 is a notable exception).
Try the elfutils and the included program eh-readelf:
eh-readelf --file-header $ELFFILE
showw you the file header and what kind of file it is:
...
Typ: EXEC (Executable file)
...
or
Typ: DYN (Shared object file)
In combination with a little sed line you should get the results you want.

Why would the size of the final binary be so much smaller than the size of the static library?

This is an iOS question.
I build a static library (a framework in iOS) which is then included in an app. The size of the result binary (500kb) is smaller than the size of the static library (6mb). How does this work? My understanding of static library is that the static library is included in the final binary
Because you are not using all the functions of your library. A static library of archive type .a is a collection of .o object files and only the object files needed in your program are included at link time.
Whenever you statically link an executable, the linker can go ahead and resolve all symbol names (i.e. map them to an address) since all the symbols it will know about you have provided to the linker now (in the form of .o files and .a libraries which are really just a collection of .o files). If there are names that aren't there, you'll get a link error (this is different than dynamic linking where you may be able to load another library at runtime). In your case, you have extra symbols that are unreferenced by the executable. Since these symbols are known to the linker as being unused they are simply removed from the executable output. So your executable will be smaller than the input libraries in this case.