elfobjdumpobjcopycarchive

How do I get the real position of a section in an ELF archive file?


I want to extract a binary section fron a .a ELF archive file in Linux.

When I run objdump -h on an archive file, it lists the object files it contains, and the section headers for each section. However, the File Offset column appears to be relative to the object file position in the archive, as otherwise they would all the sections would be overlapping.

I expected I could use dd to extract binary information from the archive file. (see How do you extract only the contents of an ELF section). How do I do this with an archive?

I should also mention the section I'm extracting is added with this command :

echo "hi" > commentFile
objcopy libmylib.a --add-section .mysection=commentFile libmylib.a

Solution

  • the File Offset column appears to be relative to the object file position in the archive

    The file offset you get from objdump is relative to the beginning of the individual object file. You can think of an archive library as a bookshelf, and the ouput of objdump -h as the index within each individual book. You wouldn't expected the index to change depending on which other books are on the shelf, or when you take the book from the shelf. Similarly, the object file itself (and the output of objdump -h) does not change when you put into the library, or extract it out again (you get bit-identical copy).

    I expected I could use dd to extract binary information from the archive file

    You could use dd, but you'd have to first find the position of each individual object file in the archive. That's not too difficult: the format of UNIX archive files is documented. But the format can change depending on which UNIX variant you use, and it's not really necessary for the task you want to perform.

    How do I do this with an archive?

    If you know that .mysection has identical contents in all object files in libmylib.a (as would be the case for the objcopy --add-section command you gave), then extract one object, from the archive, then extract the section:

    firstobj=$(ar t libmylib.a | grep '\.o$' | head -1)
    ar x libmylib.a $firstobj
    # use objdump -h and dd to extract section context.
    # or use "readelf -p .mysection $firstobj
    rm -f $firstobj
    

    If the contents of .mysection may be different in different object files, extract them to a temporary directory:

    mkdir tmp.$$ && cd tmp.$$ && ar x ../libmylib.a
    for obj in $(find . -type f); do
      # extract .mysection from $obj
    done
    cd .. && rm -rf tmp.$$