LCOV - code coverage report
Current view: top level - libebl - eblobjnote.c (source / functions) Hit Total Coverage
Test: elfutils-0.178 Lines: 159 259 61.4 %
Date: 2019-11-26 23:55:16 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          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         710 : ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type,
      48             :                  uint32_t descsz, const char *desc)
      49             : {
      50         710 :   if (! ebl->object_note (name, type, descsz, desc))
      51             :     {
      52             :       /* The machine specific function did not know this type.  */
      53             : 
      54         710 :       if (strcmp ("stapsdt", name) == 0)
      55             :         {
      56           0 :           if (type != 3)
      57             :             {
      58           0 :               printf (gettext ("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 (gettext ("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             :             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             :             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 (gettext ("    PC: "));
     127           0 :           printf ("%#" PRIx64 ",", pc);
     128           0 :           printf (gettext (" Base: "));
     129           0 :           printf ("%#" PRIx64 ",", base);
     130           0 :           printf (gettext (" Semaphore: "));
     131           0 :           printf ("%#" PRIx64 "\n", sem);
     132           0 :           printf (gettext ("    Provider: "));
     133           0 :           printf ("%s,", provider);
     134           0 :           printf (gettext (" Name: "));
     135           0 :           printf ("%s,", pname);
     136           0 :           printf (gettext (" Args: "));
     137           0 :           printf ("'%s'\n", args);
     138           0 :           return;
     139             :         }
     140             : 
     141         710 :       if (strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
     142             :                    strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0
     143         626 :           && (type == NT_GNU_BUILD_ATTRIBUTE_OPEN
     144         626 :               || type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
     145             :         {
     146             :           /* There might or might not be a pair of addresses in the desc.  */
     147         626 :           if (descsz > 0)
     148             :             {
     149          90 :               printf ("    Address Range: ");
     150             : 
     151          90 :               union
     152             :               {
     153             :                 Elf64_Addr a64[2];
     154             :                 Elf32_Addr a32[2];
     155             :               } addrs;
     156             : 
     157          90 :               size_t addr_size = gelf_fsize (ebl->elf, ELF_T_ADDR,
     158             :                                              2, EV_CURRENT);
     159          90 :               if (descsz != addr_size)
     160           0 :                 printf ("<unknown data>\n");
     161             :               else
     162             :                 {
     163          90 :                   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          90 :                   Elf_Data dst =
     170             :                     {
     171             :                      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
     172             :                      .d_buf = &addrs, .d_size = descsz
     173             :                     };
     174             : 
     175          90 :                   if (gelf_xlatetom (ebl->elf, &dst, &src,
     176          90 :                                      elf_getident (ebl->elf,
     177          90 :                                                    NULL)[EI_DATA]) == NULL)
     178           0 :                     printf ("%s\n", elf_errmsg (-1));
     179             :                   else
     180             :                     {
     181          90 :                       if (addr_size == 4)
     182           0 :                         printf ("%#" PRIx32 " - %#" PRIx32 "\n",
     183             :                                 addrs.a32[0], addrs.a32[1]);
     184             :                       else
     185          90 :                         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         626 :           const char *data = (name
     197             :                               + strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX));
     198         626 :           if (namesz < 2)
     199             :             {
     200           0 :               printf ("<insufficient data>\n");
     201           0 :               return;
     202             :             }
     203             : 
     204         626 :           printf ("    ");
     205             : 
     206             :           /* In most cases the value comes right after the encoding bytes.  */
     207         626 :           const char *value = &data[2];
     208         626 :           switch (data[1])
     209             :             {
     210             :             case GNU_BUILD_ATTRIBUTE_VERSION:
     211          85 :               printf ("VERSION: ");
     212             :               break;
     213             :             case GNU_BUILD_ATTRIBUTE_STACK_PROT:
     214          46 :               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          41 :               printf ("TOOL: ");
     224             :               break;
     225             :             case GNU_BUILD_ATTRIBUTE_ABI:
     226          46 :               printf ("ABI: ");
     227             :               break;
     228             :             case GNU_BUILD_ATTRIBUTE_PIC:
     229          46 :               printf ("PIC: ");
     230             :               break;
     231             :             case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
     232          46 :               printf ("SHORT_ENUM: ");
     233             :               break;
     234         316 :             case 32 ... 126:
     235         316 :               printf ("\"%s\": ", &data[1]);
     236         316 :               value += strlen (&data[1]) + 1;
     237         316 :               break;
     238             :             default:
     239           0 :               printf ("<unknown>: ");
     240             :               break;
     241             :             }
     242             : 
     243         626 :           switch (data[0])
     244             :             {
     245         274 :             case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
     246             :               {
     247             :                 /* Any numbers are always in (unsigned) little endian.  */
     248         274 :                 static const Dwarf dbg
     249             :                   = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
     250         274 :                 size_t bytes = namesz - (value - name);
     251         274 :                 uint64_t val;
     252         274 :                 if (bytes == 1)
     253          90 :                   val = *(unsigned char *) value;
     254         184 :                 else if (bytes == 2)
     255         138 :                   val = read_2ubyte_unaligned (&dbg, value);
     256          46 :                 else if (bytes == 4)
     257           0 :                   val = read_4ubyte_unaligned (&dbg, value);
     258          46 :                 else if (bytes == 8)
     259          46 :                   val = read_8ubyte_unaligned (&dbg, value);
     260             :                 else
     261             :                   goto unknown;
     262         274 :                 printf ("%" PRIx64, val);
     263             :               }
     264             :               break;
     265             :             case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
     266         126 :               printf ("\"%s\"", value);
     267             :               break;
     268             :             case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
     269          88 :               printf ("TRUE");
     270             :               break;
     271             :             case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
     272         138 :               printf ("FALSE");
     273             :               break;
     274             :             default:
     275             :               {
     276           0 :               unknown:
     277           0 :                 printf ("<unknown>");
     278             :               }
     279             :               break;
     280             :             }
     281             : 
     282         626 :           printf ("\n");
     283             : 
     284         626 :           return;
     285             :         }
     286             : 
     287             :       /* NT_VERSION doesn't have any info.  All data is in the name.  */
     288          84 :       if (descsz == 0 && type == NT_VERSION)
     289             :         return;
     290             : 
     291             :       /* Everything else should have the "GNU" owner name.  */
     292          79 :       if (strcmp ("GNU", name) != 0)
     293             :         return;
     294             : 
     295          78 :       switch (type)
     296             :         {
     297          44 :         case NT_GNU_BUILD_ID:
     298          44 :           if (strcmp (name, "GNU") == 0 && descsz > 0)
     299             :             {
     300          44 :               printf (gettext ("    Build ID: "));
     301          44 :               uint_fast32_t i;
     302         880 :               for (i = 0; i < descsz - 1; ++i)
     303         836 :                 printf ("%02" PRIx8, (uint8_t) desc[i]);
     304          44 :               printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
     305             :             }
     306             :           break;
     307             : 
     308           0 :         case NT_GNU_GOLD_VERSION:
     309           0 :           if (strcmp (name, "GNU") == 0 && descsz > 0)
     310             :             /* A non-null terminated version string.  */
     311           0 :             printf (gettext ("    Linker version: %.*s\n"),
     312             :                     (int) descsz, desc);
     313             :           break;
     314             : 
     315          11 :         case NT_GNU_PROPERTY_TYPE_0:
     316          11 :           if (strcmp (name, "GNU") == 0 && descsz > 0)
     317             :             {
     318             :               /* There are at least 2 words. type and datasz.  */
     319          12 :               while (descsz >= 8)
     320             :                 {
     321          12 :                   struct pr_prop
     322             :                   {
     323             :                     GElf_Word pr_type;
     324             :                     GElf_Word pr_datasz;
     325             :                   } prop;
     326             : 
     327          12 :                   Elf_Data in =
     328             :                     {
     329             :                       .d_version = EV_CURRENT,
     330             :                       .d_type = ELF_T_WORD,
     331             :                       .d_size = 8,
     332             :                       .d_buf = (void *) desc
     333             :                     };
     334          12 :                   Elf_Data out =
     335             :                     {
     336             :                       .d_version = EV_CURRENT,
     337             :                       .d_type = ELF_T_WORD,
     338             :                       .d_size = descsz,
     339             :                       .d_buf = (void *) &prop
     340             :                     };
     341             : 
     342          12 :                   if (gelf_xlatetom (ebl->elf, &out, &in,
     343          12 :                                      elf_getident (ebl->elf,
     344          12 :                                                    NULL)[EI_DATA]) == NULL)
     345             :                     {
     346           0 :                       printf ("%s\n", elf_errmsg (-1));
     347           0 :                       return;
     348             :                     }
     349             : 
     350          12 :                   desc += 8;
     351          12 :                   descsz -= 8;
     352             : 
     353          12 :                   if (prop.pr_datasz > descsz)
     354             :                     {
     355           0 :                       printf ("BAD property datasz: %" PRId32 "\n",
     356             :                               prop.pr_datasz);
     357           0 :                       return;
     358             :                     }
     359             : 
     360          12 :                   int elfclass = gelf_getclass (ebl->elf);
     361          12 :                   char *elfident = elf_getident (ebl->elf, NULL);
     362          12 :                   GElf_Ehdr ehdr;
     363          12 :                   gelf_getehdr (ebl->elf, &ehdr);
     364             : 
     365             :                   /* Prefix.  */
     366          12 :                   printf ("    ");
     367          12 :                   if (prop.pr_type == GNU_PROPERTY_STACK_SIZE)
     368             :                     {
     369           4 :                       printf ("STACK_SIZE ");
     370           4 :                       union
     371             :                         {
     372             :                           Elf64_Addr a64;
     373             :                           Elf32_Addr a32;
     374             :                         } addr;
     375           4 :                       if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4)
     376           2 :                           || (elfclass == ELFCLASS64 && prop.pr_datasz == 8))
     377             :                         {
     378           4 :                           in.d_type = ELF_T_ADDR;
     379           4 :                           out.d_type = ELF_T_ADDR;
     380           4 :                           in.d_size = prop.pr_datasz;
     381           4 :                           out.d_size = prop.pr_datasz;
     382           4 :                           in.d_buf = (void *) desc;
     383           8 :                           out.d_buf = (elfclass == ELFCLASS32
     384             :                                        ? (void *) &addr.a32
     385           4 :                                        : (void *) &addr.a64);
     386             : 
     387           4 :                           if (gelf_xlatetom (ebl->elf, &out, &in,
     388           4 :                                              elfident[EI_DATA]) == NULL)
     389             :                             {
     390           0 :                               printf ("%s\n", elf_errmsg (-1));
     391           0 :                               return;
     392             :                             }
     393           4 :                           if (elfclass == ELFCLASS32)
     394           2 :                             printf ("%#" PRIx32 "\n", addr.a32);
     395             :                           else
     396           2 :                             printf ("%#" PRIx64 "\n", addr.a64);
     397             :                         }
     398             :                       else
     399           0 :                         printf (" (garbage datasz: %" PRIx32 ")\n",
     400             :                                 prop.pr_datasz);
     401             :                     }
     402           8 :                   else if (prop.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED)
     403             :                     {
     404           4 :                       printf ("NO_COPY_ON_PROTECTION");
     405           4 :                       if (prop.pr_datasz == 0)
     406           4 :                         printf ("\n");
     407             :                       else
     408           0 :                         printf (" (garbage datasz: %" PRIx32 ")\n",
     409             :                                 prop.pr_datasz);
     410             :                     }
     411           8 :                   else if (prop.pr_type >= GNU_PROPERTY_LOPROC
     412           4 :                       && prop.pr_type <= GNU_PROPERTY_HIPROC
     413           8 :                       && (ehdr.e_machine == EM_386
     414           4 :                           || ehdr.e_machine == EM_X86_64))
     415             :                     {
     416           4 :                       printf ("X86 ");
     417           4 :                       if (prop.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
     418             :                         {
     419           2 :                           printf ("FEATURE_1_AND: ");
     420             : 
     421           2 :                           if (prop.pr_datasz == 4)
     422             :                             {
     423           2 :                               GElf_Word data;
     424           2 :                               in.d_type = ELF_T_WORD;
     425           2 :                               out.d_type = ELF_T_WORD;
     426           2 :                               in.d_size = 4;
     427           2 :                               out.d_size = 4;
     428           2 :                               in.d_buf = (void *) desc;
     429           2 :                               out.d_buf = (void *) &data;
     430             : 
     431           2 :                               if (gelf_xlatetom (ebl->elf, &out, &in,
     432           2 :                                                  elfident[EI_DATA]) == NULL)
     433             :                                 {
     434           0 :                                   printf ("%s\n", elf_errmsg (-1));
     435           0 :                                   return;
     436             :                                 }
     437           2 :                               printf ("%08" PRIx32 " ", data);
     438             : 
     439           2 :                               if ((data & GNU_PROPERTY_X86_FEATURE_1_IBT)
     440             :                                   != 0)
     441             :                                 {
     442           2 :                                   printf ("IBT");
     443           2 :                                   data &= ~GNU_PROPERTY_X86_FEATURE_1_IBT;
     444           2 :                                   if (data != 0)
     445           2 :                                     printf (" ");
     446             :                                 }
     447             : 
     448           2 :                               if ((data & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
     449             :                                   != 0)
     450             :                                 {
     451           2 :                                   printf ("SHSTK");
     452           2 :                                   data &= ~GNU_PROPERTY_X86_FEATURE_1_SHSTK;
     453           2 :                                   if (data != 0)
     454           0 :                                     printf (" ");
     455             :                                 }
     456             : 
     457           2 :                               if (data != 0)
     458           0 :                                 printf ("UNKNOWN");
     459             :                             }
     460             :                           else
     461           0 :                             printf ("<bad datasz: %" PRId32 ">",
     462             :                                     prop.pr_datasz);
     463             : 
     464           2 :                           printf ("\n");
     465             :                         }
     466             :                       else
     467             :                         {
     468           2 :                           printf ("%#" PRIx32, prop.pr_type);
     469           2 :                           if (prop.pr_datasz > 0)
     470             :                             {
     471           2 :                               printf (" data: ");
     472           2 :                               size_t i;
     473           8 :                               for (i = 0; i < prop.pr_datasz - 1; i++)
     474           6 :                                 printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
     475           2 :                               printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
     476             :                             }
     477             :                         }
     478             :                     }
     479             :                   else
     480             :                     {
     481           0 :                       if (prop.pr_type >= GNU_PROPERTY_LOPROC
     482             :                           && prop.pr_type <= GNU_PROPERTY_HIPROC)
     483           0 :                         printf ("proc_type %#" PRIx32, prop.pr_type);
     484           0 :                       else if (prop.pr_type >= GNU_PROPERTY_LOUSER
     485             :                           && prop.pr_type <= GNU_PROPERTY_HIUSER)
     486           0 :                         printf ("app_type %#" PRIx32, prop.pr_type);
     487             :                       else
     488           0 :                         printf ("unknown_type %#" PRIx32, prop.pr_type);
     489             : 
     490           0 :                       if (prop.pr_datasz > 0)
     491             :                         {
     492           0 :                           printf (" data: ");
     493           0 :                           size_t i;
     494           0 :                           for (i = 0; i < prop.pr_datasz - 1; i++)
     495           0 :                             printf ("%02" PRIx8 " ", (uint8_t) desc[i]);
     496           0 :                           printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
     497             :                         }
     498             :                     }
     499             : 
     500          12 :                   if (elfclass == ELFCLASS32)
     501           4 :                     prop.pr_datasz = NOTE_ALIGN4 (prop.pr_datasz);
     502             :                   else
     503           8 :                     prop.pr_datasz = NOTE_ALIGN8 (prop.pr_datasz);
     504             : 
     505          12 :                   desc += prop.pr_datasz;
     506          12 :                   if (descsz > prop.pr_datasz)
     507           1 :                     descsz -= prop.pr_datasz;
     508             :                   else
     509             :                     descsz = 0;
     510             :                 }
     511             :             }
     512             :           break;
     513             : 
     514          23 :         case NT_GNU_ABI_TAG:
     515          23 :           if (descsz >= 8 && descsz % 4 == 0)
     516             :             {
     517          23 :               Elf_Data in =
     518             :                 {
     519             :                   .d_version = EV_CURRENT,
     520             :                   .d_type = ELF_T_WORD,
     521             :                   .d_size = descsz,
     522             :                   .d_buf = (void *) desc
     523             :                 };
     524             :               /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes).  If it
     525             :                  is much (4*) larger dynamically allocate memory to convert.  */
     526             : #define FIXED_TAG_BYTES 16
     527          23 :               uint32_t sbuf[FIXED_TAG_BYTES];
     528          23 :               uint32_t *buf;
     529          23 :               if (unlikely (descsz / 4 > FIXED_TAG_BYTES))
     530             :                 {
     531           0 :                   buf = malloc (descsz);
     532           0 :                   if (unlikely (buf == NULL))
     533           0 :                     return;
     534             :                 }
     535             :               else
     536             :                 buf = sbuf;
     537          23 :               Elf_Data out =
     538             :                 {
     539             :                   .d_version = EV_CURRENT,
     540             :                   .d_type = ELF_T_WORD,
     541             :                   .d_size = descsz,
     542             :                   .d_buf = buf
     543             :                 };
     544             : 
     545          23 :               if (elf32_xlatetom (&out, &in, ebl->data) != NULL)
     546             :                 {
     547          23 :                   const char *os;
     548          23 :                   switch (buf[0])
     549             :                     {
     550             :                     case ELF_NOTE_OS_LINUX:
     551             :                       os = "Linux";
     552             :                       break;
     553             : 
     554           0 :                     case ELF_NOTE_OS_GNU:
     555           0 :                       os = "GNU";
     556           0 :                       break;
     557             : 
     558           0 :                     case ELF_NOTE_OS_SOLARIS2:
     559           0 :                       os = "Solaris";
     560           0 :                       break;
     561             : 
     562           0 :                     case ELF_NOTE_OS_FREEBSD:
     563           0 :                       os = "FreeBSD";
     564           0 :                       break;
     565             : 
     566           0 :                     default:
     567           0 :                       os = "???";
     568           0 :                       break;
     569             :                     }
     570             : 
     571          23 :                   printf (gettext ("    OS: %s, ABI: "), os);
     572          92 :                   for (size_t cnt = 1; cnt < descsz / 4; ++cnt)
     573             :                     {
     574          69 :                       if (cnt > 1)
     575          46 :                         putchar_unlocked ('.');
     576          69 :                       printf ("%" PRIu32, buf[cnt]);
     577             :                     }
     578          23 :                   putchar_unlocked ('\n');
     579             :                 }
     580          23 :               if (descsz / 4 > FIXED_TAG_BYTES)
     581           0 :                 free (buf);
     582          23 :               break;
     583             :             }
     584             :           FALLTHROUGH;
     585             : 
     586             :         default:
     587             :           /* Unknown type.  */
     588             :           break;
     589             :         }
     590           0 :     }
     591             : }

Generated by: LCOV version 1.13