4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 /* All Rights Reserved */
25 /* Copyright (c) 1987, 1988 Microsoft Corporation */
26 /* All Rights Reserved */
29 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
30 * Use is subject to license terms.
34 * ELF files can exceed 2GB in size. A standard 32-bit program
35 * like 'file' cannot read past 2GB, and will be unable to see
36 * the ELF section headers that typically are at the end of the
37 * object. The simplest solution to this problem would be to make
38 * the 'file' command a 64-bit application. However, as a matter of
39 * policy, we do not want to require this. A simple command like
40 * 'file' should not carry such a requirement, especially as we
41 * support 32-bit only hardware.
43 * An alternative solution is to build this code as 32-bit
44 * large file aware. The usual way to do this is to define a pair
45 * of preprocessor definitions:
48 * Map standard I/O routines to their largefile aware versions.
50 * _FILE_OFFSET_BITS=64
51 * Map off_t to off64_t
53 * The problem with this solution is that libelf is not large file capable,
54 * and the libelf header file will prevent compilation if
55 * _FILE_OFFSET_BITS is set to 64.
57 * So, the solution used in this code is to define _LARGEFILE64_SOURCE
58 * to get access to the 64-bit APIs, not to define _FILE_OFFSET_BITS, and to
59 * use our own types in place of off_t, and size_t. We read all the file
60 * data directly using pread64(), and avoid the use of libelf for anything
61 * other than the xlate functionality.
63 #define _LARGEFILE64_SOURCE
64 #define FILE_ELF_OFF_T off64_t
65 #define FILE_ELF_SIZE_T uint64_t
78 #include <sys/param.h>
79 #include <sys/types.h>
86 extern const char *File
;
88 static int get_class(void);
89 static int get_version(void);
90 static int get_format(void);
91 static int process_shdr(Elf_Info
*);
92 static int process_phdr(Elf_Info
*);
93 static int file_xlatetom(Elf_Type
, char *);
94 static int xlatetom_nhdr(Elf_Nhdr
*);
95 static int get_phdr(Elf_Info
*, int);
96 static int get_shdr(Elf_Info
*, int);
98 static Elf_Ehdr EI_Ehdr
; /* Elf_Ehdr to be stored */
99 static Elf_Word EI_Ehdr_shnum
; /* # section headers */
100 static Elf_Word EI_Ehdr_phnum
; /* # program headers */
101 static Elf_Word EI_Ehdr_shstrndx
; /* Index of section hdr string table */
102 static Elf_Shdr EI_Shdr
; /* recent Elf_Shdr to be stored */
103 static Elf_Phdr EI_Phdr
; /* recent Elf_Phdr to be stored */
109 return (EI_Ehdr
.e_ident
[EI_CLASS
]);
115 /* do as what libelf:_elf_config() does */
116 return (EI_Ehdr
.e_ident
[EI_VERSION
] ?
117 EI_Ehdr
.e_ident
[EI_VERSION
] : 1);
123 return (EI_Ehdr
.e_ident
[EI_DATA
]);
127 * file_xlatetom: translate different headers from file
128 * representation to memory representaion.
132 file_xlatetom(Elf_Type type
, char *hdr
)
138 version
= get_version();
139 format
= get_format();
141 /* will convert only these types */
142 if (type
!= ELF_T_EHDR
&& type
!= ELF_T_PHDR
&&
143 type
!= ELF_T_SHDR
&& type
!= ELF_T_WORD
&&
145 return (ELF_READ_FAIL
);
147 src
.d_buf
= (Elf_Void
*)hdr
;
149 src
.d_version
= version
;
151 dst
.d_buf
= (Elf_Void
*)&hbuf
;
152 dst
.d_version
= EV_CURRENT
;
154 src
.d_size
= elf_fsize(type
, 1, version
);
155 dst
.d_size
= elf_fsize(type
, 1, EV_CURRENT
);
156 if (elf_xlatetom(&dst
, &src
, format
) == NULL
)
157 return (ELF_READ_FAIL
);
159 (void) memcpy(hdr
, &hbuf
, dst
.d_size
);
160 return (ELF_READ_OKAY
);
164 * xlatetom_nhdr: There is no routine to convert Note header
165 * so we convert each field of this header.
168 xlatetom_nhdr(Elf_Nhdr
*nhdr
)
170 int r
= ELF_READ_FAIL
;
172 r
|= file_xlatetom(ELF_T_WORD
, (char *)&nhdr
->n_namesz
);
173 r
|= file_xlatetom(ELF_T_WORD
, (char *)&nhdr
->n_descsz
);
174 r
|= file_xlatetom(ELF_T_WORD
, (char *)&nhdr
->n_type
);
179 * elf_read: reads elf header, program, section headers to
180 * collect all information needed for file(1)
181 * output and stores them in Elf_Info.
184 elf_read(int fd
, Elf_Info
*EI
)
186 FILE_ELF_SIZE_T size
;
189 Elf_Ehdr
*ehdr
= &EI_Ehdr
;
192 size
= sizeof (Elf_Ehdr
);
194 if (pread64(EI
->elffd
, (void*)ehdr
, size
, 0) != size
)
198 if (file_xlatetom(ELF_T_EHDR
, (char *)ehdr
) == ELF_READ_FAIL
)
201 if (EI
->file
== NULL
)
202 return (ELF_READ_FAIL
);
205 * Extended section or program indexes in use? If so, special
206 * values in the ELF header redirect us to get the real values
209 EI_Ehdr_shnum
= EI_Ehdr
.e_shnum
;
210 EI_Ehdr_phnum
= EI_Ehdr
.e_phnum
;
211 EI_Ehdr_shstrndx
= EI_Ehdr
.e_shstrndx
;
212 if (((EI_Ehdr_shnum
== 0) || (EI_Ehdr_phnum
== PN_XNUM
)) &&
213 (EI_Ehdr
.e_shoff
!= 0)) {
214 if (get_shdr(EI
, 0) == ELF_READ_FAIL
)
215 return (ELF_READ_FAIL
);
216 if (EI_Ehdr_shnum
== 0)
217 EI_Ehdr_shnum
= EI_Shdr
.sh_size
;
218 if ((EI_Ehdr_phnum
== PN_XNUM
) && (EI_Shdr
.sh_info
!= 0))
219 EI_Ehdr_phnum
= EI_Shdr
.sh_info
;
220 if (EI_Ehdr_shstrndx
== SHN_XINDEX
)
221 EI_Ehdr_shstrndx
= EI_Shdr
.sh_link
;
224 EI
->type
= ehdr
->e_type
;
225 EI
->machine
= ehdr
->e_machine
;
226 EI
->flags
= ehdr
->e_flags
;
229 (void) fprintf(stderr
, gettext("%s: %s: can't "
230 "read ELF header\n"), File
, EI
->file
);
231 return (ELF_READ_FAIL
);
233 if (process_phdr(EI
) == ELF_READ_FAIL
)
234 return (ELF_READ_FAIL
);
236 /* We don't need section info for core files */
237 if (ehdr
->e_type
!= ET_CORE
)
238 if (process_shdr(EI
) == ELF_READ_FAIL
)
239 return (ELF_READ_FAIL
);
241 return (ELF_READ_OKAY
);
245 * get_phdr: reads program header of specified index.
248 get_phdr(Elf_Info
*EI
, int inx
)
250 FILE_ELF_OFF_T off
= 0;
251 FILE_ELF_SIZE_T size
;
253 if (inx
>= EI_Ehdr_phnum
)
254 return (ELF_READ_FAIL
);
256 size
= sizeof (Elf_Phdr
);
257 off
= (FILE_ELF_OFF_T
)EI_Ehdr
.e_phoff
+ (inx
* size
);
258 if (pread64(EI
->elffd
, (void *)&EI_Phdr
, size
, off
) != size
)
259 return (ELF_READ_FAIL
);
261 if (file_xlatetom(ELF_T_PHDR
, (char *)&EI_Phdr
) == ELF_READ_FAIL
)
262 return (ELF_READ_FAIL
);
264 return (ELF_READ_OKAY
);
268 * get_shdr: reads section header of specified index.
271 get_shdr(Elf_Info
*EI
, int inx
)
273 FILE_ELF_OFF_T off
= 0;
274 FILE_ELF_SIZE_T size
;
277 * Prevent access to non-existent section headers.
279 * A value of 0 for e_shoff means that there is no section header
280 * array in the file. A value of 0 for e_shndx does not necessarily
281 * mean this - there can still be a 1-element section header array
282 * to support extended section or program header indexes that
283 * exceed the 16-bit fields used in the ELF header to represent them.
285 if ((EI_Ehdr
.e_shoff
== 0) || ((inx
> 0) && (inx
>= EI_Ehdr_shnum
)))
286 return (ELF_READ_FAIL
);
288 size
= sizeof (Elf_Shdr
);
289 off
= (FILE_ELF_OFF_T
)EI_Ehdr
.e_shoff
+ (inx
* size
);
291 if (pread64(EI
->elffd
, (void *)&EI_Shdr
, size
, off
) != size
)
292 return (ELF_READ_FAIL
);
294 if (file_xlatetom(ELF_T_SHDR
, (char *)&EI_Shdr
) == ELF_READ_FAIL
)
295 return (ELF_READ_FAIL
);
297 return (ELF_READ_OKAY
);
301 * process_phdr: Read Program Headers and see if it is a core
302 * file of either new or (pre-restructured /proc)
303 * type, read the name of the file that dumped this
304 * core, else see if this is a dynamically linked.
307 process_phdr(Elf_Info
*EI
)
311 Elf_Nhdr Nhdr
, *nhdr
; /* note header just read */
312 Elf_Phdr
*phdr
= &EI_Phdr
;
314 FILE_ELF_SIZE_T nsz
, nmsz
, dsz
;
315 FILE_ELF_OFF_T offset
;
318 char *psinfo
, *fname
;
320 nsz
= sizeof (Elf_Nhdr
);
323 for (inx
= 0; inx
< EI_Ehdr_phnum
; inx
++) {
324 if (get_phdr(EI
, inx
) == ELF_READ_FAIL
)
325 return (ELF_READ_FAIL
);
327 /* read the note if it is a core */
328 if (phdr
->p_type
== PT_NOTE
&&
329 EI_Ehdr
.e_type
== ET_CORE
) {
331 * If the next segment is also a note, use it instead.
333 if (get_phdr(EI
, inx
+1) == ELF_READ_FAIL
)
334 return (ELF_READ_FAIL
);
335 if (phdr
->p_type
!= PT_NOTE
) {
336 /* read the first phdr back */
337 if (get_phdr(EI
, inx
) == ELF_READ_FAIL
)
338 return (ELF_READ_FAIL
);
340 offset
= phdr
->p_offset
;
341 if (pread64(EI
->elffd
, (void *)nhdr
, nsz
, offset
)
343 return (ELF_READ_FAIL
);
345 /* Translate the ELF note header */
346 if (xlatetom_nhdr(nhdr
) == ELF_READ_FAIL
)
347 return (ELF_READ_FAIL
);
349 ntype
= nhdr
->n_type
;
350 nmsz
= nhdr
->n_namesz
;
351 dsz
= nhdr
->n_descsz
;
353 offset
+= nsz
+ ((nmsz
+ 0x03) & ~0x3);
354 if ((psinfo
= malloc(dsz
)) == NULL
) {
356 (void) fprintf(stderr
, gettext("%s: malloc "
357 "failed: %s\n"), File
, strerror(err
));
360 if (pread64(EI
->elffd
, psinfo
, dsz
, offset
) != dsz
)
361 return (ELF_READ_FAIL
);
363 * We want to print the string contained
364 * in psinfo->pr_fname[], where 'psinfo'
365 * is either an old NT_PRPSINFO structure
366 * or a new NT_PSINFO structure.
368 * Old core files have only type NT_PRPSINFO.
369 * New core files have type NT_PSINFO.
371 * These structures are also different by
372 * virtue of being contained in a core file
373 * of either 32-bit or 64-bit type.
375 * To further complicate matters, we ourself
376 * might be compiled either 32-bit or 64-bit.
378 * For these reason, we just *know* the offsets of
379 * pr_fname[] into the four different structures
380 * here, regardless of how we are compiled.
382 if (class == ELFCLASS32
) {
383 /* 32-bit core file, 32-bit structures */
384 if (ntype
== NT_PSINFO
)
386 else /* old: NT_PRPSINFO */
388 } else if (class == ELFCLASS64
) {
389 /* 64-bit core file, 64-bit structures */
390 if (ntype
== NT_PSINFO
)
391 fname
= psinfo
+ 136;
392 else /* old: NT_PRPSINFO */
393 fname
= psinfo
+ 120;
395 EI
->core_type
= (ntype
== NT_PRPSINFO
)?
396 EC_OLDCORE
: EC_NEWCORE
;
397 (void) memcpy(EI
->fname
, fname
, strlen(fname
));
400 if (phdr
->p_type
== PT_DYNAMIC
) {
401 EI
->dynamic
= B_TRUE
;
404 return (ELF_READ_OKAY
);
408 * process_shdr: Read Section Headers to attempt to get HW/SW
409 * capabilities by looking at the SUNW_cap
410 * section and set string in Elf_Info.
411 * Also look for symbol tables and debug
412 * information sections. Set the "stripped" field
413 * in Elf_Info with corresponding flags.
416 process_shdr(Elf_Info
*EI
)
420 FILE_ELF_OFF_T cap_off
;
421 FILE_ELF_SIZE_T csize
;
425 Elf_Shdr
*shdr
= &EI_Shdr
;
428 csize
= sizeof (Elf_Cap
);
429 mac
= EI_Ehdr
.e_machine
;
431 /* if there are no sections, return success anyway */
432 if (EI_Ehdr
.e_shoff
== 0 && EI_Ehdr_shnum
== 0)
433 return (ELF_READ_OKAY
);
435 /* read section names from String Section */
436 if (get_shdr(EI
, EI_Ehdr_shstrndx
) == ELF_READ_FAIL
)
437 return (ELF_READ_FAIL
);
439 if ((strtab
= malloc(shdr
->sh_size
)) == NULL
)
440 return (ELF_READ_FAIL
);
442 if (pread64(EI
->elffd
, strtab
, shdr
->sh_size
, shdr
->sh_offset
)
444 return (ELF_READ_FAIL
);
446 strtab_sz
= shdr
->sh_size
;
448 /* read all the sections and process them */
449 for (idx
= 1, i
= 0; i
< EI_Ehdr_shnum
; idx
++, i
++) {
452 if (get_shdr(EI
, i
) == ELF_READ_FAIL
)
453 return (ELF_READ_FAIL
);
455 if (shdr
->sh_type
== SHT_NULL
) {
460 cap_off
= shdr
->sh_offset
;
461 if (shdr
->sh_type
== SHT_SUNW_cap
) {
464 if (shdr
->sh_size
== 0 || shdr
->sh_entsize
== 0) {
465 (void) fprintf(stderr
, ELF_ERR_ELFCAP1
,
467 return (ELF_READ_FAIL
);
469 capn
= (shdr
->sh_size
/ shdr
->sh_entsize
);
470 for (j
= 0; j
< capn
; j
++) {
472 * read cap and xlate the values
474 if (pread64(EI
->elffd
, &Chdr
, csize
, cap_off
)
476 file_xlatetom(ELF_T_CAP
, (char *)&Chdr
)
478 (void) fprintf(stderr
, ELF_ERR_ELFCAP2
,
480 return (ELF_READ_FAIL
);
486 * Each capatibility group is terminated with
487 * CA_SUNW_NULL. Groups other than the first
488 * represent symbol capabilities, and aren't
491 if (Chdr
.c_tag
== CA_SUNW_NULL
)
494 (void) elfcap_tag_to_str(ELFCAP_STYLE_UC
,
495 Chdr
.c_tag
, Chdr
.c_un
.c_val
, capstr
,
496 sizeof (capstr
), ELFCAP_FMT_SNGSPACE
,
499 if ((*EI
->cap_str
!= '\0') && (*capstr
!= '\0'))
500 (void) strlcat(EI
->cap_str
, " ",
501 sizeof (EI
->cap_str
));
503 (void) strlcat(EI
->cap_str
, capstr
,
504 sizeof (EI
->cap_str
));
510 * - "not stripped" means that an executable file
511 * contains a Symbol Table (.symtab)
512 * - "stripped" means that an executable file
513 * does not contain a Symbol Table.
514 * When strip -l or strip -x is run, it strips the
515 * debugging information (.line section name (strip -l),
516 * .line, .debug*, .stabs*, .dwarf* section names
517 * and SHT_SUNW_DEBUGSTR and SHT_SUNW_DEBUG
518 * section types (strip -x), however the Symbol
519 * Table will still be present.
521 * - No Symbol Table present, then report
523 * - Symbol Table present with debugging
524 * information (line number or debug section names,
525 * or SHT_SUNW_DEBUGSTR or SHT_SUNW_DEBUG section
526 * types) then report:
528 * - Symbol Table present with no debugging
529 * information (line number or debug section names,
530 * or SHT_SUNW_DEBUGSTR or SHT_SUNW_DEBUG section
531 * types) then report:
532 * "not stripped, no debugging information
535 if ((EI
->stripped
& E_NOSTRIP
) == E_NOSTRIP
)
538 if (!(EI
->stripped
& E_SYMTAB
) &&
539 (shdr
->sh_type
== SHT_SYMTAB
)) {
540 EI
->stripped
|= E_SYMTAB
;
544 if (shdr
->sh_name
>= strtab_sz
)
547 shnam
= &strtab
[shdr
->sh_name
];
549 if (!(EI
->stripped
& E_DBGINF
) &&
550 ((shdr
->sh_type
== SHT_SUNW_DEBUG
) ||
551 (shdr
->sh_type
== SHT_SUNW_DEBUGSTR
) ||
552 (shnam
!= NULL
&& is_in_list(shnam
)))) {
553 EI
->stripped
|= E_DBGINF
;
558 return (ELF_READ_OKAY
);