/* Create descriptor for assembling.
   Copyright (C) 2002 Red Hat, Inc.
   This file is part of elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2002.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

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

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <gelf.h>
#include "libasmP.h"
#include <system.h>


static AsmCtx_t *
prepare_text_output (AsmCtx_t *result)
{
  if (result->fd == -1)
    result->out.file = stdout;
  else
    {
      result->out.file = fdopen (result->fd, "a");
      if (result->out.file == NULL)
	{
	  close (result->fd);
	  free (result);
	  result = NULL;
	}

      __fsetlocking (result->out.file, FSETLOCKING_BYCALLER);
    }

  return result;
}


static AsmCtx_t *
prepare_binary_output (AsmCtx_t *result, Ebl *ebl)
{
  GElf_Ehdr *ehdr;
  GElf_Ehdr ehdr_mem;

  /* Create the ELF descriptor for the file.  */
  result->out.elf = elf_begin (result->fd, ELF_C_WRITE_MMAP, NULL);
  if (result->out.elf == NULL)
    {
    err_libelf:
      unlink (result->tmp_fname);
      close (result->fd);
      free (result);
      __libasm_seterrno (ASM_E_LIBELF);
      return NULL;
    }

  /* Create the ELF header for the output file.  */
  int class = ebl_get_elfclass (ebl);
  if (gelf_newehdr (result->out.elf, class) == 0)
    goto err_libelf;

  ehdr = gelf_getehdr (result->out.elf, &ehdr_mem);
  /* If this failed we are in trouble.  */
  assert (ehdr != NULL);

  /* We create an object file.  */
  ehdr->e_type = ET_REL;
  /* Set the ELF version.  */
  ehdr->e_version = EV_CURRENT;

  /* Use the machine, class, and endianess values from the Ebl descriptor.  */
  ehdr->e_machine = ebl_get_elfmachine (ebl);
  ehdr->e_ident[EI_CLASS] = class;
  ehdr->e_ident[EI_DATA] = ebl_get_elfdata (ebl);

  memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);

  /* Write the ELF header information back.  */
  (void) gelf_update_ehdr (result->out.elf, ehdr);

  /* No section so far.  */
  result->section_list = NULL;

  /* Initialize the hash table.  */
  asm_symbol_tab_init (&result->symbol_tab, 67);
  result->nsymbol_tab = 0;
  /* And the string tables.  */
  result->section_strtab = ebl_strtabinit (true);
  result->symbol_strtab = ebl_strtabinit (true);

  /* We have no section groups so far.  */
  result->groups = NULL;
  result->ngroups = 0;

  return result;
}


AsmCtx_t *
asm_begin (fname, ebl, textp)
     const char *fname;
     Ebl *ebl;
     bool textp;
{
  if (fname == NULL && ! textp)
    return NULL;

  size_t fname_len = fname != NULL ? strlen (fname) : 0;

  /* Create the file descriptor.  We do not generate the output file
     right away.  Instead we create a temporary file in the same
     directory which, if everything goes alright, will replace a
     possibly existing file with the given name.  */
  AsmCtx_t *result
    = (AsmCtx_t *) malloc (sizeof (AsmCtx_t) + 2 * fname_len + 9);
  if (result == NULL)
    return NULL;

      /* Initialize the lock.  */
      rwlock_init (result->lock);

  if (fname != NULL)
    {
      /* Create the name of the temporary file.  */
      result->fname = stpcpy (mempcpy (result->tmp_fname, fname, fname_len),
			      ".XXXXXX") + 1;
      memcpy (result->fname, fname, fname_len + 1);

      /* Create the temporary file.  */
      result->fd = mkstemp (result->tmp_fname);
      if (result->fd == -1)
	{
	  int save_errno = errno;
	  free (result);
	  __libasm_seterrno (ASM_E_CANNOT_CREATE);
	  errno = save_errno;
	  return NULL;
	}
    }
  else
    result->fd = -1;

  /* Initialize the counter for temporary symbols.  */
  result->tempsym_count = 0;

  /* Now we differentiate between textual and binary output.   */
  result->textp = textp;
  if (textp)
    result = prepare_text_output (result);
  else
    result = prepare_binary_output (result, ebl);

  return result;
}
