This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

elf_newdata() does not append


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
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.html suggests 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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]