dwelf: Add string table functions from ebl.

Move the strtab functions from libebl to libdw. Programs often want to
create ELF/DWARF string tables. We don't want (static) linking against
ebl since those are internal functions that might change.

This introduces dwelf_strtab_init, dwelf_strtab_add,
dwelf_strtab_add_len, dwelf_strtab_finalize, dwelf_strent_off,
dwelf_strent_str and dwelf_strtab_free. Documentation for each has
been added to libdwelf.h. The add fucntion got a variant that takes
the length explicitly and finalize was changed to return NULL on
out of memory instead of aborting. All code and tests now uses the
new functions.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index afc7e8e..4c6cb28 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,20 @@
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add libdwelf.
+	(libasm.so): Add libdw.
+	* asm_begin.c (prepare_binary_output): Use dwelf_strtab instead of
+	ebl_strtab.
+	* asm_end.c (binary_end): Likewise.
+	(__libasm_finictx): Likewise.
+	* asm_newabssym.c (asm_newabssym):  Likewise.
+	* asm_newcomsym.c (asm_newcomsym): Likewise.
+	* asm_newscn.c (binary_newscn): Likewise.
+	* asm_newscngrp.c (asm_newscngrp): Likewise.
+	* asm_newsym.c (asm_newsym): Likewise.
+	* libasmP.h: Likewise.
+	* symbolhash.c (COMPARE): Likewise.
+	* symbolhash.h (COMPARE): Likewise.
+
 2016-06-28  Richard Henderson <rth@redhat.com>
 
 	* disasm_cb.c (disasm_cb): Pass ebl to disasm hook.
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index a4bf293..8094b05 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -28,7 +28,7 @@
 ## not, see <http://www.gnu.org/licenses/>.
 ##
 include $(top_srcdir)/config/eu.am
-AM_CPPFLAGS += -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl -I$(top_srcdir)/libdw
+AM_CPPFLAGS += -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwelf
 
 GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
 VERSION = 1
@@ -65,7 +65,8 @@
 	$(AM_V_CCLD)$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
 		-Wl,--version-script,$(srcdir)/libasm.map,--no-undefined \
 		-Wl,--soname,$@.$(VERSION) \
-		../libebl/libebl.a ../libelf/libelf.so  $(libasm_so_LDLIBS)
+		../libebl/libebl.a ../libelf/libelf.so ../libdw/libdw.so \
+		$(libasm_so_LDLIBS)
 	@$(textrel_check)
 	$(AM_V_at)ln -fs $@ $@.$(VERSION)
 
diff --git a/libasm/asm_begin.c b/libasm/asm_begin.c
index dc83cd8..6248786 100644
--- a/libasm/asm_begin.c
+++ b/libasm/asm_begin.c
@@ -1,5 +1,5 @@
 /* Create descriptor for assembling.
-   Copyright (C) 2002 Red Hat, Inc.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -115,8 +115,8 @@
   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);
+  result->section_strtab = dwelf_strtab_init (true);
+  result->symbol_strtab = dwelf_strtab_init (true);
 
   /* We have no section groups so far.  */
   result->groups = NULL;
diff --git a/libasm/asm_end.c b/libasm/asm_end.c
index d21a70a..191a535 100644
--- a/libasm/asm_end.c
+++ b/libasm/asm_end.c
@@ -1,5 +1,5 @@
 /* Finalize operations on the assembler context, free all resources.
-   Copyright (C) 2002, 2003, 2005 Red Hat, Inc.
+   Copyright (C) 2002, 2003, 2005, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -62,11 +62,11 @@
 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;
+  Dwelf_Strent *symscn_strent = NULL;
+  Dwelf_Strent *strscn_strent = NULL;
+  Dwelf_Strent *xndxscn_strent = NULL;
   Elf_Scn *shstrscn;
-  struct Ebl_Strent *shstrscn_strent;
+  Dwelf_Strent *shstrscn_strent;
   size_t shstrscnndx;
   size_t symscnndx = 0;
   size_t strscnndx = 0;
@@ -136,8 +136,8 @@
   if (ctx->nsymbol_tab > 0)
     {
       /* 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);
+      symscn_strent = dwelf_strtab_add_len (ctx->section_strtab, ".symtab", 8);
+      strscn_strent = dwelf_strtab_add_len (ctx->section_strtab, ".strtab", 8);
 
       /* Create the symbol string table section.  */
       Elf_Scn *strscn = elf_newscn (ctx->out.elf);
