I'm trying to manipulate ARM elf binaries on linux using the libelf library without success. Even a minimal test-case corrupts my binaries, and I don't know why.
Here is my minimal test-code which reads an elf-file and then simply writes it back:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <libelf.h>
#include <assert.h>
void main (void)
{
if (elf_version(EV_CURRENT) == EV_NONE)
return;
int fd = open ("HelloWorld.elf", O_RDWR);
assert (fd);
Elf *e = elf_begin(fd, ELF_C_RDWR, (Elf *) 0);
assert (e);
if (elf_update(e, ELF_C_WRITE) == -1)
return;
elf_end (e);
close (fd);
printf ("ok\n");
return;
}
If I run this code on a ELF 64-bit x86-64 executable I get a bit-exact copy of the elf-file back. That's what I expected.
If however I pass in an ARM 32-bit executable the file gets corrupted. It's still an elf-file and I can parse it just fine, but the section offsets have been modified and worse: The section to Segment mapping gets corrupted:
Before running my code the mapping looks like this:
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01 .text .ARM.exidx
02 .data .bss
And after running my code it becomes:
Section to Segment mapping:
Segment Sections...
00
01 .ARM.exidx .heap .stack_dummy .ARM.attributes .comment .svc_table
02 .bss
If I convert the modified elf binary to a flash image using objcopy I only get garbage out.
So is there anything I should do to make the libelf library work with arm binaries?
Background:
I'm writing a little utility to calculate some checksums and insert them into the elf binary. That's required my microcontroller and unfortunately gnu LD can't do it on it's own. I thought using a high-level ELF manipulation library would be the best and most robust way to get this working.