/* Define new symbol for current position in given section.
   Copyright (C) 2002, 2005 Red Hat, Inc.
   This file is part of Red Hat elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2002.

   Red Hat elfutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by the
   Free Software Foundation; version 2 of the License.

   Red Hat 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 a copy of the GNU General Public License along
   with Red Hat elfutils; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.

   Red Hat elfutils is an included package of the Open Invention Network.
   An included package of the Open Invention Network is a package for which
   Open Invention Network licensees cross-license their patents.  No patent
   license is granted, either expressly or impliedly, by designation as an
   included package.  Should you wish to participate in the Open Invention
   Network licensing program, please visit www.openinventionnetwork.com
   <http://www.openinventionnetwork.com>.  */

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

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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


AsmSym_t *
asm_newsym (asmscn, name, size, type, binding)
     AsmScn_t *asmscn;
     const char *name;
     GElf_Xword size;
     int type;
     int binding;
{
#define TEMPSYMLEN 10
  char tempsym[TEMPSYMLEN];
  AsmSym_t *result;

  if (asmscn == NULL)
    /* Something went wrong before.  */
    return NULL;

  /* Generate a temporary symbol if necessary.  */
  if (name == NULL)
    {
      /* If a local symbol name is created the symbol better have
	 local binding.  */
      if (binding != STB_LOCAL)
	{
	  __libasm_seterrno (ASM_E_INVALID);
	  return NULL;
	}

      // XXX This requires getting the format from the machine backend.  */
      snprintf (tempsym, TEMPSYMLEN, ".L%07u", asmscn->ctx->tempsym_count++);

      name = tempsym;
    }

  size_t name_len = strlen (name) + 1;

  result = (AsmSym_t *) malloc (sizeof (AsmSym_t) + name_len);
  if (result == NULL)
    return NULL;

  rwlock_wrlock (asmscn->ctx->lock);

  result->scn = asmscn;
  result->offset = asmscn->offset;
  result->size = size;
  result->type = type;
  result->binding = binding;
  result->symidx = 0;
  result->strent = ebl_strtabadd (asmscn->ctx->symbol_strtab,
				  memcpy (result + 1, name, name_len), 0);

  if (unlikely (asmscn->ctx->textp))
    {
      /* We are only interested in the name and don't need to know whether
	 it is a local name or not.  */
      /* First print the binding pseudo-op.  */
      if (binding == STB_GLOBAL)
	fprintf (asmscn->ctx->out.file, "\t.globl\t%s\n", name);
      else if (binding == STB_WEAK)
	fprintf (asmscn->ctx->out.file, "\t.weak\t%s\n", name);

      /* Next the symbol type.  */
      if (type == STT_OBJECT)
	fprintf (asmscn->ctx->out.file, "\t.type\t%s,@object\n", name);
      else if (type == STT_FUNC)
	fprintf (asmscn->ctx->out.file, "\t.type\t%s,@function\n", name);

      /* Finally the size and the label.  */
      fprintf (asmscn->ctx->out.file, "\t.size\t%s,%" PRIuMAX "\n%s:\n",
	       name, (uintmax_t) size, name);
    }
  else
    {
      /* Put the symbol in the hash table so that we can later find it.  */
      if (asm_symbol_tab_insert (&asmscn->ctx->symbol_tab, elf_hash (name),
				 result) != 0)
	{
	  /* The symbol already exists.  */
	  __libasm_seterrno (ASM_E_DUPLSYM);
	  /* Note that we can free the entry since there must be no
	     reference in the string table to the string.  We can only
	     fail to insert the symbol into the symbol table if there
	     is already a symbol with this name.  In this case the
	     ebl_strtabadd function would use the previously provided
	     name.  */
	  free (result);
	  result = NULL;
	}
      else if (name != tempsym && asm_emit_symbol_p (name))
	/* Only count non-private symbols.  */
	++asmscn->ctx->nsymbol_tab;
    }

  rwlock_unlock (asmscn->ctx->lock);

  return result;
}
