Blame tests/elfshphehdr.c

Packit Service 97d2fb
/* Test program for adding section and program headers and ehdr updates.
Packit Service 97d2fb
   Copyright (C) 2015 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of the GNU General Public License as published by
Packit Service 97d2fb
   the Free Software Foundation; either version 3 of the License, or
Packit Service 97d2fb
   (at your option) any later version.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 97d2fb
   GNU General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received a copy of the GNU General Public License
Packit Service 97d2fb
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#include <config.h>
Packit Service 97d2fb
#include <assert.h>
Packit Service 97d2fb
#include ELFUTILS_HEADER(elf)
Packit Service 97d2fb
#include <gelf.h>
Packit Service 97d2fb
Packit Service 97d2fb
#include <stdio.h>
Packit Service 97d2fb
#include <stdlib.h>
Packit Service 97d2fb
Packit Service 97d2fb
#include <sys/types.h>
Packit Service 97d2fb
#include <sys/stat.h>
Packit Service 97d2fb
#include <fcntl.h>
Packit Service 97d2fb
#include <unistd.h>
Packit Service 97d2fb
Packit Service 97d2fb
#include <stdbool.h>
Packit Service 97d2fb
Packit Service 97d2fb
void
Packit Service 97d2fb
check (const char *msg, bool statement)
Packit Service 97d2fb
{
Packit Service 97d2fb
  if (! statement)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      fprintf (stderr, "%s FAILED\n", msg);
Packit Service 97d2fb
      exit (-1);
Packit Service 97d2fb
    }
Packit Service 97d2fb
  else
Packit Service 97d2fb
    fprintf (stderr, "%s OK\n", msg);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
void
Packit Service 97d2fb
check_elf (const char *msg, bool statement)
Packit Service 97d2fb
{
Packit Service 97d2fb
  if (! statement)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      fprintf (stderr, "%s: %s\n", msg, elf_errmsg (-1));
Packit Service 97d2fb
      exit (-1);
Packit Service 97d2fb
    }
Packit Service 97d2fb
  else
Packit Service 97d2fb
    fprintf (stderr, "%s OK\n", msg);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
void
Packit Service 97d2fb
test (Elf *elf, int class, bool layout)
Packit Service 97d2fb
{
Packit Service 97d2fb
  fprintf (stderr, "testing ELF class: %d, layout: %d\n", class, layout);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("gelf_newehdr", gelf_newehdr (elf, class) != 0);
Packit Service 97d2fb
  check_elf ("gelf_getclass", gelf_getclass (elf) == class);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_flagelf", elf_flagelf (elf, layout ? ELF_C_SET : ELF_C_CLR,
Packit Service 97d2fb
					 ELF_F_LAYOUT) != 0);
Packit Service 97d2fb
Packit Service 97d2fb
  GElf_Ehdr ehdr;
Packit Service 97d2fb
  check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
Packit Service 97d2fb
  check ("e_shnum == 0", ehdr.e_shnum == 0);
Packit Service 97d2fb
  check ("e_phnum == 0", ehdr.e_phnum == 0);
Packit Service 97d2fb
  check ("e_shoff == 0", ehdr.e_shoff == 0);
Packit Service 97d2fb
  check ("e_phoff == 0", ehdr.e_phoff == 0);
Packit Service 97d2fb
Packit Service 97d2fb
  size_t shnum;
Packit Service 97d2fb
  check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0);
Packit Service 97d2fb
  check ("shnum == 0", shnum == 0);
Packit Service 97d2fb
Packit Service 97d2fb
  size_t phnum;
Packit Service 97d2fb
  check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0);
Packit Service 97d2fb
  check ("phnum == 0", phnum == 0);
Packit Service 97d2fb
Packit Service 97d2fb
  /* Lets fill in some info we are always responsible for.  */
Packit Service 97d2fb
  ehdr.e_ident[EI_DATA] = ELFDATANONE; /* Ask for native encoding.  */
Packit Service 97d2fb
  ehdr.e_type = ET_EXEC;
Packit Service 97d2fb
  ehdr.e_machine = EM_386;
Packit Service 97d2fb
  ehdr.e_version = EV_NONE; /* Ask for current version. */
Packit Service 97d2fb
  check_elf ("gelf_update_ehdr", gelf_update_ehdr (elf, &ehdr) != 0);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_update", elf_update (elf, ELF_C_NULL) > 0);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
Packit Service 97d2fb
  check ("EI_DATA", ehdr.e_ident[EI_DATA] != ELFDATANONE);
Packit Service 97d2fb
  check ("e_version", ehdr.e_version == EV_CURRENT);
Packit Service 97d2fb
Packit Service 97d2fb
  /* The sh/ph values shouldn't have changed.  */
Packit Service 97d2fb
  check ("e_shnum == 0", ehdr.e_shnum == 0);
