4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2015, Joyent, Inc. All rights reserved.
37 #include <sys/sysmacros.h>
38 #include <sys/machelf.h>
41 #include "Psymtab_machelf.h"
45 * This file contains code for use by Psymtab.c that is compiled once
46 * for each supported ELFCLASS.
48 * When processing ELF files, it is common to encounter a situation where
49 * a program with one ELFCLASS (32 or 64-bit) is required to examine a
50 * file with a different ELFCLASS. For example, the 32-bit linker (ld) may
51 * be used to link a 64-bit program. The simplest solution to this problem
52 * is to duplicate each such piece of code, modifying only the data types,
53 * and to use if statements to select the code to run. The problem with
54 * doing it that way is that the resulting code is difficult to maintain.
55 * It is inevitable that the copies will not always get modified identically,
56 * and will drift apart. The only robust solution is to generate the
57 * multiple instances of code automatically from a single piece of code.
59 * The solution used within the Solaris linker is to write the code once,
60 * using the data types defined in sys/machelf.h, and then to compile that
61 * code twice, once with _ELF64 defined (to generate ELFCLASS64 code) and
62 * once without (to generate ELFCLASS32). We use the same approach here.
64 * Note that the _ELF64 definition does not refer to the ELFCLASS of
65 * the resulting code, but rather, to the ELFCLASS of the data it
66 * examines. By repeating the above double-compilation for both 32-bit
67 * and 64-bit builds, we end up with 4 instances, which collectively
68 * can handle any combination of program and ELF data class:
82 * Read data from the specified process and construct an in memory
83 * image of an ELF file that will let us use libelf for most of the
84 * work we need to later (e.g. symbol table lookups). This is used
85 * in cases where no usable on-disk image for the process is available.
86 * We need sections for the dynsym, dynstr, and plt, and we need
87 * the program headers from the text section. The former is used in
88 * Pbuild_file_symtab(); the latter is used in several functions in
89 * Pcore.c to reconstruct the origin of each mapping from the load
90 * object that spawned it.
92 * Here are some useful pieces of elf trivia that will help
93 * to elucidate this code.
95 * All the information we need about the dynstr can be found in these
96 * two entries in the dynamic section:
98 * DT_STRTAB base of dynstr
99 * DT_STRSZ size of dynstr
101 * So deciphering the dynstr is pretty straightforward.
103 * The dynsym is a little trickier.
105 * DT_SYMTAB base of dynsym
106 * DT_SYMENT size of a dynstr entry (Elf{32,64}_Sym)
107 * DT_HASH base of hash table for dynamic lookups
109 * The DT_SYMTAB entry gives us any easy way of getting to the base
110 * of the dynsym, but getting the size involves rooting around in the
111 * dynamic lookup hash table. Here's the layout of the hash table:
113 * +-------------------+
114 * | nbucket | All values are 32-bit
115 * +-------------------+ (Elf32_Word or Elf64_Word)
117 * +-------------------+
120 * | bucket[nbucket-1] |
121 * +-------------------+
124 * | chain[nchain-1] |
125 * +-------------------+
126 * (figure 5-12 from the SYS V Generic ABI)
128 * Symbols names are hashed into a particular bucket which contains
129 * an index into the symbol table. Each entry in the symbol table
130 * has a corresponding entry in the chain table which tells the
131 * consumer where the next entry in the hash chain is. We can use
132 * the nchain field to find out the size of the dynsym.
134 * If there is a dynsym present, there may also be an optional
135 * section called the SUNW_ldynsym that augments the dynsym by
136 * providing local function symbols. When the Solaris linker lays
137 * out a file that has both of these sections, it makes sure that
138 * the data for the two sections is adjacent with the SUNW_ldynsym
139 * in front. This allows the runtime linker to treat these two
140 * symbol tables as being a single larger table. There are two
141 * items in the dynamic section for this:
143 * DT_SUNW_SYMTAB base of the SUNW_ldynsym
144 * DT_SUNW_SYMSZ total size of SUNW_ldynsym and dynsym
145 * added together. We can figure out the
146 * size of the SUNW_ldynsym section by
147 * subtracting the size of the dynsym
148 * (described above) from this value.
150 * We can figure out the size of the .plt section, but it takes some
151 * doing. We need to use the following information:
153 * DT_PLTGOT GOT PLT entry offset (on x86) or PLT offset (on sparc)
154 * DT_JMPREL base of the PLT's relocation section
155 * DT_PLTRELSZ size of the PLT's relocation section
156 * DT_PLTREL type of the PLT's relocation section
158 * We can use the number of relocation entries to calculate the size of
159 * the PLT. We get the address of the PLT by looking up the
160 * _PROCEDURE_LINKAGE_TABLE_ symbol.
162 * For more information, check out the System V Generic ABI.
167 * The fake_elfXX() function generated by this file uses the following
168 * string as the string table for the section names. Since it is critical
169 * to count correctly, and to improve readability, the SHSTR_NDX_ macros
170 * supply the proper offset for each name within the string.
172 static char shstr
[] =
173 ".shstrtab\0.dynsym\0.dynstr\0.dynamic\0.plt\0.SUNW_ldynsym";
175 /* Offsets within shstr for each name */
176 #define SHSTR_NDX_shstrtab 0
177 #define SHSTR_NDX_dynsym 10
178 #define SHSTR_NDX_dynstr 18
179 #define SHSTR_NDX_dynamic 26
180 #define SHSTR_NDX_plt 35
181 #define SHSTR_NDX_SUNW_ldynsym 40
185 * Section header alignment for 32 and 64-bit ELF files differs
188 #define SH_ADDRALIGN 8
190 #define SH_ADDRALIGN 4
194 * This is the smallest number of PLT relocation entries allowed in a proper
198 #define PLTREL_MIN_ENTRIES 4 /* SPARC psABI 3.0 and SCD 2.4 */
202 * On x86, lint would complain about unsigned comparison with
203 * PLTREL_MIN_ENTRIES. This define fakes up the value of PLTREL_MIN_ENTRIES
204 * and silences lint. On SPARC, there is no such issue.
206 #define PLTREL_MIN_ENTRIES 1
208 #define PLTREL_MIN_ENTRIES 0
214 fake_elf64(struct ps_prochandle
*P
, file_info_t
*fptr
, uintptr_t addr
,
215 Ehdr
*ehdr
, uint_t phnum
, Phdr
*phdr
)
218 fake_elf32(struct ps_prochandle
*P
, file_info_t
*fptr
, uintptr_t addr
,
219 Ehdr
*ehdr
, uint_t phnum
, Phdr
*phdr
)
237 * Mask of dynamic options that must be present in a well
238 * formed dynamic section. We need all of these in order to
239 * put together a complete set of elf sections. They are
240 * mandatory in both executables and shared objects so if one
241 * of them is missing, we're in some trouble and should abort.
242 * The PLT items are expected, but we will let them slide if
243 * need be. The DI_SUNW_SYM* items are completely optional, so
244 * we use them if they are present and ignore them otherwise.
246 const int di_req_mask
= (1 << DI_SYMTAB
) |
247 (1 << DI_SYMENT
) | (1 << DI_STRTAB
) | (1 << DI_STRSZ
);
250 caddr_t elfdata
= NULL
;
252 size_t dynsym_size
= 0, ldynsym_size
;
257 Dyn
*d
[DI_NENT
] = { 0 };
260 size_t pltsz
= 0, pltentries
= 0;
261 uintptr_t hptr
= NULL
;
262 Word hnchains
= 0, hnbuckets
= 0;
264 if (ehdr
->e_type
== ET_DYN
)
265 phdr
->p_vaddr
+= addr
;
267 if (P
->rap
!= NULL
) {
268 if (rd_get_dyns(P
->rap
, addr
, (void **)&dp
, NULL
) != RD_OK
)
271 if ((dp
= malloc(phdr
->p_filesz
)) == NULL
)
273 if (Pread(P
, dp
, phdr
->p_filesz
, phdr
->p_vaddr
) !=
279 * Iterate over the items in the dynamic section, grabbing
280 * the address of items we want and saving them in dp[].
282 for (i
= 0; i
< phdr
->p_filesz
/ sizeof (Dyn
); i
++) {
283 switch (dp
[i
].d_tag
) {
284 /* For the .plt section */
286 d
[DI_PLTGOT
] = &dp
[i
];
289 d
[DI_JMPREL
] = &dp
[i
];
292 d
[DI_PLTRELSZ
] = &dp
[i
];
295 d
[DI_PLTREL
] = &dp
[i
];
298 /* For the .dynsym section */
300 d
[DI_SYMTAB
] = &dp
[i
];
301 di_mask
|= (1 << DI_SYMTAB
);
305 di_mask
|= (1 << DI_HASH
);
308 d
[DI_SYMENT
] = &dp
[i
];
309 di_mask
|= (1 << DI_SYMENT
);
312 d
[DI_SUNW_SYMTAB
] = &dp
[i
];
315 d
[DI_SUNW_SYMSZ
] = &dp
[i
];
318 /* For the .dynstr section */
320 d
[DI_STRTAB
] = &dp
[i
];
321 di_mask
|= (1 << DI_STRTAB
);
324 d
[DI_STRSZ
] = &dp
[i
];
325 di_mask
|= (1 << DI_STRSZ
);
330 /* Ensure all required entries were collected */
331 if ((di_mask
& di_req_mask
) != di_req_mask
) {
332 dprintf("text section missing required dynamic entries: "
333 "required 0x%x, found 0x%x\n", di_req_mask
, di_mask
);
337 /* SUNW_ldynsym must be adjacent to dynsym. Ignore if not */
338 if ((d
[DI_SUNW_SYMTAB
] != NULL
) && (d
[DI_SUNW_SYMSZ
] != NULL
) &&
339 ((d
[DI_SYMTAB
]->d_un
.d_ptr
<= d
[DI_SUNW_SYMTAB
]->d_un
.d_ptr
) ||
340 (d
[DI_SYMTAB
]->d_un
.d_ptr
>= (d
[DI_SUNW_SYMTAB
]->d_un
.d_ptr
+
341 d
[DI_SUNW_SYMSZ
]->d_un
.d_val
)))) {
342 d
[DI_SUNW_SYMTAB
] = NULL
;
343 d
[DI_SUNW_SYMSZ
] = NULL
;
347 size
= sizeof (Ehdr
);
349 /* program headers from in-core elf fragment */
350 size
+= phnum
* ehdr
->e_phentsize
;
352 /* unused shdr, and .shstrtab section */
353 size
+= sizeof (Shdr
);
354 size
+= sizeof (Shdr
);
355 size
+= roundup(sizeof (shstr
), SH_ADDRALIGN
);
357 if (d
[DI_HASH
] != NULL
) {
360 hptr
= d
[DI_HASH
]->d_un
.d_ptr
;
361 if (ehdr
->e_type
== ET_DYN
)
364 if (Pread(P
, hash
, sizeof (hash
), hptr
) != sizeof (hash
)) {
365 dprintf("Pread of .hash at %lx failed\n",
375 * .dynsym and .SUNW_ldynsym sections.
377 * The string table section used for the symbol table and
378 * dynamic sections lies immediately after the dynsym, so the
379 * presence of SUNW_ldynsym changes the dynstr section index.
381 if (d
[DI_SUNW_SYMTAB
] != NULL
) {
382 size
+= sizeof (Shdr
); /* SUNW_ldynsym shdr */
383 ldynsym_size
= (size_t)d
[DI_SUNW_SYMSZ
]->d_un
.d_val
;
384 dynsym_size
= ldynsym_size
- (d
[DI_SYMTAB
]->d_un
.d_ptr
385 - d
[DI_SUNW_SYMTAB
]->d_un
.d_ptr
);
386 ldynsym_size
-= dynsym_size
;
389 dynsym_size
= sizeof (Sym
) * hnchains
;
393 size
+= sizeof (Shdr
) + ldynsym_size
+ dynsym_size
;
395 /* .dynstr section */
396 size
+= sizeof (Shdr
);
397 size
+= roundup(d
[DI_STRSZ
]->d_un
.d_val
, SH_ADDRALIGN
);
399 /* .dynamic section */
400 size
+= sizeof (Shdr
);
401 size
+= roundup(phdr
->p_filesz
, SH_ADDRALIGN
);
404 if (d
[DI_PLTGOT
] != NULL
&& d
[DI_JMPREL
] != NULL
&&
405 d
[DI_PLTRELSZ
] != NULL
&& d
[DI_PLTREL
] != NULL
) {
406 size_t pltrelsz
= d
[DI_PLTRELSZ
]->d_un
.d_val
;
408 if (d
[DI_PLTREL
]->d_un
.d_val
== DT_RELA
) {
409 pltentries
= pltrelsz
/ sizeof (Rela
);
410 } else if (d
[DI_PLTREL
]->d_un
.d_val
== DT_REL
) {
411 pltentries
= pltrelsz
/ sizeof (Rel
);
413 /* fall back to the platform default */
414 #if ((defined(__i386) || defined(__amd64)) && !defined(_ELF64))
415 pltentries
= pltrelsz
/ sizeof (Rel
);
416 dprintf("DI_PLTREL not found, defaulting to Rel");
417 #else /* (!(__i386 || __amd64)) || _ELF64 */
418 pltentries
= pltrelsz
/ sizeof (Rela
);
419 dprintf("DI_PLTREL not found, defaulting to Rela");
420 #endif /* (!(__i386 || __amd64) || _ELF64 */
423 if (pltentries
< PLTREL_MIN_ENTRIES
) {
424 dprintf("too few PLT relocation entries "
425 "(found %lu, expected at least %d)\n",
426 (long)pltentries
, PLTREL_MIN_ENTRIES
);
429 if (pltentries
< PLTREL_MIN_ENTRIES
+ 2)
433 * Now that we know the number of plt relocation entries
434 * we can calculate the size of the plt.
436 pltsz
= (pltentries
+ M_PLT_XNumber
) * M_PLT_ENTSIZE
;
438 /* The sparc PLT always has a (delay slot) nop at the end */
442 size
+= sizeof (Shdr
);
443 size
+= roundup(pltsz
, SH_ADDRALIGN
);
447 if ((elfdata
= calloc(1, size
)) == NULL
) {
448 dprintf("failed to allocate size %ld\n", (long)size
);
452 /* LINTED - alignment */
453 ep
= (Ehdr
*)elfdata
;
454 (void) memcpy(ep
, ehdr
, offsetof(Ehdr
, e_phoff
));
456 ep
->e_ehsize
= sizeof (Ehdr
);
457 ep
->e_phoff
= sizeof (Ehdr
);
458 ep
->e_phentsize
= ehdr
->e_phentsize
;
460 ep
->e_shoff
= ep
->e_phoff
+ phnum
* ep
->e_phentsize
;
461 ep
->e_shentsize
= sizeof (Shdr
);
463 * Plt and SUNW_ldynsym sections are optional. C logical
464 * binary operators return a 0 or 1 value, so the following
465 * adds 1 for each optional section present.
467 ep
->e_shnum
= 5 + (pltsz
!= 0) + (d
[DI_SUNW_SYMTAB
] != NULL
);
470 /* LINTED - alignment */
471 sp
= (Shdr
*)(elfdata
+ ep
->e_shoff
);
472 off
= ep
->e_shoff
+ ep
->e_shentsize
* ep
->e_shnum
;
475 * Copying the program headers directly from the process's
476 * address space is a little suspect, but since we only
477 * use them for their address and size values, this is fine.
479 if (Pread(P
, &elfdata
[ep
->e_phoff
], phnum
* ep
->e_phentsize
,
480 addr
+ ehdr
->e_phoff
) != phnum
* ep
->e_phentsize
) {
481 dprintf("failed to read program headers\n");
486 * The first elf section is always skipped.
491 * Section Header: .shstrtab
493 sp
->sh_name
= SHSTR_NDX_shstrtab
;
494 sp
->sh_type
= SHT_STRTAB
;
495 sp
->sh_flags
= SHF_STRINGS
;
498 sp
->sh_size
= sizeof (shstr
);
501 sp
->sh_addralign
= 1;
504 (void) memcpy(&elfdata
[off
], shstr
, sizeof (shstr
));
505 off
+= roundup(sp
->sh_size
, SH_ADDRALIGN
);
509 * Section Header: .SUNW_ldynsym
511 if (d
[DI_SUNW_SYMTAB
] != NULL
) {
512 sp
->sh_name
= SHSTR_NDX_SUNW_ldynsym
;
513 sp
->sh_type
= SHT_SUNW_LDYNSYM
;
514 sp
->sh_flags
= SHF_ALLOC
;
515 sp
->sh_addr
= d
[DI_SUNW_SYMTAB
]->d_un
.d_ptr
;
516 if (ehdr
->e_type
== ET_DYN
)
519 sp
->sh_size
= ldynsym_size
;
520 sp
->sh_link
= dynstr_shndx
;
521 /* Index of 1st global in table that has none == # items */
522 sp
->sh_info
= sp
->sh_size
/ sizeof (Sym
);
523 sp
->sh_addralign
= SH_ADDRALIGN
;
524 sp
->sh_entsize
= sizeof (Sym
);
526 if (Pread(P
, &elfdata
[off
], sp
->sh_size
,
527 sp
->sh_addr
) != sp
->sh_size
) {
528 dprintf("failed to read .SUNW_ldynsym at %lx\n",
533 /* No need to round up ldynsym data. Dynsym data is same type */
538 * Section Header: .dynsym
540 sp
->sh_name
= SHSTR_NDX_dynsym
;
541 sp
->sh_type
= SHT_DYNSYM
;
542 sp
->sh_flags
= SHF_ALLOC
;
543 sp
->sh_addr
= d
[DI_SYMTAB
]->d_un
.d_ptr
;
544 if (ehdr
->e_type
== ET_DYN
)
547 sp
->sh_size
= dynsym_size
;
548 sp
->sh_link
= dynstr_shndx
;
549 sp
->sh_info
= 1; /* Index of 1st global in table */
550 sp
->sh_addralign
= SH_ADDRALIGN
;
551 sp
->sh_entsize
= sizeof (Sym
);
553 if (Pread(P
, &elfdata
[off
], sp
->sh_size
,
554 sp
->sh_addr
) != sp
->sh_size
) {
555 dprintf("failed to read .dynsym at %lx\n",
560 off
+= roundup(sp
->sh_size
, SH_ADDRALIGN
);
564 * Section Header: .dynstr
566 sp
->sh_name
= SHSTR_NDX_dynstr
;
567 sp
->sh_type
= SHT_STRTAB
;
568 sp
->sh_flags
= SHF_ALLOC
| SHF_STRINGS
;
569 sp
->sh_addr
= d
[DI_STRTAB
]->d_un
.d_ptr
;
570 if (ehdr
->e_type
== ET_DYN
)
573 sp
->sh_size
= d
[DI_STRSZ
]->d_un
.d_val
;
576 sp
->sh_addralign
= 1;
579 if (Pread(P
, &elfdata
[off
], sp
->sh_size
,
580 sp
->sh_addr
) != sp
->sh_size
) {
581 dprintf("failed to read .dynstr\n");
584 off
+= roundup(sp
->sh_size
, SH_ADDRALIGN
);
588 * Section Header: .dynamic
590 sp
->sh_name
= SHSTR_NDX_dynamic
;
591 sp
->sh_type
= SHT_DYNAMIC
;
592 sp
->sh_flags
= SHF_WRITE
| SHF_ALLOC
;
593 sp
->sh_addr
= phdr
->p_vaddr
;
594 if (ehdr
->e_type
== ET_DYN
)
597 sp
->sh_size
= phdr
->p_filesz
;
598 sp
->sh_link
= dynstr_shndx
;
600 sp
->sh_addralign
= SH_ADDRALIGN
;
601 sp
->sh_entsize
= sizeof (Dyn
);
603 (void) memcpy(&elfdata
[off
], dp
, sp
->sh_size
);
604 off
+= roundup(sp
->sh_size
, SH_ADDRALIGN
);
608 * Section Header: .plt
613 uintptr_t strtabptr
, strtabname
;
616 char strbuf
[sizeof ("_PROCEDURE_LINKAGE_TABLE_")];
619 * Now we need to find the address of the plt by looking
620 * up the "_PROCEDURE_LINKAGE_TABLE_" symbol.
623 /* get the address of the symtab and strtab sections */
624 strtabptr
= d
[DI_STRTAB
]->d_un
.d_ptr
;
625 symtabptr
= (Sym
*)(uintptr_t)d
[DI_SYMTAB
]->d_un
.d_ptr
;
626 if (ehdr
->e_type
== ET_DYN
) {
628 symtabptr
= (Sym
*)((uintptr_t)symtabptr
+ addr
);
631 if ((hptr
== NULL
) || (hnbuckets
== 0) || (hnchains
== 0)) {
632 dprintf("empty or missing .hash\n");
636 /* find the .hash bucket address for this symbol */
637 plt_symhash
= elf_hash("_PROCEDURE_LINKAGE_TABLE_");
638 htmp
= plt_symhash
% hnbuckets
;
639 hash
= &((uint_t
*)hptr
)[2 + htmp
];
641 /* read the elf hash bucket index */
642 if (Pread(P
, &ndx
, sizeof (ndx
), (uintptr_t)hash
) !=
644 dprintf("Pread of .hash at %lx failed\n", (long)hash
);
649 if (Pread(P
, &sym
, sizeof (sym
),
650 (uintptr_t)&symtabptr
[ndx
]) != sizeof (sym
)) {
651 dprintf("Pread of .symtab at %lx failed\n",
652 (long)&symtabptr
[ndx
]);
656 strtabname
= strtabptr
+ sym
.st_name
;
657 if (Pread_string(P
, strbuf
, sizeof (strbuf
),
659 dprintf("Pread of .strtab at %lx failed\n",
664 if (strcmp("_PROCEDURE_LINKAGE_TABLE_", strbuf
) == 0)
667 hash
= &((uint_t
*)hptr
)[2 + hnbuckets
+ ndx
];
668 if (Pread(P
, &ndx
, sizeof (ndx
), (uintptr_t)hash
) !=
670 dprintf("Pread of .hash at %lx failed\n",
677 if (sym
.st_value
!= d
[DI_PLTGOT
]->d_un
.d_ptr
) {
678 dprintf("warning: DI_PLTGOT (%lx) doesn't match "
679 ".plt symbol pointer (%lx)",
680 (long)d
[DI_PLTGOT
]->d_un
.d_ptr
,
687 "Failed to find \"_PROCEDURE_LINKAGE_TABLE_\"\n");
691 sp
->sh_name
= SHSTR_NDX_plt
;
692 sp
->sh_type
= SHT_PROGBITS
;
693 sp
->sh_flags
= SHF_WRITE
| SHF_ALLOC
| SHF_EXECINSTR
;
694 sp
->sh_addr
= sym
.st_value
;
695 if (ehdr
->e_type
== ET_DYN
)
701 sp
->sh_addralign
= SH_ADDRALIGN
;
702 sp
->sh_entsize
= M_PLT_ENTSIZE
;
704 if (Pread(P
, &elfdata
[off
], sp
->sh_size
, sp
->sh_addr
) !=
706 dprintf("failed to read .plt at %lx\n",
710 off
+= roundup(sp
->sh_size
, SH_ADDRALIGN
);
715 /* make sure we didn't write past the end of allocated memory */
717 assert(((uintptr_t)(sp
) - 1) < ((uintptr_t)elfdata
+ size
));
720 if ((elf
= elf_memory(elfdata
, size
)) == NULL
) {
721 dprintf("failed to create ELF object "
722 "in memory for size %ld\n", (long)size
);
727 fptr
->file_elfmem
= elfdata
;