Squashed 'third_party/elfutils/' content from commit 555e15e

Change-Id: I61cde98949e47e5c8c09c33260de17f30921be79
git-subtree-dir: third_party/elfutils
git-subtree-split: 555e15ebe8bf1eb33d00747173cfc80cc65648a4
diff --git a/libelf/version_xlate.h b/libelf/version_xlate.h
new file mode 100644
index 0000000..9fe01c6
--- /dev/null
+++ b/libelf/version_xlate.h
@@ -0,0 +1,230 @@
+/* Conversion functions for versioning information.
+   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   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/>.  */
+
+#include <assert.h>
+#include <gelf.h>
+
+#include "libelfP.h"
+
+
+static void
+elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
+{
+  /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
+     To recognize them we have to walk the data structure and convert
+     them one after the other.  The ENCODE parameter specifies whether
+     we are encoding or decoding.  When we are encoding we can immediately
+     use the data in the buffer; if not, we have to decode the data before
+     using it.  */
+  size_t def_offset = 0;
+  GElf_Verdef *ddest;
+  GElf_Verdef *dsrc;
+
+  /* We rely on the types being all the same size.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  if (len == 0)
+    return;
+
+  /* Below we rely on the next field offsets to be correct, start by
+     copying over all data as is in case some data isn't translated.
+     We don't want to leave (undefined) garbage in the dest buffer.  */
+  memmove (dest, src, len);
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Verdaux *asrc;
+
+      /* Test for correct offset.  */
+      if (def_offset > len || len - def_offset < sizeof (GElf_Verdef))
+	return;
+
+      /* Work the tree from the first record.  */
+      ddest = (GElf_Verdef *) ((char *) dest + def_offset);
+      dsrc = (GElf_Verdef *) ((char *) src + def_offset);
+
+      /* Decode first if necessary.  */
+      if (! encode)
+	{
+	  ddest->vd_version = bswap_16 (dsrc->vd_version);
+	  ddest->vd_flags = bswap_16 (dsrc->vd_flags);
+	  ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
+	  ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
+	  ddest->vd_hash = bswap_32 (dsrc->vd_hash);
+	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
+	  ddest->vd_next = bswap_32 (dsrc->vd_next);
+
+	  aux_offset = def_offset + ddest->vd_aux;
+	}
+      else
+	aux_offset = def_offset + dsrc->vd_aux;
+
+      /* Handle all the auxiliary records belonging to this definition.  */
+      do
+	{
+	  GElf_Verdaux *adest;
+
+	  /* Test for correct offset.  */
+	  if (aux_offset > len || len - aux_offset < sizeof (GElf_Verdaux))
+	    return;
+
+	  adest = (GElf_Verdaux *) ((char *) dest + aux_offset);
+	  asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
+
+	  if (encode)
+	    aux_offset += asrc->vda_next;
+
+	  adest->vda_name = bswap_32 (asrc->vda_name);
+	  adest->vda_next = bswap_32 (asrc->vda_next);
+
+	  if (! encode)
+	    aux_offset += adest->vda_next;
+	}
+      while (asrc->vda_next != 0);
+
+      /* Encode now if necessary.  */
+      if (encode)
+	{
+	  def_offset += dsrc->vd_next;
+
+	  ddest->vd_version = bswap_16 (dsrc->vd_version);
+	  ddest->vd_flags = bswap_16 (dsrc->vd_flags);
+	  ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
+	  ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
+	  ddest->vd_hash = bswap_32 (dsrc->vd_hash);
+	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
+	  ddest->vd_next = bswap_32 (dsrc->vd_next);
+	}
+      else
+	def_offset += ddest->vd_next;
+    }
+  while (dsrc->vd_next != 0);
+}
+
+
+static void
+elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
+{
+  /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
+     To recognize them we have to walk the data structure and convert
+     them one after the other.  The ENCODE parameter specifies whether
+     we are encoding or decoding.  When we are encoding we can immediately
+     use the data in the buffer; if not, we have to decode the data before
+     using it.  */
+  size_t need_offset = 0;
+  GElf_Verneed *ndest;
+  GElf_Verneed *nsrc;
+
+  /* We rely on the types being all the same size.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  if (len == 0)
+    return;
+
+  /* Below we rely on the next field offsets to be correct, start by
+     copying over all data as is in case some data isn't translated.
+     We don't want to leave (undefined) garbage in the dest buffer.  */
+  memmove (dest, src, len);
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Vernaux *asrc;
+
+      /* Test for correct offset.  */
+      if (need_offset > len || len - need_offset < sizeof (GElf_Verneed))
+	return;
+
+      /* Work the tree from the first record.  */
+      ndest = (GElf_Verneed *) ((char *) dest + need_offset);
+      nsrc = (GElf_Verneed *) ((char *) src + need_offset);
+
+      /* Decode first if necessary.  */
+      if (! encode)
+	{
+	  ndest->vn_version = bswap_16 (nsrc->vn_version);
+	  ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
+	  ndest->vn_file = bswap_32 (nsrc->vn_file);
+	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
+	  ndest->vn_next = bswap_32 (nsrc->vn_next);
+
+	  aux_offset = need_offset + ndest->vn_aux;
+	}
+      else
+	aux_offset = need_offset + nsrc->vn_aux;
+
+      /* Handle all the auxiliary records belonging to this requirement.  */
+      do
+	{
+	  GElf_Vernaux *adest;
+
+	  /* Test for correct offset.  */
+	  if (aux_offset > len || len - aux_offset < sizeof (GElf_Vernaux))
+	    return;
+
+	  adest = (GElf_Vernaux *) ((char *) dest + aux_offset);
+	  asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
+
+	  if (encode)
+	    aux_offset += asrc->vna_next;
+
+	  adest->vna_hash = bswap_32 (asrc->vna_hash);
+	  adest->vna_flags = bswap_16 (asrc->vna_flags);
+	  adest->vna_other = bswap_16 (asrc->vna_other);
+	  adest->vna_name = bswap_32 (asrc->vna_name);
+	  adest->vna_next = bswap_32 (asrc->vna_next);
+
+	  if (! encode)
+	    aux_offset += adest->vna_next;
+	}
+      while (asrc->vna_next != 0);
+
+      /* Encode now if necessary.  */
+      if (encode)
+	{
+	  need_offset += nsrc->vn_next;
+
+	  ndest->vn_version = bswap_16 (nsrc->vn_version);
+	  ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
+	  ndest->vn_file = bswap_32 (nsrc->vn_file);
+	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
+	  ndest->vn_next = bswap_32 (nsrc->vn_next);
+	}
+      else
+	need_offset += ndest->vn_next;
+    }
+  while (nsrc->vn_next != 0);
+}