Initialize Tizen 2.3
[external/prelink.git] / src / checksum.c
1 /* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
2    Written by Jakub Jelinek <jakub@redhat.com>, 2001.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #include <config.h>
19 #include <assert.h>
20 #include <endian.h>
21 #include <errno.h>
22 #include <error.h>
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include "prelink.h"
29
30 int
31 prelink_set_checksum (DSO *dso)
32 {
33   extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len);
34   uint32_t crc;
35   int i, cvt;
36
37   if (set_dynamic (dso, DT_CHECKSUM, 0, 1))
38     return 1;
39
40   if (dso->info_DT_GNU_PRELINKED
41       && set_dynamic (dso, DT_GNU_PRELINKED, 0, 1))
42     return 1;
43
44   /* Ensure any pending .mdebug/.dynsym/.dynstr etc. modifications
45      write_dso would do happen before checksumming.  */
46   if (prepare_write_dso (dso))
47     return 1;
48
49   cvt = ! ((__BYTE_ORDER == __LITTLE_ENDIAN
50             && dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
51            || (__BYTE_ORDER == __BIG_ENDIAN
52                && dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB));
53   crc = 0;
54   for (i = 1; i < dso->ehdr.e_shnum; ++i)
55     {
56       if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)))
57         continue;
58       if (dso->shdr[i].sh_type != SHT_NOBITS && dso->shdr[i].sh_size)
59         {
60           Elf_Scn *scn = dso->scn[i];
61           Elf_Data *d = NULL;
62
63           /* Cannot use elf_rawdata here, since the image is not written
64              yet.  */
65           while ((d = elf_getdata (scn, d)) != NULL)
66             {
67               if (cvt && d->d_type != ELF_T_BYTE)
68                 {
69                   gelf_xlatetof (dso->elf, d, d,
70                                  dso->ehdr.e_ident[EI_DATA]);
71                   crc = crc32 (crc, d->d_buf, d->d_size);
72                   gelf_xlatetom (dso->elf, d, d,
73                                  dso->ehdr.e_ident[EI_DATA]);
74                 }
75               else
76                 crc = crc32 (crc, d->d_buf, d->d_size);
77             }
78         }
79     }
80
81   if (set_dynamic (dso, DT_CHECKSUM, crc, 1))
82     abort ();
83   if (dso->info_DT_GNU_PRELINKED
84       && set_dynamic (dso, DT_GNU_PRELINKED, dso->info_DT_GNU_PRELINKED, 1))
85     abort ();
86   dso->info_DT_CHECKSUM = crc;
87
88   return 0;
89 }