1 /* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
2 Written by Jakub Jelinek <jakub@redhat.com>, 2001.
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)
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.
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. */
31 prelink_set_checksum (DSO *dso)
33 extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len);
37 if (set_dynamic (dso, DT_CHECKSUM, 0, 1))
40 if (dso->info_DT_GNU_PRELINKED
41 && set_dynamic (dso, DT_GNU_PRELINKED, 0, 1))
44 /* Ensure any pending .mdebug/.dynsym/.dynstr etc. modifications
45 write_dso would do happen before checksumming. */
46 if (prepare_write_dso (dso))
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));
54 for (i = 1; i < dso->ehdr.e_shnum; ++i)
56 if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)))
58 if (dso->shdr[i].sh_type != SHT_NOBITS && dso->shdr[i].sh_size)
60 Elf_Scn *scn = dso->scn[i];
63 /* Cannot use elf_rawdata here, since the image is not written
65 while ((d = elf_getdata (scn, d)) != NULL)
67 if (cvt && d->d_type != ELF_T_BYTE)
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]);
76 crc = crc32 (crc, d->d_buf, d->d_size);
81 if (set_dynamic (dso, DT_CHECKSUM, crc, 1))
83 if (dso->info_DT_GNU_PRELINKED
84 && set_dynamic (dso, DT_GNU_PRELINKED, dso->info_DT_GNU_PRELINKED, 1))
86 dso->info_DT_CHECKSUM = crc;