Print this page
4009 size(1) can't find sections in relocatable objects with extended sections
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/size/common/process.c
+++ new/usr/src/cmd/sgs/size/common/process.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 -
25 +
26 26 /* Copyright (c) 1988 AT&T */
27 27 /* Copyright (c) 1989 AT&T */
28 28 /* All Rights Reserved */
29 29
30 30
31 31 /* UNIX HEADER */
32 32 #include <stdio.h>
33 33
34 34 /* SIZE HEADERS */
35 35 #include "defs.h"
36 36
37 37 /* ELF HEADERS */
38 38 #include "gelf.h"
39 39
40 40
41 41 /* SIZE FUNCTIONS CALLED */
42 42 extern void error();
43 43
44 44
45 45 /* FORMAT STRINGS */
46 46
47 47 static const char *prusect[3] = {
48 48 "%llx",
49 49 "%llo",
50 50 "%lld"
51 51 };
52 52
53 53 static const char *prusum[3] = {
54 54 " = 0x%llx\n",
55 55 " = 0%llo\n",
56 56 " = %lld\n"
57 57 };
58 58
59 59 static const char *format[3] = {
60 60 "%llx + %llx + %llx = 0x%llx\n",
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
61 61 "%llo + %llo + %llo = 0%llo\n",
62 62 "%lld + %lld + %lld = %lld\n"
63 63 };
64 64
65 65 static void process_phdr(Elf *elf, GElf_Half num);
66 66
67 67 void
68 68 process(Elf * elf)
69 69 {
70 70 /* EXTERNAL VARIABLES USED */
71 - extern int fflag, /* full format for sections */
72 - Fflag, /* full format for segments */
73 - nflag; /* include non-loadable segments or sections */
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 74 extern int numbase; /* hex, octal, or decimal */
75 75 extern char *fname;
76 76 extern char *archive;
77 77 extern int is_archive;
78 78 extern int oneflag;
79 79
80 80 /* LOCAL VARIABLES */
81 - GElf_Xword size, /* total size in non-default case for sections */
82 - /*
83 - * size of first, second, third number and total size
84 - * in default case for sections.
85 - */
86 - first,
87 - second,
88 - third,
89 - totsize;
81 + GElf_Xword size; /* total size in non-default case for sections */
82 + /*
83 + * size of first, second, third number and total size
84 + * in default case for sections.
85 + */
86 + GElf_Xword first;
87 + GElf_Xword second;
88 + GElf_Xword third;
89 + GElf_Xword totsize;
90 90 GElf_Ehdr ehdr;
91 91 GElf_Shdr shdr;
92 92 Elf_Scn *scn;
93 - unsigned ndx = 0;
93 + size_t ndx = 0, shnum = 0;
94 94 int numsect = 0;
95 95 int notfirst = 0;
96 96 int i;
97 97 char *name = 0;
98 98
99 +
99 100 /*
100 101 * If there is a program header and the -f flag requesting section infor-
101 102 * mation is not set, then process segments with the process_phdr function.
102 103 * Otherwise, process sections. For the default case, the first number
103 104 * shall be the size of all sections that are allocatable, nonwritable and
104 105 * not of type NOBITS; the second number shall be the size of all sections
105 106 * that are allocatable, writable, and not of type NOBITS; the third number
106 107 * is the size of all sections that are writable and not of type NOBITS.
107 108 * If -f is set, print the size of each allocatable section, followed by
108 109 * the section name in parentheses.
109 110 * If -n is set, print the size of all sections, followed by the section
110 111 * name in parentheses.
111 112 */
112 113
113 114 if (gelf_getehdr(elf, &ehdr) == 0) {
114 115 error(fname, "invalid file type");
115 116 return;
116 117 }
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
117 118 if ((ehdr.e_phnum != 0) && !(fflag)) {
118 119 process_phdr(elf, ehdr.e_phnum);
119 120 return;
120 121 }
121 122
122 123 if (is_archive) {
123 124 (void) printf("%s[%s]: ", archive, fname);
124 125 } else if (!oneflag && !is_archive) {
125 126 (void) printf("%s: ", fname);
126 127 }
127 - ndx = ehdr.e_shstrndx;
128 + if (elf_getshdrstrndx(elf, &ndx) == -1)
129 + error(fname, "no string table");
128 130 scn = 0;
129 131 size = 0;
130 132 first = second = third = totsize = 0;
131 - if (ehdr.e_shnum == 0) {
133 +
134 + if (elf_getshdrnum(elf, &shnum) == -1)
135 + error(fname, "can't get number of sections");
136 +
137 + if (shnum == 0)
132 138 error(fname, "no section data");
133 - }
134 - numsect = ehdr.e_shnum;
139 +
140 + numsect = shnum;
135 141 for (i = 0; i < numsect; i++) {
136 142 if ((scn = elf_nextscn(elf, scn)) == 0) {
137 143 break;
138 144 }
139 145 if (gelf_getshdr(scn, &shdr) == 0) {
140 146 error(fname, "could not get section header");
141 147 break;
142 148 }
143 149 if ((Fflag) && !(fflag)) {
144 150 error(fname, "no segment data");
145 151 return;
146 152 } else if ((!(shdr.sh_flags & SHF_ALLOC)) &&
147 - fflag && !(nflag)) {
153 + fflag && !(nflag)) {
148 154 continue;
149 155 } else if ((!(shdr.sh_flags & SHF_ALLOC)) && !(nflag)) {
150 156 continue;
151 157 } else if ((shdr.sh_flags & SHF_ALLOC) &&
152 - (!(shdr.sh_flags & SHF_WRITE)) &&
153 - (!(shdr.sh_type == SHT_NOBITS)) &&
154 - !(fflag) && !(nflag)) {
158 + (!(shdr.sh_flags & SHF_WRITE)) &&
159 + (!(shdr.sh_type == SHT_NOBITS)) &&
160 + !(fflag) && !(nflag)) {
155 161 first += shdr.sh_size;
156 162 } else if ((shdr.sh_flags & SHF_ALLOC) &&
157 - (shdr.sh_flags & SHF_WRITE) &&
158 - (!(shdr.sh_type == SHT_NOBITS)) &&
159 - !(fflag) && !(nflag)) {
163 + (shdr.sh_flags & SHF_WRITE) &&
164 + (!(shdr.sh_type == SHT_NOBITS)) &&
165 + !(fflag) && !(nflag)) {
160 166 second += shdr.sh_size;
161 167 } else if ((shdr.sh_flags & SHF_WRITE) &&
162 - (shdr.sh_type == SHT_NOBITS) &&
163 - !(fflag) && !(nflag)) {
168 + (shdr.sh_type == SHT_NOBITS) &&
169 + !(fflag) && !(nflag)) {
164 170 third += shdr.sh_size;
165 171 }
166 172 name = elf_strptr(elf, ndx, (size_t)shdr.sh_name);
167 173
168 174 if (fflag || nflag) {
169 175 size += shdr.sh_size;
170 176 if (notfirst) {
171 177 (void) printf(" + ");
172 178 }
173 179 (void) printf(prusect[numbase], shdr.sh_size);
174 180 (void) printf("(%s)", name);
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
175 181 }
176 182 notfirst++;
177 183 }
178 184 if ((fflag || nflag) && (numsect > 0)) {
179 185 (void) printf(prusum[numbase], size);
180 186 }
181 187
182 188 if (!fflag && !nflag) {
183 189 totsize = first + second + third;
184 190 (void) printf(format[numbase],
185 - first, second, third, totsize);
191 + first, second, third, totsize);
186 192 }
187 193
188 194 if (Fflag) {
189 195 if (ehdr.e_phnum != 0) {
190 196 process_phdr(elf, ehdr.e_phnum);
191 197 return;
192 198 } else {
193 199 error(fname, "no segment data");
194 200 return;
195 201 }
196 202 }
197 203 }
198 204
199 205 /*
200 206 * If there is a program exection header, process segments. In the default
201 207 * case, the first number is the file size of all nonwritable segments
202 208 * of type PT_LOAD; the second number is the file size of all writable
203 209 * segments whose type is PT_LOAD; the third number is the memory size
204 210 * minus the file size of all writable segments of type PT_LOAD.
205 211 * If the -F flag is set, size will print the memory size of each loadable
206 212 * segment, followed by its permission flags.
207 213 * If -n is set, size will print the memory size of all loadable segments
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
208 214 * and the file size of all non-loadable segments, followed by their
209 215 * permission flags.
210 216 */
211 217
212 218 static void
213 219 process_phdr(Elf * elf, GElf_Half num)
214 220 {
215 221 int i;
216 222 int notfirst = 0;
217 223 GElf_Phdr p;
218 - GElf_Xword memsize,
219 - total,
220 - First,
221 - Second,
222 - Third,
223 - Totsize;
224 - extern int Fflag;
225 - extern int nflag;
226 - extern int numbase;
227 - extern char *fname;
228 - extern char *archive;
229 - extern int is_archive;
230 - extern int oneflag;
224 + GElf_Xword memsize;
225 + GElf_Xword total;
226 + GElf_Xword First;
227 + GElf_Xword Second;
228 + GElf_Xword Third;
229 + GElf_Xword Totsize;
230 + extern int Fflag;
231 + extern int nflag;
232 + extern int numbase;
233 + extern char *fname;
234 + extern char *archive;
235 + extern int is_archive;
236 + extern int oneflag;
231 237
232 238 memsize = total = 0;
233 239 First = Second = Third = Totsize = 0;
234 240
235 241 if (is_archive) {
236 242 (void) printf("%s[%s]: ", archive, fname);
237 243 } else if (!oneflag && !is_archive) {
238 244 (void) printf("%s: ", fname);
239 245 }
240 246
241 247 for (i = 0; i < (int)num; i++) {
242 248 if (gelf_getphdr(elf, i, &p) == NULL) {
243 249 error(fname, "no segment data");
244 250 return;
245 251 }
246 252 if ((!(p.p_flags & PF_W)) &&
247 253 (p.p_type == PT_LOAD) && !(Fflag)) {
248 254 First += p.p_filesz;
249 255 } else if ((p.p_flags & PF_W) &&
250 256 (p.p_type == PT_LOAD) && !(Fflag)) {
251 257 Second += p.p_filesz;
252 258 Third += p.p_memsz;
253 259 }
254 260 memsize += p.p_memsz;
255 261 if ((p.p_type == PT_LOAD) && nflag) {
256 262 if (notfirst) {
257 263 (void) printf(" + ");
258 264 }
259 265 (void) printf(prusect[numbase], p.p_memsz);
260 266 total += p.p_memsz;
261 267 notfirst++;
262 268 }
263 269 if (!(p.p_type == PT_LOAD) && nflag) {
264 270 if (notfirst) {
265 271 (void) printf(" + ");
266 272 }
267 273 (void) printf(prusect[numbase], p.p_filesz);
268 274 total += p.p_filesz;
269 275 notfirst++;
270 276 }
271 277 if ((p.p_type == PT_LOAD) && Fflag && !nflag) {
272 278 if (notfirst) {
273 279 (void) printf(" + ");
274 280 }
275 281 (void) printf(prusect[numbase], p.p_memsz);
276 282 notfirst++;
277 283 }
278 284 if ((Fflag) && !(nflag) && (!(p.p_type == PT_LOAD))) {
279 285 continue;
280 286 }
281 287 if (Fflag || nflag) {
282 288 switch (p.p_flags) {
283 289 case 0: (void) printf("(---)"); break;
284 290 case PF_X: (void) printf("(--x)"); break;
285 291 case PF_W: (void) printf("(-w-)"); break;
286 292 case PF_W+PF_X: (void) printf("(-wx)"); break;
287 293 case PF_R: (void) printf("(r--)"); break;
288 294 case PF_R+PF_X: (void) printf("(r-x)"); break;
289 295 case PF_R+PF_W: (void) printf("(rw-)"); break;
290 296 case PF_R+PF_W+PF_X: (void) printf("(rwx)"); break;
291 297 default: (void) printf("flags(%#x)", p.p_flags);
292 298 }
293 299 }
↓ open down ↓ |
53 lines elided |
↑ open up ↑ |
294 300 }
295 301 if (nflag) {
296 302 (void) printf(prusum[numbase], total);
297 303 }
298 304 if (Fflag && !nflag) {
299 305 (void) printf(prusum[numbase], memsize);
300 306 }
301 307 if (!Fflag && !nflag) {
302 308 Totsize = First + Second + (Third - Second);
303 309 (void) printf(format[numbase],
304 - First, Second, Third - Second, Totsize);
310 + First, Second, Third - Second, Totsize);
305 311 }
306 312 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX