1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Dump an elf file.
29 */
30 #include <stddef.h>
31 #include <sys/elf_386.h>
32 #include <sys/elf_amd64.h>
33 #include <sys/elf_SPARC.h>
34 #include <_libelf.h>
35 #include <dwarf.h>
36 #include <stdio.h>
37 #include <unistd.h>
38 #include <errno.h>
39 #include <strings.h>
40 #include <debug.h>
41 #include <conv.h>
42 #include <msg.h>
43 #include <_elfdump.h>
44
45
46 /*
47 * VERSYM_STATE is used to maintain information about the VERSYM section
48 * in the object being analyzed. It is filled in by versions(), and used
49 * by init_symtbl_state() when displaying symbol information.
50 *
51 * There are three forms of symbol versioning known to us:
52 *
53 * 1) The original form, introduced with Solaris 2.5, in which
54 * the Versym contains indexes to Verdef records, and the
55 * Versym values for UNDEF symbols resolved by other objects
56 * are all set to 0.
57 * 2) The GNU form, which is backward compatible with the original
58 * Solaris form, but which adds several extensions:
59 * - The Versym also contains indexes to Verneed records, recording
60 * which object/version contributed the external symbol at
61 * link time. These indexes start with the next value following
62 * the final Verdef index. The index is written to the previously
63 * reserved vna_other field of the ELF Vernaux structure.
64 * - The top bit of the Versym value is no longer part of the index,
65 * but is used as a "hidden bit" to prevent binding to the symbol.
66 * - Multiple implementations of a given symbol, contained in varying
67 * versions are allowed, using special assembler pseudo ops,
68 * and encoded in the symbol name using '@' characters.
69 * 3) Modified Solaris form, in which we adopt the first GNU extension
70 * (Versym indexes to Verneed records), but not the others.
71 *
72 * elfdump can handle any of these cases. The presence of a DT_VERSYM
73 * dynamic element indicates a full GNU object. An object that lacks
74 * a DT_VERSYM entry, but which has non-zero vna_other fields in the Vernaux
75 * structures is a modified Solaris object. An object that has neither of
76 * these uses the original form.
77 *
78 * max_verndx contains the largest version index that can appear
79 * in a Versym entry. This can never be less than 1: In the case where
80 * there is no verdef/verneed sections, the [0] index is reserved
81 * for local symbols, and the [1] index for globals. If the original
82 * Solaris versioning rules are in effect and there is a verdef section,
83 * then max_verndex is the number of defined versions. If one of the
84 * other versioning forms is in effect, then:
85 * 1) If there is no verneed section, it is the same as for
86 * original Solaris versioning.
87 * 2) If there is a verneed section, the vna_other field of the
88 * Vernaux structs contain versions, and max_verndx is the
89 * largest such index.
90 *
91 * If gnu_full is True, the object uses the full GNU form of versioning.
92 * The value of the gnu_full field is based on the presence of
93 * a DT_VERSYM entry in the dynamic section: GNU ld produces these, and
94 * Solaris ld does not.
95 *
96 * The gnu_needed field is True if the Versym contains indexes to
97 * Verneed records, as indicated by non-zero vna_other fields in the Verneed
98 * section. If gnu_full is True, then gnu_needed will always be true.
99 * However, gnu_needed can be true without gnu_full. This is the modified
100 * Solaris form.
101 */
102 typedef struct {
103 Cache *cache; /* Pointer to cache entry for VERSYM */
104 Versym *data; /* Pointer to versym array */
105 int gnu_full; /* True if object uses GNU versioning rules */
106 int gnu_needed; /* True if object uses VERSYM indexes for */
107 /* VERNEED (subset of gnu_full) */
108 int max_verndx; /* largest versym index value */
109 } VERSYM_STATE;
110
111 /*
112 * SYMTBL_STATE is used to maintain information about a single symbol
113 * table section, for use by the routines that display symbol information.
114 */
115 typedef struct {
116 const char *file; /* Name of file */
117 Ehdr *ehdr; /* ELF header for file */
118 Cache *cache; /* Cache of all section headers */
119 uchar_t osabi; /* OSABI to use */
120 Word shnum; /* # of sections in cache */
121 Cache *seccache; /* Cache of symbol table section hdr */
122 Word secndx; /* Index of symbol table section hdr */
123 const char *secname; /* Name of section */
124 uint_t flags; /* Command line option flags */
125 struct { /* Extended section index data */
126 int checked; /* TRUE if already checked for shxndx */
127 Word *data; /* NULL, or extended section index */
128 /* used for symbol table entries */
129 uint_t n; /* # items in shxndx.data */
130 } shxndx;
131 VERSYM_STATE *versym; /* NULL, or associated VERSYM section */
132 Sym *sym; /* Array of symbols */
133 Word symn; /* # of symbols */
134 } SYMTBL_STATE;
135
136 /*
137 * A variable of this type is used to track information related to
138 * .eh_frame and .eh_frame_hdr sections across calls to unwind_eh_frame().
139 */
140 typedef struct {
141 Word frame_cnt; /* # .eh_frame sections seen */
142 Word frame_ndx; /* Section index of 1st .eh_frame */
143 Word hdr_cnt; /* # .eh_frame_hdr sections seen */
144 Word hdr_ndx; /* Section index of 1st .eh_frame_hdr */
145 uint64_t frame_ptr; /* Value of FramePtr field from first */
146 /* .eh_frame_hdr section */
147 uint64_t frame_base; /* Data addr of 1st .eh_frame */
148 } gnu_eh_state_t;
149
150 /*
151 * C++ .exception_ranges entries make use of the signed ptrdiff_t
152 * type to record self-relative pointer values. We need a type
153 * for this that is matched to the ELFCLASS being processed.
154 */
155 #if defined(_ELF64)
156 typedef int64_t PTRDIFF_T;
157 #else
158 typedef int32_t PTRDIFF_T;
159 #endif
160
161 /*
162 * The Sun C++ ABI uses this struct to define each .exception_ranges
163 * entry. From the ABI:
164 *
165 * The field ret_addr is a self relative pointer to the start of the address
166 * range. The name was chosen because in the current implementation the range
167 * typically starts at the return address for a call site.
168 *
169 * The field length is the difference, in bytes, between the pc of the last
170 * instruction covered by the exception range and the first. When only a
171 * single call site is represented without optimization, this will equal zero.
172 *
173 * The field handler_addr is a relative pointer which stores the difference
174 * between the start of the exception range and the address of all code to
175 * catch exceptions and perform the cleanup for stack unwinding.
176 *
177 * The field type_block is a relative pointer which stores the difference
178 * between the start of the exception range and the address of an array used
179 * for storing a list of the types of exceptions which can be caught within
180 * the exception range.
181 */
182 typedef struct {
183 PTRDIFF_T ret_addr;
184 Xword length;
185 PTRDIFF_T handler_addr;
186 PTRDIFF_T type_block;
187 Xword reserved;
188 } exception_range_entry;
189
190 /*
191 * Focal point for verifying symbol names.
192 */
193 static const char *
string(Cache * refsec,Word ndx,Cache * strsec,const char * file,Word name)194 string(Cache *refsec, Word ndx, Cache *strsec, const char *file, Word name)
195 {
196 /*
197 * If an error in this routine is due to a property of the string
198 * section, as opposed to a bad offset into the section (a property of
199 * the referencing section), then we will detect the same error on
200 * every call involving those sections. We use these static variables
201 * to retain the information needed to only issue each such error once.
202 */
203 static Cache *last_refsec; /* Last referencing section seen */
204 static int strsec_err; /* True if error issued */
205
206 const char *strs;
207 Word strn;
208
209 if (strsec->c_data == NULL)
210 return (NULL);
211
212 strs = (char *)strsec->c_data->d_buf;
213 strn = strsec->c_data->d_size;
214
215 /*
216 * We only print a diagnostic regarding a bad string table once per
217 * input section being processed. If the refsec has changed, reset
218 * our retained error state.
219 */
220 if (last_refsec != refsec) {
221 last_refsec = refsec;
222 strsec_err = 0;
223 }
224
225 /* Verify that strsec really is a string table */
226 if (strsec->c_shdr->sh_type != SHT_STRTAB) {
227 if (!strsec_err) {
228 (void) fprintf(stderr, MSG_INTL(MSG_ERR_NOTSTRTAB),
229 file, strsec->c_ndx, refsec->c_ndx);
230 strsec_err = 1;
231 }
232 return (MSG_INTL(MSG_STR_UNKNOWN));
233 }
234
235 /*
236 * Is the string table offset within range of the available strings?
237 */
238 if (name >= strn) {
239 /*
240 * Do we have a empty string table?
241 */
242 if (strs == NULL) {
243 if (!strsec_err) {
244 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
245 file, strsec->c_name);
246 strsec_err = 1;
247 }
248 } else {
249 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSTOFF),
250 file, refsec->c_name, EC_WORD(ndx), strsec->c_name,
251 EC_WORD(name), EC_WORD(strn - 1));
252 }
253
254 /*
255 * Return the empty string so that the calling function can
256 * continue it's output diagnostics.
257 */
258 return (MSG_INTL(MSG_STR_UNKNOWN));
259 }
260 return (strs + name);
261 }
262
263 /*
264 * Relocations can reference section symbols and standard symbols. If the
265 * former, establish the section name.
266 */
267 static const char *
relsymname(Cache * cache,Cache * csec,Cache * strsec,Word symndx,Word symnum,Word relndx,Sym * syms,char * secstr,size_t secsz,const char * file)268 relsymname(Cache *cache, Cache *csec, Cache *strsec, Word symndx, Word symnum,
269 Word relndx, Sym *syms, char *secstr, size_t secsz, const char *file)
270 {
271 Sym *sym;
272 const char *name;
273
274 if (symndx >= symnum) {
275 (void) fprintf(stderr, MSG_INTL(MSG_ERR_RELBADSYMNDX),
276 file, EC_WORD(symndx), EC_WORD(relndx));
277 return (MSG_INTL(MSG_STR_UNKNOWN));
278 }
279
280 sym = (Sym *)(syms + symndx);
281 name = string(csec, symndx, strsec, file, sym->st_name);
282
283 /*
284 * If the symbol represents a section offset construct an appropriate
285 * string. Note, although section symbol table entries typically have
286 * a NULL name pointer, entries do exist that point into the string
287 * table to their own NULL strings.
288 */
289 if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) &&
290 ((sym->st_name == 0) || (*name == '\0'))) {
291 (void) snprintf(secstr, secsz, MSG_INTL(MSG_STR_SECTION),
292 cache[sym->st_shndx].c_name);
293 return ((const char *)secstr);
294 }
295
296 return (name);
297 }
298
299 /*
300 * Focal point for establishing a string table section. Data such as the
301 * dynamic information simply points to a string table. Data such as
302 * relocations, reference a symbol table, which in turn is associated with a
303 * string table.
304 */
305 static int
stringtbl(Cache * cache,int symtab,Word ndx,Word shnum,const char * file,Word * symnum,Cache ** symsec,Cache ** strsec)306 stringtbl(Cache *cache, int symtab, Word ndx, Word shnum, const char *file,
307 Word *symnum, Cache **symsec, Cache **strsec)
308 {
309 Shdr *shdr = cache[ndx].c_shdr;
310
311 if (symtab) {
312 /*
313 * Validate the symbol table section.
314 */
315 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
316 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
317 file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
318 return (0);
319 }
320 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
321 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
322 file, cache[ndx].c_name);
323 return (0);
324 }
325
326 /*
327 * Obtain, and verify the symbol table data.
328 */
329 if ((cache[ndx].c_data == NULL) ||
330 (cache[ndx].c_data->d_buf == NULL)) {
331 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
332 file, cache[ndx].c_name);
333 return (0);
334 }
335
336 /*
337 * Establish the string table index.
338 */
339 ndx = shdr->sh_link;
340 shdr = cache[ndx].c_shdr;
341
342 /*
343 * Return symbol table information.
344 */
345 if (symnum)
346 *symnum = (shdr->sh_size / shdr->sh_entsize);
347 if (symsec)
348 *symsec = &cache[ndx];
349 }
350
351 /*
352 * Validate the associated string table section.
353 */
354 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
355 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
356 file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
357 return (0);
358 }
359
360 if (strsec)
361 *strsec = &cache[shdr->sh_link];
362
363 return (1);
364 }
365
366 /*
367 * Lookup a symbol and set Sym accordingly.
368 *
369 * entry:
370 * name - Name of symbol to lookup
371 * cache - Cache of all section headers
372 * shnum - # of sections in cache
373 * sym - Address of pointer to receive symbol
374 * target - NULL, or section to which the symbol must be associated.
375 * symtab - Symbol table to search for symbol
376 * file - Name of file
377 *
378 * exit:
379 * If the symbol is found, *sym is set to reference it, and True is
380 * returned. If target is non-NULL, the symbol must reference the given
381 * section --- otherwise the section is not checked.
382 *
383 * If no symbol is found, False is returned.
384 */
385 static int
symlookup(const char * name,Cache * cache,Word shnum,Sym ** sym,Cache * target,Cache * symtab,const char * file)386 symlookup(const char *name, Cache *cache, Word shnum, Sym **sym,
387 Cache *target, Cache *symtab, const char *file)
388 {
389 Shdr *shdr;
390 Word symn, cnt;
391 Sym *syms;
392
393 if (symtab == 0)
394 return (0);
395
396 shdr = symtab->c_shdr;
397
398 /*
399 * Determine the symbol data and number.
400 */
401 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
402 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
403 file, symtab->c_name);
404 return (0);
405 }
406 if (symtab->c_data == NULL)
407 return (0);
408
409 /* LINTED */
410 symn = (Word)(shdr->sh_size / shdr->sh_entsize);
411 syms = (Sym *)symtab->c_data->d_buf;
412
413 /*
414 * Get the associated string table section.
415 */
416 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
417 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
418 file, symtab->c_name, EC_WORD(shdr->sh_link));
419 return (0);
420 }
421
422 /*
423 * Loop through the symbol table to find a match.
424 */
425 *sym = NULL;
426 for (cnt = 0; cnt < symn; syms++, cnt++) {
427 const char *symname;
428
429 symname = string(symtab, cnt, &cache[shdr->sh_link], file,
430 syms->st_name);
431
432 if (symname && (strcmp(name, symname) == 0) &&
433 ((target == NULL) || (target->c_ndx == syms->st_shndx))) {
434 /*
435 * It is possible, though rare, for a local and
436 * global symbol of the same name to exist, each
437 * contributed by a different input object. If the
438 * symbol just found is local, remember it, but
439 * continue looking.
440 */
441 *sym = syms;
442 if (ELF_ST_BIND(syms->st_info) != STB_LOCAL)
443 break;
444 }
445 }
446
447 return (*sym != NULL);
448 }
449
450 /*
451 * Print section headers.
452 */
453 static void
sections(const char * file,Cache * cache,Word shnum,Ehdr * ehdr,uchar_t osabi)454 sections(const char *file, Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi)
455 {
456 size_t seccnt;
457
458 for (seccnt = 1; seccnt < shnum; seccnt++) {
459 Cache *_cache = &cache[seccnt];
460 Shdr *shdr = _cache->c_shdr;
461 const char *secname = _cache->c_name;
462
463 /*
464 * Although numerous section header entries can be zero, it's
465 * usually a sign of trouble if the type is zero.
466 */
467 if (shdr->sh_type == 0) {
468 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHTYPE),
469 file, secname, EC_WORD(shdr->sh_type));
470 }
471
472 if (!match(MATCH_F_ALL, secname, seccnt, shdr->sh_type))
473 continue;
474
475 /*
476 * Identify any sections that are suspicious. A .got section
477 * shouldn't exist in a relocatable object.
478 */
479 if (ehdr->e_type == ET_REL) {
480 if (strncmp(secname, MSG_ORIG(MSG_ELF_GOT),
481 MSG_ELF_GOT_SIZE) == 0) {
482 (void) fprintf(stderr,
483 MSG_INTL(MSG_GOT_UNEXPECTED), file,
484 secname);
485 }
486 }
487
488 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
489 dbg_print(0, MSG_INTL(MSG_ELF_SHDR), EC_WORD(seccnt), secname);
490 Elf_shdr(0, osabi, ehdr->e_machine, shdr);
491 }
492 }
493
494 /*
495 * Obtain a specified Phdr entry.
496 */
497 static Phdr *
getphdr(Word phnum,Word * type_arr,Word type_cnt,const char * file,Elf * elf)498 getphdr(Word phnum, Word *type_arr, Word type_cnt, const char *file, Elf *elf)
499 {
500 Word cnt, tcnt;
501 Phdr *phdr;
502
503 if ((phdr = elf_getphdr(elf)) == NULL) {
504 failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
505 return (NULL);
506 }
507
508 for (cnt = 0; cnt < phnum; phdr++, cnt++) {
509 for (tcnt = 0; tcnt < type_cnt; tcnt++) {
510 if (phdr->p_type == type_arr[tcnt])
511 return (phdr);
512 }
513 }
514 return (NULL);
515 }
516
517 /*
518 * Display the contents of GNU/amd64 .eh_frame and .eh_frame_hdr
519 * sections.
520 *
521 * entry:
522 * cache - Cache of all section headers
523 * shndx - Index of .eh_frame or .eh_frame_hdr section to be displayed
524 * uphdr - NULL, or unwind program header associated with
525 * the .eh_frame_hdr section.
526 * ehdr - ELF header for file
527 * eh_state - Data used across calls to this routine. The
528 * caller should zero it before the first call, and
529 * pass it on every call.
530 * osabi - OSABI to use in displaying information
531 * file - Name of file
532 * flags - Command line option flags
533 */
534 static void
unwind_eh_frame(Cache * cache,Word shndx,Phdr * uphdr,Ehdr * ehdr,gnu_eh_state_t * eh_state,uchar_t osabi,const char * file,uint_t flags)535 unwind_eh_frame(Cache *cache, Word shndx, Phdr *uphdr, Ehdr *ehdr,
536 gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
537 {
538 #if defined(_ELF64)
539 #define MSG_UNW_BINSRTAB2 MSG_UNW_BINSRTAB2_64
540 #define MSG_UNW_BINSRTABENT MSG_UNW_BINSRTABENT_64
541 #else
542 #define MSG_UNW_BINSRTAB2 MSG_UNW_BINSRTAB2_32
543 #define MSG_UNW_BINSRTABENT MSG_UNW_BINSRTABENT_32
544 #endif
545
546 Cache *_cache = &cache[shndx];
547 Shdr *shdr = _cache->c_shdr;
548 uchar_t *data = (uchar_t *)(_cache->c_data->d_buf);
549 size_t datasize = _cache->c_data->d_size;
550 Conv_dwarf_ehe_buf_t dwarf_ehe_buf;
551 uint64_t ndx, frame_ptr, fde_cnt, tabndx;
552 uint_t vers, frame_ptr_enc, fde_cnt_enc, table_enc;
553 uint64_t initloc, initloc0;
554
555
556 /*
557 * Is this a .eh_frame_hdr?
558 */
559 if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
560 (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
561 MSG_SCN_FRMHDR_SIZE) == 0)) {
562 /*
563 * There can only be a single .eh_frame_hdr.
564 * Flag duplicates.
565 */
566 if (++eh_state->hdr_cnt > 1)
567 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTEHFRMHDR),
568 file, EC_WORD(shndx), _cache->c_name);
569
570 dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
571 ndx = 0;
572
573 vers = data[ndx++];
574 frame_ptr_enc = data[ndx++];
575 fde_cnt_enc = data[ndx++];
576 table_enc = data[ndx++];
577
578 dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
579
580 frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
581 ehdr->e_ident, shdr->sh_addr, ndx);
582 if (eh_state->hdr_cnt == 1) {
583 eh_state->hdr_ndx = shndx;
584 eh_state->frame_ptr = frame_ptr;
585 }
586
587 dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
588 conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
589 EC_XWORD(frame_ptr));
590
591 fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
592 ehdr->e_ident, shdr->sh_addr, ndx);
593
594 dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
595 conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
596 EC_XWORD(fde_cnt));
597 dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
598 conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
599 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
600 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
601
602 for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
603 initloc = dwarf_ehe_extract(data, &ndx, table_enc,
604 ehdr->e_ident, shdr->sh_addr, ndx);
605 /*LINTED:E_VAR_USED_BEFORE_SET*/
606 if ((tabndx != 0) && (initloc0 > initloc))
607 (void) fprintf(stderr,
608 MSG_INTL(MSG_ERR_BADSORT), file,
609 _cache->c_name, EC_WORD(tabndx));
610 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
611 EC_XWORD(initloc),
612 EC_XWORD(dwarf_ehe_extract(data, &ndx,
613 table_enc, ehdr->e_ident, shdr->sh_addr,
614 ndx)));
615 initloc0 = initloc;
616 }
617 } else { /* Display the .eh_frame section */
618 eh_state->frame_cnt++;
619 if (eh_state->frame_cnt == 1) {
620 eh_state->frame_ndx = shndx;
621 eh_state->frame_base = shdr->sh_addr;
622 } else if ((eh_state->frame_cnt > 1) &&
623 (ehdr->e_type != ET_REL)) {
624 Conv_inv_buf_t inv_buf;
625
626 (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
627 file, EC_WORD(shndx), _cache->c_name,
628 conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
629 }
630 dump_eh_frame(data, datasize, shdr->sh_addr,
631 ehdr->e_machine, ehdr->e_ident);
632 }
633
634 /*
635 * If we've seen the .eh_frame_hdr and the first .eh_frame section,
636 * compare the header frame_ptr to the address of the actual frame
637 * section to ensure the link-editor got this right. Note, this
638 * diagnostic is only produced when unwind information is explicitly
639 * asked for, as shared objects built with an older ld(1) may reveal
640 * this inconsistency. Although an inconsistency, it doesn't seem to
641 * have any adverse effect on existing tools.
642 */
643 if (((flags & FLG_MASK_SHOW) != FLG_MASK_SHOW) &&
644 (eh_state->hdr_cnt > 0) && (eh_state->frame_cnt > 0) &&
645 (eh_state->frame_ptr != eh_state->frame_base))
646 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR),
647 file, EC_WORD(eh_state->hdr_ndx),
648 cache[eh_state->hdr_ndx].c_name,
649 EC_XWORD(eh_state->frame_ptr),
650 EC_WORD(eh_state->frame_ndx),
651 cache[eh_state->frame_ndx].c_name,
652 EC_XWORD(eh_state->frame_base));
653 #undef MSG_UNW_BINSRTAB2
654 #undef MSG_UNW_BINSRTABENT
655 }
656
657 /*
658 * Convert a self relative pointer into an address. A self relative
659 * pointer adds the address where the pointer resides to the offset
660 * contained in the pointer. The benefit is that the value of the
661 * pointer does not require relocation.
662 *
663 * entry:
664 * base_addr - Address of the pointer.
665 * delta - Offset relative to base_addr giving desired address
666 *
667 * exit:
668 * The computed address is returned.
669 *
670 * note:
671 * base_addr is an unsigned value, while ret_addr is signed. This routine
672 * used explicit testing and casting to explicitly control type
673 * conversion, and ensure that we handle the maximum possible range.
674 */
675 static Addr
srelptr(Addr base_addr,PTRDIFF_T delta)676 srelptr(Addr base_addr, PTRDIFF_T delta)
677 {
678 if (delta < 0)
679 return (base_addr - (Addr) (-delta));
680
681 return (base_addr + (Addr) delta);
682 }
683
684 /*
685 * Byte swap a PTRDIFF_T value.
686 */
687 static PTRDIFF_T
swap_ptrdiff(PTRDIFF_T value)688 swap_ptrdiff(PTRDIFF_T value)
689 {
690 PTRDIFF_T r;
691 uchar_t *dst = (uchar_t *)&r;
692 uchar_t *src = (uchar_t *)&value;
693
694 UL_ASSIGN_BSWAP_XWORD(dst, src);
695 return (r);
696 }
697
698 /*
699 * Display exception_range_entry items from the .exception_ranges section
700 * of a Sun C++ object.
701 */
702 static void
unwind_exception_ranges(Cache * _cache,const char * file,int do_swap)703 unwind_exception_ranges(Cache *_cache, const char *file, int do_swap)
704 {
705 /*
706 * Translate a PTRDIFF_T self-relative address field of
707 * an exception_range_entry struct into an address.
708 *
709 * entry:
710 * exc_addr - Address of base of exception_range_entry struct
711 * cur_ent - Pointer to data in the struct to be translated
712 *
713 * _f - Field of struct to be translated
714 */
715 #define SRELPTR(_f) \
716 srelptr(exc_addr + offsetof(exception_range_entry, _f), cur_ent->_f)
717
718 #if defined(_ELF64)
719 #define MSG_EXR_TITLE MSG_EXR_TITLE_64
720 #define MSG_EXR_ENTRY MSG_EXR_ENTRY_64
721 #else
722 #define MSG_EXR_TITLE MSG_EXR_TITLE_32
723 #define MSG_EXR_ENTRY MSG_EXR_ENTRY_32
724 #endif
725
726 exception_range_entry scratch, *ent, *cur_ent = &scratch;
727 char index[MAXNDXSIZE];
728 Word i, nelts;
729 Addr addr, addr0, offset = 0;
730 Addr exc_addr = _cache->c_shdr->sh_addr;
731
732 dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
733 ent = (exception_range_entry *)(_cache->c_data->d_buf);
734 nelts = _cache->c_data->d_size / sizeof (exception_range_entry);
735
736 for (i = 0; i < nelts; i++, ent++) {
737 if (do_swap) {
738 /*
739 * Copy byte swapped values into the scratch buffer.
740 * The reserved field is not used, so we skip it.
741 */
742 scratch.ret_addr = swap_ptrdiff(ent->ret_addr);
743 scratch.length = BSWAP_XWORD(ent->length);
744 scratch.handler_addr = swap_ptrdiff(ent->handler_addr);
745 scratch.type_block = swap_ptrdiff(ent->type_block);
746 } else {
747 cur_ent = ent;
748 }
749
750 /*
751 * The table is required to be sorted by the address
752 * derived from ret_addr, to allow binary searching. Ensure
753 * that addresses grow monotonically.
754 */
755 addr = SRELPTR(ret_addr);
756 /*LINTED:E_VAR_USED_BEFORE_SET*/
757 if ((i != 0) && (addr0 > addr))
758 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
759 file, _cache->c_name, EC_WORD(i));
760
761 (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
762 EC_XWORD(i));
763 dbg_print(0, MSG_INTL(MSG_EXR_ENTRY), index, EC_ADDR(offset),
764 EC_ADDR(addr), EC_ADDR(cur_ent->length),
765 EC_ADDR(SRELPTR(handler_addr)),
766 EC_ADDR(SRELPTR(type_block)));
767
768 addr0 = addr;
769 exc_addr += sizeof (exception_range_entry);
770 offset += sizeof (exception_range_entry);
771 }
772
773 #undef SRELPTR
774 #undef MSG_EXR_TITLE
775 #undef MSG_EXR_ENTRY
776 }
777
778 /*
779 * Display information from unwind/exception sections:
780 *
781 * - GNU/amd64 .eh_frame and .eh_frame_hdr
782 * - Sun C++ .exception_ranges
783 *
784 */
785 static void
unwind(Cache * cache,Word shnum,Word phnum,Ehdr * ehdr,uchar_t osabi,const char * file,Elf * elf,uint_t flags)786 unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
787 const char *file, Elf *elf, uint_t flags)
788 {
789 static Word phdr_types[] = { PT_SUNW_UNWIND, PT_SUNW_EH_FRAME };
790
791 Word cnt;
792 Phdr *uphdr = NULL;
793 gnu_eh_state_t eh_state;
794
795 /*
796 * Historical background: .eh_frame and .eh_frame_hdr sections
797 * come from the GNU compilers (particularly C++), and are used
798 * under all architectures. Their format is based on DWARF. When
799 * the amd64 ABI was defined, these sections were adopted wholesale
800 * from the existing practice.
801 *
802 * When amd64 support was added to Solaris, support for these
803 * sections was added, using the SHT_AMD64_UNWIND section type
804 * to identify them. At first, we ignored them in objects for
805 * non-amd64 targets, but later broadened our support to include
806 * other architectures in order to better support gcc-generated
807 * objects.
808 *
809 * .exception_ranges implement the same basic concepts, but
810 * were invented at Sun for the Sun C++ compiler.
811 *
812 * We match these sections by name, rather than section type,
813 * because they can come in as either SHT_AMD64_UNWIND, or as
814 * SHT_PROGBITS, and because the type isn't enough to determine
815 * how they should be interpreted.
816 */
817 /* Find the program header for .eh_frame_hdr if present */
818 if (phnum)
819 uphdr = getphdr(phnum, phdr_types,
820 sizeof (phdr_types) / sizeof (*phdr_types), file, elf);
821
822 /*
823 * eh_state is used to retain data used by unwind_eh_frame()
824 * across calls.
825 */
826 bzero(&eh_state, sizeof (eh_state));
827
828 for (cnt = 1; cnt < shnum; cnt++) {
829 Cache *_cache = &cache[cnt];
830 Shdr *shdr = _cache->c_shdr;
831 int is_exrange;
832
833 /*
834 * Skip sections of the wrong type. On amd64, they
835 * can be SHT_AMD64_UNWIND. On all platforms, they
836 * can be SHT_PROGBITS (including amd64, if using
837 * the GNU compilers).
838 *
839 * Skip anything other than these two types. The name
840 * test below will thin out the SHT_PROGBITS that don't apply.
841 */
842 if ((shdr->sh_type != SHT_PROGBITS) &&
843 (shdr->sh_type != SHT_AMD64_UNWIND))
844 continue;
845
846 /*
847 * Only sections with certain well known names are of interest.
848 * These are:
849 *
850 * .eh_frame - amd64/GNU-compiler unwind sections
851 * .eh_frame_hdr - Sorted table referencing .eh_frame
852 * .exception_ranges - Sun C++ unwind sections
853 *
854 * We do a prefix comparison, allowing for naming conventions
855 * like .eh_frame.foo, hence the use of strncmp() rather than
856 * strcmp(). This means that we only really need to test for
857 * .eh_frame, as it's a prefix of .eh_frame_hdr.
858 */
859 is_exrange = strncmp(_cache->c_name,
860 MSG_ORIG(MSG_SCN_EXRANGE), MSG_SCN_EXRANGE_SIZE) == 0;
861 if ((strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRM),
862 MSG_SCN_FRM_SIZE) != 0) && !is_exrange)
863 continue;
864
865 if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
866 continue;
867
868 if (_cache->c_data == NULL)
869 continue;
870
871 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
872 dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name);
873
874 if (is_exrange)
875 unwind_exception_ranges(_cache, file,
876 _elf_sys_encoding() != ehdr->e_ident[EI_DATA]);
877 else
878 unwind_eh_frame(cache, cnt, uphdr, ehdr, &eh_state,
879 osabi, file, flags);
880 }
881 }
882
883 /*
884 * Initialize a symbol table state structure
885 *
886 * entry:
887 * state - State structure to be initialized
888 * cache - Cache of all section headers
889 * shnum - # of sections in cache
890 * secndx - Index of symbol table section
891 * ehdr - ELF header for file
892 * versym - Information about versym section
893 * file - Name of file
894 * flags - Command line option flags
895 */
896 static int
init_symtbl_state(SYMTBL_STATE * state,Cache * cache,Word shnum,Word secndx,Ehdr * ehdr,uchar_t osabi,VERSYM_STATE * versym,const char * file,uint_t flags)897 init_symtbl_state(SYMTBL_STATE *state, Cache *cache, Word shnum, Word secndx,
898 Ehdr *ehdr, uchar_t osabi, VERSYM_STATE *versym, const char *file,
899 uint_t flags)
900 {
901 Shdr *shdr;
902
903 state->file = file;
904 state->ehdr = ehdr;
905 state->cache = cache;
906 state->osabi = osabi;
907 state->shnum = shnum;
908 state->seccache = &cache[secndx];
909 state->secndx = secndx;
910 state->secname = state->seccache->c_name;
911 state->flags = flags;
912 state->shxndx.checked = 0;
913 state->shxndx.data = NULL;
914 state->shxndx.n = 0;
915
916 shdr = state->seccache->c_shdr;
917
918 /*
919 * Check the symbol data and per-item size.
920 */
921 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
922 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
923 file, state->secname);
924 return (0);
925 }
926 if (state->seccache->c_data == NULL)
927 return (0);
928
929 /* LINTED */
930 state->symn = (Word)(shdr->sh_size / shdr->sh_entsize);
931 state->sym = (Sym *)state->seccache->c_data->d_buf;
932
933 /*
934 * Check associated string table section.
935 */
936 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
937 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
938 file, state->secname, EC_WORD(shdr->sh_link));
939 return (0);
940 }
941
942 /*
943 * Determine if there is a associated Versym section
944 * with this Symbol Table.
945 */
946 if (versym && versym->cache &&
947 (versym->cache->c_shdr->sh_link == state->secndx))
948 state->versym = versym;
949 else
950 state->versym = NULL;
951
952
953 return (1);
954 }
955
956 /*
957 * Determine the extended section index used for symbol tables entries.
958 */
959 static void
symbols_getxindex(SYMTBL_STATE * state)960 symbols_getxindex(SYMTBL_STATE *state)
961 {
962 uint_t symn;
963 Word symcnt;
964
965 state->shxndx.checked = 1; /* Note that we've been called */
966 for (symcnt = 1; symcnt < state->shnum; symcnt++) {
967 Cache *_cache = &state->cache[symcnt];
968 Shdr *shdr = _cache->c_shdr;
969
970 if ((shdr->sh_type != SHT_SYMTAB_SHNDX) ||
971 (shdr->sh_link != state->secndx))
972 continue;
973
974 if ((shdr->sh_entsize) &&
975 /* LINTED */
976 ((symn = (uint_t)(shdr->sh_size / shdr->sh_entsize)) == 0))
977 continue;
978
979 if (_cache->c_data == NULL)
980 continue;
981
982 state->shxndx.data = _cache->c_data->d_buf;
983 state->shxndx.n = symn;
984 return;
985 }
986 }
987
988 /*
989 * Produce a line of output for the given symbol
990 *
991 * entry:
992 * state - Symbol table state
993 * symndx - Index of symbol within the table
994 * info - Value of st_info (indicates local/global range)
995 * symndx_disp - Index to display. This may not be the same
996 * as symndx if the display is relative to the logical
997 * combination of the SUNW_ldynsym/dynsym tables.
998 * sym - Symbol to display
999 */
1000 static void
output_symbol(SYMTBL_STATE * state,Word symndx,Word info,Word disp_symndx,Sym * sym)1001 output_symbol(SYMTBL_STATE *state, Word symndx, Word info, Word disp_symndx,
1002 Sym *sym)
1003 {
1004 /*
1005 * Symbol types for which we check that the specified
1006 * address/size land inside the target section.
1007 */
1008 static const int addr_symtype[] = {
1009 0, /* STT_NOTYPE */
1010 1, /* STT_OBJECT */
1011 1, /* STT_FUNC */
1012 0, /* STT_SECTION */
1013 0, /* STT_FILE */
1014 1, /* STT_COMMON */
1015 0, /* STT_TLS */
1016 0, /* 7 */
1017 0, /* 8 */
1018 0, /* 9 */
1019 0, /* 10 */
1020 0, /* 11 */
1021 0, /* 12 */
1022 0, /* STT_SPARC_REGISTER */
1023 0, /* 14 */
1024 0, /* 15 */
1025 };
1026 #if STT_NUM != (STT_TLS + 1)
1027 #error "STT_NUM has grown. Update addr_symtype[]"
1028 #endif
1029
1030 char index[MAXNDXSIZE];
1031 const char *symname, *sec;
1032 Versym verndx;
1033 int gnuver;
1034 uchar_t type;
1035 Shdr *tshdr;
1036 Word shndx;
1037 Conv_inv_buf_t inv_buf;
1038
1039 /* Ensure symbol index is in range */
1040 if (symndx >= state->symn) {
1041 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYMNDX),
1042 state->file, state->secname, EC_WORD(symndx));
1043 return;
1044 }
1045
1046 /*
1047 * If we are using extended symbol indexes, find the
1048 * corresponding SHN_SYMTAB_SHNDX table.
1049 */
1050 if ((sym->st_shndx == SHN_XINDEX) && (state->shxndx.checked == 0))
1051 symbols_getxindex(state);
1052
1053 /* LINTED */
1054 symname = string(state->seccache, symndx,
1055 &state->cache[state->seccache->c_shdr->sh_link], state->file,
1056 sym->st_name);
1057
1058 tshdr = NULL;
1059 sec = NULL;
1060
1061 if (state->ehdr->e_type == ET_CORE) {
1062 sec = (char *)MSG_INTL(MSG_STR_UNKNOWN);
1063 } else if (state->flags & FLG_CTL_FAKESHDR) {
1064 /*
1065 * If we are using fake section headers derived from
1066 * the program headers, then the section indexes
1067 * in the symbols do not correspond to these headers.
1068 * The section names are not available, so all we can
1069 * do is to display them in numeric form.
1070 */
1071 sec = conv_sym_shndx(state->osabi, state->ehdr->e_machine,
1072 sym->st_shndx, CONV_FMT_DECIMAL, &inv_buf);
1073 } else if ((sym->st_shndx < SHN_LORESERVE) &&
1074 (sym->st_shndx < state->shnum)) {
1075 shndx = sym->st_shndx;
1076 tshdr = state->cache[shndx].c_shdr;
1077 sec = state->cache[shndx].c_name;
1078 } else if (sym->st_shndx == SHN_XINDEX) {
1079 if (state->shxndx.data) {
1080 Word _shxndx;
1081
1082 if (symndx > state->shxndx.n) {
1083 (void) fprintf(stderr,
1084 MSG_INTL(MSG_ERR_BADSYMXINDEX1),
1085 state->file, state->secname,
1086 EC_WORD(symndx));
1087 } else if ((_shxndx =
1088 state->shxndx.data[symndx]) > state->shnum) {
1089 (void) fprintf(stderr,
1090 MSG_INTL(MSG_ERR_BADSYMXINDEX2),
1091 state->file, state->secname,
1092 EC_WORD(symndx), EC_WORD(_shxndx));
1093 } else {
1094 shndx = _shxndx;
1095 tshdr = state->cache[shndx].c_shdr;
1096 sec = state->cache[shndx].c_name;
1097 }
1098 } else {
1099 (void) fprintf(stderr,
1100 MSG_INTL(MSG_ERR_BADSYMXINDEX3),
1101 state->file, state->secname, EC_WORD(symndx));
1102 }
1103 } else if ((sym->st_shndx < SHN_LORESERVE) &&
1104 (sym->st_shndx >= state->shnum)) {
1105 (void) fprintf(stderr,
1106 MSG_INTL(MSG_ERR_BADSYM5), state->file,
1107 state->secname, EC_WORD(symndx),
1108 demangle(symname, state->flags), sym->st_shndx);
1109 }
1110
1111 /*
1112 * If versioning is available display the
1113 * version index. If not, then use 0.
1114 */
1115 if (state->versym) {
1116 Versym test_verndx;
1117
1118 verndx = test_verndx = state->versym->data[symndx];
1119 gnuver = state->versym->gnu_full;
1120
1121 /*
1122 * Check to see if this is a defined symbol with a
1123 * version index that is outside the valid range for
1124 * the file. The interpretation of this depends on
1125 * the style of versioning used by the object.
1126 *
1127 * Versions >= VER_NDX_LORESERVE have special meanings,
1128 * and are exempt from this checking.
1129 *
1130 * GNU style version indexes use the top bit of the
1131 * 16-bit index value (0x8000) as the "hidden bit".
1132 * We must mask off this bit in order to compare
1133 * the version against the maximum value.
1134 */
1135 if (gnuver)
1136 test_verndx &= ~0x8000;
1137
1138 if ((test_verndx > state->versym->max_verndx) &&
1139 (verndx < VER_NDX_LORESERVE))
1140 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADVER),
1141 state->file, state->secname, EC_WORD(symndx),
1142 EC_HALF(test_verndx), state->versym->max_verndx);
1143 } else {
1144 verndx = 0;
1145 gnuver = 0;
1146 }
1147
1148 /*
1149 * Error checking for TLS.
1150 */
1151 type = ELF_ST_TYPE(sym->st_info);
1152 if (type == STT_TLS) {
1153 if (tshdr &&
1154 (sym->st_shndx != SHN_UNDEF) &&
1155 ((tshdr->sh_flags & SHF_TLS) == 0)) {
1156 (void) fprintf(stderr,
1157 MSG_INTL(MSG_ERR_BADSYM3), state->file,
1158 state->secname, EC_WORD(symndx),
1159 demangle(symname, state->flags));
1160 }
1161 } else if ((type != STT_SECTION) && sym->st_size &&
1162 tshdr && (tshdr->sh_flags & SHF_TLS)) {
1163 (void) fprintf(stderr,
1164 MSG_INTL(MSG_ERR_BADSYM4), state->file,
1165 state->secname, EC_WORD(symndx),
1166 demangle(symname, state->flags));
1167 }
1168
1169 /*
1170 * If a symbol with non-zero size has a type that
1171 * specifies an address, then make sure the location
1172 * it references is actually contained within the
1173 * section. UNDEF symbols don't count in this case,
1174 * so we ignore them.
1175 *
1176 * The meaning of the st_value field in a symbol
1177 * depends on the type of object. For a relocatable
1178 * object, it is the offset within the section.
1179 * For sharable objects, it is the offset relative to
1180 * the base of the object, and for other types, it is
1181 * the virtual address. To get an offset within the
1182 * section for non-ET_REL files, we subtract the
1183 * base address of the section.
1184 */
1185 if (addr_symtype[type] && (sym->st_size > 0) &&
1186 (sym->st_shndx != SHN_UNDEF) && ((sym->st_shndx < SHN_LORESERVE) ||
1187 (sym->st_shndx == SHN_XINDEX)) && (tshdr != NULL)) {
1188 Word v = sym->st_value;
1189 if (state->ehdr->e_type != ET_REL)
1190 v -= tshdr->sh_addr;
1191 if (((v + sym->st_size) > tshdr->sh_size)) {
1192 (void) fprintf(stderr,
1193 MSG_INTL(MSG_ERR_BADSYM6), state->file,
1194 state->secname, EC_WORD(symndx),
1195 demangle(symname, state->flags),
1196 EC_WORD(shndx), EC_XWORD(tshdr->sh_size),
1197 EC_XWORD(sym->st_value), EC_XWORD(sym->st_size));
1198 }
1199 }
1200
1201 /*
1202 * A typical symbol table uses the sh_info field to indicate one greater
1203 * than the symbol table index of the last local symbol, STB_LOCAL.
1204 * Therefore, symbol indexes less than sh_info should have local
1205 * binding. Symbol indexes greater than, or equal to sh_info, should
1206 * have global binding. Note, we exclude UNDEF/NOTY symbols with zero
1207 * value and size, as these symbols may be the result of an mcs(1)
1208 * section deletion.
1209 */
1210 if (info) {
1211 uchar_t bind = ELF_ST_BIND(sym->st_info);
1212
1213 if ((symndx < info) && (bind != STB_LOCAL)) {
1214 (void) fprintf(stderr,
1215 MSG_INTL(MSG_ERR_BADSYM7), state->file,
1216 state->secname, EC_WORD(symndx),
1217 demangle(symname, state->flags), EC_XWORD(info));
1218
1219 } else if ((symndx >= info) && (bind == STB_LOCAL) &&
1220 ((sym->st_shndx != SHN_UNDEF) ||
1221 (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) ||
1222 (sym->st_size != 0) || (sym->st_value != 0))) {
1223 (void) fprintf(stderr,
1224 MSG_INTL(MSG_ERR_BADSYM8), state->file,
1225 state->secname, EC_WORD(symndx),
1226 demangle(symname, state->flags), EC_XWORD(info));
1227 }
1228 }
1229
1230 (void) snprintf(index, MAXNDXSIZE,
1231 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(disp_symndx));
1232 Elf_syms_table_entry(0, ELF_DBG_ELFDUMP, index, state->osabi,
1233 state->ehdr->e_machine, sym, verndx, gnuver, sec, symname);
1234 }
1235
1236 /*
1237 * Process a SHT_SUNW_cap capabilities section.
1238 */
1239 static int
cap_section(const char * file,Cache * cache,Word shnum,Cache * ccache,uchar_t osabi,Ehdr * ehdr,uint_t flags)1240 cap_section(const char *file, Cache *cache, Word shnum, Cache *ccache,
1241 uchar_t osabi, Ehdr *ehdr, uint_t flags)
1242 {
1243 SYMTBL_STATE state;
1244 Word cnum, capnum, nulls, symcaps;
1245 int descapndx, objcap, title;
1246 Cap *cap = (Cap *)ccache->c_data->d_buf;
1247 Shdr *cishdr, *cshdr = ccache->c_shdr;
1248 Cache *cicache, *strcache;
1249 Capinfo *capinfo = NULL;
1250 Word capinfonum;
1251 const char *strs = NULL;
1252 size_t strs_size;
1253
1254 if ((cshdr->sh_entsize == 0) || (cshdr->sh_size == 0)) {
1255 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
1256 file, ccache->c_name);
1257 return (0);
1258 }
1259
1260 /*
1261 * If this capabilities section is associated with symbols, then the
1262 * sh_link field points to the associated capabilities information
1263 * section. The sh_link field of the capabilities information section
1264 * points to the associated symbol table.
1265 */
1266 if (cshdr->sh_link) {
1267 Cache *scache;
1268 Shdr *sshdr;
1269
1270 /*
1271 * Validate that the sh_link field points to a capabilities
1272 * information section.
1273 */
1274 if (cshdr->sh_link >= shnum) {
1275 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1276 file, ccache->c_name, EC_WORD(cshdr->sh_link));
1277 return (0);
1278 }
1279
1280 cicache = &cache[cshdr->sh_link];
1281 cishdr = cicache->c_shdr;
1282
1283 if (cishdr->sh_type != SHT_SUNW_capinfo) {
1284 (void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAP),
1285 file, ccache->c_name, EC_WORD(cshdr->sh_link));
1286 return (0);
1287 }
1288
1289 capinfo = cicache->c_data->d_buf;
1290 capinfonum = (Word)(cishdr->sh_size / cishdr->sh_entsize);
1291
1292 /*
1293 * Validate that the sh_link field of the capabilities
1294 * information section points to a valid symbol table.
1295 */
1296 if ((cishdr->sh_link == 0) || (cishdr->sh_link >= shnum)) {
1297 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1298 file, cicache->c_name, EC_WORD(cishdr->sh_link));
1299 return (0);
1300 }
1301 scache = &cache[cishdr->sh_link];
1302 sshdr = scache->c_shdr;
1303
1304 if ((sshdr->sh_type != SHT_SYMTAB) &&
1305 (sshdr->sh_type != SHT_DYNSYM)) {
1306 (void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAPINFO1),
1307 file, cicache->c_name, EC_WORD(cishdr->sh_link));
1308 return (0);
1309 }
1310
1311 if (!init_symtbl_state(&state, cache, shnum,
1312 cishdr->sh_link, ehdr, osabi, NULL, file, flags))
1313 return (0);
1314 }
1315
1316 /*
1317 * If this capabilities section contains capability string entries,
1318 * then determine the associated string table. Capabilities entries
1319 * that define names require that the capability section indicate
1320 * which string table to use via sh_info.
1321 */
1322 if (cshdr->sh_info) {
1323 Shdr *strshdr;
1324
1325 /*
1326 * Validate that the sh_info field points to a string table.
1327 */
1328 if (cshdr->sh_info >= shnum) {
1329 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1330 file, ccache->c_name, EC_WORD(cshdr->sh_info));
1331 return (0);
1332 }
1333
1334 strcache = &cache[cshdr->sh_info];
1335 strshdr = strcache->c_shdr;
1336
1337 if (strshdr->sh_type != SHT_STRTAB) {
1338 (void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAP),
1339 file, ccache->c_name, EC_WORD(cshdr->sh_info));
1340 return (0);
1341 }
1342 strs = (const char *)strcache->c_data->d_buf;
1343 strs_size = strcache->c_data->d_size;
1344 }
1345
1346 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1347 dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAP), ccache->c_name);
1348
1349 capnum = (Word)(cshdr->sh_size / cshdr->sh_entsize);
1350
1351 nulls = symcaps = 0;
1352 objcap = title = 1;
1353 descapndx = -1;
1354
1355 /*
1356 * Traverse the capabilities section printing each capability group.
1357 * The first capabilities group defines any object capabilities. Any
1358 * following groups define symbol capabilities. In the case where no
1359 * object capabilities exist, but symbol capabilities do, a single
1360 * CA_SUNW_NULL terminator for the object capabilities exists.
1361 */
1362 for (cnum = 0; cnum < capnum; cap++, cnum++) {
1363 if (cap->c_tag == CA_SUNW_NULL) {
1364 /*
1365 * A CA_SUNW_NULL tag terminates a capabilities group.
1366 * If the first capabilities tag is CA_SUNW_NULL, then
1367 * no object capabilities exist.
1368 */
1369 if ((nulls++ == 0) && (cnum == 0))
1370 objcap = 0;
1371 title = 1;
1372 } else {
1373 if (title) {
1374 if (nulls == 0) {
1375 /*
1376 * If this capabilities group represents
1377 * the object capabilities (i.e., no
1378 * CA_SUNW_NULL tag has been processed
1379 * yet), then display an object
1380 * capabilities title.
1381 */
1382 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1383 dbg_print(0,
1384 MSG_INTL(MSG_OBJ_CAP_TITLE));
1385 } else {
1386 /*
1387 * If this is a symbols capabilities
1388 * group (i.e., a CA_SUNW_NULL tag has
1389 * already be found that terminates
1390 * the object capabilities group), then
1391 * display a symbol capabilities title,
1392 * and retain this capabilities index
1393 * for later processing.
1394 */
1395 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1396 dbg_print(0,
1397 MSG_INTL(MSG_SYM_CAP_TITLE));
1398 descapndx = cnum;
1399 }
1400 Elf_cap_title(0);
1401 title = 0;
1402 }
1403
1404 /*
1405 * Print the capabilities data.
1406 *
1407 * Note that CA_SUNW_PLAT, CA_SUNW_MACH and CA_SUNW_ID
1408 * entries require a string table, which should have
1409 * already been established.
1410 */
1411 if ((strs == NULL) && ((cap->c_tag == CA_SUNW_PLAT) ||
1412 (cap->c_tag == CA_SUNW_MACH) ||
1413 (cap->c_tag == CA_SUNW_ID))) {
1414 (void) fprintf(stderr,
1415 MSG_INTL(MSG_WARN_INVCAP4), file,
1416 EC_WORD(elf_ndxscn(ccache->c_scn)),
1417 ccache->c_name, EC_WORD(cshdr->sh_info));
1418 }
1419 Elf_cap_entry(0, cap, cnum, strs, strs_size,
1420 ehdr->e_machine);
1421 }
1422
1423 /*
1424 * If this CA_SUNW_NULL tag terminates a symbol capabilities
1425 * group, determine the associated symbols.
1426 */
1427 if ((cap->c_tag == CA_SUNW_NULL) && (nulls > 1) &&
1428 (descapndx != -1)) {
1429 Capinfo *cip;
1430 Word inum;
1431
1432 symcaps++;
1433
1434 /*
1435 * Make sure we've discovered a SHT_SUNW_capinfo table.
1436 */
1437 if ((cip = capinfo) == NULL) {
1438 (void) fprintf(stderr,
1439 MSG_INTL(MSG_ERR_INVCAP), file,
1440 ccache->c_name, EC_WORD(cshdr->sh_link));
1441 return (0);
1442 }
1443
1444 /*
1445 * Determine what symbols reference this capabilities
1446 * group.
1447 */
1448 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1449 dbg_print(0, MSG_INTL(MSG_CAPINFO_ENTRIES));
1450 Elf_syms_table_title(0, ELF_DBG_ELFDUMP);
1451
1452 for (inum = 1, cip++; inum < capinfonum;
1453 inum++, cip++) {
1454 Word gndx = (Word)ELF_C_GROUP(*cip);
1455
1456 if (gndx && (gndx == descapndx)) {
1457 output_symbol(&state, inum, 0,
1458 inum, state.sym + inum);
1459 }
1460 }
1461 descapndx = -1;
1462 continue;
1463 }
1464
1465 /*
1466 * An SF1_SUNW_ADDR32 software capability tag in a 32-bit
1467 * object is suspicious as it has no effect.
1468 */
1469 if ((cap->c_tag == CA_SUNW_SF_1) &&
1470 (ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
1471 (cap->c_un.c_val & SF1_SUNW_ADDR32)) {
1472 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INADDR32SF1),
1473 file, ccache->c_name);
1474 }
1475 }
1476
1477 /*
1478 * If this is a dynamic object, with symbol capabilities, then a
1479 * .SUNW_capchain section should exist. This section contains a chain
1480 * of symbol indexes for each capabilities family. This is the list
1481 * that is searched by ld.so.1 to determine the best capabilities
1482 * candidate.
1483 *
1484 * Note, more than one capabilities lead symbol can point to the same
1485 * family chain. For example, a weak/global pair of symbols can both
1486 * represent the same family of capabilities symbols. Therefore, to
1487 * display all possible families we traverse the capabilities
1488 * information section looking for CAPINFO_SUNW_GLOB lead symbols.
1489 * From these we determine the associated capabilities chain to inspect.
1490 */
1491 if (symcaps &&
1492 ((ehdr->e_type == ET_EXEC) || (ehdr->e_type == ET_DYN))) {
1493 Capinfo *cip;
1494 Capchain *chain;
1495 Cache *chcache;
1496 Shdr *chshdr;
1497 Word chainnum, inum;
1498
1499 /*
1500 * Validate that the sh_info field of the capabilities
1501 * information section points to a capabilities chain section.
1502 */
1503 if (cishdr->sh_info >= shnum) {
1504 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1505 file, cicache->c_name, EC_WORD(cishdr->sh_info));
1506 return (0);
1507 }
1508
1509 chcache = &cache[cishdr->sh_info];
1510 chshdr = chcache->c_shdr;
1511
1512 if (chshdr->sh_type != SHT_SUNW_capchain) {
1513 (void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAPINFO2),
1514 file, cicache->c_name, EC_WORD(cishdr->sh_info));
1515 return (0);
1516 }
1517
1518 chainnum = (Word)(chshdr->sh_size / chshdr->sh_entsize);
1519 chain = (Capchain *)chcache->c_data->d_buf;
1520
1521 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1522 dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAPCHAIN), chcache->c_name);
1523
1524 /*
1525 * Traverse the capabilities information section looking for
1526 * CAPINFO_SUNW_GLOB lead capabilities symbols.
1527 */
1528 cip = capinfo;
1529 for (inum = 1, cip++; inum < capinfonum; inum++, cip++) {
1530 const char *name;
1531 Sym *sym;
1532 Word sndx, cndx;
1533 Word gndx = (Word)ELF_C_GROUP(*cip);
1534
1535 if ((gndx == 0) || (gndx != CAPINFO_SUNW_GLOB))
1536 continue;
1537
1538 /*
1539 * Determine the symbol that is associated with this
1540 * capability information entry, and use this to
1541 * identify this capability family.
1542 */
1543 sym = (Sym *)(state.sym + inum);
1544 name = string(cicache, inum, strcache, file,
1545 sym->st_name);
1546
1547 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1548 dbg_print(0, MSG_INTL(MSG_CAPCHAIN_TITLE), name);
1549 dbg_print(0, MSG_INTL(MSG_CAPCHAIN_ENTRY));
1550
1551 cndx = (Word)ELF_C_SYM(*cip);
1552
1553 /*
1554 * Traverse this families chain and identify each
1555 * family member.
1556 */
1557 for (;;) {
1558 char _chain[MAXNDXSIZE], _symndx[MAXNDXSIZE];
1559
1560 if (cndx >= chainnum) {
1561 (void) fprintf(stderr,
1562 MSG_INTL(MSG_ERR_INVCAPINFO3), file,
1563 cicache->c_name, EC_WORD(inum),
1564 EC_WORD(cndx));
1565 break;
1566 }
1567 if ((sndx = chain[cndx]) == 0)
1568 break;
1569
1570 /*
1571 * Determine this entries symbol reference.
1572 */
1573 if (sndx > state.symn) {
1574 (void) fprintf(stderr,
1575 MSG_INTL(MSG_ERR_CHBADSYMNDX), file,
1576 EC_WORD(sndx), chcache->c_name,
1577 EC_WORD(cndx));
1578 name = MSG_INTL(MSG_STR_UNKNOWN);
1579 } else {
1580 sym = (Sym *)(state.sym + sndx);
1581 name = string(chcache, sndx,
1582 strcache, file, sym->st_name);
1583 }
1584
1585 /*
1586 * Display the family member.
1587 */
1588 (void) snprintf(_chain, MAXNDXSIZE,
1589 MSG_ORIG(MSG_FMT_INTEGER), cndx);
1590 (void) snprintf(_symndx, MAXNDXSIZE,
1591 MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(sndx));
1592 dbg_print(0, MSG_ORIG(MSG_FMT_CHAIN_INFO),
1593 _chain, _symndx, demangle(name, flags));
1594
1595 cndx++;
1596 }
1597 }
1598 }
1599 return (objcap);
1600 }
1601
1602 /*
1603 * Print the capabilities.
1604 *
1605 * A .SUNW_cap section can contain one or more, CA_SUNW_NULL terminated,
1606 * capabilities groups. The first group defines the object capabilities.
1607 * This group defines the minimum capability requirements of the entire
1608 * object file. If this is a dynamic object, this group should be associated
1609 * with a PT_SUNWCAP program header.
1610 *
1611 * Additional capabilities groups define the association of individual symbols
1612 * to specific capabilities.
1613 */
1614 static void
cap(const char * file,Cache * cache,Word shnum,Word phnum,Ehdr * ehdr,uchar_t osabi,Elf * elf,uint_t flags)1615 cap(const char *file, Cache *cache, Word shnum, Word phnum, Ehdr *ehdr,
1616 uchar_t osabi, Elf *elf, uint_t flags)
1617 {
1618 Word cnt;
1619 Shdr *cshdr = NULL;
1620 Cache *ccache;
1621 Off cphdr_off = 0;
1622 Xword cphdr_sz;
1623
1624 /*
1625 * Determine if a global capabilities header exists.
1626 */
1627 if (phnum) {
1628 Phdr *phdr;
1629
1630 if ((phdr = elf_getphdr(elf)) == NULL) {
1631 failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
1632 return;
1633 }
1634
1635 for (cnt = 0; cnt < phnum; phdr++, cnt++) {
1636 if (phdr->p_type == PT_SUNWCAP) {
1637 cphdr_off = phdr->p_offset;
1638 cphdr_sz = phdr->p_filesz;
1639 break;
1640 }
1641 }
1642 }
1643
1644 /*
1645 * Determine if a capabilities section exists.
1646 */
1647 for (cnt = 1; cnt < shnum; cnt++) {
1648 Cache *_cache = &cache[cnt];
1649 Shdr *shdr = _cache->c_shdr;
1650
1651 /*
1652 * Process any capabilities information.
1653 */
1654 if (shdr->sh_type == SHT_SUNW_cap) {
1655 if (cap_section(file, cache, shnum, _cache, osabi,
1656 ehdr, flags)) {
1657 /*
1658 * If this section defined an object capability
1659 * group, retain the section information for
1660 * program header validation.
1661 */
1662 ccache = _cache;
1663 cshdr = shdr;
1664 }
1665 continue;
1666 }
1667 }
1668
1669 if ((cshdr == NULL) && (cphdr_off == 0))
1670 return;
1671
1672 if (cphdr_off && (cshdr == NULL))
1673 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP1), file);
1674
1675 /*
1676 * If this object is an executable or shared object, and it provided
1677 * an object capabilities group, then the group should have an
1678 * accompanying PT_SUNWCAP program header.
1679 */
1680 if (cshdr && ((ehdr->e_type == ET_EXEC) || (ehdr->e_type == ET_DYN))) {
1681 if (cphdr_off == 0) {
1682 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP2),
1683 file, EC_WORD(elf_ndxscn(ccache->c_scn)),
1684 ccache->c_name);
1685 } else if ((cphdr_off != cshdr->sh_offset) ||
1686 (cphdr_sz != cshdr->sh_size)) {
1687 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP3),
1688 file, EC_WORD(elf_ndxscn(ccache->c_scn)),
1689 ccache->c_name);
1690 }
1691 }
1692 }
1693
1694 /*
1695 * Print the interpretor.
1696 */
1697 static void
interp(const char * file,Cache * cache,Word shnum,Word phnum,Elf * elf)1698 interp(const char *file, Cache *cache, Word shnum, Word phnum, Elf *elf)
1699 {
1700 static Word phdr_types[] = { PT_INTERP };
1701
1702
1703 Word cnt;
1704 Shdr *ishdr = NULL;
1705 Cache *icache;
1706 Off iphdr_off = 0;
1707 Xword iphdr_fsz;
1708
1709 /*
1710 * Determine if an interp header exists.
1711 */
1712 if (phnum) {
1713 Phdr *phdr;
1714
1715 phdr = getphdr(phnum, phdr_types,
1716 sizeof (phdr_types) / sizeof (*phdr_types), file, elf);
1717 if (phdr != NULL) {
1718 iphdr_off = phdr->p_offset;
1719 iphdr_fsz = phdr->p_filesz;
1720 }
1721 }
1722
1723 if (iphdr_off == 0)
1724 return;
1725
1726 /*
1727 * Determine if an interp section exists.
1728 */
1729 for (cnt = 1; cnt < shnum; cnt++) {
1730 Cache *_cache = &cache[cnt];
1731 Shdr *shdr = _cache->c_shdr;
1732
1733 /*
1734 * Scan sections to find a section which contains the PT_INTERP
1735 * string. The target section can't be in a NOBITS section.
1736 */
1737 if ((shdr->sh_type == SHT_NOBITS) ||
1738 (iphdr_off < shdr->sh_offset) ||
1739 (iphdr_off + iphdr_fsz) > (shdr->sh_offset + shdr->sh_size))
1740 continue;
1741
1742 icache = _cache;
1743 ishdr = shdr;
1744 break;
1745 }
1746
1747 /*
1748 * Print the interpreter string based on the offset defined in the
1749 * program header, as this is the offset used by the kernel.
1750 */
1751 if (ishdr && icache->c_data) {
1752 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1753 dbg_print(0, MSG_INTL(MSG_ELF_SCN_INTERP), icache->c_name);
1754 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT),
1755 (char *)icache->c_data->d_buf +
1756 (iphdr_off - ishdr->sh_offset));
1757 } else
1758 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP1), file);
1759
1760 /*
1761 * If there are any inconsistences between the program header and
1762 * section information, flag them.
1763 */
1764 if (ishdr && ((iphdr_off != ishdr->sh_offset) ||
1765 (iphdr_fsz != ishdr->sh_size))) {
1766 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP2), file,
1767 icache->c_name);
1768 }
1769 }
1770
1771 /*
1772 * Print the syminfo section.
1773 */
1774 static void
syminfo(Cache * cache,Word shnum,Ehdr * ehdr,uchar_t osabi,const char * file)1775 syminfo(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi, const char *file)
1776 {
1777 Shdr *infoshdr;
1778 Syminfo *info;
1779 Sym *syms;
1780 Dyn *dyns;
1781 Word infonum, cnt, ndx, symnum, dynnum;
1782 Cache *infocache = NULL, *dyncache = NULL, *symsec, *strsec;
1783 Boolean *dynerr;
1784
1785 for (cnt = 1; cnt < shnum; cnt++) {
1786 if (cache[cnt].c_shdr->sh_type == SHT_SUNW_syminfo) {
1787 infocache = &cache[cnt];
1788 break;
1789 }
1790 }
1791 if (infocache == NULL)
1792 return;
1793
1794 infoshdr = infocache->c_shdr;
1795 if ((infoshdr->sh_entsize == 0) || (infoshdr->sh_size == 0)) {
1796 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
1797 file, infocache->c_name);
1798 return;
1799 }
1800 if (infocache->c_data == NULL)
1801 return;
1802
1803 infonum = (Word)(infoshdr->sh_size / infoshdr->sh_entsize);
1804 info = (Syminfo *)infocache->c_data->d_buf;
1805
1806 /*
1807 * If there is no associated dynamic section, determine if one
1808 * is needed, and if so issue a warning. If there is an
1809 * associated dynamic section, validate it and get the data buffer
1810 * for it.
1811 */
1812 dyns = NULL;
1813 dynnum = 0;
1814 if (infoshdr->sh_info == 0) {
1815 Syminfo *_info = info + 1;
1816
1817 for (ndx = 1; ndx < infonum; ndx++, _info++) {
1818 if ((_info->si_flags == 0) && (_info->si_boundto == 0))
1819 continue;
1820
1821 if (_info->si_boundto < SYMINFO_BT_LOWRESERVE)
1822 (void) fprintf(stderr,
1823 MSG_INTL(MSG_ERR_BADSHINFO), file,
1824 infocache->c_name,
1825 EC_WORD(infoshdr->sh_info));
1826 }
1827 } else if ((infoshdr->sh_info >= shnum) ||
1828 (cache[infoshdr->sh_info].c_shdr->sh_type != SHT_DYNAMIC)) {
1829 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO),
1830 file, infocache->c_name, EC_WORD(infoshdr->sh_info));
1831 } else {
1832 dyncache = &cache[infoshdr->sh_info];
1833 if ((dyncache->c_data == NULL) ||
1834 ((dyns = dyncache->c_data->d_buf) == NULL)) {
1835 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
1836 file, dyncache->c_name);
1837 }
1838 if (dyns != NULL) {
1839 dynnum = dyncache->c_shdr->sh_size /
1840 dyncache->c_shdr->sh_entsize;
1841
1842 /*
1843 * We validate the type of dynamic elements referenced
1844 * from the syminfo. This array is used report any
1845 * bad dynamic entries.
1846 */
1847 if ((dynerr = calloc(dynnum, sizeof (*dynerr))) ==
1848 NULL) {
1849 int err = errno;
1850 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
1851 file, strerror(err));
1852 return;
1853 }
1854 }
1855 }
1856
1857 /*
1858 * Get the data buffer for the associated symbol table and string table.
1859 */
1860 if (stringtbl(cache, 1, cnt, shnum, file,
1861 &symnum, &symsec, &strsec) == 0)
1862 return;
1863
1864 syms = symsec->c_data->d_buf;
1865
1866 /*
1867 * Loop through the syminfo entries.
1868 */
1869 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1870 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMINFO), infocache->c_name);
1871 Elf_syminfo_title(0);
1872
1873 for (ndx = 1, info++; ndx < infonum; ndx++, info++) {
1874 Sym *sym;
1875 const char *needed, *name;
1876 Word expect_dt;
1877 Word boundto = info->si_boundto;
1878
1879 if ((info->si_flags == 0) && (boundto == 0))
1880 continue;
1881
1882 sym = &syms[ndx];
1883 name = string(infocache, ndx, strsec, file, sym->st_name);
1884
1885 /* Is si_boundto set to one of the reserved values? */
1886 if (boundto >= SYMINFO_BT_LOWRESERVE) {
1887 Elf_syminfo_entry(0, ndx, info, name, NULL);
1888 continue;
1889 }
1890
1891 /*
1892 * si_boundto is referencing a dynamic section. If we don't
1893 * have one, an error was already issued above, so it suffices
1894 * to display an empty string. If we are out of bounds, then
1895 * report that and then display an empty string.
1896 */
1897 if ((dyns == NULL) || (boundto >= dynnum)) {
1898 if (dyns != NULL)
1899 (void) fprintf(stderr,
1900 MSG_INTL(MSG_ERR_BADSIDYNNDX), file,
1901 infocache->c_ndx, infocache->c_name,
1902 EC_WORD(ndx), EC_WORD(dynnum - 1),
1903 EC_WORD(boundto));
1904 Elf_syminfo_entry(0, ndx, info, name,
1905 MSG_ORIG(MSG_STR_EMPTY));
1906 continue;
1907 }
1908
1909 /*
1910 * The si_boundto reference expects a specific dynamic element
1911 * type at the given index. The dynamic element is always a
1912 * string that gives an object name. The specific type depends
1913 * on the si_flags present. Ensure that we've got the right
1914 * type.
1915 */
1916 if (info->si_flags & SYMINFO_FLG_FILTER)
1917 expect_dt = DT_SUNW_FILTER;
1918 else if (info->si_flags & SYMINFO_FLG_AUXILIARY)
1919 expect_dt = DT_SUNW_AUXILIARY;
1920 else if (info->si_flags & (SYMINFO_FLG_DIRECT |
1921 SYMINFO_FLG_LAZYLOAD | SYMINFO_FLG_DIRECTBIND))
1922 expect_dt = DT_NEEDED;
1923 else
1924 expect_dt = DT_NULL; /* means we ignore the type */
1925
1926 if ((dyns[boundto].d_tag != expect_dt) &&
1927 (expect_dt != DT_NULL)) {
1928 Conv_inv_buf_t buf1, buf2;
1929
1930 /* Only complain about each dynamic element once */
1931 if (!dynerr[boundto]) {
1932 (void) fprintf(stderr,
1933 MSG_INTL(MSG_ERR_BADSIDYNTAG),
1934 file, infocache->c_ndx, infocache->c_name,
1935 EC_WORD(ndx), dyncache->c_ndx,
1936 dyncache->c_name, EC_WORD(boundto),
1937 conv_dyn_tag(expect_dt, osabi,
1938 ehdr->e_machine, CONV_FMT_ALT_CF, &buf1),
1939 conv_dyn_tag(dyns[boundto].d_tag, osabi,
1940 ehdr->e_machine, CONV_FMT_ALT_CF, &buf2));
1941 dynerr[boundto] = TRUE;
1942 }
1943 }
1944
1945 /*
1946 * Whether or not the DT item we're pointing at is
1947 * of the right type, if it's a type we recognize as
1948 * providing a string, go ahead and show it. Otherwise
1949 * an empty string.
1950 */
1951 switch (dyns[boundto].d_tag) {
1952 case DT_NEEDED:
1953 case DT_SONAME:
1954 case DT_RPATH:
1955 case DT_RUNPATH:
1956 case DT_CONFIG:
1957 case DT_DEPAUDIT:
1958 case DT_USED:
1959 case DT_AUDIT:
1960 case DT_SUNW_AUXILIARY:
1961 case DT_SUNW_FILTER:
1962 case DT_FILTER:
1963 case DT_AUXILIARY:
1964 needed = string(infocache, boundto,
1965 strsec, file, dyns[boundto].d_un.d_val);
1966 break;
1967 default:
1968 needed = MSG_ORIG(MSG_STR_EMPTY);
1969 }
1970 Elf_syminfo_entry(0, ndx, info, name, needed);
1971 }
1972 if (dyns != NULL)
1973 free(dynerr);
1974 }
1975
1976 /*
1977 * Print version definition section entries.
1978 */
1979 static void
version_def(Verdef * vdf,Word vdf_num,Cache * vcache,Cache * scache,const char * file)1980 version_def(Verdef *vdf, Word vdf_num, Cache *vcache, Cache *scache,
1981 const char *file)
1982 {
1983 Word cnt;
1984 char index[MAXNDXSIZE];
1985
1986 Elf_ver_def_title(0);
1987
1988 for (cnt = 1; cnt <= vdf_num; cnt++,
1989 vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) {
1990 Conv_ver_flags_buf_t ver_flags_buf;
1991 const char *name, *dep;
1992 Half vcnt = vdf->vd_cnt - 1;
1993 Half ndx = vdf->vd_ndx;
1994 Verdaux *vdap = (Verdaux *)((uintptr_t)vdf + vdf->vd_aux);
1995
1996 /*
1997 * Obtain the name and first dependency (if any).
1998 */
1999 name = string(vcache, cnt, scache, file, vdap->vda_name);
2000 vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
2001 if (vcnt)
2002 dep = string(vcache, cnt, scache, file, vdap->vda_name);
2003 else
2004 dep = MSG_ORIG(MSG_STR_EMPTY);
2005
2006 (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
2007 EC_XWORD(ndx));
2008 Elf_ver_line_1(0, index, name, dep,
2009 conv_ver_flags(vdf->vd_flags, 0, &ver_flags_buf));
2010
2011 /*
2012 * Print any additional dependencies.
2013 */
2014 if (vcnt) {
2015 vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
2016 for (vcnt--; vcnt; vcnt--,
2017 vdap = (Verdaux *)((uintptr_t)vdap +
2018 vdap->vda_next)) {
2019 dep = string(vcache, cnt, scache, file,
2020 vdap->vda_name);
2021 Elf_ver_line_2(0, MSG_ORIG(MSG_STR_EMPTY), dep);
2022 }
2023 }
2024 }
2025 }
2026
2027 /*
2028 * Print version needed section entries.
2029 *
2030 * entry:
2031 * vnd - Address of verneed data
2032 * vnd_num - # of Verneed entries
2033 * vcache - Cache of verneed section being processed
2034 * scache - Cache of associated string table section
2035 * file - Name of object being processed.
2036 * versym - Information about versym section
2037 *
2038 * exit:
2039 * The versions have been printed. If GNU style versioning
2040 * is in effect, versym->max_verndx has been updated to
2041 * contain the largest version index seen.
2042 *
2043 * note:
2044 * The versym section of an object that follows the original
2045 * Solaris versioning rules only contains indexes into the verdef
2046 * section. Symbols defined in other objects (UNDEF) are given
2047 * a version of 0, indicating that they are not defined by
2048 * this file, and the Verneed entries do not have associated version
2049 * indexes. For these reasons, we do not display a version index
2050 * for original-style Verneed sections.
2051 *
2052 * The GNU versioning extensions alter this: Symbols defined in other
2053 * objects receive a version index in the range above those defined
2054 * by the Verdef section, and the vna_other field of the Vernaux
2055 * structs inside the Verneed section contain the version index for
2056 * that item. We therefore display the index when showing the
2057 * contents of a GNU style Verneed section. You should not
2058 * necessarily expect these indexes to appear in sorted
2059 * order --- it seems that the GNU ld assigns the versions as
2060 * symbols are encountered during linking, and then the results
2061 * are assembled into the Verneed section afterwards.
2062 */
2063 static void
version_need(Verneed * vnd,Word vnd_num,Cache * vcache,Cache * scache,const char * file,VERSYM_STATE * versym)2064 version_need(Verneed *vnd, Word vnd_num, Cache *vcache, Cache *scache,
2065 const char *file, VERSYM_STATE *versym)
2066 {
2067 Word cnt;
2068 char index[MAXNDXSIZE];
2069 const char *index_str;
2070
2071 Elf_ver_need_title(0, versym->gnu_needed);
2072
2073 for (cnt = 1; cnt <= vnd_num; cnt++,
2074 vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
2075 Conv_ver_flags_buf_t ver_flags_buf;
2076 const char *name, *dep;
2077 Half vcnt = vnd->vn_cnt;
2078 Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux);
2079
2080 /*
2081 * Obtain the name of the needed file and the version name
2082 * within it that we're dependent on. Note that the count
2083 * should be at least one, otherwise this is a pretty bogus
2084 * entry.
2085 */
2086 name = string(vcache, cnt, scache, file, vnd->vn_file);
2087 if (vcnt)
2088 dep = string(vcache, cnt, scache, file, vnap->vna_name);
2089 else
2090 dep = MSG_INTL(MSG_STR_NULL);
2091
2092 if (vnap->vna_other == 0) { /* Traditional form */
2093 index_str = MSG_ORIG(MSG_STR_EMPTY);
2094 } else { /* GNU form */
2095 index_str = index;
2096 /* Format the version index value */
2097 (void) snprintf(index, MAXNDXSIZE,
2098 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(vnap->vna_other));
2099 if (vnap->vna_other > versym->max_verndx)
2100 versym->max_verndx = vnap->vna_other;
2101 }
2102 Elf_ver_line_1(0, index_str, name, dep,
2103 conv_ver_flags(vnap->vna_flags, 0, &ver_flags_buf));
2104
2105 /*
2106 * Print any additional version dependencies.
2107 */
2108 if (vcnt) {
2109 vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next);
2110 for (vcnt--; vcnt; vcnt--,
2111 vnap = (Vernaux *)((uintptr_t)vnap +
2112 vnap->vna_next)) {
2113 dep = string(vcache, cnt, scache, file,
2114 vnap->vna_name);
2115 if (vnap->vna_other > 0) {
2116 /* Format the next index value */
2117 (void) snprintf(index, MAXNDXSIZE,
2118 MSG_ORIG(MSG_FMT_INDEX),
2119 EC_XWORD(vnap->vna_other));
2120 Elf_ver_line_1(0, index,
2121 MSG_ORIG(MSG_STR_EMPTY), dep,
2122 conv_ver_flags(vnap->vna_flags,
2123 0, &ver_flags_buf));
2124 if (vnap->vna_other >
2125 versym->max_verndx)
2126 versym->max_verndx =
2127 vnap->vna_other;
2128 } else {
2129 Elf_ver_line_3(0,
2130 MSG_ORIG(MSG_STR_EMPTY), dep,
2131 conv_ver_flags(vnap->vna_flags,
2132 0, &ver_flags_buf));
2133 }
2134 }
2135 }
2136 }
2137 }
2138
2139 /*
2140 * Examine the Verneed section for information related to GNU
2141 * style Versym indexing:
2142 * - A non-zero vna_other field indicates that Versym indexes can
2143 * reference Verneed records.
2144 * - If the object uses GNU style Versym indexing, the
2145 * maximum index value is needed to detect bad Versym entries.
2146 *
2147 * entry:
2148 * vnd - Address of verneed data
2149 * vnd_num - # of Verneed entries
2150 * versym - Information about versym section
2151 *
2152 * exit:
2153 * If a non-zero vna_other field is seen, versym->gnu_needed is set.
2154 *
2155 * versym->max_verndx has been updated to contain the largest
2156 * version index seen.
2157 */
2158 static void
update_gnu_verndx(Verneed * vnd,Word vnd_num,VERSYM_STATE * versym)2159 update_gnu_verndx(Verneed *vnd, Word vnd_num, VERSYM_STATE *versym)
2160 {
2161 Word cnt;
2162
2163 for (cnt = 1; cnt <= vnd_num; cnt++,
2164 vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
2165 Half vcnt = vnd->vn_cnt;
2166 Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux);
2167
2168 /*
2169 * A non-zero value of vna_other indicates that this
2170 * object references VERNEED items from the VERSYM
2171 * array.
2172 */
2173 if (vnap->vna_other != 0) {
2174 versym->gnu_needed = 1;
2175 if (vnap->vna_other > versym->max_verndx)
2176 versym->max_verndx = vnap->vna_other;
2177 }
2178
2179 /*
2180 * Check any additional version dependencies.
2181 */
2182 if (vcnt) {
2183 vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next);
2184 for (vcnt--; vcnt; vcnt--,
2185 vnap = (Vernaux *)((uintptr_t)vnap +
2186 vnap->vna_next)) {
2187 if (vnap->vna_other == 0)
2188 continue;
2189
2190 versym->gnu_needed = 1;
2191 if (vnap->vna_other > versym->max_verndx)
2192 versym->max_verndx = vnap->vna_other;
2193 }
2194 }
2195 }
2196 }
2197
2198 /*
2199 * Display version section information if the flags require it.
2200 * Return version information needed by other output.
2201 *
2202 * entry:
2203 * cache - Cache of all section headers
2204 * shnum - # of sections in cache
2205 * file - Name of file
2206 * flags - Command line option flags
2207 * versym - VERSYM_STATE block to be filled in.
2208 */
2209 static void
versions(Cache * cache,Word shnum,const char * file,uint_t flags,VERSYM_STATE * versym)2210 versions(Cache *cache, Word shnum, const char *file, uint_t flags,
2211 VERSYM_STATE *versym)
2212 {
2213 GElf_Word cnt;
2214 Cache *verdef_cache = NULL, *verneed_cache = NULL;
2215
2216
2217 /* Gather information about the version sections */
2218 bzero(versym, sizeof (*versym));
2219 versym->max_verndx = 1;
2220 for (cnt = 1; cnt < shnum; cnt++) {
2221 Cache *_cache = &cache[cnt];
2222 Shdr *shdr = _cache->c_shdr;
2223 Dyn *dyn;
2224 ulong_t numdyn;
2225
2226 switch (shdr->sh_type) {
2227 case SHT_DYNAMIC:
2228 /*
2229 * The GNU ld puts a DT_VERSYM entry in the dynamic
2230 * section so that the runtime linker can use it to
2231 * implement their versioning rules. They allow multiple
2232 * incompatible functions with the same name to exist
2233 * in different versions. The Solaris ld does not
2234 * support this mechanism, and as such, does not
2235 * produce DT_VERSYM. We use this fact to determine
2236 * which ld produced this object, and how to interpret
2237 * the version values.
2238 */
2239 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0) ||
2240 (_cache->c_data == NULL))
2241 continue;
2242 numdyn = shdr->sh_size / shdr->sh_entsize;
2243 dyn = (Dyn *)_cache->c_data->d_buf;
2244 for (; numdyn-- > 0; dyn++)
2245 if (dyn->d_tag == DT_VERSYM) {
2246 versym->gnu_full =
2247 versym->gnu_needed = 1;
2248 break;
2249 }
2250 break;
2251
2252 case SHT_SUNW_versym:
2253 /* Record data address for later symbol processing */
2254 if (_cache->c_data != NULL) {
2255 versym->cache = _cache;
2256 versym->data = _cache->c_data->d_buf;
2257 continue;
2258 }
2259 break;
2260
2261 case SHT_SUNW_verdef:
2262 case SHT_SUNW_verneed:
2263 /*
2264 * Ensure the data is non-NULL and the number
2265 * of items is non-zero. Otherwise, we don't
2266 * understand the section, and will not use it.
2267 */
2268 if ((_cache->c_data == NULL) ||
2269 (_cache->c_data->d_buf == NULL)) {
2270 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
2271 file, _cache->c_name);
2272 continue;
2273 }
2274 if (shdr->sh_info == 0) {
2275 (void) fprintf(stderr,
2276 MSG_INTL(MSG_ERR_BADSHINFO),
2277 file, _cache->c_name,
2278 EC_WORD(shdr->sh_info));
2279 continue;
2280 }
2281
2282 /* Make sure the string table index is in range */
2283 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
2284 (void) fprintf(stderr,
2285 MSG_INTL(MSG_ERR_BADSHLINK), file,
2286 _cache->c_name, EC_WORD(shdr->sh_link));
2287 continue;
2288 }
2289
2290 /*
2291 * The section is usable. Save the cache entry.
2292 */
2293 if (shdr->sh_type == SHT_SUNW_verdef) {
2294 verdef_cache = _cache;
2295 /*
2296 * Under Solaris rules, if there is a verdef
2297 * section, the max versym index is number
2298 * of version definitions it supplies.
2299 */
2300 versym->max_verndx = shdr->sh_info;
2301 } else {
2302 verneed_cache = _cache;
2303 }
2304 break;
2305 }
2306 }
2307
2308 /*
2309 * If there is a Verneed section, examine it for information
2310 * related to GNU style versioning.
2311 */
2312 if (verneed_cache != NULL)
2313 update_gnu_verndx((Verneed *)verneed_cache->c_data->d_buf,
2314 verneed_cache->c_shdr->sh_info, versym);
2315
2316 /*
2317 * Now that all the information is available, display the
2318 * Verdef and Verneed section contents, if requested.
2319 */
2320 if ((flags & FLG_SHOW_VERSIONS) == 0)
2321 return;
2322 if (verdef_cache != NULL) {
2323 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2324 dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERDEF),
2325 verdef_cache->c_name);
2326 version_def((Verdef *)verdef_cache->c_data->d_buf,
2327 verdef_cache->c_shdr->sh_info, verdef_cache,
2328 &cache[verdef_cache->c_shdr->sh_link], file);
2329 }
2330 if (verneed_cache != NULL) {
2331 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2332 dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERNEED),
2333 verneed_cache->c_name);
2334 /*
2335 * If GNU versioning applies to this object, version_need()
2336 * will update versym->max_verndx, and it is not
2337 * necessary to call update_gnu_verndx().
2338 */
2339 version_need((Verneed *)verneed_cache->c_data->d_buf,
2340 verneed_cache->c_shdr->sh_info, verneed_cache,
2341 &cache[verneed_cache->c_shdr->sh_link], file, versym);
2342 }
2343 }
2344
2345 /*
2346 * Search for and process any symbol tables.
2347 */
2348 void
symbols(Cache * cache,Word shnum,Ehdr * ehdr,uchar_t osabi,VERSYM_STATE * versym,const char * file,uint_t flags)2349 symbols(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi,
2350 VERSYM_STATE *versym, const char *file, uint_t flags)
2351 {
2352 SYMTBL_STATE state;
2353 Cache *_cache;
2354 Word secndx;
2355
2356 for (secndx = 1; secndx < shnum; secndx++) {
2357 Word symcnt;
2358 Shdr *shdr;
2359
2360 _cache = &cache[secndx];
2361 shdr = _cache->c_shdr;
2362
2363 if ((shdr->sh_type != SHT_SYMTAB) &&
2364 (shdr->sh_type != SHT_DYNSYM) &&
2365 ((shdr->sh_type != SHT_SUNW_LDYNSYM) ||
2366 (osabi != ELFOSABI_SOLARIS)))
2367 continue;
2368 if (!match(MATCH_F_ALL, _cache->c_name, secndx, shdr->sh_type))
2369 continue;
2370
2371 if (!init_symtbl_state(&state, cache, shnum, secndx, ehdr,
2372 osabi, versym, file, flags))
2373 continue;
2374 /*
2375 * Loop through the symbol tables entries.
2376 */
2377 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2378 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMTAB), state.secname);
2379 Elf_syms_table_title(0, ELF_DBG_ELFDUMP);
2380
2381 for (symcnt = 0; symcnt < state.symn; symcnt++)
2382 output_symbol(&state, symcnt, shdr->sh_info, symcnt,
2383 state.sym + symcnt);
2384 }
2385 }
2386
2387 /*
2388 * Search for and process any SHT_SUNW_symsort or SHT_SUNW_tlssort sections.
2389 * These sections are always associated with the .SUNW_ldynsym./.dynsym pair.
2390 */
2391 static void
sunw_sort(Cache * cache,Word shnum,Ehdr * ehdr,uchar_t osabi,VERSYM_STATE * versym,const char * file,uint_t flags)2392 sunw_sort(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi,
2393 VERSYM_STATE *versym, const char *file, uint_t flags)
2394 {
2395 SYMTBL_STATE ldynsym_state, dynsym_state;
2396 Cache *sortcache, *symcache;
2397 Shdr *sortshdr, *symshdr;
2398 Word sortsecndx, symsecndx;
2399 Word ldynsym_cnt;
2400 Word *ndx;
2401 Word ndxn;
2402 int output_cnt = 0;
2403 Conv_inv_buf_t inv_buf;
2404
2405 for (sortsecndx = 1; sortsecndx < shnum; sortsecndx++) {
2406
2407 sortcache = &cache[sortsecndx];
2408 sortshdr = sortcache->c_shdr;
2409
2410 if ((sortshdr->sh_type != SHT_SUNW_symsort) &&
2411 (sortshdr->sh_type != SHT_SUNW_tlssort))
2412 continue;
2413 if (!match(MATCH_F_ALL, sortcache->c_name, sortsecndx,
2414 sortshdr->sh_type))
2415 continue;
2416
2417 /*
2418 * If the section references a SUNW_ldynsym, then we
2419 * expect to see the associated .dynsym immediately
2420 * following. If it references a .dynsym, there is no
2421 * SUNW_ldynsym. If it is any other type, then we don't
2422 * know what to do with it.
2423 */
2424 if ((sortshdr->sh_link == 0) || (sortshdr->sh_link >= shnum)) {
2425 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
2426 file, sortcache->c_name,
2427 EC_WORD(sortshdr->sh_link));
2428 continue;
2429 }
2430 symcache = &cache[sortshdr->sh_link];
2431 symshdr = symcache->c_shdr;
2432 symsecndx = sortshdr->sh_link;
2433 ldynsym_cnt = 0;
2434 switch (symshdr->sh_type) {
2435 case SHT_SUNW_LDYNSYM:
2436 if (!init_symtbl_state(&ldynsym_state, cache, shnum,
2437 symsecndx, ehdr, osabi, versym, file, flags))
2438 continue;
2439 ldynsym_cnt = ldynsym_state.symn;
2440 /*
2441 * We know that the dynsym follows immediately
2442 * after the SUNW_ldynsym, and so, should be at
2443 * (sortshdr->sh_link + 1). However, elfdump is a
2444 * diagnostic tool, so we do the full paranoid
2445 * search instead.
2446 */
2447 for (symsecndx = 1; symsecndx < shnum; symsecndx++) {
2448 symcache = &cache[symsecndx];
2449 symshdr = symcache->c_shdr;
2450 if (symshdr->sh_type == SHT_DYNSYM)
2451 break;
2452 }
2453 if (symsecndx >= shnum) { /* Dynsym not found! */
2454 (void) fprintf(stderr,
2455 MSG_INTL(MSG_ERR_NODYNSYM),
2456 file, sortcache->c_name);
2457 continue;
2458 }
2459 /* Fallthrough to process associated dynsym */
2460 /* FALLTHROUGH */
2461 case SHT_DYNSYM:
2462 if (!init_symtbl_state(&dynsym_state, cache, shnum,
2463 symsecndx, ehdr, osabi, versym, file, flags))
2464 continue;
2465 break;
2466 default:
2467 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADNDXSEC),
2468 file, sortcache->c_name,
2469 conv_sec_type(osabi, ehdr->e_machine,
2470 symshdr->sh_type, 0, &inv_buf));
2471 continue;
2472 }
2473
2474 /*
2475 * Output header
2476 */
2477 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2478 if (ldynsym_cnt > 0) {
2479 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMSORT2),
2480 sortcache->c_name, ldynsym_state.secname,
2481 dynsym_state.secname);
2482 /*
2483 * The data for .SUNW_ldynsym and dynsym sections
2484 * is supposed to be adjacent with SUNW_ldynsym coming
2485 * first. Check, and issue a warning if it isn't so.
2486 */
2487 if (((ldynsym_state.sym + ldynsym_state.symn)
2488 != dynsym_state.sym) &&
2489 ((flags & FLG_CTL_FAKESHDR) == 0))
2490 (void) fprintf(stderr,
2491 MSG_INTL(MSG_ERR_LDYNNOTADJ), file,
2492 ldynsym_state.secname,
2493 dynsym_state.secname);
2494 } else {
2495 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMSORT1),
2496 sortcache->c_name, dynsym_state.secname);
2497 }
2498 Elf_syms_table_title(0, ELF_DBG_ELFDUMP);
2499
2500 /* If not first one, insert a line of white space */
2501 if (output_cnt++ > 0)
2502 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2503
2504 /*
2505 * SUNW_dynsymsort and SUNW_dyntlssort are arrays of
2506 * symbol indices. Iterate over the array entries,
2507 * dispaying the referenced symbols.
2508 */
2509 ndxn = sortshdr->sh_size / sortshdr->sh_entsize;
2510 ndx = (Word *)sortcache->c_data->d_buf;
2511 for (; ndxn-- > 0; ndx++) {
2512 if (*ndx >= ldynsym_cnt) {
2513 Word sec_ndx = *ndx - ldynsym_cnt;
2514
2515 output_symbol(&dynsym_state, sec_ndx, 0,
2516 *ndx, dynsym_state.sym + sec_ndx);
2517 } else {
2518 output_symbol(&ldynsym_state, *ndx, 0,
2519 *ndx, ldynsym_state.sym + *ndx);
2520 }
2521 }
2522 }
2523 }
2524
2525 /*
2526 * Search for and process any relocation sections.
2527 */
2528 static void
reloc(Cache * cache,Word shnum,Ehdr * ehdr,const char * file)2529 reloc(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
2530 {
2531 Word cnt;
2532
2533 for (cnt = 1; cnt < shnum; cnt++) {
2534 Word type, symnum;
2535 Xword relndx, relnum, relsize;
2536 void *rels;
2537 Sym *syms;
2538 Cache *symsec, *strsec;
2539 Cache *_cache = &cache[cnt];
2540 Shdr *shdr = _cache->c_shdr;
2541 char *relname = _cache->c_name;
2542 Conv_inv_buf_t inv_buf;
2543
2544 if (((type = shdr->sh_type) != SHT_RELA) &&
2545 (type != SHT_REL))
2546 continue;
2547 if (!match(MATCH_F_ALL, relname, cnt, type))
2548 continue;
2549
2550 /*
2551 * Decide entry size.
2552 */
2553 if (((relsize = shdr->sh_entsize) == 0) ||
2554 (relsize > shdr->sh_size)) {
2555 if (type == SHT_RELA)
2556 relsize = sizeof (Rela);
2557 else
2558 relsize = sizeof (Rel);
2559 }
2560
2561 /*
2562 * Determine the number of relocations available.
2563 */
2564 if (shdr->sh_size == 0) {
2565 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
2566 file, relname);
2567 continue;
2568 }
2569 if (_cache->c_data == NULL)
2570 continue;
2571
2572 rels = _cache->c_data->d_buf;
2573 relnum = shdr->sh_size / relsize;
2574
2575 /*
2576 * Get the data buffer for the associated symbol table and
2577 * string table.
2578 */
2579 if (stringtbl(cache, 1, cnt, shnum, file,
2580 &symnum, &symsec, &strsec) == 0)
2581 continue;
2582
2583 syms = symsec->c_data->d_buf;
2584
2585 /*
2586 * Loop through the relocation entries.
2587 */
2588 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2589 dbg_print(0, MSG_INTL(MSG_ELF_SCN_RELOC), _cache->c_name);
2590 Elf_reloc_title(0, ELF_DBG_ELFDUMP, type);
2591
2592 for (relndx = 0; relndx < relnum; relndx++,
2593 rels = (void *)((char *)rels + relsize)) {
2594 Half mach = ehdr->e_machine;
2595 char section[BUFSIZ];
2596 const char *symname;
2597 Word symndx, reltype;
2598 Rela *rela;
2599 Rel *rel;
2600
2601 /*
2602 * Unravel the relocation and determine the symbol with
2603 * which this relocation is associated.
2604 */
2605 if (type == SHT_RELA) {
2606 rela = (Rela *)rels;
2607 symndx = ELF_R_SYM(rela->r_info);
2608 reltype = ELF_R_TYPE(rela->r_info, mach);
2609 } else {
2610 rel = (Rel *)rels;
2611 symndx = ELF_R_SYM(rel->r_info);
2612 reltype = ELF_R_TYPE(rel->r_info, mach);
2613 }
2614
2615 symname = relsymname(cache, _cache, strsec, symndx,
2616 symnum, relndx, syms, section, BUFSIZ, file);
2617
2618 /*
2619 * A zero symbol index is only valid for a few
2620 * relocations.
2621 */
2622 if (symndx == 0) {
2623 int badrel = 0;
2624
2625 if ((mach == EM_SPARC) ||
2626 (mach == EM_SPARC32PLUS) ||
2627 (mach == EM_SPARCV9)) {
2628 if ((reltype != R_SPARC_NONE) &&
2629 (reltype != R_SPARC_REGISTER) &&
2630 (reltype != R_SPARC_RELATIVE))
2631 badrel++;
2632 } else if (mach == EM_386) {
2633 if ((reltype != R_386_NONE) &&
2634 (reltype != R_386_RELATIVE))
2635 badrel++;
2636 } else if (mach == EM_AMD64) {
2637 if ((reltype != R_AMD64_NONE) &&
2638 (reltype != R_AMD64_RELATIVE))
2639 badrel++;
2640 }
2641
2642 if (badrel) {
2643 (void) fprintf(stderr,
2644 MSG_INTL(MSG_ERR_BADREL1), file,
2645 conv_reloc_type(mach, reltype,
2646 0, &inv_buf));
2647 }
2648 }
2649
2650 Elf_reloc_entry_1(0, ELF_DBG_ELFDUMP,
2651 MSG_ORIG(MSG_STR_EMPTY), ehdr->e_machine, type,
2652 rels, relname, symname, 0);
2653 }
2654 }
2655 }
2656
2657
2658 /*
2659 * This value controls which test dyn_test() performs.
2660 */
2661 typedef enum { DYN_TEST_ADDR, DYN_TEST_SIZE, DYN_TEST_ENTSIZE } dyn_test_t;
2662
2663 /*
2664 * Used by dynamic() to compare the value of a dynamic element against
2665 * the starting address of the section it references.
2666 *
2667 * entry:
2668 * test_type - Specify which dyn item is being tested.
2669 * sh_type - SHT_* type value for required section.
2670 * sec_cache - Cache entry for section, or NULL if the object lacks
2671 * a section of this type.
2672 * dyn - Dyn entry to be tested
2673 * dynsec_cnt - # of dynamic section being examined. The first
2674 * dynamic section is 1, the next is 2, and so on...
2675 * ehdr - ELF header for file
2676 * file - Name of file
2677 */
2678 static void
dyn_test(dyn_test_t test_type,Word sh_type,Cache * sec_cache,Dyn * dyn,Word dynsec_cnt,Ehdr * ehdr,uchar_t osabi,const char * file)2679 dyn_test(dyn_test_t test_type, Word sh_type, Cache *sec_cache, Dyn *dyn,
2680 Word dynsec_cnt, Ehdr *ehdr, uchar_t osabi, const char *file)
2681 {
2682 Conv_inv_buf_t buf1, buf2;
2683
2684 /*
2685 * These tests are based around the implicit assumption that
2686 * there is only one dynamic section in an object, and also only
2687 * one of the sections it references. We have therefore gathered
2688 * all of the necessary information to test this in a single pass
2689 * over the section headers, which is very efficient. We are not
2690 * aware of any case where more than one dynamic section would
2691 * be meaningful in an ELF object, so this is a reasonable solution.
2692 *
2693 * To test multiple dynamic sections correctly would be more
2694 * expensive in code and time. We would have to build a data structure
2695 * containing all the dynamic elements. Then, we would use the address
2696 * to locate the section it references and ensure the section is of
2697 * the right type and that the address in the dynamic element is
2698 * to the start of the section. Then, we could check the size and
2699 * entsize values against those same sections. This is O(n^2), and
2700 * also complicated.
2701 *
2702 * In the highly unlikely case that there is more than one dynamic
2703 * section, we only test the first one, and simply allow the values
2704 * of the subsequent one to be displayed unchallenged.
2705 */
2706 if (dynsec_cnt != 1)
2707 return;
2708
2709 /*
2710 * A DT_ item that references a section address should always find
2711 * the section in the file.
2712 */
2713 if (sec_cache == NULL) {
2714 const char *name;
2715
2716 /*
2717 * Supply section names instead of section types for
2718 * things that reference progbits so that the error
2719 * message will make more sense.
2720 */
2721 switch (dyn->d_tag) {
2722 case DT_INIT:
2723 name = MSG_ORIG(MSG_ELF_INIT);
2724 break;
2725 case DT_FINI:
2726 name = MSG_ORIG(MSG_ELF_FINI);
2727 break;
2728 default:
2729 name = conv_sec_type(osabi, ehdr->e_machine,
2730 sh_type, 0, &buf1);
2731 break;
2732 }
2733 (void) fprintf(stderr, MSG_INTL(MSG_ERR_DYNNOBCKSEC), file,
2734 name, conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2735 CONV_FMT_ALT_CF, &buf2));
2736 return;
2737 }
2738
2739
2740 switch (test_type) {
2741 case DYN_TEST_ADDR:
2742 /* The section address should match the DT_ item value */
2743 if (dyn->d_un.d_val != sec_cache->c_shdr->sh_addr)
2744 (void) fprintf(stderr,
2745 MSG_INTL(MSG_ERR_DYNBADADDR), file,
2746 conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2747 CONV_FMT_ALT_CF, &buf1), EC_ADDR(dyn->d_un.d_val),
2748 sec_cache->c_ndx, sec_cache->c_name,
2749 EC_ADDR(sec_cache->c_shdr->sh_addr));
2750 break;
2751
2752 case DYN_TEST_SIZE:
2753 /* The section size should match the DT_ item value */
2754 if (dyn->d_un.d_val != sec_cache->c_shdr->sh_size)
2755 (void) fprintf(stderr,
2756 MSG_INTL(MSG_ERR_DYNBADSIZE), file,
2757 conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2758 CONV_FMT_ALT_CF, &buf1), EC_XWORD(dyn->d_un.d_val),
2759 sec_cache->c_ndx, sec_cache->c_name,
2760 EC_XWORD(sec_cache->c_shdr->sh_size));
2761 break;
2762
2763 case DYN_TEST_ENTSIZE:
2764 /* The sh_entsize value should match the DT_ item value */
2765 if (dyn->d_un.d_val != sec_cache->c_shdr->sh_entsize)
2766 (void) fprintf(stderr,
2767 MSG_INTL(MSG_ERR_DYNBADENTSIZE), file,
2768 conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2769 CONV_FMT_ALT_CF, &buf1), EC_XWORD(dyn->d_un.d_val),
2770 sec_cache->c_ndx, sec_cache->c_name,
2771 EC_XWORD(sec_cache->c_shdr->sh_entsize));
2772 break;
2773 }
2774 }
2775
2776 /*
2777 * There are some DT_ entries that have corresponding symbols
2778 * (e.g. DT_INIT and _init). It is expected that these items will
2779 * both have the same value if both are present. This routine
2780 * examines the well known symbol tables for such symbols and
2781 * issues warnings for any that don't match.
2782 *
2783 * entry:
2784 * dyn - Dyn entry to be tested
2785 * symname - Name of symbol that corresponds to dyn
2786 * symtab_cache, dynsym_cache, ldynsym_cache - Symbol tables to check
2787 * target_cache - Section the symname section is expected to be
2788 * associated with.
2789 * cache - Cache of all section headers
2790 * shnum - # of sections in cache
2791 * ehdr - ELF header for file
2792 * osabi - OSABI to apply when interpreting object
2793 * file - Name of file
2794 */
2795 static void
dyn_symtest(Dyn * dyn,const char * symname,Cache * symtab_cache,Cache * dynsym_cache,Cache * ldynsym_cache,Cache * target_cache,Cache * cache,Word shnum,Ehdr * ehdr,uchar_t osabi,const char * file)2796 dyn_symtest(Dyn *dyn, const char *symname, Cache *symtab_cache,
2797 Cache *dynsym_cache, Cache *ldynsym_cache, Cache *target_cache,
2798 Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi, const char *file)
2799 {
2800 Conv_inv_buf_t buf;
2801 int i;
2802 Sym *sym;
2803 Cache *_cache;
2804
2805 for (i = 0; i < 3; i++) {
2806 switch (i) {
2807 case 0:
2808 _cache = symtab_cache;
2809 break;
2810 case 1:
2811 _cache = dynsym_cache;
2812 break;
2813 case 2:
2814 _cache = ldynsym_cache;
2815 break;
2816 }
2817
2818 if ((_cache != NULL) &&
2819 symlookup(symname, cache, shnum, &sym, target_cache,
2820 _cache, file) && (sym->st_value != dyn->d_un.d_val))
2821 (void) fprintf(stderr, MSG_INTL(MSG_ERR_DYNSYMVAL),
2822 file, _cache->c_name, conv_dyn_tag(dyn->d_tag,
2823 osabi, ehdr->e_machine, CONV_FMT_ALT_CF, &buf),
2824 symname, EC_ADDR(sym->st_value));
2825 }
2826 }
2827
2828 /*
2829 * Search for and process a .dynamic section.
2830 */
2831 static void
dynamic(Cache * cache,Word shnum,Ehdr * ehdr,uchar_t osabi,const char * file)2832 dynamic(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi, const char *file)
2833 {
2834 struct {
2835 Cache *symtab;
2836 Cache *dynstr;
2837 Cache *dynsym;
2838 Cache *hash;
2839 Cache *fini;
2840 Cache *fini_array;
2841 Cache *init;
2842 Cache *init_array;
2843 Cache *preinit_array;
2844 Cache *rel;
2845 Cache *rela;
2846 Cache *sunw_cap;
2847 Cache *sunw_capinfo;
2848 Cache *sunw_capchain;
2849 Cache *sunw_ldynsym;
2850 Cache *sunw_move;
2851 Cache *sunw_syminfo;
2852 Cache *sunw_symsort;
2853 Cache *sunw_tlssort;
2854 Cache *sunw_verdef;
2855 Cache *sunw_verneed;
2856 Cache *sunw_versym;
2857 } sec;
2858 Word dynsec_ndx;
2859 Word dynsec_num;
2860 int dynsec_cnt;
2861 Word cnt;
2862 int osabi_solaris = osabi == ELFOSABI_SOLARIS;
2863
2864 /*
2865 * Make a pass over all the sections, gathering section information
2866 * we'll need below.
2867 */
2868 dynsec_num = 0;
2869 bzero(&sec, sizeof (sec));
2870 for (cnt = 1; cnt < shnum; cnt++) {
2871 Cache *_cache = &cache[cnt];
2872
2873 switch (_cache->c_shdr->sh_type) {
2874 case SHT_DYNAMIC:
2875 if (dynsec_num == 0) {
2876 dynsec_ndx = cnt;
2877
2878 /* Does it have a valid string table? */
2879 (void) stringtbl(cache, 0, cnt, shnum, file,
2880 0, 0, &sec.dynstr);
2881 }
2882 dynsec_num++;
2883 break;
2884
2885
2886 case SHT_PROGBITS:
2887 /*
2888 * We want to detect the .init and .fini sections,
2889 * if present. These are SHT_PROGBITS, so all we
2890 * have to go on is the section name. Normally comparing
2891 * names is a bad idea, but there are some special
2892 * names (i.e. .init/.fini/.interp) that are very
2893 * difficult to use in any other context, and for
2894 * these symbols, we do the heuristic match.
2895 */
2896 if (strcmp(_cache->c_name,
2897 MSG_ORIG(MSG_ELF_INIT)) == 0) {
2898 if (sec.init == NULL)
2899 sec.init = _cache;
2900 } else if (strcmp(_cache->c_name,
2901 MSG_ORIG(MSG_ELF_FINI)) == 0) {
2902 if (sec.fini == NULL)
2903 sec.fini = _cache;
2904 }
2905 break;
2906
2907 case SHT_REL:
2908 /*
2909 * We want the SHT_REL section with the lowest
2910 * offset. The linker gathers them together,
2911 * and puts the address of the first one
2912 * into the DT_REL dynamic element.
2913 */
2914 if ((sec.rel == NULL) ||
2915 (_cache->c_shdr->sh_offset <
2916 sec.rel->c_shdr->sh_offset))
2917 sec.rel = _cache;
2918 break;
2919
2920 case SHT_RELA:
2921 /* RELA is handled just like RELA above */
2922 if ((sec.rela == NULL) ||
2923 (_cache->c_shdr->sh_offset <
2924 sec.rela->c_shdr->sh_offset))
2925 sec.rela = _cache;
2926 break;
2927
2928 /*
2929 * The GRAB macro is used for the simple case in which
2930 * we simply grab the first section of the desired type.
2931 */
2932 #define GRAB(_sec_type, _sec_field) \
2933 case _sec_type: \
2934 if (sec._sec_field == NULL) \
2935 sec._sec_field = _cache; \
2936 break
2937 GRAB(SHT_SYMTAB, symtab);
2938 GRAB(SHT_DYNSYM, dynsym);
2939 GRAB(SHT_FINI_ARRAY, fini_array);
2940 GRAB(SHT_HASH, hash);
2941 GRAB(SHT_INIT_ARRAY, init_array);
2942 GRAB(SHT_SUNW_move, sunw_move);
2943 GRAB(SHT_PREINIT_ARRAY, preinit_array);
2944 GRAB(SHT_SUNW_cap, sunw_cap);
2945 GRAB(SHT_SUNW_capinfo, sunw_capinfo);
2946 GRAB(SHT_SUNW_capchain, sunw_capchain);
2947 GRAB(SHT_SUNW_LDYNSYM, sunw_ldynsym);
2948 GRAB(SHT_SUNW_syminfo, sunw_syminfo);
2949 GRAB(SHT_SUNW_symsort, sunw_symsort);
2950 GRAB(SHT_SUNW_tlssort, sunw_tlssort);
2951 GRAB(SHT_SUNW_verdef, sunw_verdef);
2952 GRAB(SHT_SUNW_verneed, sunw_verneed);
2953 GRAB(SHT_SUNW_versym, sunw_versym);
2954 #undef GRAB
2955 }
2956 }
2957
2958 /*
2959 * If no dynamic section, return immediately. If more than one
2960 * dynamic section, then something odd is going on and an error
2961 * is in order, but then continue on and display them all.
2962 */
2963 if (dynsec_num == 0)
2964 return;
2965 if (dynsec_num > 1)
2966 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTDYN),
2967 file, EC_WORD(dynsec_num));
2968
2969
2970 dynsec_cnt = 0;
2971 for (cnt = dynsec_ndx; (cnt < shnum) && (dynsec_cnt < dynsec_num);
2972 cnt++) {
2973 Dyn *dyn;
2974 ulong_t numdyn;
2975 int ndx, end_ndx;
2976 Cache *_cache = &cache[cnt], *strsec;
2977 Shdr *shdr = _cache->c_shdr;
2978 int dumped = 0;
2979
2980 if (shdr->sh_type != SHT_DYNAMIC)
2981 continue;
2982 dynsec_cnt++;
2983
2984 /*
2985 * Verify the associated string table section.
2986 */
2987 if (stringtbl(cache, 0, cnt, shnum, file, 0, 0, &strsec) == 0)
2988 continue;
2989
2990 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
2991 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
2992 file, _cache->c_name);
2993 continue;
2994 }
2995 if (_cache->c_data == NULL)
2996 continue;
2997
2998 numdyn = shdr->sh_size / shdr->sh_entsize;
2999 dyn = (Dyn *)_cache->c_data->d_buf;
3000
3001 /*
3002 * We expect the REL/RELA entries to reference the reloc
3003 * section with the lowest address. However, this is
3004 * not true for dumped objects. Detect if this object has
3005 * been dumped so that we can skip the reloc address test
3006 * in that case.
3007 */
3008 for (ndx = 0; ndx < numdyn; dyn++, ndx++) {
3009 if (dyn->d_tag == DT_FLAGS_1) {
3010 dumped = (dyn->d_un.d_val & DF_1_CONFALT) != 0;
3011 break;
3012 }
3013 }
3014 dyn = (Dyn *)_cache->c_data->d_buf;
3015
3016 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3017 dbg_print(0, MSG_INTL(MSG_ELF_SCN_DYNAMIC), _cache->c_name);
3018
3019 Elf_dyn_title(0);
3020
3021 for (ndx = 0; ndx < numdyn; dyn++, ndx++) {
3022 union {
3023 Conv_inv_buf_t inv;
3024 Conv_dyn_flag_buf_t flag;
3025 Conv_dyn_flag1_buf_t flag1;
3026 Conv_dyn_posflag1_buf_t posflag1;
3027 Conv_dyn_feature1_buf_t feature1;
3028 } c_buf;
3029 const char *name = NULL;
3030
3031 /*
3032 * Print the information numerically, and if possible
3033 * as a string. If a string is available, name is
3034 * set to reference it.
3035 *
3036 * Also, take this opportunity to sanity check
3037 * the values of DT elements. In the code above,
3038 * we gathered information on sections that are
3039 * referenced by the dynamic section. Here, we
3040 * compare the attributes of those sections to
3041 * the DT_ items that reference them and report
3042 * on inconsistencies.
3043 *
3044 * Things not currently tested that could be improved
3045 * in later revisions include:
3046 * - We don't check PLT or GOT related items
3047 * - We don't handle computing the lengths of
3048 * relocation arrays. To handle this
3049 * requires examining data that spans
3050 * across sections, in a contiguous span
3051 * within a single segment.
3052 * - DT_VERDEFNUM and DT_VERNEEDNUM can't be
3053 * verified without parsing the sections.
3054 * - We don't handle DT_SUNW_SYMSZ, which would
3055 * be the sum of the lengths of .dynsym and
3056 * .SUNW_ldynsym
3057 * - DT_SUNW_STRPAD can't be verified other than
3058 * to check that it's not larger than
3059 * the string table.
3060 * - Some items come in "all or none" clusters
3061 * that give an address, element size,
3062 * and data length in bytes. We don't
3063 * verify that there are no missing items
3064 * in such groups.
3065 */
3066 switch (dyn->d_tag) {
3067 case DT_NULL:
3068 /*
3069 * Special case: DT_NULLs can come in groups
3070 * that we prefer to reduce to a single line.
3071 */
3072 end_ndx = ndx;
3073 while ((end_ndx < (numdyn - 1)) &&
3074 ((dyn + 1)->d_tag == DT_NULL)) {
3075 dyn++;
3076 end_ndx++;
3077 }
3078 Elf_dyn_null_entry(0, dyn, ndx, end_ndx);
3079 ndx = end_ndx;
3080 continue;
3081
3082 /*
3083 * String items all reference the dynstr. The string()
3084 * function does the necessary sanity checking.
3085 */
3086 case DT_NEEDED:
3087 case DT_SONAME:
3088 case DT_FILTER:
3089 case DT_AUXILIARY:
3090 case DT_CONFIG:
3091 case DT_RPATH:
3092 case DT_RUNPATH:
3093 case DT_USED:
3094 case DT_DEPAUDIT:
3095 case DT_AUDIT:
3096 name = string(_cache, ndx, strsec,
3097 file, dyn->d_un.d_ptr);
3098 break;
3099
3100 case DT_SUNW_AUXILIARY:
3101 case DT_SUNW_FILTER:
3102 if (osabi_solaris)
3103 name = string(_cache, ndx, strsec,
3104 file, dyn->d_un.d_ptr);
3105 break;
3106
3107 case DT_FLAGS:
3108 name = conv_dyn_flag(dyn->d_un.d_val,
3109 0, &c_buf.flag);
3110 break;
3111 case DT_FLAGS_1:
3112 name = conv_dyn_flag1(dyn->d_un.d_val, 0,
3113 &c_buf.flag1);
3114 break;
3115 case DT_POSFLAG_1:
3116 name = conv_dyn_posflag1(dyn->d_un.d_val, 0,
3117 &c_buf.posflag1);
3118 break;
3119 case DT_FEATURE_1:
3120 name = conv_dyn_feature1(dyn->d_un.d_val, 0,
3121 &c_buf.feature1);
3122 break;
3123 case DT_DEPRECATED_SPARC_REGISTER:
3124 name = MSG_INTL(MSG_STR_DEPRECATED);
3125 break;
3126
3127 case DT_SUNW_LDMACH:
3128 if (!osabi_solaris)
3129 break;
3130 name = conv_ehdr_mach((Half)dyn->d_un.d_val,
3131 0, &c_buf.inv);
3132 break;
3133
3134 /*
3135 * Cases below this point are strictly sanity checking,
3136 * and do not generate a name string. The TEST_ macros
3137 * are used to hide the boiler plate arguments neeeded
3138 * by dyn_test().
3139 */
3140 #define TEST_ADDR(_sh_type, _sec_field) \
3141 dyn_test(DYN_TEST_ADDR, _sh_type, \
3142 sec._sec_field, dyn, dynsec_cnt, ehdr, \
3143 osabi, file)
3144 #define TEST_SIZE(_sh_type, _sec_field) \
3145 dyn_test(DYN_TEST_SIZE, _sh_type, \
3146 sec._sec_field, dyn, dynsec_cnt, ehdr, \
3147 osabi, file)
3148 #define TEST_ENTSIZE(_sh_type, _sec_field) \
3149 dyn_test(DYN_TEST_ENTSIZE, _sh_type, \
3150 sec._sec_field, dyn, dynsec_cnt, ehdr, \
3151 osabi, file)
3152
3153 case DT_FINI:
3154 dyn_symtest(dyn, MSG_ORIG(MSG_SYM_FINI),
3155 sec.symtab, sec.dynsym, sec.sunw_ldynsym,
3156 sec.fini, cache, shnum, ehdr, osabi, file);
3157 TEST_ADDR(SHT_PROGBITS, fini);
3158 break;
3159
3160 case DT_FINI_ARRAY:
3161 TEST_ADDR(SHT_FINI_ARRAY, fini_array);
3162 break;
3163
3164 case DT_FINI_ARRAYSZ:
3165 TEST_SIZE(SHT_FINI_ARRAY, fini_array);
3166 break;
3167
3168 case DT_HASH:
3169 TEST_ADDR(SHT_HASH, hash);
3170 break;
3171
3172 case DT_INIT:
3173 dyn_symtest(dyn, MSG_ORIG(MSG_SYM_INIT),
3174 sec.symtab, sec.dynsym, sec.sunw_ldynsym,
3175 sec.init, cache, shnum, ehdr, osabi, file);
3176 TEST_ADDR(SHT_PROGBITS, init);
3177 break;
3178
3179 case DT_INIT_ARRAY:
3180 TEST_ADDR(SHT_INIT_ARRAY, init_array);
3181 break;
3182
3183 case DT_INIT_ARRAYSZ:
3184 TEST_SIZE(SHT_INIT_ARRAY, init_array);
3185 break;
3186
3187 case DT_MOVEENT:
3188 TEST_ENTSIZE(SHT_SUNW_move, sunw_move);
3189 break;
3190
3191 case DT_MOVESZ:
3192 TEST_SIZE(SHT_SUNW_move, sunw_move);
3193 break;
3194
3195 case DT_MOVETAB:
3196 TEST_ADDR(SHT_SUNW_move, sunw_move);
3197 break;
3198
3199 case DT_PREINIT_ARRAY:
3200 TEST_ADDR(SHT_PREINIT_ARRAY, preinit_array);
3201 break;
3202
3203 case DT_PREINIT_ARRAYSZ:
3204 TEST_SIZE(SHT_PREINIT_ARRAY, preinit_array);
3205 break;
3206
3207 case DT_REL:
3208 if (!dumped)
3209 TEST_ADDR(SHT_REL, rel);
3210 break;
3211
3212 case DT_RELENT:
3213 TEST_ENTSIZE(SHT_REL, rel);
3214 break;
3215
3216 case DT_RELA:
3217 if (!dumped)
3218 TEST_ADDR(SHT_RELA, rela);
3219 break;
3220
3221 case DT_RELAENT:
3222 TEST_ENTSIZE(SHT_RELA, rela);
3223 break;
3224
3225 case DT_STRTAB:
3226 TEST_ADDR(SHT_STRTAB, dynstr);
3227 break;
3228
3229 case DT_STRSZ:
3230 TEST_SIZE(SHT_STRTAB, dynstr);
3231 break;
3232
3233 case DT_SUNW_CAP:
3234 if (osabi_solaris)
3235 TEST_ADDR(SHT_SUNW_cap, sunw_cap);
3236 break;
3237
3238 case DT_SUNW_CAPINFO:
3239 if (osabi_solaris)
3240 TEST_ADDR(SHT_SUNW_capinfo,
3241 sunw_capinfo);
3242 break;
3243
3244 case DT_SUNW_CAPCHAIN:
3245 if (osabi_solaris)
3246 TEST_ADDR(SHT_SUNW_capchain,
3247 sunw_capchain);
3248 break;
3249
3250 case DT_SUNW_SYMTAB:
3251 TEST_ADDR(SHT_SUNW_LDYNSYM, sunw_ldynsym);
3252 break;
3253
3254 case DT_SYMENT:
3255 TEST_ENTSIZE(SHT_DYNSYM, dynsym);
3256 break;
3257
3258 case DT_SYMINENT:
3259 TEST_ENTSIZE(SHT_SUNW_syminfo, sunw_syminfo);
3260 break;
3261
3262 case DT_SYMINFO:
3263 TEST_ADDR(SHT_SUNW_syminfo, sunw_syminfo);
3264 break;
3265
3266 case DT_SYMINSZ:
3267 TEST_SIZE(SHT_SUNW_syminfo, sunw_syminfo);
3268 break;
3269
3270 case DT_SYMTAB:
3271 TEST_ADDR(SHT_DYNSYM, dynsym);
3272 break;
3273
3274 case DT_SUNW_SORTENT:
3275 /*
3276 * This entry is related to both the symsort and
3277 * tlssort sections.
3278 */
3279 if (osabi_solaris) {
3280 int test_tls =
3281 (sec.sunw_tlssort != NULL);
3282 int test_sym =
3283 (sec.sunw_symsort != NULL) ||
3284 !test_tls;
3285 if (test_sym)
3286 TEST_ENTSIZE(SHT_SUNW_symsort,
3287 sunw_symsort);
3288 if (test_tls)
3289 TEST_ENTSIZE(SHT_SUNW_tlssort,
3290 sunw_tlssort);
3291 }
3292 break;
3293
3294
3295 case DT_SUNW_SYMSORT:
3296 if (osabi_solaris)
3297 TEST_ADDR(SHT_SUNW_symsort,
3298 sunw_symsort);
3299 break;
3300
3301 case DT_SUNW_SYMSORTSZ:
3302 if (osabi_solaris)
3303 TEST_SIZE(SHT_SUNW_symsort,
3304 sunw_symsort);
3305 break;
3306
3307 case DT_SUNW_TLSSORT:
3308 if (osabi_solaris)
3309 TEST_ADDR(SHT_SUNW_tlssort,
3310 sunw_tlssort);
3311 break;
3312
3313 case DT_SUNW_TLSSORTSZ:
3314 if (osabi_solaris)
3315 TEST_SIZE(SHT_SUNW_tlssort,
3316 sunw_tlssort);
3317 break;
3318
3319 case DT_VERDEF:
3320 TEST_ADDR(SHT_SUNW_verdef, sunw_verdef);
3321 break;
3322
3323 case DT_VERNEED:
3324 TEST_ADDR(SHT_SUNW_verneed, sunw_verneed);
3325 break;
3326
3327 case DT_VERSYM:
3328 TEST_ADDR(SHT_SUNW_versym, sunw_versym);
3329 break;
3330 #undef TEST_ADDR
3331 #undef TEST_SIZE
3332 #undef TEST_ENTSIZE
3333 }
3334
3335 if (name == NULL)
3336 name = MSG_ORIG(MSG_STR_EMPTY);
3337 Elf_dyn_entry(0, dyn, ndx, name,
3338 osabi, ehdr->e_machine);
3339 }
3340 }
3341 }
3342
3343 /*
3344 * Search for and process a MOVE section.
3345 */
3346 static void
move(Cache * cache,Word shnum,const char * file,uint_t flags)3347 move(Cache *cache, Word shnum, const char *file, uint_t flags)
3348 {
3349 Word cnt;
3350 const char *fmt = NULL;
3351
3352 for (cnt = 1; cnt < shnum; cnt++) {
3353 Word movenum, symnum, ndx;
3354 Sym *syms;
3355 Cache *_cache = &cache[cnt];
3356 Shdr *shdr = _cache->c_shdr;
3357 Cache *symsec, *strsec;
3358 Move *move;
3359
3360 if (shdr->sh_type != SHT_SUNW_move)
3361 continue;
3362 if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
3363 continue;
3364
3365 /*
3366 * Determine the move data and number.
3367 */
3368 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
3369 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
3370 file, _cache->c_name);
3371 continue;
3372 }
3373 if (_cache->c_data == NULL)
3374 continue;
3375
3376 move = (Move *)_cache->c_data->d_buf;
3377 movenum = shdr->sh_size / shdr->sh_entsize;
3378
3379 /*
3380 * Get the data buffer for the associated symbol table and
3381 * string table.
3382 */
3383 if (stringtbl(cache, 1, cnt, shnum, file,
3384 &symnum, &symsec, &strsec) == 0)
3385 return;
3386
3387 syms = (Sym *)symsec->c_data->d_buf;
3388
3389 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3390 dbg_print(0, MSG_INTL(MSG_ELF_SCN_MOVE), _cache->c_name);
3391 dbg_print(0, MSG_INTL(MSG_MOVE_TITLE));
3392
3393 if (fmt == NULL)
3394 fmt = MSG_INTL(MSG_MOVE_ENTRY);
3395
3396 for (ndx = 0; ndx < movenum; move++, ndx++) {
3397 const char *symname;
3398 char index[MAXNDXSIZE], section[BUFSIZ];
3399 Word symndx, shndx;
3400 Sym *sym;
3401
3402 /*
3403 * Check for null entries
3404 */
3405 if ((move->m_info == 0) && (move->m_value == 0) &&
3406 (move->m_poffset == 0) && (move->m_repeat == 0) &&
3407 (move->m_stride == 0)) {
3408 dbg_print(0, fmt, MSG_ORIG(MSG_STR_EMPTY),
3409 EC_XWORD(move->m_poffset), 0, 0, 0,
3410 EC_LWORD(0), MSG_ORIG(MSG_STR_EMPTY));
3411 continue;
3412 }
3413 if (((symndx = ELF_M_SYM(move->m_info)) == 0) ||
3414 (symndx >= symnum)) {
3415 (void) fprintf(stderr,
3416 MSG_INTL(MSG_ERR_BADMINFO), file,
3417 _cache->c_name, EC_XWORD(move->m_info));
3418
3419 (void) snprintf(index, MAXNDXSIZE,
3420 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(symndx));
3421 dbg_print(0, fmt, index,
3422 EC_XWORD(move->m_poffset),
3423 ELF_M_SIZE(move->m_info), move->m_repeat,
3424 move->m_stride, move->m_value,
3425 MSG_INTL(MSG_STR_UNKNOWN));
3426 continue;
3427 }
3428
3429 symname = relsymname(cache, _cache, strsec,
3430 symndx, symnum, ndx, syms, section, BUFSIZ, file);
3431 sym = (Sym *)(syms + symndx);
3432
3433 /*
3434 * Additional sanity check.
3435 */
3436 shndx = sym->st_shndx;
3437 if (!((shndx == SHN_COMMON) ||
3438 (((shndx >= 1) && (shndx <= shnum)) &&
3439 (cache[shndx].c_shdr)->sh_type == SHT_NOBITS))) {
3440 (void) fprintf(stderr,
3441 MSG_INTL(MSG_ERR_BADSYM2), file,
3442 _cache->c_name, EC_WORD(symndx),
3443 demangle(symname, flags));
3444 }
3445
3446 (void) snprintf(index, MAXNDXSIZE,
3447 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(symndx));
3448 dbg_print(0, fmt, index, EC_XWORD(move->m_poffset),
3449 ELF_M_SIZE(move->m_info), move->m_repeat,
3450 move->m_stride, move->m_value,
3451 demangle(symname, flags));
3452 }
3453 }
3454 }
3455
3456 /*
3457 * parse_note_t is used to track the state used by parse_note_entry()
3458 * between calls, and also to return the results of each call.
3459 */
3460 typedef struct {
3461 /* pns_ fields track progress through the data */
3462 const char *pns_file; /* File name */
3463 Cache *pns_cache; /* Note section cache entry */
3464 size_t pns_size; /* # unprocessed data bytes */
3465 Word *pns_data; /* # to next unused data byte */
3466
3467 /* pn_ fields return the results for a single call */
3468 Word pn_namesz; /* Value of note namesz field */
3469 Word pn_descsz; /* Value of note descsz field */
3470 Word pn_type; /* Value of note type field */
3471 const char *pn_name; /* if (namesz > 0) ptr to name bytes */
3472 const char *pn_desc; /* if (descsx > 0) ptr to data bytes */
3473 } parse_note_t;
3474
3475 /*
3476 * Extract the various sub-parts of a note entry, and advance the
3477 * data pointer past it.
3478 *
3479 * entry:
3480 * The state pns_ fields contain current values for the Note section
3481 *
3482 * exit:
3483 * On success, True (1) is returned, the state pns_ fields have been
3484 * advanced to point at the start of the next entry, and the information
3485 * for the recovered note entry is found in the state pn_ fields.
3486 *
3487 * On failure, False (0) is returned. The values contained in state
3488 * are undefined.
3489 */
3490 static int
parse_note_entry(parse_note_t * state)3491 parse_note_entry(parse_note_t *state)
3492 {
3493 size_t pad, noteoff;
3494
3495 noteoff = (Word)state->pns_cache->c_data->d_size - state->pns_size;
3496 /*
3497 * Make sure we can at least reference the 3 initial entries
3498 * (4-byte words) of the note information block.
3499 */
3500 if (state->pns_size >= (sizeof (Word) * 3)) {
3501 state->pns_size -= (sizeof (Word) * 3);
3502 } else {
3503 (void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADDATASZ),
3504 state->pns_file, state->pns_cache->c_name,
3505 EC_WORD(noteoff));
3506 return (0);
3507 }
3508
3509 /*
3510 * Make sure any specified name string can be referenced.
3511 */
3512 if ((state->pn_namesz = *state->pns_data++) != 0) {
3513 if (state->pns_size >= state->pn_namesz) {
3514 state->pns_size -= state->pn_namesz;
3515 } else {
3516 (void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADNMSZ),
3517 state->pns_file, state->pns_cache->c_name,
3518 EC_WORD(noteoff), EC_WORD(state->pn_namesz));
3519 return (0);
3520 }
3521 }
3522
3523 /*
3524 * Make sure any specified descriptor can be referenced.
3525 */
3526 if ((state->pn_descsz = *state->pns_data++) != 0) {
3527 /*
3528 * If namesz isn't a 4-byte multiple, account for any
3529 * padding that must exist before the descriptor.
3530 */
3531 if ((pad = (state->pn_namesz & (sizeof (Word) - 1))) != 0) {
3532 pad = sizeof (Word) - pad;
3533 state->pns_size -= pad;
3534 }
3535 if (state->pns_size >= state->pn_descsz) {
3536 state->pns_size -= state->pn_descsz;
3537 } else {
3538 (void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADDESZ),
3539 state->pns_file, state->pns_cache->c_name,
3540 EC_WORD(noteoff), EC_WORD(state->pn_namesz));
3541 return (0);
3542 }
3543 }
3544
3545 state->pn_type = *state->pns_data++;
3546
3547 /* Name */
3548 if (state->pn_namesz) {
3549 state->pn_name = (char *)state->pns_data;
3550 pad = (state->pn_namesz +
3551 (sizeof (Word) - 1)) & ~(sizeof (Word) - 1);
3552 /* LINTED */
3553 state->pns_data = (Word *)(state->pn_name + pad);
3554 }
3555
3556 /*
3557 * If multiple information blocks exist within a .note section
3558 * account for any padding that must exist before the next
3559 * information block.
3560 */
3561 if ((pad = (state->pn_descsz & (sizeof (Word) - 1))) != 0) {
3562 pad = sizeof (Word) - pad;
3563 if (state->pns_size > pad)
3564 state->pns_size -= pad;
3565 }
3566
3567 /* Data */
3568 if (state->pn_descsz) {
3569 state->pn_desc = (const char *)state->pns_data;
3570 /* LINTED */
3571 state->pns_data = (Word *)(state->pn_desc +
3572 state->pn_descsz + pad);
3573 }
3574
3575 return (1);
3576 }
3577
3578 /*
3579 * Callback function for use with conv_str_to_c_literal() below.
3580 */
3581 /*ARGSUSED2*/
3582 static void
c_literal_cb(const void * ptr,size_t size,void * uvalue)3583 c_literal_cb(const void *ptr, size_t size, void *uvalue)
3584 {
3585 (void) fwrite(ptr, size, 1, stdout);
3586 }
3587
3588 /*
3589 * Traverse a note section analyzing each note information block.
3590 * The data buffers size is used to validate references before they are made,
3591 * and is decremented as each element is processed.
3592 */
3593 void
note_entry(Cache * cache,Word * data,size_t size,Ehdr * ehdr,const char * file)3594 note_entry(Cache *cache, Word *data, size_t size, Ehdr *ehdr, const char *file)
3595 {
3596 int cnt = 0;
3597 int is_corenote;
3598 int do_swap;
3599 Conv_inv_buf_t inv_buf;
3600 parse_note_t pnstate;
3601
3602 pnstate.pns_file = file;
3603 pnstate.pns_cache = cache;
3604 pnstate.pns_size = size;
3605 pnstate.pns_data = data;
3606 do_swap = _elf_sys_encoding() != ehdr->e_ident[EI_DATA];
3607
3608 /*
3609 * Print out a single `note' information block.
3610 */
3611 while (pnstate.pns_size > 0) {
3612
3613 if (parse_note_entry(&pnstate) == 0)
3614 return;
3615
3616 /*
3617 * Is this a Solaris core note? Such notes all have
3618 * the name "CORE".
3619 */
3620 is_corenote = (ehdr->e_type == ET_CORE) &&
3621 (pnstate.pn_namesz == (MSG_STR_CORE_SIZE + 1)) &&
3622 (strncmp(MSG_ORIG(MSG_STR_CORE), pnstate.pn_name,
3623 MSG_STR_CORE_SIZE + 1) == 0);
3624
3625 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3626 dbg_print(0, MSG_INTL(MSG_FMT_NOTEENTNDX), EC_WORD(cnt));
3627 cnt++;
3628 dbg_print(0, MSG_ORIG(MSG_NOTE_NAMESZ),
3629 EC_WORD(pnstate.pn_namesz));
3630 dbg_print(0, MSG_ORIG(MSG_NOTE_DESCSZ),
3631 EC_WORD(pnstate.pn_descsz));
3632
3633 if (is_corenote)
3634 dbg_print(0, MSG_ORIG(MSG_NOTE_TYPE_STR),
3635 conv_cnote_type(pnstate.pn_type, 0, &inv_buf));
3636 else
3637 dbg_print(0, MSG_ORIG(MSG_NOTE_TYPE),
3638 EC_WORD(pnstate.pn_type));
3639 if (pnstate.pn_namesz) {
3640 dbg_print(0, MSG_ORIG(MSG_NOTE_NAME));
3641 /*
3642 * The name string can contain embedded 'null'
3643 * bytes and/or unprintable characters. Also,
3644 * the final NULL is documented in the ELF ABI
3645 * as being included in the namesz. So, display
3646 * the name using C literal string notation, and
3647 * include the terminating NULL in the output.
3648 * We don't show surrounding double quotes, as
3649 * that implies the termination that we are showing
3650 * explicitly.
3651 */
3652 (void) fwrite(MSG_ORIG(MSG_STR_8SP),
3653 MSG_STR_8SP_SIZE, 1, stdout);
3654 conv_str_to_c_literal(pnstate.pn_name,
3655 pnstate.pn_namesz, c_literal_cb, NULL);
3656 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3657 }
3658
3659 if (pnstate.pn_descsz) {
3660 int hexdump = 1;
3661
3662 /*
3663 * If this is a core note, let the corenote()
3664 * function handle it.
3665 */
3666 if (is_corenote) {
3667 /* We only issue the bad arch error once */
3668 static int badnote_done = 0;
3669 corenote_ret_t corenote_ret;
3670
3671 corenote_ret = corenote(ehdr->e_machine,
3672 do_swap, pnstate.pn_type, pnstate.pn_desc,
3673 pnstate.pn_descsz);
3674 switch (corenote_ret) {
3675 case CORENOTE_R_OK:
3676 hexdump = 0;
3677 break;
3678 case CORENOTE_R_BADDATA:
3679 (void) fprintf(stderr,
3680 MSG_INTL(MSG_NOTE_BADCOREDATA),
3681 file);
3682 break;
3683 case CORENOTE_R_BADARCH:
3684 if (badnote_done)
3685 break;
3686 (void) fprintf(stderr,
3687 MSG_INTL(MSG_NOTE_BADCOREARCH),
3688 file,
3689 conv_ehdr_mach(ehdr->e_machine,
3690 0, &inv_buf));
3691 break;
3692 }
3693 }
3694
3695 /*
3696 * The default thing when we don't understand
3697 * the note data is to display it as hex bytes.
3698 */
3699 if (hexdump) {
3700 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
3701 dump_hex_bytes(pnstate.pn_desc,
3702 pnstate.pn_descsz, 8, 4, 4);
3703 }
3704 }
3705 }
3706 }
3707
3708 /*
3709 * Search for and process .note sections.
3710 *
3711 * Returns the number of note sections seen.
3712 */
3713 static Word
note(Cache * cache,Word shnum,Ehdr * ehdr,const char * file)3714 note(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
3715 {
3716 Word cnt, note_cnt = 0;
3717
3718 /*
3719 * Otherwise look for any .note sections.
3720 */
3721 for (cnt = 1; cnt < shnum; cnt++) {
3722 Cache *_cache = &cache[cnt];
3723 Shdr *shdr = _cache->c_shdr;
3724
3725 if (shdr->sh_type != SHT_NOTE)
3726 continue;
3727 note_cnt++;
3728 if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
3729 continue;
3730
3731 /*
3732 * As these sections are often hand rolled, make sure they're
3733 * properly aligned before proceeding, and issue an error
3734 * as necessary.
3735 *
3736 * Note that we will continue on to display the note even
3737 * if it has bad alignment. We can do this safely, because
3738 * libelf knows the alignment required for SHT_NOTE, and
3739 * takes steps to deliver a properly aligned buffer to us
3740 * even if the actual file is misaligned.
3741 */
3742 if (shdr->sh_offset & (sizeof (Word) - 1))
3743 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADALIGN),
3744 file, _cache->c_name);
3745
3746 if (_cache->c_data == NULL)
3747 continue;
3748
3749 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3750 dbg_print(0, MSG_INTL(MSG_ELF_SCN_NOTE), _cache->c_name);
3751 note_entry(_cache, (Word *)_cache->c_data->d_buf,
3752 /* LINTED */
3753 (Word)_cache->c_data->d_size, ehdr, file);
3754 }
3755
3756 return (note_cnt);
3757 }
3758
3759 /*
3760 * The Linux Standard Base defines a special note named .note.ABI-tag
3761 * that is used to maintain Linux ABI information. Presence of this section
3762 * is a strong indication that the object should be considered to be
3763 * ELFOSABI_LINUX.
3764 *
3765 * This function returns True (1) if such a note is seen, and False (0)
3766 * otherwise.
3767 */
3768 static int
has_linux_abi_note(Cache * cache,Word shnum,const char * file)3769 has_linux_abi_note(Cache *cache, Word shnum, const char *file)
3770 {
3771 Word cnt;
3772
3773 for (cnt = 1; cnt < shnum; cnt++) {
3774 parse_note_t pnstate;
3775 Cache *_cache = &cache[cnt];
3776 Shdr *shdr = _cache->c_shdr;
3777
3778 /*
3779 * Section must be SHT_NOTE, must have the name
3780 * .note.ABI-tag, and must have data.
3781 */
3782 if ((shdr->sh_type != SHT_NOTE) ||
3783 (strcmp(MSG_ORIG(MSG_STR_NOTEABITAG),
3784 _cache->c_name) != 0) || (_cache->c_data == NULL))
3785 continue;
3786
3787 pnstate.pns_file = file;
3788 pnstate.pns_cache = _cache;
3789 pnstate.pns_size = _cache->c_data->d_size;
3790 pnstate.pns_data = (Word *)_cache->c_data->d_buf;
3791
3792 while (pnstate.pns_size > 0) {
3793 Word *w;
3794
3795 if (parse_note_entry(&pnstate) == 0)
3796 break;
3797
3798 /*
3799 * The type must be 1, and the name must be "GNU".
3800 * The descsz must be at least 16 bytes.
3801 */
3802 if ((pnstate.pn_type != 1) ||
3803 (pnstate.pn_namesz != (MSG_STR_GNU_SIZE + 1)) ||
3804 (strncmp(MSG_ORIG(MSG_STR_GNU), pnstate.pn_name,
3805 MSG_STR_CORE_SIZE + 1) != 0) ||
3806 (pnstate.pn_descsz < 16))
3807 continue;
3808
3809 /*
3810 * desc contains 4 32-bit fields. Field 0 must be 0,
3811 * indicating Linux. The second, third, and fourth
3812 * fields represent the earliest Linux kernel
3813 * version compatible with this object.
3814 */
3815 /*LINTED*/
3816 w = (Word *) pnstate.pn_desc;
3817 if (*w == 0)
3818 return (1);
3819 }
3820 }
3821
3822 return (0);
3823 }
3824
3825 /*
3826 * Determine an individual hash entry. This may be the initial hash entry,
3827 * or an associated chain entry.
3828 */
3829 static void
hash_entry(Cache * refsec,Cache * strsec,const char * hsecname,Word hashndx,Word symndx,Word symn,Sym * syms,const char * file,ulong_t bkts,uint_t flags,int chain)3830 hash_entry(Cache *refsec, Cache *strsec, const char *hsecname, Word hashndx,
3831 Word symndx, Word symn, Sym *syms, const char *file, ulong_t bkts,
3832 uint_t flags, int chain)
3833 {
3834 Sym *sym;
3835 const char *symname, *str;
3836 char _bucket[MAXNDXSIZE], _symndx[MAXNDXSIZE];
3837 ulong_t nbkt, nhash;
3838
3839 if (symndx > symn) {
3840 (void) fprintf(stderr, MSG_INTL(MSG_ERR_HSBADSYMNDX), file,
3841 EC_WORD(symndx), EC_WORD(hashndx));
3842 symname = MSG_INTL(MSG_STR_UNKNOWN);
3843 } else {
3844 sym = (Sym *)(syms + symndx);
3845 symname = string(refsec, symndx, strsec, file, sym->st_name);
3846 }
3847
3848 if (chain == 0) {
3849 (void) snprintf(_bucket, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INTEGER),
3850 hashndx);
3851 str = (const char *)_bucket;
3852 } else
3853 str = MSG_ORIG(MSG_STR_EMPTY);
3854
3855 (void) snprintf(_symndx, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX2),
3856 EC_WORD(symndx));
3857 dbg_print(0, MSG_ORIG(MSG_FMT_HASH_INFO), str, _symndx,
3858 demangle(symname, flags));
3859
3860 /*
3861 * Determine if this string is in the correct bucket.
3862 */
3863 nhash = elf_hash(symname);
3864 nbkt = nhash % bkts;
3865
3866 if (nbkt != hashndx) {
3867 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADHASH), file,
3868 hsecname, symname, EC_WORD(hashndx), nbkt);
3869 }
3870 }
3871
3872 #define MAXCOUNT 500
3873
3874 static void
hash(Cache * cache,Word shnum,const char * file,uint_t flags)3875 hash(Cache *cache, Word shnum, const char *file, uint_t flags)
3876 {
3877 static int count[MAXCOUNT];
3878 Word cnt;
3879 ulong_t ndx, bkts;
3880 char number[MAXNDXSIZE];
3881
3882 for (cnt = 1; cnt < shnum; cnt++) {
3883 uint_t *hash, *chain;
3884 Cache *_cache = &cache[cnt];
3885 Shdr *sshdr, *hshdr = _cache->c_shdr;
3886 char *ssecname, *hsecname = _cache->c_name;
3887 Sym *syms;
3888 Word symn;
3889
3890 if (hshdr->sh_type != SHT_HASH)
3891 continue;
3892
3893 /*
3894 * Determine the hash table data and size.
3895 */
3896 if ((hshdr->sh_entsize == 0) || (hshdr->sh_size == 0)) {
3897 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
3898 file, hsecname);
3899 continue;
3900 }
3901 if (_cache->c_data == NULL)
3902 continue;
3903
3904 hash = (uint_t *)_cache->c_data->d_buf;
3905 bkts = *hash;
3906 chain = hash + 2 + bkts;
3907 hash += 2;
3908
3909 /*
3910 * Get the data buffer for the associated symbol table.
3911 */
3912 if ((hshdr->sh_link == 0) || (hshdr->sh_link >= shnum)) {
3913 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
3914 file, hsecname, EC_WORD(hshdr->sh_link));
3915 continue;
3916 }
3917
3918 _cache = &cache[hshdr->sh_link];
3919 ssecname = _cache->c_name;
3920
3921 if (_cache->c_data == NULL)
3922 continue;
3923
3924 if ((syms = (Sym *)_cache->c_data->d_buf) == NULL) {
3925 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
3926 file, ssecname);
3927 continue;
3928 }
3929
3930 sshdr = _cache->c_shdr;
3931 /* LINTED */
3932 symn = (Word)(sshdr->sh_size / sshdr->sh_entsize);
3933
3934 /*
3935 * Get the associated string table section.
3936 */
3937 if ((sshdr->sh_link == 0) || (sshdr->sh_link >= shnum)) {
3938 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
3939 file, ssecname, EC_WORD(sshdr->sh_link));
3940 continue;
3941 }
3942
3943 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3944 dbg_print(0, MSG_INTL(MSG_ELF_SCN_HASH), hsecname);
3945 dbg_print(0, MSG_INTL(MSG_ELF_HASH_INFO));
3946
3947 /*
3948 * Loop through the hash buckets, printing the appropriate
3949 * symbols.
3950 */
3951 for (ndx = 0; ndx < bkts; ndx++, hash++) {
3952 Word _ndx, _cnt;
3953
3954 if (*hash == 0) {
3955 count[0]++;
3956 continue;
3957 }
3958
3959 hash_entry(_cache, &cache[sshdr->sh_link], hsecname,
3960 ndx, *hash, symn, syms, file, bkts, flags, 0);
3961
3962 /*
3963 * Determine if any other symbols are chained to this
3964 * bucket.
3965 */
3966 _ndx = chain[*hash];
3967 _cnt = 1;
3968 while (_ndx) {
3969 hash_entry(_cache, &cache[sshdr->sh_link],
3970 hsecname, ndx, _ndx, symn, syms, file,
3971 bkts, flags, 1);
3972 _ndx = chain[_ndx];
3973 _cnt++;
3974 }
3975
3976 if (_cnt >= MAXCOUNT) {
3977 (void) fprintf(stderr,
3978 MSG_INTL(MSG_HASH_OVERFLW), file,
3979 _cache->c_name, EC_WORD(ndx),
3980 EC_WORD(_cnt));
3981 } else
3982 count[_cnt]++;
3983 }
3984 break;
3985 }
3986
3987 /*
3988 * Print out the count information.
3989 */
3990 bkts = cnt = 0;
3991 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3992
3993 for (ndx = 0; ndx < MAXCOUNT; ndx++) {
3994 Word _cnt;
3995
3996 if ((_cnt = count[ndx]) == 0)
3997 continue;
3998
3999 (void) snprintf(number, MAXNDXSIZE,
4000 MSG_ORIG(MSG_FMT_INTEGER), _cnt);
4001 dbg_print(0, MSG_INTL(MSG_ELF_HASH_BKTS1), number,
4002 EC_WORD(ndx));
4003 bkts += _cnt;
4004 cnt += (Word)(ndx * _cnt);
4005 }
4006 if (cnt) {
4007 (void) snprintf(number, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INTEGER),
4008 bkts);
4009 dbg_print(0, MSG_INTL(MSG_ELF_HASH_BKTS2), number,
4010 EC_WORD(cnt));
4011 }
4012 }
4013
4014 static void
group(Cache * cache,Word shnum,const char * file,uint_t flags)4015 group(Cache *cache, Word shnum, const char *file, uint_t flags)
4016 {
4017 Word scnt;
4018
4019 for (scnt = 1; scnt < shnum; scnt++) {
4020 Cache *_cache = &cache[scnt];
4021 Shdr *shdr = _cache->c_shdr;
4022 Word *grpdata, gcnt, grpcnt, symnum, unknown;
4023 Cache *symsec, *strsec;
4024 Sym *syms, *sym;
4025 char flgstrbuf[MSG_GRP_COMDAT_SIZE + 10];
4026 const char *grpnam;
4027
4028 if (shdr->sh_type != SHT_GROUP)
4029 continue;
4030 if (!match(MATCH_F_ALL, _cache->c_name, scnt, shdr->sh_type))
4031 continue;
4032 if ((_cache->c_data == NULL) ||
4033 ((grpdata = (Word *)_cache->c_data->d_buf) == NULL))
4034 continue;
4035 grpcnt = shdr->sh_size / sizeof (Word);
4036
4037 /*
4038 * Get the data buffer for the associated symbol table and
4039 * string table.
4040 */
4041 if (stringtbl(cache, 1, scnt, shnum, file,
4042 &symnum, &symsec, &strsec) == 0)
4043 return;
4044
4045 syms = symsec->c_data->d_buf;
4046
4047 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4048 dbg_print(0, MSG_INTL(MSG_ELF_SCN_GRP), _cache->c_name);
4049 dbg_print(0, MSG_INTL(MSG_GRP_TITLE));
4050
4051 /*
4052 * The first element of the group defines the group. The
4053 * associated symbol is defined by the sh_link field.
4054 */
4055 if ((shdr->sh_info == SHN_UNDEF) || (shdr->sh_info > symnum)) {
4056 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO),
4057 file, _cache->c_name, EC_WORD(shdr->sh_info));
4058 return;
4059 }
4060
4061 (void) strcpy(flgstrbuf, MSG_ORIG(MSG_STR_OSQBRKT));
4062 if (grpdata[0] & GRP_COMDAT) {
4063 (void) strcat(flgstrbuf, MSG_ORIG(MSG_GRP_COMDAT));
4064 }
4065 if ((unknown = (grpdata[0] & ~GRP_COMDAT)) != 0) {
4066 size_t len = strlen(flgstrbuf);
4067
4068 (void) snprintf(&flgstrbuf[len],
4069 (MSG_GRP_COMDAT_SIZE + 10 - len),
4070 MSG_ORIG(MSG_GRP_UNKNOWN), unknown);
4071 }
4072 (void) strcat(flgstrbuf, MSG_ORIG(MSG_STR_CSQBRKT));
4073 sym = (Sym *)(syms + shdr->sh_info);
4074
4075 /*
4076 * The GNU assembler can use section symbols as the signature
4077 * symbol as described by this comment in the gold linker
4078 * (found via google):
4079 *
4080 * It seems that some versions of gas will create a
4081 * section group associated with a section symbol, and
4082 * then fail to give a name to the section symbol. In
4083 * such a case, use the name of the section.
4084 *
4085 * In order to support such objects, we do the same.
4086 */
4087 grpnam = string(_cache, 0, strsec, file, sym->st_name);
4088 if (((sym->st_name == 0) || (*grpnam == '\0')) &&
4089 (ELF_ST_TYPE(sym->st_info) == STT_SECTION))
4090 grpnam = cache[sym->st_shndx].c_name;
4091
4092 dbg_print(0, MSG_INTL(MSG_GRP_SIGNATURE), flgstrbuf,
4093 demangle(grpnam, flags));
4094
4095 for (gcnt = 1; gcnt < grpcnt; gcnt++) {
4096 char index[MAXNDXSIZE];
4097 const char *name;
4098
4099 (void) snprintf(index, MAXNDXSIZE,
4100 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(gcnt));
4101
4102 if (grpdata[gcnt] >= shnum)
4103 name = MSG_INTL(MSG_GRP_INVALSCN);
4104 else
4105 name = cache[grpdata[gcnt]].c_name;
4106
4107 (void) printf(MSG_ORIG(MSG_GRP_ENTRY), index, name,
4108 EC_XWORD(grpdata[gcnt]));
4109 }
4110 }
4111 }
4112
4113 static void
got(Cache * cache,Word shnum,Ehdr * ehdr,const char * file)4114 got(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
4115 {
4116 Cache *gotcache = NULL, *symtab = NULL;
4117 Addr gotbgn, gotend;
4118 Shdr *gotshdr;
4119 Word cnt, gotents, gotndx;
4120 size_t gentsize;
4121 Got_info *gottable;
4122 char *gotdata;
4123 Sym *gotsym;
4124 Xword gotsymaddr;
4125 uint_t sys_encoding;
4126
4127 /*
4128 * First, find the got.
4129 */
4130 for (cnt = 1; cnt < shnum; cnt++) {
4131 if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
4132 MSG_ELF_GOT_SIZE) == 0) {
4133 gotcache = &cache[cnt];
4134 break;
4135 }
4136 }
4137 if (gotcache == NULL)
4138 return;
4139
4140 /*
4141 * A got section within a relocatable object is suspicious.
4142 */
4143 if (ehdr->e_type == ET_REL) {
4144 (void) fprintf(stderr, MSG_INTL(MSG_GOT_UNEXPECTED), file,
4145 gotcache->c_name);
4146 }
4147
4148 gotshdr = gotcache->c_shdr;
4149 if (gotshdr->sh_size == 0) {
4150 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
4151 file, gotcache->c_name);
4152 return;
4153 }
4154
4155 gotbgn = gotshdr->sh_addr;
4156 gotend = gotbgn + gotshdr->sh_size;
4157
4158 /*
4159 * Some architectures don't properly set the sh_entsize for the GOT
4160 * table. If it's not set, default to a size of a pointer.
4161 */
4162 if ((gentsize = gotshdr->sh_entsize) == 0)
4163 gentsize = sizeof (Xword);
4164
4165 if (gotcache->c_data == NULL)
4166 return;
4167
4168 /* LINTED */
4169 gotents = (Word)(gotshdr->sh_size / gentsize);
4170 gotdata = gotcache->c_data->d_buf;
4171
4172 if ((gottable = calloc(gotents, sizeof (Got_info))) == 0) {
4173 int err = errno;
4174 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), file,
4175 strerror(err));
4176 return;
4177 }
4178
4179 /*
4180 * Now we scan through all the sections looking for any relocations
4181 * that may be against the GOT. Since these may not be isolated to a
4182 * .rel[a].got section we check them all.
4183 * While scanning sections save the symbol table entry (a symtab
4184 * overriding a dynsym) so that we can lookup _GLOBAL_OFFSET_TABLE_.
4185 */
4186 for (cnt = 1; cnt < shnum; cnt++) {
4187 Word type, symnum;
4188 Xword relndx, relnum, relsize;
4189 void *rels;
4190 Sym *syms;
4191 Cache *symsec, *strsec;
4192 Cache *_cache = &cache[cnt];
4193 Shdr *shdr;
4194
4195 shdr = _cache->c_shdr;
4196 type = shdr->sh_type;
4197
4198 if ((symtab == 0) && (type == SHT_DYNSYM)) {
4199 symtab = _cache;
4200 continue;
4201 }
4202 if (type == SHT_SYMTAB) {
4203 symtab = _cache;
4204 continue;
4205 }
4206 if ((type != SHT_RELA) && (type != SHT_REL))
4207 continue;
4208
4209 /*
4210 * Decide entry size.
4211 */
4212 if (((relsize = shdr->sh_entsize) == 0) ||
4213 (relsize > shdr->sh_size)) {
4214 if (type == SHT_RELA)
4215 relsize = sizeof (Rela);
4216 else
4217 relsize = sizeof (Rel);
4218 }
4219
4220 /*
4221 * Determine the number of relocations available.
4222 */
4223 if (shdr->sh_size == 0) {
4224 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
4225 file, _cache->c_name);
4226 continue;
4227 }
4228 if (_cache->c_data == NULL)
4229 continue;
4230
4231 rels = _cache->c_data->d_buf;
4232 relnum = shdr->sh_size / relsize;
4233
4234 /*
4235 * Get the data buffer for the associated symbol table and
4236 * string table.
4237 */
4238 if (stringtbl(cache, 1, cnt, shnum, file,
4239 &symnum, &symsec, &strsec) == 0)
4240 continue;
4241
4242 syms = symsec->c_data->d_buf;
4243
4244 /*
4245 * Loop through the relocation entries.
4246 */
4247 for (relndx = 0; relndx < relnum; relndx++,
4248 rels = (void *)((char *)rels + relsize)) {
4249 char section[BUFSIZ];
4250 Addr offset;
4251 Got_info *gip;
4252 Word symndx, reltype;
4253 Rela *rela;
4254 Rel *rel;
4255
4256 /*
4257 * Unravel the relocation.
4258 */
4259 if (type == SHT_RELA) {
4260 rela = (Rela *)rels;
4261 symndx = ELF_R_SYM(rela->r_info);
4262 reltype = ELF_R_TYPE(rela->r_info,
4263 ehdr->e_machine);
4264 offset = rela->r_offset;
4265 } else {
4266 rel = (Rel *)rels;
4267 symndx = ELF_R_SYM(rel->r_info);
4268 reltype = ELF_R_TYPE(rel->r_info,
4269 ehdr->e_machine);
4270 offset = rel->r_offset;
4271 }
4272
4273 /*
4274 * Only pay attention to relocations against the GOT.
4275 */
4276 if ((offset < gotbgn) || (offset >= gotend))
4277 continue;
4278
4279 /* LINTED */
4280 gotndx = (Word)((offset - gotbgn) /
4281 gotshdr->sh_entsize);
4282 gip = &gottable[gotndx];
4283
4284 if (gip->g_reltype != 0) {
4285 (void) fprintf(stderr,
4286 MSG_INTL(MSG_GOT_MULTIPLE), file,
4287 EC_WORD(gotndx), EC_ADDR(offset));
4288 continue;
4289 }
4290
4291 if (symndx)
4292 gip->g_symname = relsymname(cache, _cache,
4293 strsec, symndx, symnum, relndx, syms,
4294 section, BUFSIZ, file);
4295 gip->g_reltype = reltype;
4296 gip->g_rel = rels;
4297 }
4298 }
4299
4300 if (symlookup(MSG_ORIG(MSG_SYM_GOT), cache, shnum, &gotsym, NULL,
4301 symtab, file))
4302 gotsymaddr = gotsym->st_value;
4303 else
4304 gotsymaddr = gotbgn;
4305
4306 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4307 dbg_print(0, MSG_INTL(MSG_ELF_SCN_GOT), gotcache->c_name);
4308 Elf_got_title(0);
4309
4310 sys_encoding = _elf_sys_encoding();
4311 for (gotndx = 0; gotndx < gotents; gotndx++) {
4312 Got_info *gip;
4313 Sword gindex;
4314 Addr gaddr;
4315 Xword gotentry;
4316
4317 gip = &gottable[gotndx];
4318
4319 gaddr = gotbgn + (gotndx * gentsize);
4320 gindex = (Sword)(gaddr - gotsymaddr) / (Sword)gentsize;
4321
4322 if (gentsize == sizeof (Word))
4323 /* LINTED */
4324 gotentry = (Xword)(*((Word *)(gotdata) + gotndx));
4325 else
4326 /* LINTED */
4327 gotentry = *((Xword *)(gotdata) + gotndx);
4328
4329 Elf_got_entry(0, gindex, gaddr, gotentry, ehdr->e_machine,
4330 ehdr->e_ident[EI_DATA], sys_encoding,
4331 gip->g_reltype, gip->g_rel, gip->g_symname);
4332 }
4333 free(gottable);
4334 }
4335
4336 void
checksum(Elf * elf)4337 checksum(Elf *elf)
4338 {
4339 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4340 dbg_print(0, MSG_INTL(MSG_STR_CHECKSUM), elf_checksum(elf));
4341 }
4342
4343 /*
4344 * This variable is used by regular() to communicate the address of
4345 * the section header cache to sort_shdr_ndx_arr(). Unfortunately,
4346 * the qsort() interface does not include a userdata argument by which
4347 * such arbitrary data can be passed, so we are stuck using global data.
4348 */
4349 static Cache *sort_shdr_ndx_arr_cache;
4350
4351
4352 /*
4353 * Used with qsort() to sort the section indices so that they can be
4354 * used to access the section headers in order of increasing data offset.
4355 *
4356 * entry:
4357 * sort_shdr_ndx_arr_cache - Contains address of
4358 * section header cache.
4359 * v1, v2 - Point at elements of sort_shdr_bits array to be compared.
4360 *
4361 * exit:
4362 * Returns -1 (less than), 0 (equal) or 1 (greater than).
4363 */
4364 static int
sort_shdr_ndx_arr(const void * v1,const void * v2)4365 sort_shdr_ndx_arr(const void *v1, const void *v2)
4366 {
4367 Cache *cache1 = sort_shdr_ndx_arr_cache + *((size_t *)v1);
4368 Cache *cache2 = sort_shdr_ndx_arr_cache + *((size_t *)v2);
4369
4370 if (cache1->c_shdr->sh_offset < cache2->c_shdr->sh_offset)
4371 return (-1);
4372
4373 if (cache1->c_shdr->sh_offset > cache2->c_shdr->sh_offset)
4374 return (1);
4375
4376 return (0);
4377 }
4378
4379
4380 static int
shdr_cache(const char * file,Elf * elf,Ehdr * ehdr,size_t shstrndx,size_t shnum,Cache ** cache_ret,Word flags)4381 shdr_cache(const char *file, Elf *elf, Ehdr *ehdr, size_t shstrndx,
4382 size_t shnum, Cache **cache_ret, Word flags)
4383 {
4384 Elf_Scn *scn;
4385 Elf_Data *data;
4386 size_t ndx;
4387 Shdr *nameshdr;
4388 char *names = NULL;
4389 Cache *cache, *_cache;
4390 size_t *shdr_ndx_arr, shdr_ndx_arr_cnt;
4391
4392
4393 /*
4394 * Obtain the .shstrtab data buffer to provide the required section
4395 * name strings.
4396 */
4397 if (shstrndx == SHN_UNDEF) {
4398 /*
4399 * It is rare, but legal, for an object to lack a
4400 * header string table section.
4401 */
4402 names = NULL;
4403 (void) fprintf(stderr, MSG_INTL(MSG_ERR_NOSHSTRSEC), file);
4404 } else if ((scn = elf_getscn(elf, shstrndx)) == NULL) {
4405 failure(file, MSG_ORIG(MSG_ELF_GETSCN));
4406 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SHDR),
4407 EC_XWORD(shstrndx));
4408
4409 } else if ((data = elf_getdata(scn, NULL)) == NULL) {
4410 failure(file, MSG_ORIG(MSG_ELF_GETDATA));
4411 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_DATA),
4412 EC_XWORD(shstrndx));
4413
4414 } else if ((nameshdr = elf_getshdr(scn)) == NULL) {
4415 failure(file, MSG_ORIG(MSG_ELF_GETSHDR));
4416 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN),
4417 EC_WORD(elf_ndxscn(scn)));
4418
4419 } else if ((names = data->d_buf) == NULL)
4420 (void) fprintf(stderr, MSG_INTL(MSG_ERR_SHSTRNULL), file);
4421
4422 /*
4423 * Allocate a cache to maintain a descriptor for each section.
4424 */
4425 if ((*cache_ret = cache = malloc(shnum * sizeof (Cache))) == NULL) {
4426 int err = errno;
4427 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
4428 file, strerror(err));
4429 return (0);
4430 }
4431
4432 *cache = cache_init;
4433 _cache = cache;
4434 _cache++;
4435
4436 /*
4437 * Allocate an array that will hold the section index for
4438 * each section that has data in the ELF file:
4439 *
4440 * - Is not a NOBITS section
4441 * - Data has non-zero length
4442 *
4443 * Note that shnum is an upper bound on the size required. It
4444 * is likely that we won't use a few of these array elements.
4445 * Allocating a modest amount of extra memory in this case means
4446 * that we can avoid an extra loop to count the number of needed
4447 * items, and can fill this array immediately in the first loop
4448 * below.
4449 */
4450 if ((shdr_ndx_arr = malloc(shnum * sizeof (*shdr_ndx_arr))) == NULL) {
4451 int err = errno;
4452 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
4453 file, strerror(err));
4454 return (0);
4455 }
4456 shdr_ndx_arr_cnt = 0;
4457
4458 /*
4459 * Traverse the sections of the file. This gathering of data is
4460 * carried out in two passes. First, the section headers are captured
4461 * and the section header names are evaluated. A verification pass is
4462 * then carried out over the section information. Files have been
4463 * known to exhibit overlapping (and hence erroneous) section header
4464 * information.
4465 *
4466 * Finally, the data for each section is obtained. This processing is
4467 * carried out after section verification because should any section
4468 * header overlap occur, and a file needs translating (ie. xlate'ing
4469 * information from a non-native architecture file), then the process
4470 * of translation can corrupt the section header information. Of
4471 * course, if there is any section overlap, the data related to the
4472 * sections is going to be compromised. However, it is the translation
4473 * of this data that has caused problems with elfdump()'s ability to
4474 * extract the data.
4475 */
4476 for (ndx = 1, scn = NULL; scn = elf_nextscn(elf, scn);
4477 ndx++, _cache++) {
4478 char scnndxnm[100];
4479
4480 _cache->c_ndx = ndx;
4481 _cache->c_scn = scn;
4482
4483 if ((_cache->c_shdr = elf_getshdr(scn)) == NULL) {
4484 failure(file, MSG_ORIG(MSG_ELF_GETSHDR));
4485 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN),
4486 EC_WORD(elf_ndxscn(scn)));
4487 }
4488
4489 /*
4490 * If this section has data in the file, include it in
4491 * the array of sections to check for address overlap.
4492 */
4493 if ((_cache->c_shdr->sh_size != 0) &&
4494 (_cache->c_shdr->sh_type != SHT_NOBITS))
4495 shdr_ndx_arr[shdr_ndx_arr_cnt++] = ndx;
4496
4497 /*
4498 * If a shstrtab exists, assign the section name.
4499 */
4500 if (names && _cache->c_shdr) {
4501 if (_cache->c_shdr->sh_name &&
4502 /* LINTED */
4503 (nameshdr->sh_size > _cache->c_shdr->sh_name)) {
4504 const char *symname;
4505 char *secname;
4506
4507 secname = names + _cache->c_shdr->sh_name;
4508
4509 /*
4510 * A SUN naming convention employs a "%" within
4511 * a section name to indicate a section/symbol
4512 * name. This originated from the compilers
4513 * -xF option, that places functions into their
4514 * own sections. This convention (which has no
4515 * formal standard) has also been followed for
4516 * COMDAT sections. To demangle the symbol
4517 * name, the name must be separated from the
4518 * section name.
4519 */
4520 if (((flags & FLG_CTL_DEMANGLE) == 0) ||
4521 ((symname = strchr(secname, '%')) == NULL))
4522 _cache->c_name = secname;
4523 else {
4524 size_t secsz = ++symname - secname;
4525 size_t strsz;
4526
4527 symname = demangle(symname, flags);
4528 strsz = secsz + strlen(symname) + 1;
4529
4530 if ((_cache->c_name =
4531 malloc(strsz)) == NULL) {
4532 int err = errno;
4533 (void) fprintf(stderr,
4534 MSG_INTL(MSG_ERR_MALLOC),
4535 file, strerror(err));
4536 return (0);
4537 }
4538 (void) snprintf(_cache->c_name, strsz,
4539 MSG_ORIG(MSG_FMT_SECSYM),
4540 EC_WORD(secsz), secname, symname);
4541 }
4542
4543 continue;
4544 }
4545
4546 /*
4547 * Generate an error if the section name index is zero
4548 * or exceeds the shstrtab data. Fall through to
4549 * fabricate a section name.
4550 */
4551 if ((_cache->c_shdr->sh_name == 0) ||
4552 /* LINTED */
4553 (nameshdr->sh_size <= _cache->c_shdr->sh_name)) {
4554 (void) fprintf(stderr,
4555 MSG_INTL(MSG_ERR_BADSHNAME), file,
4556 EC_WORD(ndx),
4557 EC_XWORD(_cache->c_shdr->sh_name));
4558 }
4559 }
4560
4561 /*
4562 * If there exists no shstrtab data, or a section header has no
4563 * name (an invalid index of 0), then compose a name for the
4564 * section.
4565 */
4566 (void) snprintf(scnndxnm, sizeof (scnndxnm),
4567 MSG_INTL(MSG_FMT_SCNNDX), ndx);
4568
4569 if ((_cache->c_name = malloc(strlen(scnndxnm) + 1)) == NULL) {
4570 int err = errno;
4571 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
4572 file, strerror(err));
4573 return (0);
4574 }
4575 (void) strcpy(_cache->c_name, scnndxnm);
4576 }
4577
4578 /*
4579 * Having collected all the sections, validate their address range.
4580 * Cases have existed where the section information has been invalid.
4581 * This can lead to all sorts of other, hard to diagnose errors, as
4582 * each section is processed individually (ie. with elf_getdata()).
4583 * Here, we carry out some address comparisons to catch a family of
4584 * overlapping memory issues we have observed (likely, there are others
4585 * that we have yet to discover).
4586 *
4587 * Note, should any memory overlap occur, obtaining any additional
4588 * data from the file is questionable. However, it might still be
4589 * possible to inspect the ELF header, Programs headers, or individual
4590 * sections, so rather than bailing on an error condition, continue
4591 * processing to see if any data can be salvaged.
4592 */
4593 if (shdr_ndx_arr_cnt > 1) {
4594 sort_shdr_ndx_arr_cache = cache;
4595 qsort(shdr_ndx_arr, shdr_ndx_arr_cnt,
4596 sizeof (*shdr_ndx_arr), sort_shdr_ndx_arr);
4597 }
4598 for (ndx = 0; ndx < shdr_ndx_arr_cnt; ndx++) {
4599 Cache *_cache = cache + shdr_ndx_arr[ndx];
4600 Shdr *shdr = _cache->c_shdr;
4601 Off bgn1, bgn = shdr->sh_offset;
4602 Off end1, end = shdr->sh_offset + shdr->sh_size;
4603 size_t ndx1;
4604
4605 /*
4606 * Check the section against all following ones, reporting
4607 * any overlaps. Since we've sorted the sections by offset,
4608 * we can stop after the first comparison that fails. There
4609 * are no overlaps in a properly formed ELF file, in which
4610 * case this algorithm runs in O(n) time. This will degenerate
4611 * to O(n^2) for a completely broken file. Such a file is
4612 * (1) highly unlikely, and (2) unusable, so it is reasonable
4613 * for the analysis to take longer.
4614 */
4615 for (ndx1 = ndx + 1; ndx1 < shdr_ndx_arr_cnt; ndx1++) {
4616 Cache *_cache1 = cache + shdr_ndx_arr[ndx1];
4617 Shdr *shdr1 = _cache1->c_shdr;
4618
4619 bgn1 = shdr1->sh_offset;
4620 end1 = shdr1->sh_offset + shdr1->sh_size;
4621
4622 if (((bgn1 <= bgn) && (end1 > bgn)) ||
4623 ((bgn1 < end) && (end1 >= end))) {
4624 (void) fprintf(stderr,
4625 MSG_INTL(MSG_ERR_SECMEMOVER), file,
4626 EC_WORD(elf_ndxscn(_cache->c_scn)),
4627 _cache->c_name, EC_OFF(bgn), EC_OFF(end),
4628 EC_WORD(elf_ndxscn(_cache1->c_scn)),
4629 _cache1->c_name, EC_OFF(bgn1),
4630 EC_OFF(end1));
4631 } else { /* No overlap, so can stop */
4632 break;
4633 }
4634 }
4635
4636 /*
4637 * In addition to checking for sections overlapping
4638 * each other (done above), we should also make sure
4639 * the section doesn't overlap the section header array.
4640 */
4641 bgn1 = ehdr->e_shoff;
4642 end1 = ehdr->e_shoff + (ehdr->e_shentsize * ehdr->e_shnum);
4643
4644 if (((bgn1 <= bgn) && (end1 > bgn)) ||
4645 ((bgn1 < end) && (end1 >= end))) {
4646 (void) fprintf(stderr,
4647 MSG_INTL(MSG_ERR_SHDRMEMOVER), file, EC_OFF(bgn1),
4648 EC_OFF(end1),
4649 EC_WORD(elf_ndxscn(_cache->c_scn)),
4650 _cache->c_name, EC_OFF(bgn), EC_OFF(end));
4651 }
4652 }
4653
4654 /*
4655 * Obtain the data for each section.
4656 */
4657 for (ndx = 1; ndx < shnum; ndx++) {
4658 Cache *_cache = &cache[ndx];
4659 Elf_Scn *scn = _cache->c_scn;
4660
4661 if ((_cache->c_data = elf_getdata(scn, NULL)) == NULL) {
4662 failure(file, MSG_ORIG(MSG_ELF_GETDATA));
4663 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCNDATA),
4664 EC_WORD(elf_ndxscn(scn)));
4665 }
4666
4667 /*
4668 * If a string table, verify that it has NULL first and
4669 * final bytes.
4670 */
4671 if ((_cache->c_shdr->sh_type == SHT_STRTAB) &&
4672 (_cache->c_data->d_buf != NULL) &&
4673 (_cache->c_data->d_size > 0)) {
4674 const char *s = _cache->c_data->d_buf;
4675
4676 if ((*s != '\0') ||
4677 (*(s + _cache->c_data->d_size - 1) != '\0'))
4678 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALSTR),
4679 file, _cache->c_name);
4680 }
4681 }
4682
4683 return (1);
4684 }
4685
4686
4687
4688 /*
4689 * Generate a cache of section headers and related information
4690 * for use by the rest of elfdump. If requested (or the file
4691 * contains no section headers), we generate a fake set of
4692 * headers from the information accessible from the program headers.
4693 * Otherwise, we use the real section headers contained in the file.
4694 */
4695 static int
create_cache(const char * file,int fd,Elf * elf,Ehdr * ehdr,Cache ** cache,size_t shstrndx,size_t * shnum,uint_t * flags)4696 create_cache(const char *file, int fd, Elf *elf, Ehdr *ehdr, Cache **cache,
4697 size_t shstrndx, size_t *shnum, uint_t *flags)
4698 {
4699 /*
4700 * If there are no section headers, then resort to synthesizing
4701 * section headers from the program headers. This is normally
4702 * only done by explicit request, but in this case there's no
4703 * reason not to go ahead, since the alternative is simply to quit.
4704 */
4705 if ((*shnum <= 1) && ((*flags & FLG_CTL_FAKESHDR) == 0)) {
4706 (void) fprintf(stderr, MSG_INTL(MSG_ERR_NOSHDR), file);
4707 *flags |= FLG_CTL_FAKESHDR;
4708 }
4709
4710 if (*flags & FLG_CTL_FAKESHDR) {
4711 if (fake_shdr_cache(file, fd, elf, ehdr, cache, shnum) == 0)
4712 return (0);
4713 } else {
4714 if (shdr_cache(file, elf, ehdr, shstrndx, *shnum,
4715 cache, *flags) == 0)
4716 return (0);
4717 }
4718
4719 return (1);
4720 }
4721
4722 int
regular(const char * file,int fd,Elf * elf,uint_t flags,const char * wname,int wfd,uchar_t osabi)4723 regular(const char *file, int fd, Elf *elf, uint_t flags,
4724 const char *wname, int wfd, uchar_t osabi)
4725 {
4726 enum { CACHE_NEEDED, CACHE_OK, CACHE_FAIL} cache_state = CACHE_NEEDED;
4727 Elf_Scn *scn;
4728 Ehdr *ehdr;
4729 size_t ndx, shstrndx, shnum, phnum;
4730 Shdr *shdr;
4731 Cache *cache;
4732 VERSYM_STATE versym;
4733 int ret = 0;
4734 int addr_align;
4735
4736 if ((ehdr = elf_getehdr(elf)) == NULL) {
4737 failure(file, MSG_ORIG(MSG_ELF_GETEHDR));
4738 return (ret);
4739 }
4740
4741 if (elf_getshdrnum(elf, &shnum) == -1) {
4742 failure(file, MSG_ORIG(MSG_ELF_GETSHDRNUM));
4743 return (ret);
4744 }
4745
4746 if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
4747 failure(file, MSG_ORIG(MSG_ELF_GETSHDRSTRNDX));
4748 return (ret);
4749 }
4750
4751 if (elf_getphdrnum(elf, &phnum) == -1) {
4752 failure(file, MSG_ORIG(MSG_ELF_GETPHDRNUM));
4753 return (ret);
4754 }
4755 /*
4756 * If the user requested section headers derived from the
4757 * program headers (-P option) and this file doesn't have
4758 * any program headers (i.e. ET_REL), then we can't do it.
4759 */
4760 if ((phnum == 0) && (flags & FLG_CTL_FAKESHDR)) {
4761 (void) fprintf(stderr, MSG_INTL(MSG_ERR_PNEEDSPH), file);
4762 return (ret);
4763 }
4764
4765
4766 if ((scn = elf_getscn(elf, 0)) != NULL) {
4767 if ((shdr = elf_getshdr(scn)) == NULL) {
4768 failure(file, MSG_ORIG(MSG_ELF_GETSHDR));
4769 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN), 0);
4770 return (ret);
4771 }
4772 } else
4773 shdr = NULL;
4774
4775 /*
4776 * Print the elf header.
4777 */
4778 if (flags & FLG_SHOW_EHDR)
4779 Elf_ehdr(0, ehdr, shdr);
4780
4781 /*
4782 * If the section headers or program headers have inadequate
4783 * alignment for the class of object, print a warning. libelf
4784 * can handle such files, but programs that use them can crash
4785 * when they dereference unaligned items.
4786 *
4787 * Note that the AMD64 ABI, although it is a 64-bit architecture,
4788 * allows access to data types smaller than 128-bits to be on
4789 * word alignment.
4790 */
4791 if (ehdr->e_machine == EM_AMD64)
4792 addr_align = sizeof (Word);
4793 else
4794 addr_align = sizeof (Addr);
4795
4796 if (ehdr->e_phoff & (addr_align - 1))
4797 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADPHDRALIGN), file);
4798 if (ehdr->e_shoff & (addr_align - 1))
4799 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHDRALIGN), file);
4800
4801
4802 /*
4803 * Determine the Operating System ABI (osabi) we will use to
4804 * interpret the object.
4805 */
4806 if (flags & FLG_CTL_OSABI) {
4807 /*
4808 * If the user explicitly specifies '-O none', we need
4809 * to display a completely generic view of the file.
4810 * However, libconv is written to assume that ELFOSABI_NONE
4811 * is equivalent to ELFOSABI_SOLARIS. To get the desired
4812 * effect, we use an osabi that libconv has no knowledge of.
4813 */
4814 if (osabi == ELFOSABI_NONE)
4815 osabi = ELFOSABI_UNKNOWN4;
4816 } else {
4817 /* Determine osabi from file */
4818 osabi = ehdr->e_ident[EI_OSABI];
4819 if (osabi == ELFOSABI_NONE) {
4820 /*
4821 * Chicken/Egg scenario:
4822 *
4823 * Ideally, we wait to create the section header cache
4824 * until after the program headers are printed. If we
4825 * only output program headers, we can skip building
4826 * the cache entirely.
4827 *
4828 * Proper interpretation of program headers requires
4829 * the osabi, which is supposed to be in the ELF header.
4830 * However, many systems (Solaris and Linux included)
4831 * have a history of setting the osabi to the generic
4832 * SysV ABI (ELFOSABI_NONE). We assume ELFOSABI_SOLARIS
4833 * in such cases, but would like to check the object
4834 * to see if it has a Linux .note.ABI-tag section,
4835 * which implies ELFOSABI_LINUX. This requires a
4836 * section header cache.
4837 *
4838 * To break the cycle, we create section headers now
4839 * if osabi is ELFOSABI_NONE, and later otherwise.
4840 * If it succeeds, we use them, if not, we defer
4841 * exiting until after the program headers are out.
4842 */
4843 if (create_cache(file, fd, elf, ehdr, &cache,
4844 shstrndx, &shnum, &flags) == 0) {
4845 cache_state = CACHE_FAIL;
4846 } else {
4847 cache_state = CACHE_OK;
4848 if (has_linux_abi_note(cache, shnum, file)) {
4849 Conv_inv_buf_t ibuf1, ibuf2;
4850
4851 (void) fprintf(stderr,
4852 MSG_INTL(MSG_INFO_LINUXOSABI), file,
4853 conv_ehdr_osabi(osabi, 0, &ibuf1),
4854 conv_ehdr_osabi(ELFOSABI_LINUX,
4855 0, &ibuf2));
4856 osabi = ELFOSABI_LINUX;
4857 }
4858 }
4859 }
4860 /*
4861 * We treat ELFOSABI_NONE identically to ELFOSABI_SOLARIS.
4862 * Mapping NONE to SOLARIS simplifies the required test.
4863 */
4864 if (osabi == ELFOSABI_NONE)
4865 osabi = ELFOSABI_SOLARIS;
4866 }
4867
4868 /*
4869 * Print the program headers.
4870 */
4871 if ((flags & FLG_SHOW_PHDR) && (phnum != 0)) {
4872 Phdr *phdr;
4873
4874 if ((phdr = elf_getphdr(elf)) == NULL) {
4875 failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
4876 return (ret);
4877 }
4878
4879 for (ndx = 0; ndx < phnum; phdr++, ndx++) {
4880 if (!match(MATCH_F_PHDR| MATCH_F_NDX | MATCH_F_TYPE,
4881 NULL, ndx, phdr->p_type))
4882 continue;
4883
4884 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4885 dbg_print(0, MSG_INTL(MSG_ELF_PHDR), EC_WORD(ndx));
4886 Elf_phdr(0, osabi, ehdr->e_machine, phdr);
4887 }
4888 }
4889
4890 /*
4891 * If we have flag bits set that explicitly require a show or calc
4892 * operation, but none of them require the section headers, then
4893 * we are done and can return now.
4894 */
4895 if (((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) != 0) &&
4896 ((flags & (FLG_MASK_SHOW_SHDR | FLG_MASK_CALC_SHDR)) == 0))
4897 return (ret);
4898
4899 /*
4900 * Everything from this point on requires section headers.
4901 * If we have no section headers, there is no reason to continue.
4902 *
4903 * If we tried above to create the section header cache and failed,
4904 * it is time to exit. Otherwise, create it if needed.
4905 */
4906 switch (cache_state) {
4907 case CACHE_NEEDED:
4908 if (create_cache(file, fd, elf, ehdr, &cache, shstrndx,
4909 &shnum, &flags) == 0)
4910 return (ret);
4911 break;
4912 case CACHE_FAIL:
4913 return (ret);
4914 }
4915 if (shnum <= 1)
4916 goto done;
4917
4918 /*
4919 * If -w was specified, find and write out the section(s) data.
4920 */
4921 if (wfd) {
4922 for (ndx = 1; ndx < shnum; ndx++) {
4923 Cache *_cache = &cache[ndx];
4924
4925 if (match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name,
4926 ndx, _cache->c_shdr->sh_type) &&
4927 _cache->c_data && _cache->c_data->d_buf) {
4928 if (write(wfd, _cache->c_data->d_buf,
4929 _cache->c_data->d_size) !=
4930 _cache->c_data->d_size) {
4931 int err = errno;
4932 (void) fprintf(stderr,
4933 MSG_INTL(MSG_ERR_WRITE), wname,
4934 strerror(err));
4935 /*
4936 * Return an exit status of 1, because
4937 * the failure is not related to the
4938 * ELF file, but by system resources.
4939 */
4940 ret = 1;
4941 goto done;
4942 }
4943 }
4944 }
4945 }
4946
4947 /*
4948 * If we have no flag bits set that explicitly require a show or calc
4949 * operation, but match options (-I, -N, -T) were used, then run
4950 * through the section headers and see if we can't deduce show flags
4951 * from the match options given.
4952 *
4953 * We don't do this if -w was specified, because (-I, -N, -T) used
4954 * with -w in lieu of some other option is supposed to be quiet.
4955 */
4956 if ((wfd == 0) && (flags & FLG_CTL_MATCH) &&
4957 ((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) == 0)) {
4958 for (ndx = 1; ndx < shnum; ndx++) {
4959 Cache *_cache = &cache[ndx];
4960
4961 if (!match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name,
4962 ndx, _cache->c_shdr->sh_type))
4963 continue;
4964
4965 switch (_cache->c_shdr->sh_type) {
4966 case SHT_PROGBITS:
4967 /*
4968 * Heuristic time: It is usually bad form
4969 * to assume the meaning/format of a PROGBITS
4970 * section based on its name. However, there
4971 * are ABI mandated exceptions. Check for
4972 * these special names.
4973 */
4974
4975 /* The ELF ABI specifies .interp and .got */
4976 if (strcmp(_cache->c_name,
4977 MSG_ORIG(MSG_ELF_INTERP)) == 0) {
4978 flags |= FLG_SHOW_INTERP;
4979 break;
4980 }
4981 if (strcmp(_cache->c_name,
4982 MSG_ORIG(MSG_ELF_GOT)) == 0) {
4983 flags |= FLG_SHOW_GOT;
4984 break;
4985 }
4986 /*
4987 * The GNU compilers, and amd64 ABI, define
4988 * .eh_frame and .eh_frame_hdr. The Sun
4989 * C++ ABI defines .exception_ranges.
4990 */
4991 if ((strncmp(_cache->c_name,
4992 MSG_ORIG(MSG_SCN_FRM),
4993 MSG_SCN_FRM_SIZE) == 0) ||
4994 (strncmp(_cache->c_name,
4995 MSG_ORIG(MSG_SCN_EXRANGE),
4996 MSG_SCN_EXRANGE_SIZE) == 0)) {
4997 flags |= FLG_SHOW_UNWIND;
4998 break;
4999 }
5000 break;
5001
5002 case SHT_SYMTAB:
5003 case SHT_DYNSYM:
5004 case SHT_SUNW_LDYNSYM:
5005 case SHT_SUNW_versym:
5006 case SHT_SYMTAB_SHNDX:
5007 flags |= FLG_SHOW_SYMBOLS;
5008 break;
5009
5010 case SHT_RELA:
5011 case SHT_REL:
5012 flags |= FLG_SHOW_RELOC;
5013 break;
5014
5015 case SHT_HASH:
5016 flags |= FLG_SHOW_HASH;
5017 break;
5018
5019 case SHT_DYNAMIC:
5020 flags |= FLG_SHOW_DYNAMIC;
5021 break;
5022
5023 case SHT_NOTE:
5024 flags |= FLG_SHOW_NOTE;
5025 break;
5026
5027 case SHT_GROUP:
5028 flags |= FLG_SHOW_GROUP;
5029 break;
5030
5031 case SHT_SUNW_symsort:
5032 case SHT_SUNW_tlssort:
5033 flags |= FLG_SHOW_SORT;
5034 break;
5035
5036 case SHT_SUNW_cap:
5037 flags |= FLG_SHOW_CAP;
5038 break;
5039
5040 case SHT_SUNW_move:
5041 flags |= FLG_SHOW_MOVE;
5042 break;
5043
5044 case SHT_SUNW_syminfo:
5045 flags |= FLG_SHOW_SYMINFO;
5046 break;
5047
5048 case SHT_SUNW_verdef:
5049 case SHT_SUNW_verneed:
5050 flags |= FLG_SHOW_VERSIONS;
5051 break;
5052
5053 case SHT_AMD64_UNWIND:
5054 flags |= FLG_SHOW_UNWIND;
5055 break;
5056 }
5057 }
5058 }
5059
5060
5061 if (flags & FLG_SHOW_SHDR)
5062 sections(file, cache, shnum, ehdr, osabi);
5063
5064 if (flags & FLG_SHOW_INTERP)
5065 interp(file, cache, shnum, phnum, elf);
5066
5067 if ((osabi == ELFOSABI_SOLARIS) || (osabi == ELFOSABI_LINUX))
5068 versions(cache, shnum, file, flags, &versym);
5069
5070 if (flags & FLG_SHOW_SYMBOLS)
5071 symbols(cache, shnum, ehdr, osabi, &versym, file, flags);
5072
5073 if ((flags & FLG_SHOW_SORT) && (osabi == ELFOSABI_SOLARIS))
5074 sunw_sort(cache, shnum, ehdr, osabi, &versym, file, flags);
5075
5076 if (flags & FLG_SHOW_HASH)
5077 hash(cache, shnum, file, flags);
5078
5079 if (flags & FLG_SHOW_GOT)
5080 got(cache, shnum, ehdr, file);
5081
5082 if (flags & FLG_SHOW_GROUP)
5083 group(cache, shnum, file, flags);
5084
5085 if (flags & FLG_SHOW_SYMINFO)
5086 syminfo(cache, shnum, ehdr, osabi, file);
5087
5088 if (flags & FLG_SHOW_RELOC)
5089 reloc(cache, shnum, ehdr, file);
5090
5091 if (flags & FLG_SHOW_DYNAMIC)
5092 dynamic(cache, shnum, ehdr, osabi, file);
5093
5094 if (flags & FLG_SHOW_NOTE) {
5095 Word note_cnt;
5096 size_t note_shnum;
5097 Cache *note_cache;
5098
5099 note_cnt = note(cache, shnum, ehdr, file);
5100
5101 /*
5102 * Solaris core files have section headers, but these
5103 * headers do not include SHT_NOTE sections that reference
5104 * the core note sections. This means that note() won't
5105 * find the core notes. Fake section headers (-P option)
5106 * recover these sections, but it is inconvenient to require
5107 * users to specify -P in this situation. If the following
5108 * are all true:
5109 *
5110 * - No note sections were found
5111 * - This is a core file
5112 * - We are not already using fake section headers
5113 *
5114 * then we will automatically generate fake section headers
5115 * and then process them in a second call to note().
5116 */
5117 if ((note_cnt == 0) && (ehdr->e_type == ET_CORE) &&
5118 !(flags & FLG_CTL_FAKESHDR) &&
5119 (fake_shdr_cache(file, fd, elf, ehdr,
5120 ¬e_cache, ¬e_shnum) != 0)) {
5121 (void) note(note_cache, note_shnum, ehdr, file);
5122 fake_shdr_cache_free(note_cache, note_shnum);
5123 }
5124 }
5125
5126 if ((flags & FLG_SHOW_MOVE) && (osabi == ELFOSABI_SOLARIS))
5127 move(cache, shnum, file, flags);
5128
5129 if (flags & FLG_CALC_CHECKSUM)
5130 checksum(elf);
5131
5132 if ((flags & FLG_SHOW_CAP) && (osabi == ELFOSABI_SOLARIS))
5133 cap(file, cache, shnum, phnum, ehdr, osabi, elf, flags);
5134
5135 if ((flags & FLG_SHOW_UNWIND) &&
5136 ((osabi == ELFOSABI_SOLARIS) || (osabi == ELFOSABI_LINUX)))
5137 unwind(cache, shnum, phnum, ehdr, osabi, file, elf, flags);
5138
5139
5140 /* Release the memory used to cache section headers */
5141 done:
5142 if (flags & FLG_CTL_FAKESHDR)
5143 fake_shdr_cache_free(cache, shnum);
5144 else
5145 free(cache);
5146
5147 return (ret);
5148 }
5149