/* Create new section in output file.
   Copyright (C) 2002 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 <stdlib.h>
#include <string.h>

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


/* Memory for the default pattern.  The type uses a flexible array
   which does work well with a static initializer.  So we play some
   dirty tricks here.  */
static const struct
{
  struct FillPattern pattern;
  char zero;
} xdefault_pattern =
  {
    .pattern =
    {
      .len = 1
    },
    .zero = '\0'
  };
const struct FillPattern *__libasm_default_pattern = &xdefault_pattern.pattern;


static AsmScn_t *
text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags)
{
  /* Buffer where we construct the flag string.  */
  char flagstr[sizeof (GElf_Xword) * 8 + 5];
  char *wp = flagstr;
  const char *typestr = "";

  /* Only write out the flag string if this is the first time the
     section is selected.  Some assemblers cannot cope with the
     .section pseudo-op otherwise.  */
  wp = stpcpy (wp, ", \"");

  if (flags & SHF_WRITE)
    *wp++ = 'w';
  if (flags & SHF_ALLOC)
    *wp++ = 'a';
  if (flags & SHF_EXECINSTR)
    *wp++ = 'x';
  if (flags & SHF_MERGE)
    *wp++ = 'M';
  if (flags & SHF_STRINGS)
    *wp++ = 'S';
  if (flags & SHF_LINK_ORDER)
    *wp++ = 'L';

  *wp++ = '"';

  if (type == SHT_PROGBITS)
    typestr = ",@progbits";
  else if (type == SHT_NOBITS)
    typestr = ",@nobits";

  /* Terminate the string.  */
  *wp = '\0';

  printf ("\t.section \"%s\"%s%s\n", result->name, flagstr, typestr);

  return result;
}


static AsmScn_t *
binary_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags,
	       size_t scnname_len)
{
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;
  Elf_Scn *scn;

  /* The initial subsection has the number zero.  */
  result->subsection_id = 0;

  /* We start at offset zero.  */
  result->offset = 0;
  /* And generic alignment.  */
  result->max_align = 1;

  /* No output yet.  */
  result->content = NULL;

  /* Put the default fill pattern in place.  */
  result->pattern = (struct FillPattern *) __libasm_default_pattern;

  /* There are no subsections so far.  */
  result->subnext = NULL;

  /* Add the name to the section header string table.  */
  result->data.main.strent = ebl_strtabadd (result->ctx->section_strtab,
					    result->name, scnname_len);
  assert (result->data.main.strent != NULL);

  /* Create the new ELF section.  */
  result->data.main.scn = scn = elf_newscn (result->ctx->out.elf);
  if (scn == NULL)
    {
      free (result);
      __libasm_seterrno (ASM_E_LIBELF);
      return NULL;
    }

  /* Not part of a section group (yet).  */
  result->data.main.next_in_group = NULL;

  /* Remember the flags.  */
  shdr = gelf_getshdr (scn, &shdr_mem);

  shdr->sh_flags = flags;
  result->type = shdr->sh_type = type;

  (void) gelf_update_shdr (scn, shdr);

  return result;
}


AsmScn_t *
asm_newscn (ctx, scnname, type, flags)
     AsmCtx_t *ctx;
     const char *scnname;
     GElf_Word type;
     GElf_Xword flags;
{
  size_t scnname_len = strlen (scnname) + 1;
  unsigned long int hval;
  AsmScn_t *result;

  /* If no context is given there might be an earlier error.  */
  if (ctx == NULL)
    return NULL;

  /* Check whether only flags are set which areselectable by the user.  */
  if (unlikely ((flags & ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE
			   | SHF_STRINGS | SHF_LINK_ORDER)) != 0)
      /* We allow only two section types: data and data without file
	 representation.  */
      || (type != SHT_PROGBITS && unlikely (type != SHT_NOBITS)))
    {
      __libasm_seterrno (ASM_E_INVALID);
      return NULL;
    }

  hval = elf_hash (scnname);

  rwlock_wrlock (ctx->lock);

  /* This is a new section.  */
  result = (AsmScn_t *) malloc (sizeof (AsmScn_t) + scnname_len);
  if (result != NULL)
    {
      /* Add the name.  */
      memcpy (result->name, scnname, scnname_len);

      /* Add the reference to the context.  */
      result->ctx = ctx;

      /* Perform operations according to output mode.  */
      result = (unlikely (ctx->textp)
		? text_newscn (result, type, flags)
		: binary_newscn (result, type, flags, scnname_len));

      /* If everything went well finally add the new section to the hash
	 table.  */
      if (result != NULL)
	{
	  result->allnext = ctx->section_list;
	  ctx->section_list = result;
	}
    }

  rwlock_unlock (ctx->lock);

  return result;
}
INTDEF(asm_newscn)