@@ -150,7 +150,7 @@
 	}
       strscnndx = elf_ndxscn (strscn);
 
-      ebl_strtabfinalize (ctx->symbol_strtab, strtabdata);
+      dwelf_strtab_finalize (ctx->symbol_strtab, strtabdata);
 
       shdr->sh_type = SHT_STRTAB;
       assert (shdr->sh_entsize == 0);
@@ -190,11 +190,11 @@
       uint32_t *xshndx = NULL;
       AsmSym_t *sym;
       while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL)
-	if (asm_emit_symbol_p (ebl_string (sym->strent)))
+	if (asm_emit_symbol_p (dwelf_strent_str (sym->strent)))
 	  {
 	    assert (ptr_local <= ptr_nonlocal);
 
-	    syment.st_name = ebl_strtaboffset (sym->strent);
+	    syment.st_name = dwelf_strent_off (sym->strent);
 	    syment.st_info = GELF_ST_INFO (sym->binding, sym->type);
 	    syment.st_other = 0;
 	    syment.st_value = sym->scn->offset + sym->offset;
@@ -240,8 +240,9 @@
 
 		    (void) gelf_update_shdr (xndxscn, shdr);
 
-		    xndxscn_strent = ebl_strtabadd (ctx->section_strtab,
-						    ".symtab_shndx", 14);
+		    xndxscn_strent = dwelf_strtab_add_len (ctx->section_strtab,
+							   ".symtab_shndx",
+							   14);
 
 		    /* Note that using 'elf32_fsize' instead of
 		       'gelf_fsize' here is correct.  */
@@ -299,13 +300,14 @@
 
 
   /* Add the name of the section header string table.  */
-  shstrscn_strent = ebl_strtabadd (ctx->section_strtab, ".shstrtab", 10);
+  shstrscn_strent = dwelf_strtab_add_len (ctx->section_strtab,
+					  ".shstrtab", 10);
 
-  ebl_strtabfinalize (ctx->section_strtab, shstrtabdata);
+  dwelf_strtab_finalize (ctx->section_strtab, shstrtabdata);
 
   shdr->sh_type = SHT_STRTAB;
   assert (shdr->sh_entsize == 0);
-  shdr->sh_name = ebl_strtaboffset (shstrscn_strent);
+  shdr->sh_name = dwelf_strent_off (shstrscn_strent);
 
   (void) gelf_update_shdr (shstrscn, shdr);
 
@@ -364,7 +366,7 @@
 	    }
 
 	  /* Construct the section header.  */
-	  shdr->sh_name = ebl_strtaboffset (runp->strent);
+	  shdr->sh_name = dwelf_strent_off (runp->strent);
 	  shdr->sh_type = SHT_GROUP;
 	  shdr->sh_flags = 0;
 	  shdr->sh_link = symscnndx;
@@ -386,7 +388,7 @@
 
       shdr = gelf_getshdr (scn, &shdr_mem);
 
-      shdr->sh_name = ebl_strtaboffset (symscn_strent);
+      shdr->sh_name = dwelf_strent_off (symscn_strent);
 
       (void) gelf_update_shdr (scn, shdr);
 
@@ -397,7 +399,7 @@
 
       shdr = gelf_getshdr (scn, &shdr_mem);
 
-      shdr->sh_name = ebl_strtaboffset (strscn_strent);
+      shdr->sh_name = dwelf_strent_off (strscn_strent);
 
       (void) gelf_update_shdr (scn, shdr);
 
@@ -409,7 +411,7 @@
 
 	  shdr = gelf_getshdr (scn, &shdr_mem);
 
-	  shdr->sh_name = ebl_strtaboffset (xndxscn_strent);
+	  shdr->sh_name = dwelf_strent_off (xndxscn_strent);
 
 	  (void) gelf_update_shdr (scn, shdr);
 	}
