4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 /* Copyright (c) 1987, 1988 Microsoft Corporation */
31 /* All Rights Reserved */
40 * Routines for generating a checksum for an elf image. Typically used to create
41 * a DT_CHECKSUM entry. This checksum is intended to remain constant after
42 * operations such as strip(1)/mcs(1), thus only allocatable sections are
43 * processed, and of those, any that might be modified by these external
44 * commands are skipped.
46 #define MSW(l) (((l) >> 16) & 0x0000ffffL)
47 #define LSW(l) ((l) & 0x0000ffffL)
51 * update and epilogue sum functions (stolen from libcmd)
54 sumupd(long sum
, char *cp
, unsigned long cnt
)
56 if ((cp
== 0) || (cnt
== 0))
60 sum
+= *cp
++ & 0x00ff;
70 _sum
= LSW(sum
) + MSW(sum
);
71 return ((ushort_t
)(LSW(_sum
) + MSW(_sum
)));
75 * This module is compiled twice, the second time having
76 * -D_ELF64 defined. The following set of macros represent
77 * the differences between the two compilations. Be
78 * careful *not* to add any class dependent code (anything
79 * that has elf32 or elf64 in the name) to this code
80 * without hiding it behind a switchable macro like these.
84 #define elf_checksum elf64_checksum
85 #define Elf_Ehdr Elf64_Ehdr
86 #define Elf_Shdr Elf64_Shdr
87 #define getehdr elf64_getehdr
88 #define getshdr elf64_getshdr
90 #else /* else ELF32 */
92 #define elf_checksum elf32_checksum
93 #define Elf_Ehdr Elf32_Ehdr
94 #define Elf_Shdr Elf32_Shdr
95 #define getehdr elf32_getehdr
96 #define getshdr elf32_getshdr
101 elf_checksum(Elf
* elf
)
107 Elf_Data
* data
, * (* getdata
)(Elf_Scn
*, Elf_Data
*);
110 if ((ehdr
= getehdr(elf
)) == 0)
114 * Determine the data information to retrieve. When called from ld()
115 * we're processing an ELF_C_IMAGE (memory) image and thus need to use
116 * elf_getdata(), as there is not yet a file image (or raw data) backing
117 * this. When called from utilities like elfdump(1) we're processing a
118 * file image and thus using the elf_rawdata() allows the same byte
119 * stream to be processed from different architectures - presently this
120 * is irrelevant, as the checksum simply sums the data bytes, their
121 * order doesn't matter. But being uncooked is slightly less overhead.
123 * If the file is writable, the raw data will not reflect any
124 * changes made in the process, so the uncooked version is only
125 * for readonly files.
127 if ((elf
->ed_myflags
& (EDF_MEMORY
| EDF_WRITE
)) != 0)
128 getdata
= elf_getdata
;
130 getdata
= elf_rawdata
;
132 for (shnum
= 1; shnum
< ehdr
->e_shnum
; shnum
++) {
133 if ((scn
= elf_getscn(elf
, shnum
)) == 0)
135 if ((shdr
= getshdr(scn
)) == 0)
138 /* Exclude strippable sections */
139 if (!(shdr
->sh_flags
& SHF_ALLOC
))
143 * Exclude allocable sections that can change:
144 * - The .dynsym section can contain section symbols
145 * that strip might remove.
146 * - The .dynamic section is modified by the setting of
147 * this checksum value.
148 * - The .SUNW_dof section uses ftok(3C), which returns
149 * different values, to define a key for the
150 * objects in that section.
152 if ((shdr
->sh_type
== SHT_DYNSYM
) ||
153 (shdr
->sh_type
== SHT_DYNAMIC
) ||
154 (shdr
->sh_type
== SHT_SUNW_dof
))
158 while ((data
= (*getdata
)(scn
, data
)) != 0)
159 sum
= sumupd(sum
, data
->d_buf
, data
->d_size
);
162 return (sumepi(sum
));