xref: /aosp_15_r20/external/elfutils/libebl/eblobjnote.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
1*7304104dSAndroid Build Coastguard Worker /* Print contents of object file note.
2*7304104dSAndroid Build Coastguard Worker    Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016, 2018 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker    This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker    Written by Ulrich Drepper <[email protected]>, 2002.
5*7304104dSAndroid Build Coastguard Worker 
6*7304104dSAndroid Build Coastguard Worker    This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker    it under the terms of either
8*7304104dSAndroid Build Coastguard Worker 
9*7304104dSAndroid Build Coastguard Worker      * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker        your option) any later version
12*7304104dSAndroid Build Coastguard Worker 
13*7304104dSAndroid Build Coastguard Worker    or
14*7304104dSAndroid Build Coastguard Worker 
15*7304104dSAndroid Build Coastguard Worker      * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker        your option) any later version
18*7304104dSAndroid Build Coastguard Worker 
19*7304104dSAndroid Build Coastguard Worker    or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker 
21*7304104dSAndroid Build Coastguard Worker    elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24*7304104dSAndroid Build Coastguard Worker    General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker 
26*7304104dSAndroid Build Coastguard Worker    You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker    the GNU Lesser General Public License along with this program.  If
28*7304104dSAndroid Build Coastguard Worker    not, see <http://www.gnu.org/licenses/>.  */
29*7304104dSAndroid Build Coastguard Worker 
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker 
34*7304104dSAndroid Build Coastguard Worker #include <inttypes.h>
35*7304104dSAndroid Build Coastguard Worker #include <stdio.h>
36*7304104dSAndroid Build Coastguard Worker #include <stdlib.h>
37*7304104dSAndroid Build Coastguard Worker #include <string.h>
38*7304104dSAndroid Build Coastguard Worker #include <libeblP.h>
39*7304104dSAndroid Build Coastguard Worker 
40*7304104dSAndroid Build Coastguard Worker #include "common.h"
41*7304104dSAndroid Build Coastguard Worker #include "libelfP.h"
42*7304104dSAndroid Build Coastguard Worker #include "libdwP.h"
43*7304104dSAndroid Build Coastguard Worker #include "memory-access.h"
44*7304104dSAndroid Build Coastguard Worker 
45*7304104dSAndroid Build Coastguard Worker 
46*7304104dSAndroid Build Coastguard Worker void
ebl_object_note(Ebl * ebl,uint32_t namesz,const char * name,uint32_t type,uint32_t descsz,const char * desc)47*7304104dSAndroid Build Coastguard Worker ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type,
48*7304104dSAndroid Build Coastguard Worker 		 uint32_t descsz, const char *desc)
49*7304104dSAndroid Build Coastguard Worker {
50*7304104dSAndroid Build Coastguard Worker   if (! ebl->object_note (name, type, descsz, desc))
51*7304104dSAndroid Build Coastguard Worker     {
52*7304104dSAndroid Build Coastguard Worker       /* The machine specific function did not know this type.  */
53*7304104dSAndroid Build Coastguard Worker 
54*7304104dSAndroid Build Coastguard Worker       if (strcmp ("stapsdt", name) == 0)
55*7304104dSAndroid Build Coastguard Worker 	{
56*7304104dSAndroid Build Coastguard Worker 	  if (type != 3)
57*7304104dSAndroid Build Coastguard Worker 	    {
58*7304104dSAndroid Build Coastguard Worker 	      printf (_("unknown SDT version %u\n"), type);
59*7304104dSAndroid Build Coastguard Worker 	      return;
60*7304104dSAndroid Build Coastguard Worker 	    }
61*7304104dSAndroid Build Coastguard Worker 
62*7304104dSAndroid Build Coastguard Worker 	  /* Descriptor starts with three addresses, pc, base ref and
63*7304104dSAndroid Build Coastguard Worker 	     semaphore.  Then three zero terminated strings provider,
64*7304104dSAndroid Build Coastguard Worker 	     name and arguments.  */
65*7304104dSAndroid Build Coastguard Worker 
66*7304104dSAndroid Build Coastguard Worker 	  union
67*7304104dSAndroid Build Coastguard Worker 	  {
68*7304104dSAndroid Build Coastguard Worker 	    Elf64_Addr a64[3];
69*7304104dSAndroid Build Coastguard Worker 	    Elf32_Addr a32[3];
70*7304104dSAndroid Build Coastguard Worker 	  } addrs;
71*7304104dSAndroid Build Coastguard Worker 
72*7304104dSAndroid Build Coastguard Worker 	  size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT);
73*7304104dSAndroid Build Coastguard Worker 	  if (descsz < addrs_size + 3)
74*7304104dSAndroid Build Coastguard Worker 	    {
75*7304104dSAndroid Build Coastguard Worker 	    invalid_sdt:
76*7304104dSAndroid Build Coastguard Worker 	      printf (_("invalid SDT probe descriptor\n"));
77*7304104dSAndroid Build Coastguard Worker 	      return;
78*7304104dSAndroid Build Coastguard Worker 	    }
79*7304104dSAndroid Build Coastguard Worker 
80*7304104dSAndroid Build Coastguard Worker 	  Elf_Data src =
81*7304104dSAndroid Build Coastguard Worker 	    {
82*7304104dSAndroid Build Coastguard Worker 	      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
83*7304104dSAndroid Build Coastguard Worker 	      .d_buf = (void *) desc, .d_size = addrs_size
84*7304104dSAndroid Build Coastguard Worker 	    };
85*7304104dSAndroid Build Coastguard Worker 
86*7304104dSAndroid Build Coastguard Worker 	  Elf_Data dst =
87*7304104dSAndroid Build Coastguard Worker 	    {
88*7304104dSAndroid Build Coastguard Worker 	      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
89*7304104dSAndroid Build Coastguard Worker 	      .d_buf = &addrs, .d_size = addrs_size
90*7304104dSAndroid Build Coastguard Worker 	    };
91*7304104dSAndroid Build Coastguard Worker 
92*7304104dSAndroid Build Coastguard Worker 	  if (gelf_xlatetom (ebl->elf, &dst, &src,
93*7304104dSAndroid Build Coastguard Worker 			     elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL)
94*7304104dSAndroid Build Coastguard Worker 	    {
95*7304104dSAndroid Build Coastguard Worker 	      printf ("%s\n", elf_errmsg (-1));
96*7304104dSAndroid Build Coastguard Worker 	      return;
97*7304104dSAndroid Build Coastguard Worker 	    }
98*7304104dSAndroid Build Coastguard Worker 
99*7304104dSAndroid Build Coastguard Worker 	  const char *provider = desc + addrs_size;
100*7304104dSAndroid Build Coastguard Worker 	  const char *pname = memchr (provider, '\0', desc + descsz - provider);
101*7304104dSAndroid Build Coastguard Worker 	  if (pname == NULL)
102*7304104dSAndroid Build Coastguard Worker 	    goto invalid_sdt;
103*7304104dSAndroid Build Coastguard Worker 
104*7304104dSAndroid Build Coastguard Worker 	  ++pname;
105*7304104dSAndroid Build Coastguard Worker 	  const char *args = memchr (pname, '\0', desc + descsz - pname);
106*7304104dSAndroid Build Coastguard Worker 	  if (args == NULL ||
107*7304104dSAndroid Build Coastguard Worker 	      memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1)
108*7304104dSAndroid Build Coastguard Worker 	    goto invalid_sdt;
109*7304104dSAndroid Build Coastguard Worker 
110*7304104dSAndroid Build Coastguard Worker 	  GElf_Addr pc;
111*7304104dSAndroid Build Coastguard Worker 	  GElf_Addr base;
112*7304104dSAndroid Build Coastguard Worker 	  GElf_Addr sem;
113*7304104dSAndroid Build Coastguard Worker 	  if (gelf_getclass (ebl->elf) == ELFCLASS32)
114*7304104dSAndroid Build Coastguard Worker 	    {
115*7304104dSAndroid Build Coastguard Worker 	      pc = addrs.a32[0];
116*7304104dSAndroid Build Coastguard Worker 	      base = addrs.a32[1];
117*7304104dSAndroid Build Coastguard Worker 	      sem = addrs.a32[2];
118*7304104dSAndroid Build Coastguard Worker 	    }
119*7304104dSAndroid Build Coastguard Worker 	  else
120*7304104dSAndroid Build Coastguard Worker 	    {
121*7304104dSAndroid Build Coastguard Worker 	      pc = addrs.a64[0];
122*7304104dSAndroid Build Coastguard Worker 	      base = addrs.a64[1];
123*7304104dSAndroid Build Coastguard Worker 	      sem = addrs.a64[2];
124*7304104dSAndroid Build Coastguard Worker 	    }
125*7304104dSAndroid Build Coastguard Worker 
126*7304104dSAndroid Build Coastguard Worker 	  printf (_("    PC: "));
127*7304104dSAndroid Build Coastguard Worker 	  printf ("%#" PRIx64 ",", pc);
128*7304104dSAndroid Build Coastguard Worker 	  printf (_(" Base: "));
129*7304104dSAndroid Build Coastguard Worker 	  printf ("%#" PRIx64 ",", base);
130*7304104dSAndroid Build Coastguard Worker 	  printf (_(" Semaphore: "));
131*7304104dSAndroid Build Coastguard Worker 	  printf ("%#" PRIx64 "\n", sem);
132*7304104dSAndroid Build Coastguard Worker 	  printf (_("    Provider: "));
133*7304104dSAndroid Build Coastguard Worker 	  printf ("%s,", provider);
134*7304104dSAndroid Build Coastguard Worker 	  printf (_(" Name: "));
135*7304104dSAndroid Build Coastguard Worker 	  printf ("%s,", pname);
136*7304104dSAndroid Build Coastguard Worker 	  printf (_(" Args: "));
137*7304104dSAndroid Build Coastguard Worker 	  printf ("'%s'\n", args);
138*7304104dSAndroid Build Coastguard Worker 	  return;
139*7304104dSAndroid Build Coastguard Worker 	}
140*7304104dSAndroid Build Coastguard Worker 
141*7304104dSAndroid Build Coastguard Worker       if (strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
142*7304104dSAndroid Build Coastguard Worker 		   strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0
143*7304104dSAndroid Build Coastguard Worker 	  && (type == NT_GNU_BUILD_ATTRIBUTE_OPEN
144*7304104dSAndroid Build Coastguard Worker 	      || type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
145*7304104dSAndroid Build Coastguard Worker 	{
146*7304104dSAndroid Build Coastguard Worker 	  /* There might or might not be a pair of addresses in the desc.  */
147*7304104dSAndroid Build Coastguard Worker 	  if (descsz > 0)
148*7304104dSAndroid Build Coastguard Worker 	    {
149*7304104dSAndroid Build Coastguard Worker 	      printf ("    Address Range: ");
150*7304104dSAndroid Build Coastguard Worker 
151*7304104dSAndroid Build Coastguard Worker 	      union
152*7304104dSAndroid Build Coastguard Worker 	      {
153*7304104dSAndroid Build Coastguard Worker 		Elf64_Addr a64[2];
154*7304104dSAndroid Build Coastguard Worker 		Elf32_Addr a32[2];
155*7304104dSAndroid Build Coastguard Worker 	      } addrs;
156*7304104dSAndroid Build Coastguard Worker 
157*7304104dSAndroid Build Coastguard Worker 	      size_t addr_size = gelf_fsize (ebl->elf, ELF_T_ADDR,
158*7304104dSAndroid Build Coastguard Worker 					     1, EV_CURRENT);
159*7304104dSAndroid Build Coastguard Worker 	      if (descsz != addr_size * 2)
160*7304104dSAndroid Build Coastguard Worker 		printf ("<unknown data>\n");
161*7304104dSAndroid Build Coastguard Worker 	      else
162*7304104dSAndroid Build Coastguard Worker 		{
163*7304104dSAndroid Build Coastguard Worker 		  Elf_Data src =
164*7304104dSAndroid Build Coastguard Worker 		    {
165*7304104dSAndroid Build Coastguard Worker 		     .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
166*7304104dSAndroid Build Coastguard Worker 		     .d_buf = (void *) desc, .d_size = descsz
167*7304104dSAndroid Build Coastguard Worker 		    };
168*7304104dSAndroid Build Coastguard Worker 
169*7304104dSAndroid Build Coastguard Worker 		  Elf_Data dst =
170*7304104dSAndroid Build Coastguard Worker 		    {
171*7304104dSAndroid Build Coastguard Worker 		     .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
172*7304104dSAndroid Build Coastguard Worker 		     .d_buf = &addrs, .d_size = descsz
173*7304104dSAndroid Build Coastguard Worker 		    };
174*7304104dSAndroid Build Coastguard Worker 
175*7304104dSAndroid Build Coastguard Worker 		  if (gelf_xlatetom (ebl->elf, &dst, &src,
176*7304104dSAndroid Build Coastguard Worker 				     elf_getident (ebl->elf,
177*7304104dSAndroid Build Coastguard Worker 						   NULL)[EI_DATA]) == NULL)
178*7304104dSAndroid Build Coastguard Worker 		    printf ("%s\n", elf_errmsg (-1));
179*7304104dSAndroid Build Coastguard Worker 		  else
180*7304104dSAndroid Build Coastguard Worker 		    {
181*7304104dSAndroid Build Coastguard Worker 		      if (addr_size == 4)
182*7304104dSAndroid Build Coastguard Worker 			printf ("%#" PRIx32 " - %#" PRIx32 "\n",
183*7304104dSAndroid Build Coastguard Worker 				addrs.a32[0], addrs.a32[1]);
184*7304104dSAndroid Build Coastguard Worker 		      else
185*7304104dSAndroid Build Coastguard Worker 			printf ("%#" PRIx64 " - %#" PRIx64 "\n",
186*7304104dSAndroid Build Coastguard Worker 				addrs.a64[0], addrs.a64[1]);
187*7304104dSAndroid Build Coastguard Worker 		    }
188*7304104dSAndroid Build Coastguard Worker 		}
189*7304104dSAndroid Build Coastguard Worker 	    }
190*7304104dSAndroid Build Coastguard Worker 
191*7304104dSAndroid Build Coastguard Worker 	  /* Most data actually is inside the name.
192*7304104dSAndroid Build Coastguard Worker 	     https://fedoraproject.org/wiki/Toolchain/Watermark  */
193*7304104dSAndroid Build Coastguard Worker 
194*7304104dSAndroid Build Coastguard Worker 	  /* We need at least 2 chars of data to describe the
195*7304104dSAndroid Build Coastguard Worker 	     attribute and value encodings.  */
196*7304104dSAndroid Build Coastguard Worker 	  const char *data = (name
197*7304104dSAndroid Build Coastguard Worker 			      + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX));
198*7304104dSAndroid Build Coastguard Worker 	  if (namesz < 2)
199*7304104dSAndroid Build Coastguard Worker 	    {
200*7304104dSAndroid Build Coastguard Worker 	      printf ("<insufficient data>\n");
201*7304104dSAndroid Build Coastguard Worker 	      return;
202*7304104dSAndroid Build Coastguard Worker 	    }
203*7304104dSAndroid Build Coastguard Worker 
204*7304104dSAndroid Build Coastguard Worker 	  printf ("    ");
205*7304104dSAndroid Build Coastguard Worker 
206*7304104dSAndroid Build Coastguard Worker 	  /* In most cases the value comes right after the encoding bytes.  */
207*7304104dSAndroid Build Coastguard Worker 	  const char *value = &data[2];
208*7304104dSAndroid Build Coastguard Worker 	  switch (data[1])
209*7304104dSAndroid Build Coastguard Worker 	    {
210*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_VERSION:
211*7304104dSAndroid Build Coastguard Worker 	      printf ("VERSION: ");
212*7304104dSAndroid Build Coastguard Worker 	      break;
213*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_STACK_PROT:
214*7304104dSAndroid Build Coastguard Worker 	      printf ("STACK_PROT: ");
215*7304104dSAndroid Build Coastguard Worker 	      break;
216*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_RELRO:
217*7304104dSAndroid Build Coastguard Worker 	      printf ("RELRO: ");
218*7304104dSAndroid Build Coastguard Worker 	      break;
219*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
220*7304104dSAndroid Build Coastguard Worker 	      printf ("STACK_SIZE: ");
221*7304104dSAndroid Build Coastguard Worker 	      break;
222*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_TOOL:
223*7304104dSAndroid Build Coastguard Worker 	      printf ("TOOL: ");
224*7304104dSAndroid Build Coastguard Worker 	      break;
225*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_ABI:
226*7304104dSAndroid Build Coastguard Worker 	      printf ("ABI: ");
227*7304104dSAndroid Build Coastguard Worker 	      break;
228*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_PIC:
229*7304104dSAndroid Build Coastguard Worker 	      printf ("PIC: ");
230*7304104dSAndroid Build Coastguard Worker 	      break;
231*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
232*7304104dSAndroid Build Coastguard Worker 	      printf ("SHORT_ENUM: ");
233*7304104dSAndroid Build Coastguard Worker 	      break;
234*7304104dSAndroid Build Coastguard Worker 	    case 32 ... 126:
235*7304104dSAndroid Build Coastguard Worker 	      printf ("\"%s\": ", &data[1]);
236*7304104dSAndroid Build Coastguard Worker 	      value += strlen (&data[1]) + 1;
237*7304104dSAndroid Build Coastguard Worker 	      break;
238*7304104dSAndroid Build Coastguard Worker 	    default:
239*7304104dSAndroid Build Coastguard Worker 	      printf ("<unknown>: ");
240*7304104dSAndroid Build Coastguard Worker 	      break;
241*7304104dSAndroid Build Coastguard Worker 	    }
242*7304104dSAndroid Build Coastguard Worker 
243*7304104dSAndroid Build Coastguard Worker 	  switch (data[0])
244*7304104dSAndroid Build Coastguard Worker 	    {
245*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
246*7304104dSAndroid Build Coastguard Worker 	      {
247*7304104dSAndroid Build Coastguard Worker 		/* Any numbers are always in (unsigned) little endian.  */
248*7304104dSAndroid Build Coastguard Worker 		static const Dwarf dbg
249*7304104dSAndroid Build Coastguard Worker 		  = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
250*7304104dSAndroid Build Coastguard Worker 		size_t bytes = namesz - (value - name);
251*7304104dSAndroid Build Coastguard Worker 		uint64_t val;
252*7304104dSAndroid Build Coastguard Worker 		if (bytes == 1)
253*7304104dSAndroid Build Coastguard Worker 		  val = *(unsigned char *) value;
254*7304104dSAndroid Build Coastguard Worker 		else if (bytes == 2)
255*7304104dSAndroid Build Coastguard Worker 		  val = read_2ubyte_unaligned (&dbg, value);
256*7304104dSAndroid Build Coastguard Worker 		else if (bytes == 4)
257*7304104dSAndroid Build Coastguard Worker 		  val = read_4ubyte_unaligned (&dbg, value);
258*7304104dSAndroid Build Coastguard Worker 		else if (bytes == 8)
259*7304104dSAndroid Build Coastguard Worker 		  val = read_8ubyte_unaligned (&dbg, value);
260*7304104dSAndroid Build Coastguard Worker 		else
261*7304104dSAndroid Build Coastguard Worker 		  goto unknown;
262*7304104dSAndroid Build Coastguard Worker 		printf ("%" PRIx64, val);
263*7304104dSAndroid Build Coastguard Worker 	      }
264*7304104dSAndroid Build Coastguard Worker 	      break;
265*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
266*7304104dSAndroid Build Coastguard Worker 	      printf ("\"%s\"", value);
267*7304104dSAndroid Build Coastguard Worker 	      break;
268*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
269*7304104dSAndroid Build Coastguard Worker 	      printf ("TRUE");
270*7304104dSAndroid Build Coastguard Worker 	      break;
271*7304104dSAndroid Build Coastguard Worker 	    case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
272*7304104dSAndroid Build Coastguard Worker 	      printf ("FALSE");
273*7304104dSAndroid Build Coastguard Worker 	      break;
274*7304104dSAndroid Build Coastguard Worker 	    default:
275*7304104dSAndroid Build Coastguard Worker 	      {
276*7304104dSAndroid Build Coastguard Worker 	      unknown:
277*7304104dSAndroid Build Coastguard Worker 		printf ("<unknown>");
278*7304104dSAndroid Build Coastguard Worker 	      }
279*7304104dSAndroid Build Coastguard Worker 	      break;
280*7304104dSAndroid Build Coastguard Worker 	    }
281*7304104dSAndroid Build Coastguard Worker 
282*7304104dSAndroid Build Coastguard Worker 	  printf ("\n");
283*7304104dSAndroid Build Coastguard Worker 
284*7304104dSAndroid Build Coastguard Worker 	  return;
285*7304104dSAndroid Build Coastguard Worker 	}
286*7304104dSAndroid Build Coastguard Worker 
287*7304104dSAndroid Build Coastguard Worker       /* NT_VERSION doesn't have any info.  All data is in the name.  */
288*7304104dSAndroid Build Coastguard Worker       if (descsz == 0 && type == NT_VERSION)
289*7304104dSAndroid Build Coastguard Worker 	return;
290*7304104dSAndroid Build Coastguard Worker 
291*7304104dSAndroid Build Coastguard Worker       if (strcmp ("FDO", name) == 0 && type == NT_FDO_PACKAGING_METADATA
292*7304104dSAndroid Build Coastguard Worker 	  && descsz > 0 && desc[descsz - 1] == '\0')
293*7304104dSAndroid Build Coastguard Worker 	printf("    Packaging Metadata: %.*s\n", (int) descsz, desc);
294*7304104dSAndroid Build Coastguard Worker 
295*7304104dSAndroid Build Coastguard Worker       /* Everything else should have the "GNU" owner name.  */
296*7304104dSAndroid Build Coastguard Worker       if (strcmp ("GNU", name) != 0)
297*7304104dSAndroid Build Coastguard Worker 	return;
298*7304104dSAndroid Build Coastguard Worker 
299*7304104dSAndroid Build Coastguard Worker       switch (type)
300*7304104dSAndroid Build Coastguard Worker 	{
301*7304104dSAndroid Build Coastguard Worker 	case NT_GNU_BUILD_ID:
302*7304104dSAndroid Build Coastguard Worker 	  if (strcmp (name, "GNU") == 0 && descsz > 0)
303*7304104dSAndroid Build Coastguard Worker 	    {
304*7304104dSAndroid Build Coastguard Worker 	      printf (_("    Build ID: "));
305*7304104dSAndroid Build Coastguard Worker 	      uint_fast32_t i;
306*7304104dSAndroid Build Coastguard Worker 	      for (i = 0; i < descsz - 1; ++i)
307*7304104dSAndroid Build Coastguard Worker 		printf ("%02" PRIx8, (uint8_t) desc[i]);
308*7304104dSAndroid Build Coastguard Worker 	      printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
309*7304104dSAndroid Build Coastguard Worker 	    }
310*7304104dSAndroid Build Coastguard Worker 	  break;
311*7304104dSAndroid Build Coastguard Worker 
312*7304104dSAndroid Build Coastguard Worker 	case NT_GNU_GOLD_VERSION:
313*7304104dSAndroid Build Coastguard Worker 	  if (strcmp (name, "GNU") == 0 && descsz > 0)
314*7304104dSAndroid Build Coastguard Worker 	    /* A non-null terminated version string.  */
315*7304104dSAndroid Build Coastguard Worker 	    printf (_("    Linker version: %.*s\n"),
316*7304104dSAndroid Build Coastguard Worker 		    (int) descsz, desc);
317*7304104dSAndroid Build Coastguard Worker 	  break;
318*7304104dSAndroid Build Coastguard Worker 
319*7304104dSAndroid Build Coastguard Worker 	case NT_GNU_PROPERTY_TYPE_0:
320*7304104dSAndroid Build Coastguard Worker 	  if (strcmp (name, "GNU") == 0 && descsz > 0)
321*7304104dSAndroid Build Coastguard Worker 	    {
322*7304104dSAndroid Build Coastguard Worker 	      /* There are at least 2 words. type and datasz.  */
323*7304104dSAndroid Build Coastguard Worker 	      while (descsz >= 8)
324*7304104dSAndroid Build Coastguard Worker 		{
325*7304104dSAndroid Build Coastguard Worker 		  struct pr_prop
326*7304104dSAndroid Build Coastguard Worker 		  {
327*7304104dSAndroid Build Coastguard Worker 		    GElf_Word pr_type;
328*7304104dSAndroid Build Coastguard Worker 		    GElf_Word pr_datasz;
329*7304104dSAndroid Build Coastguard Worker 		  } prop;
330*7304104dSAndroid Build Coastguard Worker 
331*7304104dSAndroid Build Coastguard Worker 		  Elf_Data in =
332*7304104dSAndroid Build Coastguard Worker 		    {
333*7304104dSAndroid Build Coastguard Worker 		      .d_version = EV_CURRENT,
334*7304104dSAndroid Build Coastguard Worker 		      .d_type = ELF_T_WORD,
335*7304104dSAndroid Build Coastguard Worker 		      .d_size = 8,
336*7304104dSAndroid Build Coastguard Worker 		      .d_buf = (void *) desc
337*7304104dSAndroid Build Coastguard Worker 		    };
338*7304104dSAndroid Build Coastguard Worker 		  Elf_Data out =
339*7304104dSAndroid Build Coastguard Worker 		    {
340*7304104dSAndroid Build Coastguard Worker 		      .d_version = EV_CURRENT,
341*7304104dSAndroid Build Coastguard Worker 		      .d_type = ELF_T_WORD,
342*7304104dSAndroid Build Coastguard Worker 		      .d_size = descsz,
343*7304104dSAndroid Build Coastguard Worker 		      .d_buf = (void *) &prop
344*7304104dSAndroid Build Coastguard Worker 		    };
345*7304104dSAndroid Build Coastguard Worker 
346*7304104dSAndroid Build Coastguard Worker 		  if (gelf_xlatetom (ebl->elf, &out, &in,
347*7304104dSAndroid Build Coastguard Worker 				     elf_getident (ebl->elf,
348*7304104dSAndroid Build Coastguard Worker 						   NULL)[EI_DATA]) == NULL)
349*7304104dSAndroid Build Coastguard Worker 		    {
350*7304104dSAndroid Build Coastguard Worker 		      printf ("%s\n", elf_errmsg (-1));
351*7304104dSAndroid Build Coastguard Worker 		      return;
352*7304104dSAndroid Build Coastguard Worker 		    }
353*7304104dSAndroid Build Coastguard Worker 
354*7304104dSAndroid Build Coastguard Worker 		  desc += 8;
355*7304104dSAndroid Build Coastguard Worker 		  descsz -= 8;
356*7304104dSAndroid Build Coastguard Worker 
357*7304104dSAndroid Build Coastguard Worker 		  if (prop.pr_datasz > descsz)
358*7304104dSAndroid Build Coastguard Worker 		    {
359*7304104dSAndroid Build Coastguard Worker 		      printf ("BAD property datasz: %" PRId32 "\n",
360*7304104dSAndroid Build Coastguard Worker 			      prop.pr_datasz);
361*7304104dSAndroid Build Coastguard Worker 		      return;
362*7304104dSAndroid Build Coastguard Worker 		    }
363*7304104dSAndroid Build Coastguard Worker 
364*7304104dSAndroid Build Coastguard Worker 		  int elfclass = gelf_getclass (ebl->elf);
365*7304104dSAndroid Build Coastguard Worker 		  char *elfident = elf_getident (ebl->elf, NULL);
366*7304104dSAndroid Build Coastguard Worker 		  GElf_Ehdr ehdr;
367*7304104dSAndroid Build Coastguard Worker 		  gelf_getehdr (ebl->elf, &ehdr);
368*7304104dSAndroid Build Coastguard Worker 
369*7304104dSAndroid Build Coastguard Worker 		  /* Prefix.  */
370*7304104dSAndroid Build Coastguard Worker 		  printf ("    ");
371*7304104dSAndroid Build Coastguard Worker 		  if (prop.pr_type == GNU_PROPERTY_STACK_SIZE)
372*7304104dSAndroid Build Coastguard Worker 		    {
373*7304104dSAndroid Build Coastguard Worker 		      printf ("STACK_SIZE ");
374*7304104dSAndroid Build Coastguard Worker 		      union
375*7304104dSAndroid Build Coastguard Worker 			{
376*7304104dSAndroid Build Coastguard Worker 			  Elf64_Addr a64;
377*7304104dSAndroid Build Coastguard Worker 			  Elf32_Addr a32;
378*7304104dSAndroid Build Coastguard Worker 			} addr;
379*7304104dSAndroid Build Coastguard Worker 		      if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4)
380*7304104dSAndroid Build Coastguard Worker 			  || (elfclass == ELFCLASS64 && prop.pr_datasz == 8))
381*7304104dSAndroid Build Coastguard Worker 			{
382*7304104dSAndroid Build Coastguard Worker 			  in.d_type = ELF_T_ADDR;
383*7304104dSAndroid Build Coastguard Worker 			  out.d_type = ELF_T_ADDR;
384*7304104dSAndroid Build Coastguard Worker 			  in.d_size = prop.pr_datasz;
385*7304104dSAndroid Build Coastguard Worker 			  out.d_size = prop.pr_datasz;
386*7304104dSAndroid Build Coastguard Worker 			  in.d_buf = (void *) desc;
387*7304104dSAndroid Build Coastguard Worker 			  out.d_buf = (elfclass == ELFCLASS32
388*7304104dSAndroid Build Coastguard Worker 				       ? (void *) &addr.a32
389*7304104dSAndroid Build Coastguard Worker 				       : (void *) &addr.a64);
390*7304104dSAndroid Build Coastguard Worker 
391*7304104dSAndroid Build Coastguard Worker 			  if (gelf_xlatetom (ebl->elf, &out, &in,
392*7304104dSAndroid Build Coastguard Worker 					     elfident[EI_DATA]) == NULL)
393*7304104dSAndroid Build Coastguard Worker 			    {
394*7304104dSAndroid Build Coastguard Worker 			      printf ("%s\n", elf_errmsg (-1));
395*7304104dSAndroid Build Coastguard Worker 			      return;
396*7304104dSAndroid Build Coastguard Worker 			    }
397*7304104dSAndroid Build Coastguard Worker 			  if (elfclass == ELFCLASS32)
398*7304104dSAndroid Build Coastguard Worker 			    printf ("%#" PRIx32 "\n", addr.a32);
399*7304104dSAndroid Build Coastguard Worker 			  else
400*7304104dSAndroid Build Coastguard Worker 			    printf ("%#" PRIx64 "\n", addr.a64);
401*7304104dSAndroid Build Coastguard Worker 			}
402*7304104dSAndroid Build Coastguard Worker 		      else
403*7304104dSAndroid Build Coastguard Worker 			printf (" (garbage datasz: %" PRIx32 ")\n",
404*7304104dSAndroid Build Coastguard Worker 				prop.pr_datasz);
405*7304104dSAndroid Build Coastguard Worker 		    }
406*7304104dSAndroid Build Coastguard Worker 		  else if (prop.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED)
407*7304104dSAndroid Build Coastguard Worker 		    {
408*7304104dSAndroid Build Coastguard Worker 		      printf ("NO_COPY_ON_PROTECTION");
409*7304104dSAndroid Build Coastguard Worker 		      if (prop.pr_datasz == 0)
410*7304104dSAndroid Build Coastguard Worker 			printf ("\n");
411*7304104dSAndroid Build Coastguard Worker 		      else
412*7304104dSAndroid Build Coastguard Worker 			printf (" (garbage datasz: %" PRIx32 ")\n",
413*7304104dSAndroid Build Coastguard Worker 				prop.pr_datasz);
414*7304104dSAndroid Build Coastguard Worker 		    }
415*7304104dSAndroid Build Coastguard Worker 		  else if (prop.pr_type >= GNU_PROPERTY_LOPROC
416*7304104dSAndroid Build Coastguard Worker 		      && prop.pr_type <= GNU_PROPERTY_HIPROC
417*7304104dSAndroid Build Coastguard Worker 		      && (ehdr.e_machine == EM_386
418*7304104dSAndroid Build Coastguard Worker 			  || ehdr.e_machine == EM_X86_64))
419*7304104dSAndroid Build Coastguard Worker 		    {
420*7304104dSAndroid Build Coastguard Worker 		      printf ("X86 ");
421*7304104dSAndroid Build Coastguard Worker 		      if (prop.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
422*7304104dSAndroid Build Coastguard Worker 			{
423*7304104dSAndroid Build Coastguard Worker 			  printf ("FEATURE_1_AND: ");
424*7304104dSAndroid Build Coastguard Worker 
425*7304104dSAndroid Build Coastguard Worker 			  if (prop.pr_datasz == 4)
426*7304104dSAndroid Build Coastguard Worker 			    {
427*7304104dSAndroid Build Coastguard Worker 			      GElf_Word data;
428*7304104dSAndroid Build Coastguard Worker 			      in.d_type = ELF_T_WORD;
429*7304104dSAndroid Build Coastguard Worker 			      out.d_type = ELF_T_WORD;
430*7304104dSAndroid Build Coastguard Worker 			      in.d_size = 4;
431*7304104dSAndroid Build Coastguard Worker 			      out.d_size = 4;
432*7304104dSAndroid Build Coastguard Worker 			      in.d_buf = (void *) desc;
433*7304104dSAndroid Build Coastguard Worker 			      out.d_buf = (void *) &data;
434*7304104dSAndroid Build Coastguard Worker 
435*7304104dSAndroid Build Coastguard Worker 			      if (gelf_xlatetom (ebl->elf, &out, &in,
436*7304104dSAndroid Build Coastguard Worker 						 elfident[EI_DATA]) == NULL)
437*7304104dSAndroid Build Coastguard Worker 				{
438*7304104dSAndroid Build Coastguard Worker 				  printf ("%s\n", elf_errmsg (-1));
439*7304104dSAndroid Build Coastguard Worker 				  return;
440*7304104dSAndroid Build Coastguard Worker 				}
441*7304104dSAndroid Build Coastguard Worker 			      printf ("%08" PRIx32 " ", data);
442*7304104dSAndroid Build Coastguard Worker 
443*7304104dSAndroid Build Coastguard Worker 			      if ((data & GNU_PROPERTY_X86_FEATURE_1_IBT)
444*7304104dSAndroid Build Coastguard Worker 				  != 0)
445*7304104dSAndroid Build Coastguard Worker 				{
446*7304104dSAndroid Build Coastguard Worker 				  printf ("IBT");
447*7304104dSAndroid Build Coastguard Worker 				  data &= ~GNU_PROPERTY_X86_FEATURE_1_IBT;
448*7304104dSAndroid Build Coastguard Worker 				  if (data != 0)
449*7304104dSAndroid Build Coastguard Worker 				    printf (" ");
450*7304104dSAndroid Build Coastguard Worker 				}
451*7304104dSAndroid Build Coastguard Worker 
452*7304104dSAndroid Build Coastguard Worker 			      if ((data & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
453*7304104dSAndroid Build Coastguard Worker 				  != 0)
454*7304104dSAndroid Build Coastguard Worker 				{
455*7304104dSAndroid Build Coastguard Worker 				  printf ("SHSTK");
456*7304104dSAndroid Build Coastguard Worker 				  data &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK;
457*7304104dSAndroid Build Coastguard Worker 				  if (data != 0)
458*7304104dSAndroid Build Coastguard Worker 				    printf (" ");
459*7304104dSAndroid Build Coastguard Worker 				}
460*7304104dSAndroid Build Coastguard Worker 
461*7304104dSAndroid Build Coastguard Worker 			      if (data != 0)
462*7304104dSAndroid Build Coastguard Worker 				printf ("UNKNOWN");
463*7304104dSAndroid Build Coastguard Worker 			    }
464*7304104dSAndroid Build Coastguard Worker 			  else
465*7304104dSAndroid Build Coastguard Worker 			    printf ("<bad datasz: %" PRId32 ">",
466*7304104dSAndroid Build Coastguard Worker 				    prop.pr_datasz);
467*7304104dSAndroid Build Coastguard Worker 
468*7304104dSAndroid Build Coastguard Worker 			  printf ("\n");
469*7304104dSAndroid Build Coastguard Worker 			}
470*7304104dSAndroid Build Coastguard Worker 		      else
471*7304104dSAndroid Build Coastguard Worker 			{
472*7304104dSAndroid Build Coastguard Worker 			  printf ("%#" PRIx32, prop.pr_type);
473*7304104dSAndroid Build Coastguard Worker 			  if (prop.pr_datasz > 0)
474*7304104dSAndroid Build Coastguard Worker 			    {
475*7304104dSAndroid Build Coastguard Worker 			      printf (" data: ");
476*7304104dSAndroid Build Coastguard Worker 			      size_t i;
477*7304104dSAndroid Build Coastguard Worker 			      for (i = 0; i < prop.pr_datasz - 1; i++)
478*7304104dSAndroid Build Coastguard Worker 				printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
479*7304104dSAndroid Build Coastguard Worker 			      printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
480*7304104dSAndroid Build Coastguard Worker 			    }
481*7304104dSAndroid Build Coastguard Worker 			}
482*7304104dSAndroid Build Coastguard Worker 		    }
483*7304104dSAndroid Build Coastguard Worker 		  else if (prop.pr_type >= GNU_PROPERTY_LOPROC
484*7304104dSAndroid Build Coastguard Worker 			   && prop.pr_type <= GNU_PROPERTY_HIPROC
485*7304104dSAndroid Build Coastguard Worker 			   && ehdr.e_machine == EM_AARCH64)
486*7304104dSAndroid Build Coastguard Worker 		    {
487*7304104dSAndroid Build Coastguard Worker 		      printf ("AARCH64 ");
488*7304104dSAndroid Build Coastguard Worker 		      if (prop.pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
489*7304104dSAndroid Build Coastguard Worker 			{
490*7304104dSAndroid Build Coastguard Worker 			  printf ("FEATURE_1_AND: ");
491*7304104dSAndroid Build Coastguard Worker 
492*7304104dSAndroid Build Coastguard Worker 			  if (prop.pr_datasz == 4)
493*7304104dSAndroid Build Coastguard Worker 			    {
494*7304104dSAndroid Build Coastguard Worker 			      GElf_Word data;
495*7304104dSAndroid Build Coastguard Worker 			      in.d_type = ELF_T_WORD;
496*7304104dSAndroid Build Coastguard Worker 			      out.d_type = ELF_T_WORD;
497*7304104dSAndroid Build Coastguard Worker 			      in.d_size = 4;
498*7304104dSAndroid Build Coastguard Worker 			      out.d_size = 4;
499*7304104dSAndroid Build Coastguard Worker 			      in.d_buf = (void *) desc;
500*7304104dSAndroid Build Coastguard Worker 			      out.d_buf = (void *) &data;
501*7304104dSAndroid Build Coastguard Worker 
502*7304104dSAndroid Build Coastguard Worker 			      if (gelf_xlatetom (ebl->elf, &out, &in,
503*7304104dSAndroid Build Coastguard Worker 						 elfident[EI_DATA]) == NULL)
504*7304104dSAndroid Build Coastguard Worker 				{
505*7304104dSAndroid Build Coastguard Worker 				  printf ("%s\n", elf_errmsg (-1));
506*7304104dSAndroid Build Coastguard Worker 				  return;
507*7304104dSAndroid Build Coastguard Worker 				}
508*7304104dSAndroid Build Coastguard Worker 			      printf ("%08" PRIx32 " ", data);
509*7304104dSAndroid Build Coastguard Worker 
510*7304104dSAndroid Build Coastguard Worker 			      if ((data & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
511*7304104dSAndroid Build Coastguard Worker 				  != 0)
512*7304104dSAndroid Build Coastguard Worker 				{
513*7304104dSAndroid Build Coastguard Worker 				  printf ("BTI");
514*7304104dSAndroid Build Coastguard Worker 				  data &= ~GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
515*7304104dSAndroid Build Coastguard Worker 				  if (data != 0)
516*7304104dSAndroid Build Coastguard Worker 				    printf (" ");
517*7304104dSAndroid Build Coastguard Worker 				}
518*7304104dSAndroid Build Coastguard Worker 
519*7304104dSAndroid Build Coastguard Worker 			      if ((data & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
520*7304104dSAndroid Build Coastguard Worker 				  != 0)
521*7304104dSAndroid Build Coastguard Worker 				{
522*7304104dSAndroid Build Coastguard Worker 				  printf ("PAC");
523*7304104dSAndroid Build Coastguard Worker 				  data &= ~GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
524*7304104dSAndroid Build Coastguard Worker 				  if (data != 0)
525*7304104dSAndroid Build Coastguard Worker 				    printf (" ");
526*7304104dSAndroid Build Coastguard Worker 				}
527*7304104dSAndroid Build Coastguard Worker 
528*7304104dSAndroid Build Coastguard Worker 			      if (data != 0)
529*7304104dSAndroid Build Coastguard Worker 				printf ("UNKNOWN");
530*7304104dSAndroid Build Coastguard Worker 			    }
531*7304104dSAndroid Build Coastguard Worker 			  else
532*7304104dSAndroid Build Coastguard Worker 			    printf ("<bad datasz: %" PRId32 ">",
533*7304104dSAndroid Build Coastguard Worker 				    prop.pr_datasz);
534*7304104dSAndroid Build Coastguard Worker 
535*7304104dSAndroid Build Coastguard Worker 			  printf ("\n");
536*7304104dSAndroid Build Coastguard Worker 			}
537*7304104dSAndroid Build Coastguard Worker 		      else
538*7304104dSAndroid Build Coastguard Worker 			{
539*7304104dSAndroid Build Coastguard Worker 			  printf ("%#" PRIx32, prop.pr_type);
540*7304104dSAndroid Build Coastguard Worker 			  if (prop.pr_datasz > 0)
541*7304104dSAndroid Build Coastguard Worker 			    {
542*7304104dSAndroid Build Coastguard Worker 			      printf (" data: ");
543*7304104dSAndroid Build Coastguard Worker 			      size_t i;
544*7304104dSAndroid Build Coastguard Worker 			      for (i = 0; i < prop.pr_datasz - 1; i++)
545*7304104dSAndroid Build Coastguard Worker 				printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
546*7304104dSAndroid Build Coastguard Worker 			      printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
547*7304104dSAndroid Build Coastguard Worker 			    }
548*7304104dSAndroid Build Coastguard Worker 			}
549*7304104dSAndroid Build Coastguard Worker 		    }
550*7304104dSAndroid Build Coastguard Worker 		  else
551*7304104dSAndroid Build Coastguard Worker 		    {
552*7304104dSAndroid Build Coastguard Worker 		      if (prop.pr_type >= GNU_PROPERTY_LOPROC
553*7304104dSAndroid Build Coastguard Worker 			  && prop.pr_type <= GNU_PROPERTY_HIPROC)
554*7304104dSAndroid Build Coastguard Worker 			printf ("proc_type %#" PRIx32, prop.pr_type);
555*7304104dSAndroid Build Coastguard Worker 		      else if (prop.pr_type >= GNU_PROPERTY_LOUSER
556*7304104dSAndroid Build Coastguard Worker 			  && prop.pr_type <= GNU_PROPERTY_HIUSER)
557*7304104dSAndroid Build Coastguard Worker 			printf ("app_type %#" PRIx32, prop.pr_type);
558*7304104dSAndroid Build Coastguard Worker 		      else
559*7304104dSAndroid Build Coastguard Worker 			printf ("unknown_type %#" PRIx32, prop.pr_type);
560*7304104dSAndroid Build Coastguard Worker 
561*7304104dSAndroid Build Coastguard Worker 		      if (prop.pr_datasz > 0)
562*7304104dSAndroid Build Coastguard Worker 			{
563*7304104dSAndroid Build Coastguard Worker 			  printf (" data: ");
564*7304104dSAndroid Build Coastguard Worker 			  size_t i;
565*7304104dSAndroid Build Coastguard Worker 			  for (i = 0; i < prop.pr_datasz - 1; i++)
566*7304104dSAndroid Build Coastguard Worker 			    printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
567*7304104dSAndroid Build Coastguard Worker 			  printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
568*7304104dSAndroid Build Coastguard Worker 			}
569*7304104dSAndroid Build Coastguard Worker 		    }
570*7304104dSAndroid Build Coastguard Worker 
571*7304104dSAndroid Build Coastguard Worker 		  if (elfclass == ELFCLASS32)
572*7304104dSAndroid Build Coastguard Worker 		    prop.pr_datasz = NOTE_ALIGN4 (prop.pr_datasz);
573*7304104dSAndroid Build Coastguard Worker 		  else
574*7304104dSAndroid Build Coastguard Worker 		    prop.pr_datasz = NOTE_ALIGN8 (prop.pr_datasz);
575*7304104dSAndroid Build Coastguard Worker 
576*7304104dSAndroid Build Coastguard Worker 		  desc += prop.pr_datasz;
577*7304104dSAndroid Build Coastguard Worker 		  if (descsz > prop.pr_datasz)
578*7304104dSAndroid Build Coastguard Worker 		    descsz -= prop.pr_datasz;
579*7304104dSAndroid Build Coastguard Worker 		  else
580*7304104dSAndroid Build Coastguard Worker 		    descsz = 0;
581*7304104dSAndroid Build Coastguard Worker 		}
582*7304104dSAndroid Build Coastguard Worker 	    }
583*7304104dSAndroid Build Coastguard Worker 	  break;
584*7304104dSAndroid Build Coastguard Worker 
585*7304104dSAndroid Build Coastguard Worker 	case NT_GNU_ABI_TAG:
586*7304104dSAndroid Build Coastguard Worker 	  if (descsz >= 8 && descsz % 4 == 0)
587*7304104dSAndroid Build Coastguard Worker 	    {
588*7304104dSAndroid Build Coastguard Worker 	      Elf_Data in =
589*7304104dSAndroid Build Coastguard Worker 		{
590*7304104dSAndroid Build Coastguard Worker 		  .d_version = EV_CURRENT,
591*7304104dSAndroid Build Coastguard Worker 		  .d_type = ELF_T_WORD,
592*7304104dSAndroid Build Coastguard Worker 		  .d_size = descsz,
593*7304104dSAndroid Build Coastguard Worker 		  .d_buf = (void *) desc
594*7304104dSAndroid Build Coastguard Worker 		};
595*7304104dSAndroid Build Coastguard Worker 	      /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes).  If it
596*7304104dSAndroid Build Coastguard Worker 		 is much (4*) larger dynamically allocate memory to convert.  */
597*7304104dSAndroid Build Coastguard Worker #define FIXED_TAG_BYTES 16
598*7304104dSAndroid Build Coastguard Worker 	      uint32_t sbuf[FIXED_TAG_BYTES];
599*7304104dSAndroid Build Coastguard Worker 	      uint32_t *buf;
600*7304104dSAndroid Build Coastguard Worker 	      if (unlikely (descsz / 4 > FIXED_TAG_BYTES))
601*7304104dSAndroid Build Coastguard Worker 		{
602*7304104dSAndroid Build Coastguard Worker 		  buf = malloc (descsz);
603*7304104dSAndroid Build Coastguard Worker 		  if (unlikely (buf == NULL))
604*7304104dSAndroid Build Coastguard Worker 		    return;
605*7304104dSAndroid Build Coastguard Worker 		}
606*7304104dSAndroid Build Coastguard Worker 	      else
607*7304104dSAndroid Build Coastguard Worker 		buf = sbuf;
608*7304104dSAndroid Build Coastguard Worker 	      Elf_Data out =
609*7304104dSAndroid Build Coastguard Worker 		{
610*7304104dSAndroid Build Coastguard Worker 		  .d_version = EV_CURRENT,
611*7304104dSAndroid Build Coastguard Worker 		  .d_type = ELF_T_WORD,
612*7304104dSAndroid Build Coastguard Worker 		  .d_size = descsz,
613*7304104dSAndroid Build Coastguard Worker 		  .d_buf = buf
614*7304104dSAndroid Build Coastguard Worker 		};
615*7304104dSAndroid Build Coastguard Worker 
616*7304104dSAndroid Build Coastguard Worker 	      if (elf32_xlatetom (&out, &in, ebl->data) != NULL)
617*7304104dSAndroid Build Coastguard Worker 		{
618*7304104dSAndroid Build Coastguard Worker 		  const char *os;
619*7304104dSAndroid Build Coastguard Worker 		  switch (buf[0])
620*7304104dSAndroid Build Coastguard Worker 		    {
621*7304104dSAndroid Build Coastguard Worker 		    case ELF_NOTE_OS_LINUX:
622*7304104dSAndroid Build Coastguard Worker 		      os = "Linux";
623*7304104dSAndroid Build Coastguard Worker 		      break;
624*7304104dSAndroid Build Coastguard Worker 
625*7304104dSAndroid Build Coastguard Worker 		    case ELF_NOTE_OS_GNU:
626*7304104dSAndroid Build Coastguard Worker 		      os = "GNU";
627*7304104dSAndroid Build Coastguard Worker 		      break;
628*7304104dSAndroid Build Coastguard Worker 
629*7304104dSAndroid Build Coastguard Worker 		    case ELF_NOTE_OS_SOLARIS2:
630*7304104dSAndroid Build Coastguard Worker 		      os = "Solaris";
631*7304104dSAndroid Build Coastguard Worker 		      break;
632*7304104dSAndroid Build Coastguard Worker 
633*7304104dSAndroid Build Coastguard Worker 		    case ELF_NOTE_OS_FREEBSD:
634*7304104dSAndroid Build Coastguard Worker 		      os = "FreeBSD";
635*7304104dSAndroid Build Coastguard Worker 		      break;
636*7304104dSAndroid Build Coastguard Worker 
637*7304104dSAndroid Build Coastguard Worker 		    default:
638*7304104dSAndroid Build Coastguard Worker 		      os = "???";
639*7304104dSAndroid Build Coastguard Worker 		      break;
640*7304104dSAndroid Build Coastguard Worker 		    }
641*7304104dSAndroid Build Coastguard Worker 
642*7304104dSAndroid Build Coastguard Worker 		  printf (_("    OS: %s, ABI: "), os);
643*7304104dSAndroid Build Coastguard Worker 		  for (size_t cnt = 1; cnt < descsz / 4; ++cnt)
644*7304104dSAndroid Build Coastguard Worker 		    {
645*7304104dSAndroid Build Coastguard Worker 		      if (cnt > 1)
646*7304104dSAndroid Build Coastguard Worker 			putchar_unlocked ('.');
647*7304104dSAndroid Build Coastguard Worker 		      printf ("%" PRIu32, buf[cnt]);
648*7304104dSAndroid Build Coastguard Worker 		    }
649*7304104dSAndroid Build Coastguard Worker 		  putchar_unlocked ('\n');
650*7304104dSAndroid Build Coastguard Worker 		}
651*7304104dSAndroid Build Coastguard Worker 	      if (descsz / 4 > FIXED_TAG_BYTES)
652*7304104dSAndroid Build Coastguard Worker 		free (buf);
653*7304104dSAndroid Build Coastguard Worker 	      break;
654*7304104dSAndroid Build Coastguard Worker 	    }
655*7304104dSAndroid Build Coastguard Worker 	  FALLTHROUGH;
656*7304104dSAndroid Build Coastguard Worker 
657*7304104dSAndroid Build Coastguard Worker 	default:
658*7304104dSAndroid Build Coastguard Worker 	  /* Unknown type.  */
659*7304104dSAndroid Build Coastguard Worker 	  break;
660*7304104dSAndroid Build Coastguard Worker 	}
661*7304104dSAndroid Build Coastguard Worker     }
662*7304104dSAndroid Build Coastguard Worker }
663