@@ -423,7 +425,7 @@
       /* This better should not fail.  */
       assert (shdr != NULL);
 
-      shdr->sh_name = ebl_strtaboffset (asmscn->data.main.strent);
+      shdr->sh_name = dwelf_strent_off (asmscn->data.main.strent);
 
       /* We now know the maximum alignment.  */
       shdr->sh_addralign = asmscn->max_align;
@@ -600,8 +602,8 @@
       (void) close (ctx->fd);
 
       /* And the string tables.  */
-      ebl_strtabfree (ctx->section_strtab);
-      ebl_strtabfree (ctx->symbol_strtab);
+      dwelf_strtab_free (ctx->section_strtab);
+      dwelf_strtab_free (ctx->symbol_strtab);
     }
 
   /* Initialize the lock.  */
diff --git a/libasm/asm_newabssym.c b/libasm/asm_newabssym.c
index c5b7bea..34fef3e 100644
--- a/libasm/asm_newabssym.c
+++ b/libasm/asm_newabssym.c
@@ -1,5 +1,5 @@
 /* Create new ABS symbol.
-   Copyright (C) 2002 Red Hat, Inc.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -80,7 +80,7 @@
   result->type = type;
   result->binding = binding;
   result->symidx = 0;
-  result->strent = ebl_strtabadd (ctx->symbol_strtab, name, 0);
+  result->strent = dwelf_strtab_add (ctx->symbol_strtab, name);
 
   /* The value of an ABS symbol must not be modified.  Since there are
      no subsection and the initial offset of the section is 0 we can
diff --git a/libasm/asm_newcomsym.c b/libasm/asm_newcomsym.c
index ee5c140..ee3b696 100644
--- a/libasm/asm_newcomsym.c
+++ b/libasm/asm_newcomsym.c
@@ -1,5 +1,5 @@
 /* Create new COMMON symbol.
-   Copyright (C) 2002 Red Hat, Inc.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -82,7 +82,7 @@
   /* XXX Do we have to allow a different binding?  */
   result->binding = STB_GLOBAL;
   result->symidx = 0;
-  result->strent = ebl_strtabadd (ctx->symbol_strtab, name, 0);
+  result->strent = dwelf_strtab_add (ctx->symbol_strtab, name);
 
   /* The value of a COM symbol is the alignment.  Since there are no
      subsection and the initial offset of the section is 0 we can get
diff --git a/libasm/asm_newscn.c b/libasm/asm_newscn.c
index e236769..ddbb25d 100644
--- a/libasm/asm_newscn.c
+++ b/libasm/asm_newscn.c
@@ -1,5 +1,5 @@
 /* Create new section in output file.
-   Copyright (C) 2002-2011 Red Hat, Inc.
+   Copyright (C) 2002-2011, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -129,8 +129,8 @@
   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);
+  result->data.main.strent = dwelf_strtab_add_len (result->ctx->section_strtab,
+						   result->name, scnname_len);
   assert (result->data.main.strent != NULL);
 
   /* Create the new ELF section.  */
diff --git a/libasm/asm_newscngrp.c b/libasm/asm_newscngrp.c
index c5968c1..80757a9 100644
--- a/libasm/asm_newscngrp.c
+++ b/libasm/asm_newscngrp.c
@@ -1,5 +1,5 @@
 /* Create new section group.
-   Copyright (C) 2002 Red Hat, Inc.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -67,8 +67,8 @@
   result->flags = flags;
 
   memcpy (result->name, grpname, grpname_len);
-  result->strent = ebl_strtabadd (ctx->section_strtab, result->name,
-				  grpname_len);
+  result->strent = dwelf_strtab_add_len (ctx->section_strtab, result->name,
+					 grpname_len);
 
   if (unlikely (ctx->textp))
     // XXX TBI.  What is the format?
diff --git a/libasm/asm_newsym.c b/libasm/asm_newsym.c
index 7f52291..332432a 100644
--- a/libasm/asm_newsym.c
+++ b/libasm/asm_newsym.c
@@ -1,5 +1,5 @@
 /* Define new symbol for current position in given section.
-   Copyright (C) 2002, 2005 Red Hat, Inc.
+   Copyright (C) 2002, 2005, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -83,8 +83,8 @@
   result->type = type;
   result->binding = binding;
   result->symidx = 0;
-  result->strent = ebl_strtabadd (asmscn->ctx->symbol_strtab,
-				  memcpy (result + 1, name, name_len), 0);
+  result->strent = dwelf_strtab_add (asmscn->ctx->symbol_strtab,
+				     memcpy (result + 1, name, name_len));
 
   if (unlikely (asmscn->ctx->textp))
     {
@@ -118,7 +118,7 @@
 	     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
+	     dwelf_strtab_add function would use the previously provided
 	     name.  */
 	  free (result);
 	  result = NULL;
