/* Finalize operations on the assembler context, free all resources.
   Copyright (C) 2002, 2003 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 <assert.h>
#include <error.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

#include <libasmP.h>
#include <libelf.h>
#include <system.h>


static int
text_end (AsmCtx_t *ctx)
{
  // XXX Does anything have to be done?
  return 0;
}


static int
binary_end (AsmCtx_t *ctx)
{
  void *symtab = NULL;
  struct Ebl_Strent *symscn_strent = NULL;
  struct Ebl_Strent *strscn_strent = NULL;
  struct Ebl_Strent *xndxscn_strent = NULL;
  Elf_Scn *shstrscn;
  struct Ebl_Strent *shstrscn_strent;
  size_t shstrscnndx;
  size_t symscnndx = 0;
  size_t strscnndx = 0;
  size_t xndxscnndx = 0;
  Elf_Data *data;
  Elf_Data *shstrtabdata;
  Elf_Data *strtabdata = NULL;
  Elf_Data *xndxdata = NULL;
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  GElf_Ehdr ehdr_mem;
  GElf_Ehdr *ehdr;
  AsmScn_t *asmscn;
  int result = 0;

  /* Iterate over the created sections and compute the offsets of the
     various subsections and fill in the content.  */
  for (asmscn = ctx->section_list; asmscn != NULL; asmscn = asmscn->allnext)
    {
#if 0
      Elf_Scn *scn = elf_getscn (ctx->out.elf, asmscn->data.main.scnndx);
#else
      Elf_Scn *scn = asmscn->data.main.scn;
#endif
      off_t offset = 0;
      AsmScn_t *asmsubscn = asmscn;

      do
	{
	  struct AsmData *content = asmsubscn->content;
	  bool first = true;

	  offset = ((offset + asmsubscn->max_align - 1)
		    & ~(asmsubscn->max_align - 1));

	  /* Update the offset for this subsection.  This field now
	     stores the offset of the first by in this subsection.  */
	  asmsubscn->offset = offset;

	  /* Note that the content list is circular.  */
	  if (content != NULL)
	    do
	      {
		Elf_Data *newdata = elf_newdata (scn);

		if (newdata == NULL)
		  error (EXIT_FAILURE, 0,
			 _("cannot create section for output file: %s"),
			 elf_errmsg (-1));

		newdata->d_buf = content->data;
		newdata->d_type = ELF_T_BYTE;
		newdata->d_size = content->len;
		newdata->d_off = offset;
		newdata->d_align = first ? asmsubscn->max_align : 1;

		offset += content->len;
	      }
	    while ((content = content->next) != asmsubscn->content);
	}
      while ((asmsubscn = asmsubscn->subnext) != NULL);
    }


  /* Create the symbol table if necessary.  */
  if (ctx->nsymbol_tab > 0)
    {
      Elf_Scn *symscn;
      Elf_Scn *strscn;
      AsmSym_t *sym;
      int ptr_local;
      int ptr_nonlocal;
      GElf_Sym syment;
      uint32_t *xshndx = NULL;
      void *runp;

      /* Create the symbol table and string table section names.  */
      symscn_strent = ebl_strtabadd (ctx->section_strtab, ".symtab", 8);
      strscn_strent = ebl_strtabadd (ctx->section_strtab, ".strtab", 8);

      /* Create the symbol string table section.  */
      strscn = elf_newscn (ctx->out.elf);
      strtabdata = elf_newdata (strscn);
      shdr = gelf_getshdr (strscn, &shdr_mem);
      if (strtabdata == NULL || shdr == NULL)
	error (EXIT_FAILURE, 0, _("cannot create section for output file: %s"),
	       elf_errmsg (-1));
      strscnndx = elf_ndxscn (strscn);

      ebl_strtabfinalize (ctx->symbol_strtab, strtabdata);

      shdr->sh_type = SHT_STRTAB;
      assert (shdr->sh_entsize == 0);

      (void) gelf_update_shdr (strscn, shdr);

      /* Create the symbol table section.  */
      symscn = elf_newscn (ctx->out.elf);
      data = elf_newdata (symscn);
      shdr = gelf_getshdr (symscn, &shdr_mem);
      if (data == NULL || shdr == NULL)
	error (EXIT_FAILURE, 0, _("cannot create section for output file: %s"),
	       elf_errmsg (-1));
      symscnndx = elf_ndxscn (symscn);

      /* We know how many symbols there will be in the symbol table.  */
      data->d_size = gelf_fsize (ctx->out.elf, ELF_T_SYM,
				 ctx->nsymbol_tab + 1, EV_CURRENT);
      symtab = malloc (data->d_size);
      if (symtab == NULL)
	return -1;
      data->d_buf = symtab;
      data->d_type = ELF_T_SYM;
      data->d_off = 0;

      /* Clear the first entry.  */
      memset (&syment, '\0', sizeof (syment));
      (void) gelf_update_sym (data, 0, &syment);

      /* Iterate over the symbol table.  */
      runp = NULL;
      ptr_local = 1;		/* Start with index 1; zero remains unused.  */
      ptr_nonlocal = ctx->nsymbol_tab;
      while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL)
	if (asm_emit_symbol_p (ebl_string (sym->strent)))
	  {
	    int ptr;
	    Elf32_Word ndx;
	    Elf_Scn *scn;

	    assert (ptr_local <= ptr_nonlocal);

	    syment.st_name = ebl_strtaboffset (sym->strent);
	    syment.st_info = GELF_ST_INFO (sym->binding, sym->type);
	    syment.st_other = 0;
	    syment.st_value = sym->scn->offset + sym->offset;
	    syment.st_size = sym->size;

	    /* Add local symbols at the beginning, the other from
	       the end.  */
	    ptr = sym->binding == STB_LOCAL ? ptr_local++ : ptr_nonlocal--;

	    /* Determine the section index.  We have to handle the
	       overflow correctly.  */
	    scn = (sym->scn->subsection_id == 0
		   ? sym->scn->data.main.scn
		   : sym->scn->data.up->data.main.scn);

	    if (unlikely (scn == ASM_ABS_SCN))
	      ndx = SHN_ABS;
	    else if (unlikely (scn == ASM_COM_SCN))
	      ndx = SHN_COMMON;
	    else if (unlikely ((ndx = elf_ndxscn (scn)) >= SHN_LORESERVE))
	      {
		if (unlikely (xshndx == NULL))
		  {
		    /* The extended section index section does not yet
		       exist.  */
		    Elf_Scn *xndxscn;
		    size_t symscnndx = elf_ndxscn (symscn);

		    xndxscn = elf_newscn (ctx->out.elf);
		    xndxdata = elf_newdata (xndxscn);
		    shdr = gelf_getshdr (xndxscn, &shdr_mem);
		    if (xndxdata == NULL || shdr == NULL)
		      error (EXIT_FAILURE, 0, _("\
cannot create extended section index table: %s"),
			     elf_errmsg (-1));
		    xndxscnndx = elf_ndxscn (xndxscn);

		    shdr->sh_type = SHT_SYMTAB_SHNDX;
		    shdr->sh_entsize = sizeof (Elf32_Word);
		    shdr->sh_addralign = sizeof (Elf32_Word);
		    shdr->sh_link = symscnndx;

		    (void) gelf_update_shdr (xndxscn, shdr);

		    xndxscn_strent = ebl_strtabadd (ctx->section_strtab,
						    ".symtab_shndx", 14);

		    /* Note that using 'elf32_fsize' instead of
		       'gelf_fsize' here is correct.  */
		    xndxdata->d_size = elf32_fsize (ELF_T_WORD,
						    ctx->nsymbol_tab + 1,
						    EV_CURRENT);
		    xshndx = xndxdata->d_buf = calloc (1, xndxdata->d_size);
		    if (xshndx == NULL)
		      return -1;
		    /* Using ELF_T_WORD here relies on the fact that the
		       32- and 64-bit types are the same size.  */
		    xndxdata->d_type = ELF_T_WORD;
		    xndxdata->d_off = 0;
		  }

		/* Store the real section index in the extended setion
		   index table.  */
		assert ((size_t) ptr < ctx->nsymbol_tab + 1);
		xshndx[ptr] = ndx;

		/* And signal that this happened.  */
		ndx = SHN_XINDEX;
	      }
	    syment.st_shndx = ndx;

	    /* Remember where we put the symbol.  */
	    sym->symidx = ptr;

	    (void) gelf_update_sym (data, ptr, &syment);
	  }

      assert (ptr_local == ptr_nonlocal + 1);

      shdr->sh_type = SHT_SYMTAB;
      shdr->sh_link = strscnndx;
      shdr->sh_info = ptr_local;
      shdr->sh_entsize = gelf_fsize (ctx->out.elf, ELF_T_SYM, 1, EV_CURRENT);
      shdr->sh_addralign = gelf_fsize (ctx->out.elf, ELF_T_ADDR, 1,
				       EV_CURRENT);

      (void) gelf_update_shdr (symscn, shdr);
    }


  /* Create the section header string table section and fill in the
     references in the section headers.  */
  shstrscn = elf_newscn (ctx->out.elf);
  shstrtabdata = elf_newdata (shstrscn);
  shdr = gelf_getshdr (shstrscn, &shdr_mem);
  if (shstrscn == NULL || shstrtabdata == NULL || shdr == NULL)
    error (EXIT_FAILURE, 0, _("cannot create section for output file: %s"),
	   elf_errmsg (-1));


  /* Add the name of the section header string table.  */
  shstrscn_strent = ebl_strtabadd (ctx->section_strtab, ".shstrtab", 10);

  ebl_strtabfinalize (ctx->section_strtab, shstrtabdata);

  shdr->sh_type = SHT_STRTAB;
  assert (shdr->sh_entsize == 0);
  shdr->sh_name = ebl_strtaboffset (shstrscn_strent);

  (void) gelf_update_shdr (shstrscn, shdr);


  /* Create the section groups.  */
  if (ctx->groups != NULL)
    {
      AsmScnGrp_t *runp = ctx->groups->next;

      do
	{
	  Elf_Scn *scn;
	  GElf_Shdr shdr_mem;
	  GElf_Shdr *shdr;
	  Elf_Data *data;
	  Elf32_Word *grpdata;

	  scn = runp->scn;
	  assert (scn != NULL);
	  shdr = gelf_getshdr (scn, &shdr_mem);
	  assert (shdr != NULL);

	  data = elf_newdata (scn);
	  if (data == NULL)
	    error (EXIT_FAILURE, 0,
		   _("cannot create section group for output file: %s"),
		   elf_errmsg (-1));

	  /* It is correct to use 'elf32_fsize' instead of 'gelf_fsize'
	     here.  */
	  data->d_size = elf32_fsize (ELF_T_WORD, runp->nmembers + 1,
				      EV_CURRENT);
	  grpdata = data->d_buf = malloc (data->d_size);
	  if (grpdata == NULL)
	    return -1;
	  data->d_type = ELF_T_WORD;
	  data->d_off = 0;
	  data->d_align = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT);

	  /* The first word of the section is filled with the flag word.  */
	  *grpdata++ = runp->flags;

	  if (runp->members != NULL)
	    {
	      AsmScn_t *member = runp->members->data.main.next_in_group;

	      do
		{
		  /* Only sections, not subsections, can be registered
		     as member of a group.  The subsections get
		     automatically included.  */
		  assert (member->subsection_id == 0);

		  *grpdata++ = elf_ndxscn (member->data.main.scn);
		}
	      while ((member = member->data.main.next_in_group)
		     != runp->members->data.main.next_in_group);
	    }

	  /* Construct the section header.  */
	  shdr->sh_name = ebl_strtaboffset (runp->strent);
	  shdr->sh_type = SHT_GROUP;
	  shdr->sh_flags = 0;
	  shdr->sh_link = symscnndx;
	  /* If the user did not specify a signature we use the initial
	     empty symbol in the symbol table as the signature.  */
	  shdr->sh_info = (runp->signature != NULL
			   ? runp->signature->symidx : 0);

	  (void) gelf_update_shdr (scn, shdr);
	}
      while ((runp = runp->next) != ctx->groups->next);
    }


  /* Add the name to the symbol section.  */
  if (likely (symscnndx != 0))
    {
      Elf_Scn *scn = elf_getscn (ctx->out.elf, symscnndx);

      shdr = gelf_getshdr (scn, &shdr_mem);

      shdr->sh_name = ebl_strtaboffset (symscn_strent);

      (void) gelf_update_shdr (scn, shdr);


      /* Add the name to the string section.  */
      assert (strscnndx != 0);
      scn = elf_getscn (ctx->out.elf, strscnndx);

      shdr = gelf_getshdr (scn, &shdr_mem);

      shdr->sh_name = ebl_strtaboffset (strscn_strent);

      (void) gelf_update_shdr (scn, shdr);


      /* Add the name to the extended symbol index section.  */
      if (xndxscnndx != 0)
	{
	  scn = elf_getscn (ctx->out.elf, xndxscnndx);

	  shdr = gelf_getshdr (scn, &shdr_mem);

	  shdr->sh_name = ebl_strtaboffset (xndxscn_strent);

	  (void) gelf_update_shdr (scn, shdr);
	}
    }


  /* Iterate over the created sections and fill in the names.  */
  for (asmscn = ctx->section_list; asmscn != NULL; asmscn = asmscn->allnext)
    {
      shdr = gelf_getshdr (asmscn->data.main.scn, &shdr_mem);
      /* This better should not fail.  */
      assert (shdr != NULL);

      shdr->sh_name = ebl_strtaboffset (asmscn->data.main.strent);

      /* We now know the maximum alignment.  */
      shdr->sh_addralign = asmscn->max_align;

      (void) gelf_update_shdr (asmscn->data.main.scn, shdr);
    }

  /* Put the reference to the section header string table in the ELF
     header.  */
  ehdr = gelf_getehdr (ctx->out.elf, &ehdr_mem);
  assert (ehdr != NULL);

  shstrscnndx = elf_ndxscn (shstrscn);
  if (unlikely (shstrscnndx > SHN_HIRESERVE)
      || unlikely (shstrscnndx == SHN_XINDEX))
    {
      /* The index of the section header string sectio is too large.  */
      Elf_Scn *scn = elf_getscn (ctx->out.elf, 0);

      /* Get the header for the zeroth section.  */
      shdr = gelf_getshdr (scn, &shdr_mem);
      /* This better does not fail.  */
      assert (shdr != NULL);

      /* The sh_link field of the zeroth section header contains the value.  */
      shdr->sh_link = shstrscnndx;

      (void) gelf_update_shdr (scn, shdr);

      /* This is the sign for the overflow.  */
      ehdr->e_shstrndx = SHN_XINDEX;
    }
  else
    ehdr->e_shstrndx = elf_ndxscn (shstrscn);

  gelf_update_ehdr (ctx->out.elf, ehdr);

  /* Write out the ELF file.  */
  if (unlikely (elf_update (ctx->out.elf, ELF_C_WRITE_MMAP)) < 0)
    {
      __libasm_seterrno (ASM_E_LIBELF);
      result = -1;
    }

  /* We do not need the section header and symbol string tables anymore.  */
  free (shstrtabdata->d_buf);
  if (strtabdata != NULL)
    free (strtabdata->d_buf);
  /* We might have allocated the extended symbol table index.  */
  if (xndxdata != NULL)
    free (xndxdata->d_buf);

  /* Free section groups memory.  */
  AsmScnGrp_t *scngrp = ctx->groups;
  if (scngrp != NULL)
    do
      free (elf_getdata (scngrp->scn, NULL)->d_buf);
    while ((scngrp = scngrp->next) != ctx->groups);

  /* Finalize the ELF handling.  */
  if (unlikely (elf_end (ctx->out.elf)) != 0)
    {
      __libasm_seterrno (ASM_E_LIBELF);
      result = -1;
    }

  /* Free the temporary resources.  */
  free (symtab);

  return result;
}


