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