Blame libebl/eblobjnote.c

Packit 032894
/* Print contents of object file note.
Packit 032894
   Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016, 2018 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifdef HAVE_CONFIG_H
Packit 032894
# include <config.h>
Packit 032894
#endif
Packit 032894
Packit 032894
#include <inttypes.h>
Packit 032894
#include <stdio.h>
Packit 032894
#include <stdlib.h>
Packit 032894
#include <string.h>
Packit 032894
#include <libeblP.h>
Packit 032894
Packit 032894
#include "common.h"
Packit 032894
#include "libelfP.h"
Packit 032894
#include "libdwP.h"
Packit 032894
#include "memory-access.h"
Packit 032894
Packit 032894
Packit 032894
void
Packit 032894
ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type,
Packit 032894
		 uint32_t descsz, const char *desc)
Packit 032894
{
Packit 032894
  if (! ebl->object_note (name, type, descsz, desc))
Packit 032894
    {
Packit 032894
      /* The machine specific function did not know this type.  */
Packit 032894
Packit 032894
      if (strcmp ("stapsdt", name) == 0)
Packit 032894
	{
Packit 032894
	  if (type != 3)
Packit 032894
	    {
Packit 032894
	      printf (gettext ("unknown SDT version %u\n"), type);
Packit 032894
	      return;
Packit 032894
	    }
Packit 032894
Packit 032894
	  /* Descriptor starts with three addresses, pc, base ref and
Packit 032894
	     semaphore.  Then three zero terminated strings provider,
Packit 032894
	     name and arguments.  */
Packit 032894
Packit 032894
	  union
Packit 032894
	  {
Packit 032894
	    Elf64_Addr a64[3];
Packit 032894
	    Elf32_Addr a32[3];
Packit 032894
	  } addrs;
Packit 032894
Packit 032894
	  size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT);
Packit 032894
	  if (descsz < addrs_size + 3)
Packit 032894
	    {
Packit 032894
	    invalid_sdt:
Packit 032894
	      printf (gettext ("invalid SDT probe descriptor\n"));
Packit 032894
	      return;
Packit 032894
	    }
Packit 032894
Packit 032894
	  Elf_Data src =
Packit 032894
	    {
Packit 032894
	      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
Packit 032894
	      .d_buf = (void *) desc, .d_size = addrs_size
Packit 032894
	    };
Packit 032894
Packit 032894
	  Elf_Data dst =
Packit 032894
	    {
Packit 032894
	      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
Packit 032894
	      .d_buf = &addrs, .d_size = addrs_size
Packit 032894
	    };
Packit 032894
Packit 032894
	  if (gelf_xlatetom (ebl->elf, &dst, &src,
Packit 032894
			     elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL)
Packit 032894
	    {
Packit 032894
	      printf ("%s\n", elf_errmsg (-1));
Packit 032894
	      return;
Packit 032894
	    }
Packit 032894
Packit 032894
	  const char *provider = desc + addrs_size;
Packit 032894
	  const char *pname = memchr (provider, '\0', desc + descsz - provider);
Packit 032894
	  if (pname == NULL)
Packit 032894
	    goto invalid_sdt;
Packit 032894
Packit 032894
	  ++pname;
Packit 032894
	  const char *args = memchr (pname, '\0', desc + descsz - pname);
Packit 032894
	  if (args == NULL ||
Packit 032894
	      memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1)
Packit 032894
	    goto invalid_sdt;
Packit 032894
Packit 032894
	  GElf_Addr pc;
Packit 032894
	  GElf_Addr base;
Packit 032894
	  GElf_Addr sem;
Packit 032894
	  if (gelf_getclass (ebl->elf) == ELFCLASS32)
Packit 032894
	    {
Packit 032894
	      pc = addrs.a32[0];
Packit 032894
	      base = addrs.a32[1];
Packit 032894
	      sem = addrs.a32[2];
Packit 032894
	    }
Packit 032894
	  else
Packit 032894
	    {
Packit 032894
	      pc = addrs.a64[0];
Packit 032894
	      base = addrs.a64[1];
Packit 032894
	      sem = addrs.a64[2];
Packit 032894
	    }
Packit 032894
Packit 032894
	  printf (gettext ("    PC: "));
Packit 032894
	  printf ("%#" PRIx64 ",", pc);
Packit 032894
	  printf (gettext (" Base: "));
Packit 032894
	  printf ("%#" PRIx64 ",", base);
Packit 032894
	  printf (gettext (" Semaphore: "));
Packit 032894
	  printf ("%#" PRIx64 "\n", sem);
Packit 032894
	  printf (gettext ("    Provider: "));
Packit 032894
	  printf ("%s,", provider);
Packit 032894
	  printf (gettext (" Name: "));
Packit 032894
	  printf ("%s,", pname);
Packit 032894
	  printf (gettext (" Args: "));
Packit 032894
	  printf ("'%s'\n", args);
Packit 032894
	  return;
Packit 032894
	}
