Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* ldbuildid.c - Build Id support routines
  2.    Copyright (C) 2013-2015 Free Software Foundation, Inc.
  3.  
  4.    This file is part of the GNU Binutils.
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 3 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  19.    MA 02110-1301, USA.  */
  20.  
  21. #include "sysdep.h"
  22. #include "bfd.h"
  23. #include "safe-ctype.h"
  24. #include "md5.h"
  25. #include "sha1.h"
  26. #include "ldbuildid.h"
  27.  
  28. #define streq(a,b)     strcmp ((a), (b)) == 0
  29. #define strneq(a,b,n)  strncmp ((a), (b), (n)) == 0
  30.  
  31. bfd_boolean
  32. validate_build_id_style (const char *style)
  33. {
  34.  if ((streq (style, "md5")) || (streq (style, "sha1"))
  35. #ifndef __MINGW32__
  36.      || (streq (style, "uuid"))
  37. #endif
  38.      || (strneq (style, "0x", 2)))
  39.    return TRUE;
  40.  
  41.  return FALSE;
  42. }
  43.  
  44. bfd_size_type
  45. compute_build_id_size (const char *style)
  46. {
  47.   if (streq (style, "md5") || streq (style, "uuid"))
  48.     return  128 / 8;
  49.  
  50.   if (streq (style, "sha1"))
  51.     return  160 / 8;
  52.  
  53.   if (strneq (style, "0x", 2))
  54.     {
  55.       bfd_size_type size = 0;
  56.       /* ID is in string form (hex).  Count the bytes.  */
  57.       const char *id = style + 2;
  58.  
  59.       do
  60.         {
  61.           if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
  62.             {
  63.               ++size;
  64.               id += 2;
  65.             }
  66.           else if (*id == '-' || *id == ':')
  67.             ++id;
  68.           else
  69.             {
  70.               size = 0;
  71.               break;
  72.             }
  73.         } while (*id != '\0');
  74.       return size;
  75.     }
  76.  
  77.   return 0;
  78. }
  79.  
  80. static unsigned char
  81. read_hex (const char xdigit)
  82. {
  83.   if (ISDIGIT (xdigit))
  84.     return xdigit - '0';
  85.  
  86.   if (ISUPPER (xdigit))
  87.     return xdigit - 'A' + 0xa;
  88.  
  89.   if (ISLOWER (xdigit))
  90.     return xdigit - 'a' + 0xa;
  91.  
  92.   abort ();
  93.   return 0;
  94. }
  95.  
  96. bfd_boolean
  97. generate_build_id (bfd *abfd,
  98.                    const char *style,
  99.                    checksum_fn checksum_contents,
  100.                    unsigned char *id_bits,
  101.                    int size ATTRIBUTE_UNUSED)
  102. {
  103.   if (streq (style, "md5"))
  104.     {
  105.       struct md5_ctx ctx;
  106.  
  107.       md5_init_ctx (&ctx);
  108.       if (!(*checksum_contents) (abfd, (sum_fn) &md5_process_bytes, &ctx))
  109.         return FALSE;
  110.       md5_finish_ctx (&ctx, id_bits);
  111.     }
  112.   else if (streq (style, "sha1"))
  113.     {
  114.       struct sha1_ctx ctx;
  115.  
  116.       sha1_init_ctx (&ctx);
  117.       if (!(*checksum_contents) (abfd, (sum_fn) &sha1_process_bytes, &ctx))
  118.         return FALSE;
  119.       sha1_finish_ctx (&ctx, id_bits);
  120.     }
  121. #ifndef __MINGW32__
  122.   else if (streq (style, "uuid"))
  123.     {
  124.       int n;
  125.       int fd = open ("/dev/urandom", O_RDONLY);
  126.  
  127.       if (fd < 0)
  128.         return FALSE;
  129.       n = read (fd, id_bits, size);
  130.       close (fd);
  131.       if (n < size)
  132.         return FALSE;
  133.     }
  134. #endif
  135.   else if (strneq (style, "0x", 2))
  136.     {
  137.       /* ID is in string form (hex).  Convert to bits.  */
  138.       const char *id = style + 2;
  139.       size_t n = 0;
  140.  
  141.       do
  142.         {
  143.           if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
  144.             {
  145.               id_bits[n] = read_hex (*id++) << 4;
  146.               id_bits[n++] |= read_hex (*id++);
  147.             }
  148.           else if (*id == '-' || *id == ':')
  149.             ++id;
  150.           else
  151.             abort ();           /* Should have been validated earlier.  */
  152.         } while (*id != '\0');
  153.     }
  154.   else
  155.     abort ();                   /* Should have been validated earlier.  */
  156.  
  157.   return TRUE;
  158. }
  159.