int
asm_end (ctx)
     AsmCtx_t *ctx;
{
  int result;

  if (ctx == NULL)
    /* Something went wrong earlier.  */
    return -1;

  result = unlikely (ctx->textp) ? text_end (ctx) : binary_end (ctx);
  if (result != 0)
    return result;

  /* Make the new file globally readable and user/group-writable.  */
  if (fchmod (ctx->fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) != 0)
    {
      __libasm_seterrno (ASM_E_CANNOT_CHMOD);
      return -1;
    }

  /* Rename output file.  */
  if (rename (ctx->tmp_fname, ctx->fname) != 0)
    {
      __libasm_seterrno (ASM_E_CANNOT_RENAME);
      return -1;
    }

  /* Free the resources.  */
  __libasm_finictx (ctx);

  return 0;
}


static void
free_section (AsmScn_t *scnp)
{
  void *oldp;

  if (scnp->subnext != NULL)
    free_section (scnp->subnext);

  struct AsmData *data = scnp->content;
  if (data != NULL)
    do
      {
	oldp = data;
	data = data->next;
	free (oldp);
      }
    while (oldp != scnp->content);

  free (scnp);
}


void
__libasm_finictx (ctx)
     AsmCtx_t *ctx;
{
  /* Iterate through section table and free individual entries.  */
  AsmScn_t *scn = ctx->section_list;
  while (scn != NULL)
    {
      AsmScn_t *oldp = scn;
      scn = scn->allnext;
      free_section (oldp);
    }

  /* Free the resources of the symbol table.  */
  void *runp = NULL;
  AsmSym_t *sym;
  while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL)
    free (sym);
  asm_symbol_tab_free (&ctx->symbol_tab);


  /* Free section groups.  */
  AsmScnGrp_t *scngrp = ctx->groups;
  if (scngrp != NULL)
    do
      {
	AsmScnGrp_t *oldp = scngrp;

	scngrp = scngrp->next;
	free (oldp);
      }
    while (scngrp != ctx->groups);


  if (unlikely (ctx->textp))
    {
      /* Close the stream.  */
      fclose (ctx->out.file);
    }
  else
    {
      /* Close the output file.  */
      /* XXX We should test for errors here but what would we do if we'd
	 find any.  */
      (void) close (ctx->fd);

      /* And the string tables.  */
      ebl_strtabfree (ctx->section_strtab);
      ebl_strtabfree (ctx->symbol_strtab);
    }

  /* Initialize the lock.  */
  rwlock_fini (ctx->lock);

  /* Finally free the data structure.   */
  free (ctx);
}
