My intention is to read an ELF file, then append some data to the end of a
section, then update the existing ELF file.
I wrote a small example program that works fine with libelfg0, but it fails
to append with elfutils (it replaces the data instead of appending to it).
The following is observed on Ubuntu-11.10 (installed version of libelf1 is
0.152). I have attached a small example program that demonstrates the
behavior.
With libelfg0 version 0.8.13 the effect of the elf_newdata() call is to
__append__ the new data buffer to the end of any existing data in a section.
However, with libelf1 the elf_newdata() call actually __replaces__ existing
data when elf_update() executes.
The man page at
http://docs.oracle.com/cd/E19253-01/816-5172/elf-getdata-3elf/index.htmlsuggests
that appending is the intended behavior. Can anyone confirm this?
It would be very inconvenient to have two libraries in the world that seem
to provide the same source-level API but with slightly different semantics
...
Thanks for clearing this up,
Paul Stravers
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <libelf.h>
#include <gelf.h>
void __attribute__ ((noreturn)) err(const char *msg, ...)
{
va_list ap;
va_start(ap,msg);
fprintf(stderr,"Error: ");
vfprintf(stderr,msg,ap);
fprintf(stderr,"\n");
fflush(stderr);
exit(1);
va_end(ap);
}
Elf_Scn *get_symbol_strtab(Elf *elf)
{
Elf_Scn *scn = NULL;
while ((scn = elf_nextscn(elf, scn)) != NULL)
{
GElf_Shdr shdr;
gelf_getshdr(scn, &shdr);
if (shdr.sh_type == SHT_SYMTAB)
{
GElf_Shdr symtab_shdr;
gelf_getshdr(scn, &symtab_shdr);
size_t strtab_ndx = symtab_shdr.sh_link;
return elf_getscn(elf, strtab_ndx);
}
}
return NULL;
}
int main(int argc, const char *argv[])
{
/* ***** open an ELF object in read/write mode *****
*/
if (argc != 2)
err("Usage: %s elf_file", argv[0]);
const char *elf_file = argv[1];
if (elf_version(EV_CURRENT) == EV_NONE)
err("ELF library is out-dated, cannot handle ELF object");
int elf_fd = open(elf_file, O_RDWR);
if (elf_fd == -1)
err("cannot open %s", elf_file);
Elf *elf = elf_begin(elf_fd, ELF_C_RDWR, NULL);
Elf_Kind kind = elf_kind(elf);
if (kind != ELF_K_ELF)
err("%s is not an ELF object", elf_file);
/* ***** append a string to first STRTAB in the object *****
*/
Elf_Scn *strtab_scn = get_symbol_strtab(elf);
if (strtab_scn == NULL)
err("cannot find strtab");
Elf_Data *data = elf_newdata(strtab_scn);
/* NOTE: with libelfg0 version 0.8.13 the effect of the
* elf_newdata() call is to append the new data buffer to the end of
* the existing data in strtab_scn. HOWEVER, with libelf1 the
* elf_newdata() actually __replaces__ the existing data when
* elf_update() executes (on Ubuntu-11.10). The man page at
* http://docs.oracle.com/cd/E19253-01/816-5172/elf-getdata-3elf/index.html
* suggest that appending is the intended behavior.
*/
char *append_this = strdup("append_this");
data->d_buf = append_this;
data->d_size = 1 + strlen(append_this);
data->d_align = 0;
data->d_type = ELF_T_BYTE;
/* ***** write-back the updated image to the ELF file *****
*/
loff_t file_sz = elf_update(elf, ELF_C_WRITE);
if (file_sz == -1)
err("cannot update ELF image");
printf("Updated object file %s with new size %lld\n", elf_file, (long long)file_sz);
if (elf_end(elf) != 0)
err("cannot terminate ELF editing session");
if (close(elf_fd) == -1)
err("cannot close ELF object file %s", elf_file);
return 0;
}
_______________________________________________
elfutils-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/elfutils-devel