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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1988 AT&T */
27 /* Copyright (c) 1989 AT&T */
28 /* All Rights Reserved */
41 /* SIZE FUNCTIONS CALLED */
47 static const char *prusect
[3] = {
53 static const char *prusum
[3] = {
59 static const char *format
[3] = {
60 "%llx + %llx + %llx = 0x%llx\n",
61 "%llo + %llo + %llo = 0%llo\n",
62 "%lld + %lld + %lld = %lld\n"
65 static void process_phdr(Elf
*elf
, GElf_Half num
);
70 /* EXTERNAL VARIABLES USED */
71 extern int fflag
; /* full format for sections */
72 extern int Fflag
; /* full format for segments */
73 extern int nflag
; /* include non-loadable segments or sections */
74 extern int numbase
; /* hex, octal, or decimal */
77 extern int is_archive
;
81 GElf_Xword size
; /* total size in non-default case for sections */
83 * size of first, second, third number and total size
84 * in default case for sections.
93 size_t ndx
= 0, shnum
= 0;
101 * If there is a program header and the -f flag requesting section infor-
102 * mation is not set, then process segments with the process_phdr function.
103 * Otherwise, process sections. For the default case, the first number
104 * shall be the size of all sections that are allocatable, nonwritable and
105 * not of type NOBITS; the second number shall be the size of all sections
106 * that are allocatable, writable, and not of type NOBITS; the third number
107 * is the size of all sections that are writable and not of type NOBITS.
108 * If -f is set, print the size of each allocatable section, followed by
109 * the section name in parentheses.
110 * If -n is set, print the size of all sections, followed by the section
111 * name in parentheses.
114 if (gelf_getehdr(elf
, &ehdr
) == 0) {
115 error(fname
, "invalid file type");
118 if ((ehdr
.e_phnum
!= 0) && !(fflag
)) {
119 process_phdr(elf
, ehdr
.e_phnum
);
124 (void) printf("%s[%s]: ", archive
, fname
);
125 } else if (!oneflag
&& !is_archive
) {
126 (void) printf("%s: ", fname
);
128 if (elf_getshdrstrndx(elf
, &ndx
) == -1)
129 error(fname
, "no string table");
132 first
= second
= third
= totsize
= 0;
134 if (elf_getshdrnum(elf
, &shnum
) == -1)
135 error(fname
, "can't get number of sections");
138 error(fname
, "no section data");
141 for (i
= 0; i
< numsect
; i
++) {
142 if ((scn
= elf_nextscn(elf
, scn
)) == 0) {
145 if (gelf_getshdr(scn
, &shdr
) == 0) {
146 error(fname
, "could not get section header");
149 if ((Fflag
) && !(fflag
)) {
150 error(fname
, "no segment data");
152 } else if ((!(shdr
.sh_flags
& SHF_ALLOC
)) &&
155 } else if ((!(shdr
.sh_flags
& SHF_ALLOC
)) && !(nflag
)) {
157 } else if ((shdr
.sh_flags
& SHF_ALLOC
) &&
158 (!(shdr
.sh_flags
& SHF_WRITE
)) &&
159 (!(shdr
.sh_type
== SHT_NOBITS
)) &&
160 !(fflag
) && !(nflag
)) {
161 first
+= shdr
.sh_size
;
162 } else if ((shdr
.sh_flags
& SHF_ALLOC
) &&
163 (shdr
.sh_flags
& SHF_WRITE
) &&
164 (!(shdr
.sh_type
== SHT_NOBITS
)) &&
165 !(fflag
) && !(nflag
)) {
166 second
+= shdr
.sh_size
;
167 } else if ((shdr
.sh_flags
& SHF_WRITE
) &&
168 (shdr
.sh_type
== SHT_NOBITS
) &&
169 !(fflag
) && !(nflag
)) {
170 third
+= shdr
.sh_size
;
172 name
= elf_strptr(elf
, ndx
, (size_t)shdr
.sh_name
);
174 if (fflag
|| nflag
) {
175 size
+= shdr
.sh_size
;
177 (void) printf(" + ");
179 (void) printf(prusect
[numbase
], shdr
.sh_size
);
180 (void) printf("(%s)", name
);
184 if ((fflag
|| nflag
) && (numsect
> 0)) {
185 (void) printf(prusum
[numbase
], size
);
188 if (!fflag
&& !nflag
) {
189 totsize
= first
+ second
+ third
;
190 (void) printf(format
[numbase
],
191 first
, second
, third
, totsize
);
195 if (ehdr
.e_phnum
!= 0) {
196 process_phdr(elf
, ehdr
.e_phnum
);
199 error(fname
, "no segment data");
206 * If there is a program exection header, process segments. In the default
207 * case, the first number is the file size of all nonwritable segments
208 * of type PT_LOAD; the second number is the file size of all writable
209 * segments whose type is PT_LOAD; the third number is the memory size
210 * minus the file size of all writable segments of type PT_LOAD.
211 * If the -F flag is set, size will print the memory size of each loadable
212 * segment, followed by its permission flags.
213 * If -n is set, size will print the memory size of all loadable segments
214 * and the file size of all non-loadable segments, followed by their
219 process_phdr(Elf
* elf
, GElf_Half num
)
234 extern char *archive
;
235 extern int is_archive
;
239 First
= Second
= Third
= Totsize
= 0;
242 (void) printf("%s[%s]: ", archive
, fname
);
243 } else if (!oneflag
&& !is_archive
) {
244 (void) printf("%s: ", fname
);
247 for (i
= 0; i
< (int)num
; i
++) {
248 if (gelf_getphdr(elf
, i
, &p
) == NULL
) {
249 error(fname
, "no segment data");
252 if ((!(p
.p_flags
& PF_W
)) &&
253 (p
.p_type
== PT_LOAD
) && !(Fflag
)) {
255 } else if ((p
.p_flags
& PF_W
) &&
256 (p
.p_type
== PT_LOAD
) && !(Fflag
)) {
257 Second
+= p
.p_filesz
;
260 memsize
+= p
.p_memsz
;
261 if ((p
.p_type
== PT_LOAD
) && nflag
) {
263 (void) printf(" + ");
265 (void) printf(prusect
[numbase
], p
.p_memsz
);
269 if (!(p
.p_type
== PT_LOAD
) && nflag
) {
271 (void) printf(" + ");
273 (void) printf(prusect
[numbase
], p
.p_filesz
);
277 if ((p
.p_type
== PT_LOAD
) && Fflag
&& !nflag
) {
279 (void) printf(" + ");
281 (void) printf(prusect
[numbase
], p
.p_memsz
);
284 if ((Fflag
) && !(nflag
) && (!(p
.p_type
== PT_LOAD
))) {
287 if (Fflag
|| nflag
) {
289 case 0: (void) printf("(---)"); break;
290 case PF_X
: (void) printf("(--x)"); break;
291 case PF_W
: (void) printf("(-w-)"); break;
292 case PF_W
+PF_X
: (void) printf("(-wx)"); break;
293 case PF_R
: (void) printf("(r--)"); break;
294 case PF_R
+PF_X
: (void) printf("(r-x)"); break;
295 case PF_R
+PF_W
: (void) printf("(rw-)"); break;
296 case PF_R
+PF_W
+PF_X
: (void) printf("(rwx)"); break;
297 default: (void) printf("flags(%#x)", p
.p_flags
);
302 (void) printf(prusum
[numbase
], total
);
304 if (Fflag
&& !nflag
) {
305 (void) printf(prusum
[numbase
], memsize
);
307 if (!Fflag
&& !nflag
) {
308 Totsize
= First
+ Second
+ (Third
- Second
);
309 (void) printf(format
[numbase
],
310 First
, Second
, Third
- Second
, Totsize
);