Packit 032894
Packit 032894
      if (strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
Packit 032894
		   strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0
Packit 032894
	  && (type == NT_GNU_BUILD_ATTRIBUTE_OPEN
Packit 032894
	      || type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
Packit 032894
	{
Packit 032894
	  /* There might or might not be a pair of addresses in the desc.  */
Packit 032894
	  if (descsz > 0)
Packit 032894
	    {
Packit 032894
	      printf ("    Address Range: ");
Packit 032894
Packit 032894
	      union
Packit 032894
	      {
Packit 032894
		Elf64_Addr a64[2];
Packit 032894
		Elf32_Addr a32[2];
Packit 032894
	      } addrs;
Packit 032894
Packit 032894
	      size_t addr_size = gelf_fsize (ebl->elf, ELF_T_ADDR,
Packit 032894
					     2, EV_CURRENT);
Packit 032894
	      if (descsz != addr_size)
Packit 032894
		printf ("<unknown data>\n");
Packit 032894
	      else
Packit 032894
		{
Packit 032894
		  Elf_Data src =
Packit 032894
		    {
Packit 032894
		     .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
Packit 032894
		     .d_buf = (void *) desc, .d_size = descsz
Packit 032894
		    };
Packit 032894
Packit 032894
		  Elf_Data dst =
Packit 032894
		    {
Packit 032894
		     .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
Packit 032894
		     .d_buf = &addrs, .d_size = descsz
Packit 032894
		    };
Packit 032894
Packit 032894
		  if (gelf_xlatetom (ebl->elf, &dst, &src,
Packit 032894
				     elf_getident (ebl->elf,
Packit 032894
						   NULL)[EI_DATA]) == NULL)
Packit 032894
		    printf ("%s\n", elf_errmsg (-1));
Packit 032894
		  else
Packit 032894
		    {
Packit 032894
		      if (addr_size == 4)
Packit 032894
			printf ("%#" PRIx32 " - %#" PRIx32 "\n",
Packit 032894
				addrs.a32[0], addrs.a32[1]);
Packit 032894
		      else
Packit 032894
			printf ("%#" PRIx64 " - %#" PRIx64 "\n",
Packit 032894
				addrs.a64[0], addrs.a64[1]);
Packit 032894
		    }
Packit 032894
		}
Packit 032894
	    }
Packit 032894
Packit 032894
	  /* Most data actually is inside the name.
Packit 032894
	     https://fedoraproject.org/wiki/Toolchain/Watermark  */
Packit 032894
Packit 032894
	  /* We need at least 2 chars of data to describe the
Packit 032894
	     attribute and value encodings.  */
Packit 032894
	  const char *data = (name
Packit 032894
			      + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX));
Packit 032894
	  if (namesz < 2)
Packit 032894
	    {
Packit 032894
	      printf ("<insufficient data>\n");
Packit 032894
	      return;
Packit 032894
	    }
Packit 032894
Packit 032894
	  printf ("    ");
Packit 032894
Packit 032894
	  /* In most cases the value comes right after the encoding bytes.  */
Packit 032894
	  const char *value = &data[2];
Packit 032894
	  switch (data[1])
Packit 032894
	    {
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_VERSION:
Packit 032894
	      printf ("VERSION: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_STACK_PROT:
Packit 032894
	      printf ("STACK_PROT: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_RELRO:
Packit 032894
	      printf ("RELRO: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
Packit 032894
	      printf ("STACK_SIZE: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_TOOL:
Packit 032894
	      printf ("TOOL: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_ABI:
Packit 032894
	      printf ("ABI: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_PIC:
Packit 032894
	      printf ("PIC: ");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
Packit 032894
	      printf ("SHORT_ENUM: ");
Packit 032894
	      break;
Packit 032894
	    case 32 ... 126:
Packit 032894
	      printf ("\"%s\": ", &data[1]);
Packit 032894
	      value += strlen (&data[1]) + 1;
Packit 032894
	      break;
Packit 032894
	    default:
Packit 032894
	      printf ("<unknown>: ");
Packit 032894
	      break;
Packit 032894
	    }
Packit 032894
Packit 032894
	  switch (data[0])
Packit 032894
	    {
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
Packit 032894
	      {
Packit 032894
		/* Any numbers are always in (unsigned) little endian.  */
Packit 032894
		static const Dwarf dbg
Packit 032894
		  = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
Packit 032894
		size_t bytes = namesz - (value - name);
Packit 032894
		uint64_t val;
Packit 032894
		if (bytes == 1)
Packit 032894
		  val = *(unsigned char *) value;
Packit 032894
		else if (bytes == 2)
Packit 032894
		  val = read_2ubyte_unaligned (&dbg, value);
Packit 032894
		else if (bytes == 4)
Packit 032894
		  val = read_4ubyte_unaligned (&dbg, value);
Packit 032894
		else if (bytes == 8)
Packit 032894
		  val = read_8ubyte_unaligned (&dbg, value);
Packit 032894
		else
Packit 032894
		  goto unknown;
Packit 032894
		printf ("%" PRIx64, val);
Packit 032894
	      }
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
Packit 032894
	      printf ("\"%s\"", value);
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
Packit 032894
	      printf ("TRUE");
Packit 032894
	      break;
Packit 032894
	    case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
Packit 032894
	      printf ("FALSE");
Packit 032894
	      break;
Packit 032894
	    default:
Packit 032894
	      {
Packit 032894
	      unknown:
Packit 032894
		printf ("<unknown>");
Packit 032894
	      }
Packit 032894
	      break;
Packit 032894
	    }
Packit 032894
Packit 032894
	  printf ("\n");
Packit 032894
Packit 032894
	  return;
Packit 032894
	}
Packit 032894
Packit 032894
      /* NT_VERSION doesn't have any info.  All data is in the name.  */
Packit 032894
      if (descsz == 0 && type == NT_VERSION)
Packit 032894
	return;
Packit 032894
Packit 032894
      /* Everything else should have the "GNU" owner name.  */
Packit 032894
      if (strcmp ("GNU", name) != 0)
Packit 032894
	return;
Packit 032894
Packit 032894
      switch (type)
Packit 032894
	{
Packit 032894
	case NT_GNU_BUILD_ID:
Packit 032894
	  if (strcmp (name, "GNU") == 0 && descsz > 0)
Packit 032894
	    {
Packit 032894
	      printf (gettext ("    Build ID: "));
Packit 032894
	      uint_fast32_t i;
Packit 032894
	      for (i = 0; i < descsz - 1; ++i)
Packit 032894
		printf ("%02" PRIx8, (uint8_t) desc[i]);
Packit 032894
	      printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
Packit 032894
	    }
Packit 032894
	  break;
Packit 032894
Packit 032894
	case NT_GNU_GOLD_VERSION:
Packit 032894
	  if (strcmp (name, "GNU") == 0 && descsz > 0)
Packit 032894
	    /* A non-null terminated version string.  */
Packit 032894
	    printf (gettext ("    Linker version: %.*s\n"),
Packit 032894
		    (int) descsz, desc);
Packit 032894
	  break;
Packit 032894
Packit 032894
	case NT_GNU_PROPERTY_TYPE_0:
Packit 032894
	  if (strcmp (name, "GNU") == 0 && descsz > 0)
Packit 032894
	    {
Packit 032894
	      /* There are at least 2 words. type and datasz.  */
Packit 032894
	      while (descsz >= 8)
Packit 032894
		{
Packit 032894
		  struct pr_prop
Packit 032894
		  {
Packit 032894
		    GElf_Word pr_type;
Packit 032894
		    GElf_Word pr_datasz;
Packit 032894
		  } prop;
Packit 032894
Packit 032894
		  Elf_Data in =
Packit 032894
		    {
Packit 032894
		      .d_version = EV_CURRENT,
Packit 032894
		      .d_type = ELF_T_WORD,
Packit 032894
		      .d_size = 8,
Packit 032894
		      .d_buf = (void *) desc
Packit 032894
		    };
Packit 032894
		  Elf_Data out =
Packit 032894
		    {
Packit 032894
		      .d_version = EV_CURRENT,
Packit 032894
		      .d_type = ELF_T_WORD,
Packit 032894
		      .d_size = descsz,
Packit 032894
		      .d_buf = (void *) &prop
Packit 032894
		    };
Packit 032894
Packit 032894
		  if (gelf_xlatetom (ebl->elf, &out, &in,
Packit 032894
				     elf_getident (ebl->elf,
Packit 032894
						   NULL)[EI_DATA]) == NULL)
Packit 032894
		    {
Packit 032894
		      printf ("%s\n", elf_errmsg (-1));
Packit 032894
		      return;
Packit 032894
		    }
Packit 032894
Packit 032894
		  desc += 8;
Packit 032894
		  descsz -= 8;
Packit 032894
Packit 032894
		  if (prop.pr_datasz > descsz)
Packit 032894
		    {
Packit 032894
		      printf ("BAD property datasz: %" PRId32 "\n",
Packit 032894
			      prop.pr_datasz);
Packit 032894
		      return;
Packit 032894
		    }
Packit 032894
Packit 032894
		  int elfclass = gelf_getclass (ebl->elf);
Packit 032894
		  char *elfident = elf_getident (ebl->elf, NULL);
Packit 032894
		  GElf_Ehdr ehdr;
Packit 032894
		  gelf_getehdr (ebl->elf, &ehdr);
Packit 032894
Packit 032894
		  /* Prefix.  */
Packit 032894
		  printf ("    ");
Packit 032894
		  if (prop.pr_type == GNU_PROPERTY_STACK_SIZE)
Packit 032894
		    {
Packit 032894
		      printf ("STACK_SIZE ");
Packit 032894
		      union
Packit 032894
			{
Packit 032894
			  Elf64_Addr a64;
Packit 032894
			  Elf32_Addr a32;
Packit 032894
			} addr;
Packit 032894
		      if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4)
Packit 032894
			  || (elfclass == ELFCLASS64 && prop.pr_datasz == 8))
Packit 032894
			{
Packit 032894
			  in.d_type = ELF_T_ADDR;
Packit 032894
			  out.d_type = ELF_T_ADDR;
Packit 032894
			  in.d_size = prop.pr_datasz;
Packit 032894
			  out.d_size = prop.pr_datasz;
Packit 032894
			  in.d_buf = (void *) desc;
Packit 032894
			  out.d_buf = (elfclass == ELFCLASS32
Packit 032894
				       ? (void *) &addr.a32
Packit 032894
				       : (void *) &addr.a64);
Packit 032894
Packit 032894
			  if (gelf_xlatetom (ebl->elf, &out, &in,
Packit 032894
					     elfident[EI_DATA]) == NULL)
Packit 032894
			    {
Packit 032894
			      printf ("%s\n", elf_errmsg (-1));
Packit 032894
			      return;
Packit 032894
			    }
Packit 032894
			  if (elfclass == ELFCLASS32)
Packit 032894
			    printf ("%#" PRIx32 "\n", addr.a32);
Packit 032894
			  else
Packit 032894
			    printf ("%#" PRIx64 "\n", addr.a64);
Packit 032894
			}
Packit 032894
		      else
Packit 032894
			printf (" (garbage datasz: %" PRIx32 ")\n",
Packit 032894
				prop.pr_datasz);
Packit 032894
		    }
Packit 032894
		  else if (prop.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED)
Packit 032894
		    {
Packit 032894
		      printf ("NO_COPY_ON_PROTECTION");
Packit 032894
		      if (prop.pr_datasz == 0)
Packit 032894
			printf ("\n");
Packit 032894
		      else
Packit 032894
			printf (" (garbage datasz: %" PRIx32 ")\n",
Packit 032894
				prop.pr_datasz);
Packit 032894
		    }
Packit 032894
		  else if (prop.pr_type >= GNU_PROPERTY_LOPROC
Packit 032894
		      && prop.pr_type <= GNU_PROPERTY_HIPROC
Packit 032894
		      && (ehdr.e_machine == EM_386
Packit 032894
			  || ehdr.e_machine == EM_X86_64))
Packit 032894
		    {
Packit 032894
		      printf ("X86 ");
Packit 032894
		      if (prop.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
Packit 032894
			{
Packit 032894
			  printf ("FEATURE_1_AND: ");
Packit 032894
Packit 032894
			  if (prop.pr_datasz == 4)
Packit 032894
			    {
Packit 032894
			      GElf_Word data;
Packit 032894
			      in.d_type = ELF_T_WORD;
Packit 032894
			      out.d_type = ELF_T_WORD;
Packit 032894
			      in.d_size = 4;
Packit 032894
			      out.d_size = 4;
Packit 032894
			      in.d_buf = (void *) desc;
Packit 032894
			      out.d_buf = (void *) &dat;;
Packit 032894
Packit 032894
			      if (gelf_xlatetom (ebl->elf, &out, &in,
Packit 032894
						 elfident[EI_DATA]) == NULL)
Packit 032894
				{
Packit 032894
				  printf ("%s\n", elf_errmsg (-1));
Packit 032894
				  return;
Packit 032894
				}
Packit 032894
			      printf ("%08" PRIx32 " ", data);
Packit 032894
Packit 032894
			      if ((data & GNU_PROPERTY_X86_FEATURE_1_IBT)
Packit 032894
				  != 0)
Packit 032894
				{
Packit 032894
				  printf ("IBT");
Packit 032894
				  data &= ~GNU_PROPERTY_X86_FEATURE_1_IBT;
Packit 032894
				  if (data != 0)
Packit 032894
				    printf (" ");
Packit 032894
				}
Packit 032894
Packit 032894
			      if ((data & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
Packit 032894
				  != 0)
Packit 032894
				{
Packit 032894
				  printf ("SHSTK");
Packit 032894
				  data &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK;
Packit 032894
				  if (data != 0)
Packit 032894
				    printf (" ");
Packit 032894
				}
Packit 032894
Packit 032894
			      if (data != 0)
Packit 032894
				printf ("UNKNOWN");
Packit 032894
			    }
Packit 032894
			  else
Packit 032894
			    printf ("<bad datasz: %" PRId32 ">",
Packit 032894
				    prop.pr_datasz);
Packit 032894
Packit 032894
			  printf ("\n");
Packit 032894
			}
Packit 032894
		      else
Packit 032894
			{
Packit 032894
			  printf ("%#" PRIx32, prop.pr_type);
Packit 032894
			  if (prop.pr_datasz > 0)
Packit 032894
			    {
Packit 032894
			      printf (" data: ");
Packit 032894
			      size_t i;
Packit 032894
			      for (i = 0; i < prop.pr_datasz - 1; i++)
Packit 032894
				printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
Packit 032894
			      printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
Packit 032894
			    }
Packit 032894
			}
Packit 032894
		    }
Packit 032894
		  else
Packit 032894
		    {
Packit 032894
		      if (prop.pr_type >= GNU_PROPERTY_LOPROC
Packit 032894
			  && prop.pr_type <= GNU_PROPERTY_HIPROC)
Packit 032894
			printf ("proc_type %#" PRIx32, prop.pr_type);
Packit 032894
		      else if (prop.pr_type >= GNU_PROPERTY_LOUSER
Packit 032894
			  && prop.pr_type <= GNU_PROPERTY_HIUSER)
Packit 032894
			printf ("app_type %#" PRIx32, prop.pr_type);
Packit 032894
		      else
Packit 032894
			printf ("unknown_type %#" PRIx32, prop.pr_type);
Packit 032894
Packit 032894
		      if (prop.pr_datasz > 0)
Packit 032894
			{
Packit 032894
			  printf (" data: ");
Packit 032894
			  size_t i;
Packit 032894
			  for (i = 0; i < prop.pr_datasz - 1; i++)
Packit 032894
			    printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
Packit 032894
			  printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
Packit 032894
			}
Packit 032894
		    }
Packit 032894
Packit 032894
		  if (elfclass == ELFCLASS32)
Packit 032894
		    prop.pr_datasz = NOTE_ALIGN4 (prop.pr_datasz);
Packit 032894
		  else
Packit 032894
		    prop.pr_datasz = NOTE_ALIGN8 (prop.pr_datasz);
Packit 032894
Packit 032894
		  desc += prop.pr_datasz;
Packit 032894
		  if (descsz > prop.pr_datasz)
Packit 032894
		    descsz -= prop.pr_datasz;
Packit 032894
		  else
Packit 032894
		    descsz = 0;
Packit 032894
		}
Packit 032894
	    }
Packit 032894
	  break;
Packit 032894
Packit 032894
	case NT_GNU_ABI_TAG:
Packit 032894
	  if (descsz >= 8 && descsz % 4 == 0)
Packit 032894
	    {
Packit 032894
	      Elf_Data in =
Packit 032894
		{
Packit 032894
		  .d_version = EV_CURRENT,
Packit 032894
		  .d_type = ELF_T_WORD,
Packit 032894
		  .d_size = descsz,
Packit 032894
		  .d_buf = (void *) desc
Packit 032894
		};
Packit 032894
	      /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes).  If it
Packit 032894
		 is much (4*) larger dynamically allocate memory to convert.  */
Packit 032894
#define FIXED_TAG_BYTES 16
Packit 032894
	      uint32_t sbuf[FIXED_TAG_BYTES];
Packit 032894
	      uint32_t *buf;
Packit 032894
	      if (unlikely (descsz / 4 > FIXED_TAG_BYTES))
Packit 032894
		{
Packit 032894
		  buf = malloc (descsz);
Packit 032894
		  if (unlikely (buf == NULL))
Packit 032894
		    return;
Packit 032894
		}
Packit 032894
	      else
Packit 032894
		buf = sbuf;
Packit 032894
	      Elf_Data out =
Packit 032894
		{
Packit 032894
		  .d_version = EV_CURRENT,
Packit 032894
		  .d_type = ELF_T_WORD,
Packit 032894
		  .d_size = descsz,
Packit 032894
		  .d_buf = buf
Packit 032894
		};
Packit 032894
Packit 032894
	      if (elf32_xlatetom (&out, &in, ebl->data) != NULL)
Packit 032894
		{
Packit 032894
		  const char *os;
Packit 032894
		  switch (buf[0])
Packit 032894
		    {
Packit 032894
		    case ELF_NOTE_OS_LINUX:
Packit 032894
		      os = "Linux";
Packit 032894
		      break;
Packit 032894
Packit 032894
		    case ELF_NOTE_OS_GNU:
Packit 032894
		      os = "GNU";
Packit 032894
		      break;
Packit 032894
Packit 032894
		    case ELF_NOTE_OS_SOLARIS2:
Packit 032894
		      os = "Solaris";
Packit 032894
		      break;
Packit 032894
Packit 032894
		    case ELF_NOTE_OS_FREEBSD:
Packit 032894
		      os = "FreeBSD";
Packit 032894
		      break;
Packit 032894
Packit 032894
		    default:
Packit 032894
		      os = "???";
Packit 032894
		      break;
Packit 032894
		    }
Packit 032894
Packit 032894
		  printf (gettext ("    OS: %s, ABI: "), os);
Packit 032894
		  for (size_t cnt = 1; cnt < descsz / 4; ++cnt)
Packit 032894
		    {
Packit 032894
		      if (cnt > 1)
Packit 032894
			putchar_unlocked ('.');
Packit 032894
		      printf ("%" PRIu32, buf[cnt]);
Packit 032894
		    }
Packit 032894
		  putchar_unlocked ('\n');
Packit 032894
		}
Packit 032894
	      if (descsz / 4 > FIXED_TAG_BYTES)
Packit 032894
		free (buf);
Packit 032894
	      break;
Packit 032894
	    }
Packit 032894
	  FALLTHROUGH;
Packit 032894
Packit 032894
	default:
Packit 032894
	  /* Unknown type.  */
Packit 032894
	  break;
Packit 032894
	}
Packit 032894
    }
Packit 032894
}