Hi there elfutils-devel'ers!
I am writing an application which is being used internally to flag ELF objects in our team .. the idea is that we want to be able to add a custom NOTE to our internal binaries to assist with tracking our builds and so on. We do not wish to change our toolchain, thus using the 'ld --build-id' feature isn't really feasible at the moment, so I have been given the responsibility of using libelf to accomplish the same thing ..
In order to make this 'easy', I have decided that my tool will take two args - INFILE and OUTFILE - and simply process the ELF objects of INFILE through libelf, writing them all out to OUTFILE, and then .. when done .. appending a new NOTE Section to the OUTFILE. I have seen this technique working just fine .. e.g. in the elfutils test suite .. so I believe this is an acceptable approach for me so far.
All works fine - I am able to copy the files smoothly, as well as locate my own NOTE section that will be copied into the new binary .. this NOTE section is stored in my tool using __attribute__((section(OURSECTION_NAME)) and I retrieve this section (for 'cloning') before I do the write-out to the new OUTFILE..
However.. I am getting this error when I attempt to elf_update() the OUTFILE:
ecpnoter: elf32_updatefile.c:622: __elf32_updatefile: Assertion `last_offset < scn_start + dl->data.d.d_off' failed.
(ecpnoter is the name of my tool) ..
Does this mean that the last_offset of my newly added section is greater than the length of data in my section?
Am I correct in assuming that the Section Header for OUTFILE needs to be adjusted - or flag'ed in some way - in order to make elf_update re-adjust all the sections to accomodate the newly added section and that I do *not* have to manually adjust the section header itself, somehow?
Please note that I am copying the old EHDR and PHDR's from INFILE to OUTFILE at the beginning of the process .. how do I get ehdr->e_shnum incremented "automagically" to accomodate the newly added NOTE section? I assume (correct me please) that the elf_* functions can be told to re-compute these headers appropriately, no?
Right now I'm doing this :
/* Flag our ELF objects for update */ elf_flagelf(out_elf, ELF_C_SET, ELF_F_LAYOUT); elf_flagphdr(out_elf, ELF_C_SET, ELF_F_DIRTY); elf_flagshdr(new_scn_p, ELF_C_SET, ELF_F_DIRTY);
.. but I'm not sure this is correct, as I am really struggling to understand fully the libelf functionality with the given *ahem* documentation ..
Any help provided is greatly appreciated, especially if my_cluefulness++; // happens .. :)
You cannot add an SHF_ALLOC section to an already-final (non-ET_REL) ELF file without doing a lot more work. If you want a non-allocated section created with the compiler, you have to play some games with asm () to get the section flags right. For adding a simple string or binary blob, it is easier to write or generate assembly source where you write exactly the section directive you want (.section .note.foo, "", @note).
If you use ELF_F_LAYOUT (which you must unless you recompute the phdrs too), then you have to set sh_offset manually in your new section.
Indeed you do not have to adjust e_shnum; that is automatic in elf_update after you have used elf_newscn. Of course, you do need to add your section's name to .shstrtab.
You may find it easier to write a script using objcopy --add-section (binutils) rather than writing your own tool with libelf.
Thanks, Roland
elfutils-devel@lists.fedorahosted.org