Packit Service 97d2fb
  check ("e_phnum == 0", ehdr.e_phnum == 0);
Packit Service 97d2fb
  check ("e_shoff == 0", ehdr.e_shoff == 0);
Packit Service 97d2fb
  check ("e_phoff == 0", ehdr.e_phoff == 0);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0);
Packit Service 97d2fb
  check ("shnum == 0", shnum == 0);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0);
Packit Service 97d2fb
  check ("phnum == 0", phnum == 0);
Packit Service 97d2fb
Packit Service 97d2fb
  /* Lets add a header.  */
Packit Service 97d2fb
  check_elf ("elf_newscn", elf_newscn (elf) != NULL);
Packit Service 97d2fb
  check_elf ("gelf_newphdr", gelf_newphdr (elf, 1) != 0);
Packit Service 97d2fb
Packit Service 97d2fb
  /* If we are responsible for the layout ourselves we should also
Packit Service 97d2fb
     tell where to put them.  */
Packit Service 97d2fb
  if (layout)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
Packit Service 97d2fb
      /* phdrs go right after the ehdr.  */
Packit Service 97d2fb
      ehdr.e_phoff = ehdr.e_ehsize;
Packit Service 97d2fb
      /* shdrs go right after the phdrs.  */
Packit Service 97d2fb
      ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
Packit Service 97d2fb
      check_elf ("gelf_update_ehdr", gelf_update_ehdr (elf, &ehdr) != 0);
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_update", elf_update (elf, ELF_C_NULL) > 0);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0);
Packit Service 97d2fb
  check ("shnum == 1", shnum == 2); /* section zero is also created.  */
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0);
Packit Service 97d2fb
  check ("phnum == 1", phnum == 1);
Packit Service 97d2fb
Packit Service 97d2fb
  check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
Packit Service 97d2fb
Packit Service 97d2fb
  check ("EI_DATA", ehdr.e_ident[EI_DATA] != ELFDATANONE);
Packit Service 97d2fb
  check ("e_version", ehdr.e_version == EV_CURRENT);
Packit Service 97d2fb
Packit Service 97d2fb
  check ("e_shnum == 2", ehdr.e_shnum == 2);
Packit Service 97d2fb
  check ("e_phnum == 1", ehdr.e_phnum == 1);
Packit Service 97d2fb
  check ("e_shoff != 0", ehdr.e_shoff != 0);
Packit Service 97d2fb
  check ("e_phoff != 0", ehdr.e_phoff != 0);
Packit Service 97d2fb
Packit Service 97d2fb
  size_t shentsize = (class == ELFCLASS32
Packit Service 97d2fb
		      ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr));
Packit Service 97d2fb
  check ("e_shentsize", ehdr.e_shentsize == shentsize);
Packit Service 97d2fb
  size_t phentsize = (class == ELFCLASS32
Packit Service 97d2fb
		      ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr));
Packit Service 97d2fb
  check ("e_phentsize", ehdr.e_phentsize == phentsize);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
main (int argc __attribute__ ((unused)), char **argv __attribute ((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
  elf_version (EV_CURRENT);
Packit Service 97d2fb
Packit Service 97d2fb
  int fd = open("/dev/null", O_WRONLY);
Packit Service 97d2fb
  check ("open", fd >= 0);
Packit Service 97d2fb
Packit Service 97d2fb
  Elf *elf;
Packit Service 97d2fb
Packit Service 97d2fb
  elf = elf_begin (fd, ELF_C_WRITE, NULL);
Packit Service 97d2fb
  check_elf ("elf_begin", elf != NULL);
Packit Service 97d2fb
  test (elf, ELFCLASS32, false);
Packit Service 97d2fb
  elf_end (elf);
Packit Service 97d2fb
Packit Service 97d2fb
  elf = elf_begin (fd, ELF_C_WRITE, NULL);
Packit Service 97d2fb
  check_elf ("elf_begin", elf != NULL);
Packit Service 97d2fb
  test (elf, ELFCLASS32, true);
Packit Service 97d2fb
  elf_end (elf);
Packit Service 97d2fb
Packit Service 97d2fb
  elf = elf_begin (fd, ELF_C_WRITE, NULL);
Packit Service 97d2fb
  check_elf ("elf_begin", elf != NULL);
Packit Service 97d2fb
  test (elf, ELFCLASS64, false);
Packit Service 97d2fb
  elf_end (elf);
Packit Service 97d2fb
Packit Service 97d2fb
  elf = elf_begin (fd, ELF_C_WRITE, NULL);
Packit Service 97d2fb
  check_elf ("elf_begin", elf != NULL);
Packit Service 97d2fb
  test (elf, ELFCLASS64, true);
Packit Service 97d2fb
  elf_end (elf);
Packit Service 97d2fb
Packit Service 97d2fb
  close (fd);
Packit Service 97d2fb
  return 0;
Packit Service 97d2fb
}