1 /* Print contents of object file note.
2 Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016, 2018 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
43 #include "memory-access.h"
47 ebl_object_note (Ebl
*ebl
, uint32_t namesz
, const char *name
, uint32_t type
,
48 uint32_t descsz
, const char *desc
)
50 if (! ebl
->object_note (name
, type
, descsz
, desc
))
52 /* The machine specific function did not know this type. */
54 if (strcmp ("stapsdt", name
) == 0)
58 printf (_("unknown SDT version %u\n"), type
);
62 /* Descriptor starts with three addresses, pc, base ref and
63 semaphore. Then three zero terminated strings provider,
64 name and arguments. */
72 size_t addrs_size
= gelf_fsize (ebl
->elf
, ELF_T_ADDR
, 3, EV_CURRENT
);
73 if (descsz
< addrs_size
+ 3)
76 printf (_("invalid SDT probe descriptor\n"));
82 .d_type
= ELF_T_ADDR
, .d_version
= EV_CURRENT
,
83 .d_buf
= (void *) desc
, .d_size
= addrs_size
88 .d_type
= ELF_T_ADDR
, .d_version
= EV_CURRENT
,
89 .d_buf
= &addrs
, .d_size
= addrs_size
92 if (gelf_xlatetom (ebl
->elf
, &dst
, &src
,
93 elf_getident (ebl
->elf
, NULL
)[EI_DATA
]) == NULL
)
95 printf ("%s\n", elf_errmsg (-1));
99 const char *provider
= desc
+ addrs_size
;
100 const char *pname
= memchr (provider
, '\0', desc
+ descsz
- provider
);
105 const char *args
= memchr (pname
, '\0', desc
+ descsz
- pname
);
107 memchr (++args
, '\0', desc
+ descsz
- pname
) != desc
+ descsz
- 1)
113 if (gelf_getclass (ebl
->elf
) == ELFCLASS32
)
127 printf ("%#" PRIx64
",", pc
);
128 printf (_(" Base: "));
129 printf ("%#" PRIx64
",", base
);
130 printf (_(" Semaphore: "));
131 printf ("%#" PRIx64
"\n", sem
);
132 printf (_(" Provider: "));
133 printf ("%s,", provider
);
134 printf (_(" Name: "));
135 printf ("%s,", pname
);
136 printf (_(" Args: "));
137 printf ("'%s'\n", args
);
141 if (strncmp (name
, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX
,
142 strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX
)) == 0
143 && (type
== NT_GNU_BUILD_ATTRIBUTE_OPEN
144 || type
== NT_GNU_BUILD_ATTRIBUTE_FUNC
))
146 /* There might or might not be a pair of addresses in the desc. */
149 printf (" Address Range: ");
157 size_t addr_size
= gelf_fsize (ebl
->elf
, ELF_T_ADDR
,
159 if (descsz
!= addr_size
)
160 printf ("<unknown data>\n");
165 .d_type
= ELF_T_ADDR
, .d_version
= EV_CURRENT
,
166 .d_buf
= (void *) desc
, .d_size
= descsz
171 .d_type
= ELF_T_ADDR
, .d_version
= EV_CURRENT
,
172 .d_buf
= &addrs
, .d_size
= descsz
175 if (gelf_xlatetom (ebl
->elf
, &dst
, &src
,
176 elf_getident (ebl
->elf
,
177 NULL
)[EI_DATA
]) == NULL
)
178 printf ("%s\n", elf_errmsg (-1));
182 printf ("%#" PRIx32
" - %#" PRIx32
"\n",
183 addrs
.a32
[0], addrs
.a32
[1]);
185 printf ("%#" PRIx64
" - %#" PRIx64
"\n",
186 addrs
.a64
[0], addrs
.a64
[1]);
191 /* Most data actually is inside the name.
192 https://fedoraproject.org/wiki/Toolchain/Watermark */
194 /* We need at least 2 chars of data to describe the
195 attribute and value encodings. */
196 const char *data
= (name
197 + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX
));
200 printf ("<insufficient data>\n");
206 /* In most cases the value comes right after the encoding bytes. */
207 const char *value
= &data
[2];
210 case GNU_BUILD_ATTRIBUTE_VERSION
:
211 printf ("VERSION: ");
213 case GNU_BUILD_ATTRIBUTE_STACK_PROT
:
214 printf ("STACK_PROT: ");
216 case GNU_BUILD_ATTRIBUTE_RELRO
:
219 case GNU_BUILD_ATTRIBUTE_STACK_SIZE
:
220 printf ("STACK_SIZE: ");
222 case GNU_BUILD_ATTRIBUTE_TOOL
:
225 case GNU_BUILD_ATTRIBUTE_ABI
:
228 case GNU_BUILD_ATTRIBUTE_PIC
:
231 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM
:
232 printf ("SHORT_ENUM: ");
235 printf ("\"%s\": ", &data
[1]);
236 value
+= strlen (&data
[1]) + 1;
239 printf ("<unknown>: ");
245 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC
:
247 /* Any numbers are always in (unsigned) little endian. */
248 static const Dwarf dbg
249 = { .other_byte_order
= MY_ELFDATA
!= ELFDATA2LSB
};
250 size_t bytes
= namesz
- (value
- name
);
253 val
= *(unsigned char *) value
;
255 val
= read_2ubyte_unaligned (&dbg
, value
);
257 val
= read_4ubyte_unaligned (&dbg
, value
);
259 val
= read_8ubyte_unaligned (&dbg
, value
);
262 printf ("%" PRIx64
, val
);
265 case GNU_BUILD_ATTRIBUTE_TYPE_STRING
:
266 printf ("\"%s\"", value
);
268 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE
:
271 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE
:
277 printf ("<unknown>");
287 /* NT_VERSION doesn't have any info. All data is in the name. */
288 if (descsz
== 0 && type
== NT_VERSION
)
291 /* Everything else should have the "GNU" owner name. */
292 if (strcmp ("GNU", name
) != 0)
297 case NT_GNU_BUILD_ID
:
298 if (strcmp (name
, "GNU") == 0 && descsz
> 0)
300 printf (_(" Build ID: "));
302 for (i
= 0; i
< descsz
- 1; ++i
)
303 printf ("%02" PRIx8
, (uint8_t) desc
[i
]);
304 printf ("%02" PRIx8
"\n", (uint8_t) desc
[i
]);
308 case NT_GNU_GOLD_VERSION
:
309 if (strcmp (name
, "GNU") == 0 && descsz
> 0)
310 /* A non-null terminated version string. */
311 printf (_(" Linker version: %.*s\n"),
315 case NT_GNU_PROPERTY_TYPE_0
:
316 if (strcmp (name
, "GNU") == 0 && descsz
> 0)
318 /* There are at least 2 words. type and datasz. */
329 .d_version
= EV_CURRENT
,
330 .d_type
= ELF_T_WORD
,
332 .d_buf
= (void *) desc
336 .d_version
= EV_CURRENT
,
337 .d_type
= ELF_T_WORD
,
339 .d_buf
= (void *) &prop
342 if (gelf_xlatetom (ebl
->elf
, &out
, &in
,
343 elf_getident (ebl
->elf
,
344 NULL
)[EI_DATA
]) == NULL
)
346 printf ("%s\n", elf_errmsg (-1));
353 if (prop
.pr_datasz
> descsz
)
355 printf ("BAD property datasz: %" PRId32
"\n",
360 int elfclass
= gelf_getclass (ebl
->elf
);
361 char *elfident
= elf_getident (ebl
->elf
, NULL
);
363 gelf_getehdr (ebl
->elf
, &ehdr
);
367 if (prop
.pr_type
== GNU_PROPERTY_STACK_SIZE
)
369 printf ("STACK_SIZE ");
375 if ((elfclass
== ELFCLASS32
&& prop
.pr_datasz
== 4)
376 || (elfclass
== ELFCLASS64
&& prop
.pr_datasz
== 8))
378 in
.d_type
= ELF_T_ADDR
;
379 out
.d_type
= ELF_T_ADDR
;
380 in
.d_size
= prop
.pr_datasz
;
381 out
.d_size
= prop
.pr_datasz
;
382 in
.d_buf
= (void *) desc
;
383 out
.d_buf
= (elfclass
== ELFCLASS32
385 : (void *) &addr
.a64
);
387 if (gelf_xlatetom (ebl
->elf
, &out
, &in
,
388 elfident
[EI_DATA
]) == NULL
)
390 printf ("%s\n", elf_errmsg (-1));
393 if (elfclass
== ELFCLASS32
)
394 printf ("%#" PRIx32
"\n", addr
.a32
);
396 printf ("%#" PRIx64
"\n", addr
.a64
);
399 printf (" (garbage datasz: %" PRIx32
")\n",
402 else if (prop
.pr_type
== GNU_PROPERTY_NO_COPY_ON_PROTECTED
)
404 printf ("NO_COPY_ON_PROTECTION");
405 if (prop
.pr_datasz
== 0)
408 printf (" (garbage datasz: %" PRIx32
")\n",
411 else if (prop
.pr_type
>= GNU_PROPERTY_LOPROC
412 && prop
.pr_type
<= GNU_PROPERTY_HIPROC
413 && (ehdr
.e_machine
== EM_386
414 || ehdr
.e_machine
== EM_X86_64
))
417 if (prop
.pr_type
== GNU_PROPERTY_X86_FEATURE_1_AND
)
419 printf ("FEATURE_1_AND: ");
421 if (prop
.pr_datasz
== 4)
424 in
.d_type
= ELF_T_WORD
;
425 out
.d_type
= ELF_T_WORD
;
428 in
.d_buf
= (void *) desc
;
429 out
.d_buf
= (void *) &data
;
431 if (gelf_xlatetom (ebl
->elf
, &out
, &in
,
432 elfident
[EI_DATA
]) == NULL
)
434 printf ("%s\n", elf_errmsg (-1));
437 printf ("%08" PRIx32
" ", data
);
439 if ((data
& GNU_PROPERTY_X86_FEATURE_1_IBT
)
443 data
&= ~GNU_PROPERTY_X86_FEATURE_1_IBT
;
448 if ((data
& GNU_PROPERTY_X86_FEATURE_1_SHSTK
)
452 data
&= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK
;
461 printf ("<bad datasz: %" PRId32
">",
468 printf ("%#" PRIx32
, prop
.pr_type
);
469 if (prop
.pr_datasz
> 0)
473 for (i
= 0; i
< prop
.pr_datasz
- 1; i
++)
474 printf ("%02" PRIx8
" ", (uint8_t) desc
[i
]);
475 printf ("%02" PRIx8
"\n", (uint8_t) desc
[i
]);
479 else if (prop
.pr_type
>= GNU_PROPERTY_LOPROC
480 && prop
.pr_type
<= GNU_PROPERTY_HIPROC
481 && ehdr
.e_machine
== EM_AARCH64
)
484 if (prop
.pr_type
== GNU_PROPERTY_AARCH64_FEATURE_1_AND
)
486 printf ("FEATURE_1_AND: ");
488 if (prop
.pr_datasz
== 4)
491 in
.d_type
= ELF_T_WORD
;
492 out
.d_type
= ELF_T_WORD
;
495 in
.d_buf
= (void *) desc
;
496 out
.d_buf
= (void *) &data
;
498 if (gelf_xlatetom (ebl
->elf
, &out
, &in
,
499 elfident
[EI_DATA
]) == NULL
)
501 printf ("%s\n", elf_errmsg (-1));
504 printf ("%08" PRIx32
" ", data
);
506 if ((data
& GNU_PROPERTY_AARCH64_FEATURE_1_BTI
)
510 data
&= ~GNU_PROPERTY_AARCH64_FEATURE_1_BTI
;
515 if ((data
& GNU_PROPERTY_AARCH64_FEATURE_1_PAC
)
519 data
&= ~GNU_PROPERTY_AARCH64_FEATURE_1_PAC
;
528 printf ("<bad datasz: %" PRId32
">",
535 printf ("%#" PRIx32
, prop
.pr_type
);
536 if (prop
.pr_datasz
> 0)
540 for (i
= 0; i
< prop
.pr_datasz
- 1; i
++)
541 printf ("%02" PRIx8
" ", (uint8_t) desc
[i
]);
542 printf ("%02" PRIx8
"\n", (uint8_t) desc
[i
]);
548 if (prop
.pr_type
>= GNU_PROPERTY_LOPROC
549 && prop
.pr_type
<= GNU_PROPERTY_HIPROC
)
550 printf ("proc_type %#" PRIx32
, prop
.pr_type
);
551 else if (prop
.pr_type
>= GNU_PROPERTY_LOUSER
552 && prop
.pr_type
<= GNU_PROPERTY_HIUSER
)
553 printf ("app_type %#" PRIx32
, prop
.pr_type
);
555 printf ("unknown_type %#" PRIx32
, prop
.pr_type
);
557 if (prop
.pr_datasz
> 0)
561 for (i
= 0; i
< prop
.pr_datasz
- 1; i
++)
562 printf ("%02" PRIx8
" ", (uint8_t) desc
[i
]);
563 printf ("%02" PRIx8
"\n", (uint8_t) desc
[i
]);
567 if (elfclass
== ELFCLASS32
)
568 prop
.pr_datasz
= NOTE_ALIGN4 (prop
.pr_datasz
);
570 prop
.pr_datasz
= NOTE_ALIGN8 (prop
.pr_datasz
);
572 desc
+= prop
.pr_datasz
;
573 if (descsz
> prop
.pr_datasz
)
574 descsz
-= prop
.pr_datasz
;
582 if (descsz
>= 8 && descsz
% 4 == 0)
586 .d_version
= EV_CURRENT
,
587 .d_type
= ELF_T_WORD
,
589 .d_buf
= (void *) desc
591 /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes). If it
592 is much (4*) larger dynamically allocate memory to convert. */
593 #define FIXED_TAG_BYTES 16
594 uint32_t sbuf
[FIXED_TAG_BYTES
];
596 if (unlikely (descsz
/ 4 > FIXED_TAG_BYTES
))
598 buf
= malloc (descsz
);
599 if (unlikely (buf
== NULL
))
606 .d_version
= EV_CURRENT
,
607 .d_type
= ELF_T_WORD
,
612 if (elf32_xlatetom (&out
, &in
, ebl
->data
) != NULL
)
617 case ELF_NOTE_OS_LINUX
:
621 case ELF_NOTE_OS_GNU
:
625 case ELF_NOTE_OS_SOLARIS2
:
629 case ELF_NOTE_OS_FREEBSD
:
638 printf (_(" OS: %s, ABI: "), os
);
639 for (size_t cnt
= 1; cnt
< descsz
/ 4; ++cnt
)
642 putchar_unlocked ('.');
643 printf ("%" PRIu32
, buf
[cnt
]);
645 putchar_unlocked ('\n');
647 if (descsz
/ 4 > FIXED_TAG_BYTES
)