diff --git a/libasm/libasmP.h b/libasm/libasmP.h
index 49b6484..54460cf 100644
--- a/libasm/libasmP.h
+++ b/libasm/libasmP.h
@@ -1,5 +1,5 @@
 /* Internal definitions for libasm.
-   Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2002, 2004, 2005, 2016 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -33,6 +33,8 @@
 
 #include <libasm.h>
 
+#include "libdwelf.h"
+
 /* gettext helper macros.  */
 #define _(Str) dgettext ("elfutils", Str)
 
@@ -85,7 +87,7 @@
       Elf_Scn *scn;
 
       /* Entry in the section header string table.  */
-      struct Ebl_Strent *strent;
+      Dwelf_Strent *strent;
 
       /* Next member of group.  */
       struct AsmScn *next_in_group;
@@ -156,14 +158,14 @@
   /* List with defined sections.  */
   AsmScn_t *section_list;
   /* Section header string table.  */
-  struct Ebl_Strtab *section_strtab;
+  Dwelf_Strtab *section_strtab;
 
   /* Table with defined symbols.  */
   asm_symbol_tab symbol_tab;
   /* Number of symbols in the table.  */
   unsigned int nsymbol_tab;
   /* Symbol string table.  */
-  struct Ebl_Strtab *symbol_strtab;
+  Dwelf_Strtab *symbol_strtab;
 
   /* List of section groups.  */
   struct AsmScnGrp *groups;
@@ -207,7 +209,7 @@
   size_t symidx;
 
   /* Reference to name of the symbol.  */
-  struct Ebl_Strent *strent;
+  Dwelf_Strent *strent;
 };
 
 
@@ -215,7 +217,7 @@
 struct AsmScnGrp
 {
   /* Entry in the section header string table.  */
-  struct Ebl_Strent *strent;
+  Dwelf_Strent *strent;
 
   /* The ELF section.  */
   Elf_Scn *scn;
diff --git a/libasm/symbolhash.c b/libasm/symbolhash.c
index 1c95418..57c9e76 100644
--- a/libasm/symbolhash.c
+++ b/libasm/symbolhash.c
@@ -1,5 +1,5 @@
 /* Symbol hash table implementation.
-   Copyright (C) 2001, 2002 Red Hat, Inc.
+   Copyright (C) 2001, 2002, 2016 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -42,7 +42,7 @@
 #define ITERATE 1
 #define REVERSE 1
 #define COMPARE(a, b) \
-  strcmp (ebl_string ((a)->strent), ebl_string ((b)->strent))
+  strcmp (dwelf_strent_str ((a)->strent), dwelf_strent_str ((b)->strent))
 
 #define next_prime __libasm_next_prime
 extern size_t next_prime (size_t) attribute_hidden;
diff --git a/libasm/symbolhash.h b/libasm/symbolhash.h
index a5bceff..d05a40a 100644
--- a/libasm/symbolhash.h
+++ b/libasm/symbolhash.h
@@ -34,7 +34,7 @@
 #define NAME asm_symbol_tab
 #define ITERATE 1
 #define COMPARE(a, b) \
-  strcmp (ebl_string ((a)->strent), ebl_string ((b)->strent))
+  strcmp (dwelf_strent_str ((a)->strent), dwelf_strent_str ((b)->strent))
 #include <dynamicsizehash.h>
 
 #endif	/* symbolhash.h */