/* Copyright (C) 2002, 2005 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 2002.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <fcntl.h>
#include ELFUTILS_HEADER(asm)
#include <libelf.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


static const char fname[] = "asm-tst3-out.o";


static const char *scnnames[5] =
  {
    [0] = "",
    [1] = ".data",
    [2] = ".strtab",
    [3] = ".symtab",
    [4] = ".shstrtab"
  };


static unsigned int scntypes[5] =
  {
    [0] = SHT_NULL,
    [1] = SHT_PROGBITS,
    [2] = SHT_STRTAB,
    [3] = SHT_SYMTAB,
    [4] = SHT_STRTAB
  };


int
main (void)
{
  AsmCtx_t *ctx;
  AsmScn_t *scn1;
  AsmScn_t *scn2;
  int result = 0;
  int fd;
  Elf *elf;
  GElf_Ehdr ehdr_mem;
  GElf_Ehdr *ehdr;
  size_t cnt;

  elf_version (EV_CURRENT);

  Ebl *ebl = ebl_openbackend_machine (EM_386);
  if (ebl == NULL)
    {
      puts ("cannot open backend library");
      return 1;
    }

  ctx = asm_begin (fname, ebl, false);
  if (ctx == NULL)
    {
      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
      return 1;
    }

  /* Create two sections.  */
  scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
  scn2 = asm_newsubscn (scn1, 1);
  if (scn1 == NULL || scn2 == NULL)
    {
      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Special alignment for the .text section.  */
  if (asm_align (scn1, 16) != 0)
    {
      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
      result = 1;
    }

  /* Add a few strings with names.  */
  if (asm_newsym (scn1, "one", 4, STT_OBJECT, STB_GLOBAL) == NULL)
    {
      printf ("cannot create first name: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_addstrz (scn1, "one", 4) != 0)
    {
      printf ("cannot insert first string: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_newsym (scn2, "three", 6, STT_OBJECT, STB_WEAK) == NULL)
    {
      printf ("cannot create second name: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_addstrz (scn2, "three", 0) != 0)
    {
      printf ("cannot insert second string: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_newsym (scn1, "two", 4, STT_OBJECT, STB_LOCAL) == NULL)
    {
      printf ("cannot create third name: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_addstrz (scn1, "two", 4) != 0)
    {
      printf ("cannot insert third string: %s\n", asm_errmsg (-1));
      result = 1;
    }

  /* Create the output file.  */
  if (asm_end (ctx) != 0)
    {
      printf ("cannot create output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Check the file.  */
  fd = open (fname, O_RDONLY);
  if (fd == -1)
    {
      printf ("cannot open generated file: %m\n");
      result = 1;
      goto out;
    }

  elf = elf_begin (fd, ELF_C_READ, NULL);
  if (elf == NULL)
    {
      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close;
    }
  if (elf_kind (elf) != ELF_K_ELF)
    {
      puts ("not a valid ELF file");
      result = 1;
      goto out_close2;
    }

  ehdr = gelf_getehdr (elf, &ehdr_mem);
  if (ehdr == NULL)
    {
      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close2;
    }

  for (cnt = 1; cnt < 5; ++cnt)
    {
      Elf_Scn *scn;
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr;

      scn = elf_getscn (elf, cnt);
      if (scn == NULL)
	{
	  printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr == NULL)
	{
	  printf ("cannot get section header for section %Zd: %s\n",
		  cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
		  scnnames[cnt]) != 0)
	{
	  printf ("section %Zd's name differs: %s vs %s\n", cnt,
		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
		  scnnames[cnt]);
	  result = 1;
	}

      if (shdr->sh_type != scntypes[cnt])
	{
	  printf ("section %Zd's type differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
	  || (cnt != 1 && shdr->sh_flags != 0))
	{
	  printf ("section %Zd's flags differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_addr != 0)
	{
	  printf ("section %Zd's address differs\n", cnt);
	  result = 1;
	}

      if (cnt == 3)
	{
	  Elf_Data *data;

	  if (shdr->sh_link != 2)
	    {
	      puts ("symbol table has incorrect link");
	      result = 1;
	    }

	  data = elf_getdata (scn, NULL);
	  if (data == NULL)
	    {
	      puts ("cannot get data of symbol table");
	      result = 1;
	    }
	  else
	    {
	      size_t inner;

	      for (inner = 1;
		   inner < (shdr->sh_size
			    / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
		   ++inner)
		{
		  GElf_Sym sym_mem;
		  GElf_Sym *sym;

		  sym = gelf_getsym (data, inner, &sym_mem);
		  if (sym == NULL)
		    {
		      printf ("cannot get symbol %zu: %s\n",
			      inner, elf_errmsg (-1));
		      result = 1;
		    }
		  else
		    {
		      /* The order of the third and fourth entry depends
			 on how the hash table is organized.  */
		      static const char *names[4] =
			{
			  [0] = "",
			  [1] = "two",
			  [2] = "one",
			  [3] = "three"
			};
		      static const int info[4] =
			{
			  [0] = GELF_ST_INFO (STB_LOCAL, STT_NOTYPE),
			  [1] = GELF_ST_INFO (STB_LOCAL, STT_OBJECT),
			  [2] = GELF_ST_INFO (STB_GLOBAL, STT_OBJECT),
			  [3] = GELF_ST_INFO (STB_WEAK, STT_OBJECT)
			};
		      static const unsigned value[4] =
			{
			  [0] = 0,
			  [1] = 4,
			  [2] = 0,
			  [3] = 8
			};

		      if (strcmp (names[inner],
				  elf_strptr (elf, shdr->sh_link,
					      sym->st_name)) != 0)
			{
			  printf ("symbol %zu has different name\n", inner);
			  result = 1;
			}

		      if (sym->st_value != value[inner])
			{
			  printf ("symbol %zu has wrong value\n", inner);
			  result = 1;
			}

		      if (sym->st_other != 0)
			{
			  printf ("symbol %zu has wrong other info\n", inner);
			  result = 1;
			}

		      if (sym->st_shndx != 1)
			{
			  printf ("symbol %zu has wrong section reference\n",
				  inner);
			  result = 1;
			}

		      if (sym->st_info != info[inner])
			{
			  printf ("symbol %zu has wrong type or binding\n",
				  inner);
			  result = 1;
			}

		      if ((inner != 3 && sym->st_size != 4)
			  || (inner == 3 && sym->st_size != 6))
			{
			  printf ("symbol %zu has wrong size\n", inner);
			  result = 1;
			}
		    }
		}
	    }
	}
    }

 out_close2:
  elf_end (elf);
 out_close:
  close (fd);
 out:
  /* We don't need the file anymore.  */
  unlink (fname);

  ebl_closebackend (ebl);

  return result;
}
