Blame libebl/eblobjnote.c

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