diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/sgs/include/i386/machdep_x86.h | 24 | ||||
-rw-r--r-- | usr/src/cmd/sgs/include/sparc/machdep_sparc.h | 50 | ||||
-rw-r--r-- | usr/src/lib/libproc/amd64/Pisadep.c | 10 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcontrol.c | 7 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Pcore.c | 11 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Psymtab.c | 101 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/Psymtab_machelf32.c | 249 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/libproc.h | 1 | ||||
-rw-r--r-- | usr/src/lib/libproc/i386/Pisadep.c | 10 | ||||
-rw-r--r-- | usr/src/lib/libproc/sparc/Pisadep.c | 14 | ||||
-rw-r--r-- | usr/src/lib/libproc/sparcv9/Pisadep.c | 45 | ||||
-rw-r--r-- | usr/src/uts/common/sys/elf_386.h | 50 | ||||
-rw-r--r-- | usr/src/uts/common/sys/elf_SPARC.h | 80 | ||||
-rw-r--r-- | usr/src/uts/common/sys/elf_amd64.h | 42 | ||||
-rw-r--r-- | usr/src/uts/common/sys/machelf.h | 6 |
15 files changed, 423 insertions, 277 deletions
diff --git a/usr/src/cmd/sgs/include/i386/machdep_x86.h b/usr/src/cmd/sgs/include/i386/machdep_x86.h index 9904a8d7c6..b53f02554a 100644 --- a/usr/src/cmd/sgs/include/i386/machdep_x86.h +++ b/usr/src/cmd/sgs/include/i386/machdep_x86.h @@ -133,35 +133,11 @@ extern "C" { #define M_SEGM_ORIGIN (Addr)0x400000ULL /* default 1st segment origin */ #define M_SEGM_AORIGIN (Addr)0x10000ULL /* alternative 1st segment */ /* origin */ -#define M_WORD_ALIGN 8 #else #define M_STACK_GAP (0x08000000) #define M_STACK_PGS (0x00048000) #define M_SEGM_ORIGIN (Addr)(M_STACK_GAP + M_STACK_PGS) #define M_SEGM_AORIGIN M_SEGM_ORIGIN -#define M_WORD_ALIGN 4 -#endif - - -/* - * Plt and Got information; the first few .got and .plt entries are reserved - * PLT[0] jump to dynamic linker - * GOT[0] address of _DYNAMIC - */ -#define M_PLT_ENTSIZE 16 /* plt entry size in bytes */ -#define M_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ -#define M_PLT_INSSIZE 6 /* single plt instruction size */ -#define M_PLT_RESERVSZ M_PLT_ENTSIZE /* PLT[0] reserved */ - -#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ -#define M_GOT_XLINKMAP 1 /* got index for link map */ -#define M_GOT_XRTLD 2 /* got index for rtbinder */ -#define M_GOT_XNumber 3 /* reserved no. of got entries */ - -#ifdef _ELF64 -#define M_GOT_ENTSIZE 8 /* got entry size in bytes */ -#else /* ELF32 */ -#define M_GOT_ENTSIZE 4 /* got entry size in bytes */ #endif /* diff --git a/usr/src/cmd/sgs/include/sparc/machdep_sparc.h b/usr/src/cmd/sgs/include/sparc/machdep_sparc.h index 22c8f512c6..fa361b6425 100644 --- a/usr/src/cmd/sgs/include/sparc/machdep_sparc.h +++ b/usr/src/cmd/sgs/include/sparc/machdep_sparc.h @@ -113,57 +113,11 @@ extern "C" { #define M_BIND_ADJ 4 /* adjustment for end of */ /* elf_rtbndr() address */ - -/* - * Plt and Got information; the first few .got and .plt entries are reserved - * PLT[0] jump to dynamic linker - * GOT[0] address of _DYNAMIC - */ -#define M_PLT_INSSIZE 4 /* single plt instruction size */ -#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ -#define M_GOT_XNumber 1 /* reserved no. of got entries */ - -/* - * ELF32 bit PLT constants - */ -#define M32_PLT_ENTSIZE 12 /* 32bit plt entry size in bytes */ - -/* - * ELF64 bit PLT constants - */ -#define M64_PLT_NEARPLTS 0x8000 /* # of NEAR PLTS we can have */ -#define M64_PLT_ENTSIZE 32 /* plt entry size in bytes */ -#define M64_PLT_FENTSIZE 24 /* size of far plt is 6 instructions */ - /* x 4bytes */ -#define M64_PLT_PSIZE 8 /* size of PLTP pointer */ -#define M64_PLT_FBLKCNTS 160 /* # of plts in far PLT blocks */ -#define M64_PLT_FBLOCKSZ (M64_PLT_FBLKCNTS *\ - M64_PLT_ENTSIZE) /* size of far PLT block */ - - -#ifdef _ELF64 -#define M_PLT_ENTSIZE M64_PLT_ENTSIZE /* plt entry size in bytes */ -#define M_PLT_XNumber 4 /* reserved no. of plt entries */ -#define M_PLT_ALIGN 256 /* alignment of .plt section */ -#define M_PLT_RESERVSZ (M_PLT_XNumber * \ - M_PLT_ENTSIZE) /* first 4 plt's reserved */ -#define M_GOT_ENTSIZE 8 /* got entry size in bytes */ -#define M_GOT_MAXSMALL 1024 /* maximum no. of small gots */ -#else /* Elf32 */ -#define M_PLT_ENTSIZE M32_PLT_ENTSIZE /* plt entry size in bytes */ -#define M_PLT_XNumber 4 /* reserved no. of plt entries */ -#define M_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ -#define M_PLT_RESERVSZ (M_PLT_XNumber * \ - M_PLT_ENTSIZE) /* first 4 plt's reserved */ -#define M_GOT_ENTSIZE 4 /* got entry size in bytes */ -#define M_GOT_MAXSMALL 2048 /* maximum no. of small gots */ -#endif /* _ELF64 */ - /* transition flags for got sizing */ +/* transition flags for got sizing */ #define M_GOT_LARGE (Sword)(-M_GOT_MAXSMALL - 1) #define M_GOT_SMALL (Sword)(-M_GOT_MAXSMALL - 2) #define M_GOT_MIXED (Sword)(-M_GOT_MAXSMALL - 3) - /* * Other machine dependent entities */ @@ -179,13 +133,11 @@ extern "C" { #define M_SEGM_ORIGIN (Addr)0x100000000ULL /* default 1st segment origin */ #define M_SEGM_AORIGIN (Addr)0x100000ULL /* alternative 1st segment */ /* origin */ -#define M_WORD_ALIGN 8 #else #define M_SEGM_ALIGN ELF_SPARC_MAXPGSZ #define M_SEGM_ORIGIN (Addr)0x10000 /* default 1st segment origin */ #define M_SEGM_AORIGIN M_SEGM_ORIGIN /* alternative 1st segment */ /* origin */ -#define M_WORD_ALIGN 4 #endif /* diff --git a/usr/src/lib/libproc/amd64/Pisadep.c b/usr/src/lib/libproc/amd64/Pisadep.c index c2ab4dd3ab..a78e304d4c 100644 --- a/usr/src/lib/libproc/amd64/Pisadep.c +++ b/usr/src/lib/libproc/amd64/Pisadep.c @@ -19,17 +19,16 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/stack.h> #include <sys/regset.h> #include <sys/frame.h> #include <sys/sysmacros.h> #include <sys/trap.h> +#include <sys/machelf.h> #include <stdlib.h> #include <unistd.h> @@ -40,9 +39,6 @@ #include "Pcontrol.h" #include "Pstack.h" -#define M_PLT_NRSV 1 /* reserved PLT entries */ -#define M_PLT_ENTSIZE 16 /* size of each PLT entry */ - static uchar_t int_syscall_instr[] = { 0xCD, T_SYSCALLINT }; static uchar_t syscall_instr[] = { 0x0f, 0x05 }; @@ -61,7 +57,7 @@ Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr) return (NULL); } - i = (pltaddr - fp->file_plt_base) / M_PLT_ENTSIZE - M_PLT_NRSV; + i = (pltaddr - fp->file_plt_base) / M_PLT_ENTSIZE - M_PLT_XNumber; if (P->status.pr_dmodel == PR_MODEL_LP64) { Elf64_Rela r; diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c index fd4e10fb74..deccb122c3 100644 --- a/usr/src/lib/libproc/common/Pcontrol.c +++ b/usr/src/lib/libproc/common/Pcontrol.c @@ -20,14 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Portions Copyright 2007 Chad Mynhier */ -#pragma ident "%Z%%M% %I% %E% SMI" - +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -59,6 +58,7 @@ int _libproc_debug; /* set non-zero to enable debugging printfs */ int _libproc_no_qsort; /* set non-zero to inhibit sorting */ /* of symbol tables */ +int _libproc_incore_elf; /* only use in-core elf data */ sigset_t blockable_sigs; /* signals to block when we need to be safe */ static int minfd; /* minimum file descriptor returned by dupfd(fd, 0) */ @@ -99,6 +99,7 @@ _libproc_init(void) { _libproc_debug = getenv("LIBPROC_DEBUG") != NULL; _libproc_no_qsort = getenv("LIBPROC_NO_QSORT") != NULL; + _libproc_incore_elf = getenv("LIBPROC_INCORE_ELF") != NULL; (void) sigfillset(&blockable_sigs); (void) sigdelset(&blockable_sigs, SIGKILL); diff --git a/usr/src/lib/libproc/common/Pcore.c b/usr/src/lib/libproc/common/Pcore.c index 2357be4364..234538eb0b 100644 --- a/usr/src/lib/libproc/common/Pcore.c +++ b/usr/src/lib/libproc/common/Pcore.c @@ -810,9 +810,16 @@ fake_up_symtab(struct ps_prochandle *P, const elf_file_header_t *ehdr, if (symtab->sh_addr == 0 || (mp = Paddr2mptr(P, symtab->sh_addr)) == NULL || - (fp = mp->map_file) == NULL || - fp->file_symtab.sym_data_pri != NULL) { + (fp = mp->map_file) == NULL) { dprintf("fake_up_symtab: invalid section\n"); + dprintf("fp->file_symtab.sym_data_pri == %lx\n", + (long)fp->file_symtab.sym_data_pri); + return; + } + + if (fp->file_symtab.sym_data_pri != NULL) { + dprintf("Symbol table already loaded (sh_addr 0x%lx)\n", + (long)symtab->sh_addr); return; } diff --git a/usr/src/lib/libproc/common/Psymtab.c b/usr/src/lib/libproc/common/Psymtab.c index 725a765798..7a71fa155d 100644 --- a/usr/src/lib/libproc/common/Psymtab.c +++ b/usr/src/lib/libproc/common/Psymtab.c @@ -1587,6 +1587,31 @@ optimize_symtab(sym_tbl_t *symtab) free(syms); } + +static Elf * +build_fake_elf(struct ps_prochandle *P, file_info_t *fptr, GElf_Ehdr *ehdr, + size_t *nshdrs, Elf_Data **shdata) +{ + size_t shstrndx; + Elf_Scn *scn; + Elf *elf; + + if ((elf = fake_elf(P, fptr)) == NULL || + elf_kind(elf) != ELF_K_ELF || + gelf_getehdr(elf, ehdr) == NULL || + elf_getshdrnum(elf, nshdrs) == -1 || + elf_getshdrstrndx(elf, &shstrndx) == -1 || + (scn = elf_getscn(elf, shstrndx)) == NULL || + (*shdata = elf_getdata(scn, NULL)) == NULL) { + if (elf != NULL) + (void) elf_end(elf); + dprintf("failed to fake up ELF file\n"); + return (NULL); + } + + return (elf); +} + /* * Build the symbol table for the given mapped file. */ @@ -1657,20 +1682,22 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) * name. If anything goes wrong try to fake up an elf file from * the in-core elf image. */ - if ((fptr->file_fd = open(objectfile, O_RDONLY)) < 0) { + + if (_libproc_incore_elf) { + dprintf("Pbuild_file_symtab: using in-core data for: %s\n", + fptr->file_pname); + + if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) == + NULL) + return; + + } else if ((fptr->file_fd = open(objectfile, O_RDONLY)) < 0) { dprintf("Pbuild_file_symtab: failed to open %s: %s\n", objectfile, strerror(errno)); - if ((elf = fake_elf(P, fptr)) == NULL || - elf_kind(elf) != ELF_K_ELF || - gelf_getehdr(elf, &ehdr) == NULL || - elf_getshdrnum(elf, &nshdrs) == -1 || - elf_getshdrstrndx(elf, &shstrndx) == -1 || - (scn = elf_getscn(elf, shstrndx)) == NULL || - (shdata = elf_getdata(scn, NULL)) == NULL) { - dprintf("failed to fake up ELF file\n"); + if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) == + NULL) return; - } } else if ((elf = elf_begin(fptr->file_fd, ELF_C_READ, NULL)) == NULL || elf_kind(elf) != ELF_K_ELF || @@ -1683,17 +1710,11 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) dprintf("failed to process ELF file %s: %s\n", objectfile, (err == 0) ? "<null>" : elf_errmsg(err)); + (void) elf_end(elf); - if ((elf = fake_elf(P, fptr)) == NULL || - elf_kind(elf) != ELF_K_ELF || - gelf_getehdr(elf, &ehdr) == NULL || - elf_getshdrnum(elf, &nshdrs) == -1 || - elf_getshdrstrndx(elf, &shstrndx) == -1 || - (scn = elf_getscn(elf, shstrndx)) == NULL || - (shdata = elf_getdata(scn, NULL)) == NULL) { - dprintf("failed to fake up ELF file\n"); - goto bad; - } + if ((elf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) == + NULL) + return; } else if (file_differs(P, elf, fptr)) { Elf *newelf; @@ -1704,23 +1725,14 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) * they don't agree, we try to fake up a new elf file and * proceed with that instead. */ - dprintf("ELF file %s (%lx) doesn't match in-core image\n", fptr->file_pname, (ulong_t)fptr->file_map->map_pmap.pr_vaddr); - if ((newelf = fake_elf(P, fptr)) == NULL || - elf_kind(newelf) != ELF_K_ELF || - gelf_getehdr(newelf, &ehdr) == NULL || - elf_getshdrnum(newelf, &nshdrs) == -1 || - elf_getshdrstrndx(newelf, &shstrndx) == -1 || - (scn = elf_getscn(newelf, shstrndx)) == NULL || - (shdata = elf_getdata(scn, NULL)) == NULL) { - dprintf("failed to fake up ELF file\n"); - } else { + if ((newelf = build_fake_elf(P, fptr, &ehdr, &nshdrs, &shdata)) + != NULL) { (void) elf_end(elf); elf = newelf; - dprintf("switched to faked up ELF file\n"); } } @@ -1910,13 +1922,36 @@ Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) GElf_Dyn d; for (i = 0; i < ndyn; i++) { - if (gelf_getdyn(dyn->c_data, i, &d) != NULL && - d.d_tag == DT_JMPREL) { + if (gelf_getdyn(dyn->c_data, i, &d) == NULL) + continue; + + switch (d.d_tag) { + case DT_JMPREL: dprintf("DT_JMPREL is %p\n", (void *)(uintptr_t)d.d_un.d_ptr); fptr->file_jmp_rel = d.d_un.d_ptr + fptr->file_dyn_base; break; + case DT_STRTAB: + dprintf("DT_STRTAB is %p\n", + (void *)(uintptr_t)d.d_un.d_ptr); + break; + case DT_PLTGOT: + dprintf("DT_PLTGOT is %p\n", + (void *)(uintptr_t)d.d_un.d_ptr); + break; + case DT_SUNW_SYMTAB: + dprintf("DT_SUNW_SYMTAB is %p\n", + (void *)(uintptr_t)d.d_un.d_ptr); + break; + case DT_SYMTAB: + dprintf("DT_SYMTAB is %p\n", + (void *)(uintptr_t)d.d_un.d_ptr); + break; + case DT_HASH: + dprintf("DT_HASH is %p\n", + (void *)(uintptr_t)d.d_un.d_ptr); + break; } } diff --git a/usr/src/lib/libproc/common/Psymtab_machelf32.c b/usr/src/lib/libproc/common/Psymtab_machelf32.c index 704e41547c..9c57b3e5c7 100644 --- a/usr/src/lib/libproc/common/Psymtab_machelf32.c +++ b/usr/src/lib/libproc/common/Psymtab_machelf32.c @@ -20,15 +20,15 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> +#include <string.h> #include <memory.h> #include <sys/sysmacros.h> #include <sys/machelf.h> @@ -146,14 +146,14 @@ * We can figure out the size of the .plt section, but it takes some * doing. We need to use the following information: * - * DT_PLTGOT base of the PLT + * DT_PLTGOT GOT PLT entry offset (on x86) or PLT offset (on sparc) * DT_JMPREL base of the PLT's relocation section * DT_PLTRELSZ size of the PLT's relocation section * DT_PLTREL type of the PLT's relocation section * - * We can use the relocation section to figure out the address of the - * last entry and subtract off the value of DT_PLTGOT to calculate - * the size of the PLT. + * We can use the number of relocation entries to calculate the size of + * the PLT. We get the address of the PLT by looking up the + * _PROCEDURE_LINKAGE_TABLE_ symbol. * * For more information, check out the System V Generic ABI. */ @@ -245,7 +245,7 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr, size_t size = 0; caddr_t elfdata = NULL; Elf *elf; - size_t dynsym_size, ldynsym_size; + size_t dynsym_size = 0, ldynsym_size; int dynstr_shndx; Ehdr *ep; Shdr *sp; @@ -253,7 +253,9 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr, Dyn *d[DI_NENT] = { 0 }; uint_t i; Off off; - size_t pltsz = 0, pltentsz; + size_t pltsz = 0, pltentries = 0; + uintptr_t hptr = NULL; + Word hnchains, hnbuckets; if (ehdr->e_type == ET_DYN) phdr->p_vaddr += addr; @@ -327,18 +329,6 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr, goto bad; } - if (ehdr->e_type == ET_DYN) { - if (d[DI_PLTGOT] != NULL) - d[DI_PLTGOT]->d_un.d_ptr += addr; - if (d[DI_JMPREL] != NULL) - d[DI_JMPREL]->d_un.d_ptr += addr; - d[DI_SYMTAB]->d_un.d_ptr += addr; - d[DI_HASH]->d_un.d_ptr += addr; - d[DI_STRTAB]->d_un.d_ptr += addr; - if (d[DI_SUNW_SYMTAB] != NULL) - d[DI_SUNW_SYMTAB]->d_un.d_ptr += addr; - } - /* SUNW_ldynsym must be adjacent to dynsym. Ignore if not */ if ((d[DI_SUNW_SYMTAB] != NULL) && (d[DI_SUNW_SYMSZ] != NULL) && ((d[DI_SYMTAB]->d_un.d_ptr <= d[DI_SUNW_SYMTAB]->d_un.d_ptr) || @@ -359,6 +349,23 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr, size += sizeof (Shdr); size += roundup(sizeof (shstr), SH_ADDRALIGN); + if (d[DI_HASH] != NULL) { + Word hash[2]; + + hptr = d[DI_HASH]->d_un.d_ptr; + if (ehdr->e_type == ET_DYN) + hptr += addr; + + if (Pread(P, hash, sizeof (hash), hptr) != sizeof (hash)) { + dprintf("Pread of .hash at %lx failed\n", + (long)(hptr)); + goto bad; + } + + hnbuckets = hash[0]; + hnchains = hash[1]; + } + /* * .dynsym and .SUNW_ldynsym sections. * @@ -374,16 +381,7 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr, ldynsym_size -= dynsym_size; dynstr_shndx = 4; } else { - Word nchain; - - if (Pread(P, &nchain, sizeof (nchain), - d[DI_HASH]->d_un.d_ptr + sizeof (nchain)) != - sizeof (nchain)) { - dprintf("Pread of .dynsym at %lx failed\n", - (long)(d[DI_HASH]->d_un.d_val + sizeof (nchain))); - goto bad; - } - dynsym_size = sizeof (Sym) * nchain; + dynsym_size = sizeof (Sym) * hnchains; ldynsym_size = 0; dynstr_shndx = 3; } @@ -400,64 +398,41 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr, /* .plt section */ if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL && d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) { - uintptr_t penult, ult; - uintptr_t jmprel = d[DI_JMPREL]->d_un.d_ptr; size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val; if (d[DI_PLTREL]->d_un.d_val == DT_RELA) { - uint_t entries = pltrelsz / sizeof (Rela); - Rela r[2]; - - if (entries < PLTREL_MIN_ENTRIES) { - dprintf("too few PLT relocation entries " - "(found %d, expected at least %d)\n", - entries, PLTREL_MIN_ENTRIES); - goto bad; - } - if (entries < PLTREL_MIN_ENTRIES + 2) - goto done_with_plt; - - if (Pread(P, r, sizeof (r), jmprel + sizeof (r[0]) * - entries - sizeof (r)) != sizeof (r)) { - dprintf("Pread of DT_RELA failed\n"); - goto bad; - } - - penult = r[0].r_offset; - ult = r[1].r_offset; - + pltentries = pltrelsz / sizeof (Rela); } else if (d[DI_PLTREL]->d_un.d_val == DT_REL) { - uint_t entries = pltrelsz / sizeof (Rel); - Rel r[2]; - - if (entries < PLTREL_MIN_ENTRIES) { - dprintf("too few PLT relocation entries " - "(found %d, expected at least %d)\n", - entries, PLTREL_MIN_ENTRIES); - goto bad; - } - if (entries < PLTREL_MIN_ENTRIES + 2) - goto done_with_plt; - - if (Pread(P, r, sizeof (r), jmprel + sizeof (r[0]) * - entries - sizeof (r)) != sizeof (r)) { - dprintf("Pread of DT_REL failed\n"); - goto bad; - } - - penult = r[0].r_offset; - ult = r[1].r_offset; + pltentries = pltrelsz / sizeof (Rel); } else { - dprintf(".plt: unknown jmprel value\n"); - goto bad; + /* fall back to the platform default */ +#if ((defined(__i386) || defined(__amd64)) && !defined(_ELF64)) + pltentries = pltrelsz / sizeof (Rel); + dprintf("DI_PLTREL not found, defaulting to Rel"); +#else /* (!(__i386 || __amd64)) || _ELF64 */ + pltentries = pltrelsz / sizeof (Rela); + dprintf("DI_PLTREL not found, defaulting to Rela"); +#endif /* (!(__i386 || __amd64) || _ELF64 */ } - pltentsz = ult - penult; - - if (ehdr->e_type == ET_DYN) - ult += addr; - - pltsz = ult - d[DI_PLTGOT]->d_un.d_ptr + pltentsz; + if (pltentries < PLTREL_MIN_ENTRIES) { + dprintf("too few PLT relocation entries " + "(found %lu, expected at least %d)\n", + (long)pltentries, PLTREL_MIN_ENTRIES); + goto bad; + } + if (pltentries < PLTREL_MIN_ENTRIES + 2) + goto done_with_plt; + + /* + * Now that we know the number of plt relocation entries + * we can calculate the size of the plt. + */ + pltsz = (pltentries + M_PLT_XNumber) * M_PLT_ENTSIZE; +#if defined(__sparc) + /* The sparc PLT always has a (delay slot) nop at the end */ + pltsz += 4; +#endif /* __sparc */ size += sizeof (Shdr); size += roundup(pltsz, SH_ADDRALIGN); @@ -532,7 +507,7 @@ done_with_plt: sp->sh_flags = SHF_ALLOC; sp->sh_addr = d[DI_SUNW_SYMTAB]->d_un.d_ptr; if (ehdr->e_type == ET_DYN) - sp->sh_addr -= addr; + sp->sh_addr += addr; sp->sh_offset = off; sp->sh_size = ldynsym_size; sp->sh_link = dynstr_shndx; @@ -542,9 +517,9 @@ done_with_plt: sp->sh_entsize = sizeof (Sym); if (Pread(P, &elfdata[off], sp->sh_size, - d[DI_SUNW_SYMTAB]->d_un.d_ptr) != sp->sh_size) { + sp->sh_addr) != sp->sh_size) { dprintf("failed to read .SUNW_ldynsym at %lx\n", - (long)d[DI_SUNW_SYMTAB]->d_un.d_ptr); + (long)sp->sh_addr); goto bad; } off += sp->sh_size; @@ -560,7 +535,7 @@ done_with_plt: sp->sh_flags = SHF_ALLOC; sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr; if (ehdr->e_type == ET_DYN) - sp->sh_addr -= addr; + sp->sh_addr += addr; sp->sh_offset = off; sp->sh_size = dynsym_size; sp->sh_link = dynstr_shndx; @@ -569,9 +544,9 @@ done_with_plt: sp->sh_entsize = sizeof (Sym); if (Pread(P, &elfdata[off], sp->sh_size, - d[DI_SYMTAB]->d_un.d_ptr) != sp->sh_size) { + sp->sh_addr) != sp->sh_size) { dprintf("failed to read .dynsym at %lx\n", - (long)d[DI_SYMTAB]->d_un.d_ptr); + (long)sp->sh_addr); goto bad; } @@ -586,7 +561,7 @@ done_with_plt: sp->sh_flags = SHF_ALLOC | SHF_STRINGS; sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr; if (ehdr->e_type == ET_DYN) - sp->sh_addr -= addr; + sp->sh_addr += addr; sp->sh_offset = off; sp->sh_size = d[DI_STRSZ]->d_un.d_val; sp->sh_link = 0; @@ -595,7 +570,7 @@ done_with_plt: sp->sh_entsize = 0; if (Pread(P, &elfdata[off], sp->sh_size, - d[DI_STRTAB]->d_un.d_ptr) != sp->sh_size) { + sp->sh_addr) != sp->sh_size) { dprintf("failed to read .dynstr\n"); goto bad; } @@ -626,28 +601,108 @@ done_with_plt: * Section Header: .plt */ if (pltsz != 0) { + ulong_t plt_symhash; + uint_t htmp, ndx; + uintptr_t strtabptr, strtabname; + Sym sym, *symtabptr; + uint_t *hash; + char strbuf[sizeof ("_PROCEDURE_LINKAGE_TABLE_")]; + + /* + * Now we need to find the address of the plt by looking + * up the "_PROCEDURE_LINKAGE_TABLE_" symbol. + */ + + /* get the address of the symtab and strtab sections */ + strtabptr = d[DI_STRTAB]->d_un.d_ptr; + symtabptr = (Sym *)(uintptr_t)d[DI_SYMTAB]->d_un.d_ptr; + if (ehdr->e_type == ET_DYN) { + strtabptr += addr; + symtabptr = (Sym*)((uintptr_t)symtabptr + addr); + } + + /* find the .hash bucket address for this symbol */ + plt_symhash = elf_hash("_PROCEDURE_LINKAGE_TABLE_"); + htmp = plt_symhash % hnbuckets; + hash = &((uint_t *)hptr)[2 + htmp]; + + /* read the elf hash bucket index */ + if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) != + sizeof (ndx)) { + dprintf("Pread of .hash at %lx failed\n", (long)hash); + goto bad; + } + + while (ndx) { + if (Pread(P, &sym, sizeof (sym), + (uintptr_t)&symtabptr[ndx]) != sizeof (sym)) { + dprintf("Pread of .symtab at %lx failed\n", + (long)&symtabptr[ndx]); + goto bad; + } + + strtabname = strtabptr + sym.st_name; + if (Pread_string(P, strbuf, sizeof (strbuf), + strtabname) < 0) { + dprintf("Pread of .strtab at %lx failed\n", + (long)strtabname); + goto bad; + } + + if (strcmp("_PROCEDURE_LINKAGE_TABLE_", strbuf) == 0) + break; + + hash = &((uint_t *)hptr)[2 + hnbuckets + ndx]; + if (Pread(P, &ndx, sizeof (ndx), (uintptr_t)hash) != + sizeof (ndx)) { + dprintf("Pread of .hash at %lx failed\n", + (long)hash); + goto bad; + } + } + +#if defined(__sparc) + if (sym.st_value != d[DI_PLTGOT]->d_un.d_ptr) { + dprintf("warning: DI_PLTGOT (%lx) doesn't match " + ".plt symbol pointer (%lx)", + (long)d[DI_PLTGOT]->d_un.d_ptr, + (long)sym.st_value); + } +#endif /* __sparc */ + + if (ndx == 0) { + dprintf( + "Failed to find \"_PROCEDURE_LINKAGE_TABLE_\"\n"); + goto bad; + } + sp->sh_name = SHSTR_NDX_plt; sp->sh_type = SHT_PROGBITS; sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR; - sp->sh_addr = d[DI_PLTGOT]->d_un.d_ptr; + sp->sh_addr = sym.st_value; if (ehdr->e_type == ET_DYN) - sp->sh_addr -= addr; + sp->sh_addr += addr; sp->sh_offset = off; sp->sh_size = pltsz; sp->sh_link = 0; sp->sh_info = 0; sp->sh_addralign = SH_ADDRALIGN; - sp->sh_entsize = pltentsz; + sp->sh_entsize = M_PLT_ENTSIZE; - if (Pread(P, &elfdata[off], sp->sh_size, - d[DI_PLTGOT]->d_un.d_ptr) != sp->sh_size) { - dprintf("failed to read .plt\n"); + if (Pread(P, &elfdata[off], sp->sh_size, sp->sh_addr) != + sp->sh_size) { + dprintf("failed to read .plt at %lx\n", + (long)sp->sh_addr); goto bad; } off += roundup(sp->sh_size, SH_ADDRALIGN); sp++; } + /* make sure we didn't write past the end of allocated memory */ + sp++; + assert(((uintptr_t)(sp) - 1) < ((uintptr_t)elfdata + size)); + free(dp); if ((elf = elf_memory(elfdata, size)) == NULL) { free(elfdata); @@ -664,6 +719,4 @@ bad: if (elfdata != NULL) free(elfdata); return (NULL); - - } diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index a425d3c211..8f3730c3a0 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -85,6 +85,7 @@ struct ps_lwphandle; extern int _libproc_debug; /* set non-zero to enable debugging fprintfs */ extern int _libproc_no_qsort; /* set non-zero to inhibit sorting */ /* of symbol tables */ +extern int _libproc_incore_elf; /* only use in-core elf data */ #if defined(__sparc) #define R_RVAL1 R_O0 /* register holding a function return value */ diff --git a/usr/src/lib/libproc/i386/Pisadep.c b/usr/src/lib/libproc/i386/Pisadep.c index f8334149d7..e09b40bb73 100644 --- a/usr/src/lib/libproc/i386/Pisadep.c +++ b/usr/src/lib/libproc/i386/Pisadep.c @@ -19,17 +19,16 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/stack.h> #include <sys/regset.h> #include <sys/frame.h> #include <sys/sysmacros.h> #include <sys/trap.h> +#include <sys/machelf.h> #include <stdlib.h> #include <unistd.h> @@ -40,9 +39,6 @@ #include "Pcontrol.h" #include "Pstack.h" -#define M_PLT_NRSV 1 /* reserved PLT entries */ -#define M_PLT_ENTSIZE 16 /* size of each PLT entry */ - static uchar_t int_syscall_instr[] = { 0xCD, T_SYSCALLINT }; const char * @@ -62,7 +58,7 @@ Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr) return (NULL); } - i = (pltaddr - fp->file_plt_base) / M_PLT_ENTSIZE - M_PLT_NRSV; + i = (pltaddr - fp->file_plt_base) / M_PLT_ENTSIZE - M_PLT_XNumber; r_addr = fp->file_jmp_rel + i * sizeof (r); diff --git a/usr/src/lib/libproc/sparc/Pisadep.c b/usr/src/lib/libproc/sparc/Pisadep.c index 2edf8c024e..9bdb2703ce 100644 --- a/usr/src/lib/libproc/sparc/Pisadep.c +++ b/usr/src/lib/libproc/sparc/Pisadep.c @@ -19,16 +19,15 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/stack.h> #include <sys/regset.h> #include <sys/frame.h> #include <sys/sysmacros.h> +#include <sys/machelf.h> #include <stdlib.h> #include <unistd.h> @@ -40,9 +39,6 @@ #include "Pstack.h" #include "Pisadep.h" -#define M_PLT_NRSV 4 /* reserved PLT entries */ -#define M_PLT_ENTSIZE 12 /* size of each PLT entry */ - #define SYSCALL32 0x91d02008 /* 32-bit syscall (ta 8) instruction */ #ifndef WINDOWSIZE32 @@ -67,7 +63,7 @@ Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr) } i = (pltaddr - fp->file_plt_base - - M_PLT_NRSV * M_PLT_ENTSIZE) / M_PLT_ENTSIZE; + M_PLT_XNumber * M32_PLT_ENTSIZE) / M32_PLT_ENTSIZE; r_addr = fp->file_jmp_rel + i * sizeof (Elf32_Rela); @@ -328,8 +324,8 @@ uintptr_t Psyscall_setup(struct ps_prochandle *P, int nargs, int sysindex, uintptr_t sp) { sp -= (nargs > 6)? - WINDOWSIZE32 + sizeof (int32_t) * (1 + nargs) : - WINDOWSIZE32 + sizeof (int32_t) * (1 + 6); + WINDOWSIZE32 + sizeof (int32_t) * (1 + nargs) : + WINDOWSIZE32 + sizeof (int32_t) * (1 + 6); sp = PSTACK_ALIGN32(sp); P->status.pr_lwp.pr_reg[R_G1] = sysindex; diff --git a/usr/src/lib/libproc/sparcv9/Pisadep.c b/usr/src/lib/libproc/sparcv9/Pisadep.c index 6d7284a939..9a78ed08a5 100644 --- a/usr/src/lib/libproc/sparcv9/Pisadep.c +++ b/usr/src/lib/libproc/sparcv9/Pisadep.c @@ -19,18 +19,17 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #define __sparcv9cpu #include <sys/stack.h> #include <sys/regset.h> #include <sys/frame.h> #include <sys/sysmacros.h> +#include <sys/machelf.h> #include <stdlib.h> #include <unistd.h> @@ -43,18 +42,6 @@ #include "Pisadep.h" #include "P32ton.h" -#define M_PLT32_NRSV 4 /* reserved PLT entries */ -#define M_PLT32_ENTSIZE 12 /* size of each PLT entry */ - -#define M_PLT64_NRSV 4 /* reserved bit PLT entries */ -#define M_PLT64_ENTSIZE 32 /* size of each PLT entry */ -#define M_PLT64_FENTSIZE 24 /* size of far PLT entry */ -#define M_PLT64_NEARPLTS 0x8000 /* # of NEAR PLTS we can have */ -#define M_PLT64_FBLKCNTS 160 /* # of plts in far PLT blocks */ -#define M_PLT64_FBLOCKSZ (M_PLT64_FBLKCNTS * \ - (M_PLT64_FENTSIZE + sizeof (uint64_t))) - /* size of far PLT block */ - #define SYSCALL32 0x91d02008 /* 32-bit syscall (ta 8) instruction */ #define SYSCALL64 0x91d02040 /* 64-bit syscall (ta 64) instruction */ @@ -79,18 +66,18 @@ Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr) uintptr_t pltoff; pltoff = pltaddr - fp->file_plt_base; - if (pltoff < (M_PLT64_NEARPLTS * M_PLT64_ENTSIZE)) { + if (pltoff < (M64_PLT_NEARPLTS * M64_PLT_ENTSIZE)) { i = (pltaddr - fp->file_plt_base - - M_PLT64_NRSV * M_PLT64_ENTSIZE) / M_PLT64_ENTSIZE; + M_PLT_XNumber * M64_PLT_ENTSIZE) / M64_PLT_ENTSIZE; } else { uintptr_t pltblockoff; - pltblockoff = pltoff - (M_PLT64_NEARPLTS * - M_PLT64_ENTSIZE); - i = M_PLT64_NEARPLTS + - ((pltblockoff / M_PLT64_FBLOCKSZ) * - M_PLT64_FBLKCNTS) + ((pltblockoff % - M_PLT64_FBLOCKSZ) / M_PLT64_FENTSIZE) - - M_PLT64_NRSV; + pltblockoff = pltoff - (M64_PLT_NEARPLTS * + M64_PLT_ENTSIZE); + i = M64_PLT_NEARPLTS + + ((pltblockoff / M64_PLT_FBLOCKSZ) * + M64_PLT_FBLKCNTS) + ((pltblockoff % + M64_PLT_FBLOCKSZ) / M64_PLT_FENTSIZE) - + M_PLT_XNumber; } r_addr = fp->file_jmp_rel + i * sizeof (Elf64_Rela); @@ -108,7 +95,7 @@ Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr) Elf32_Rela r; i = (pltaddr - fp->file_plt_base - - M_PLT32_NRSV * M_PLT32_ENTSIZE) / M_PLT32_ENTSIZE; + M_PLT_XNumber * M32_PLT_ENTSIZE) / M32_PLT_ENTSIZE; r_addr = fp->file_jmp_rel + i * sizeof (Elf32_Rela); @@ -445,14 +432,14 @@ Psyscall_setup(struct ps_prochandle *P, int nargs, int sysindex, uintptr_t sp) if (model == PR_MODEL_LP64) { sp -= (nargs > 6)? - WINDOWSIZE64 + sizeof (int64_t) * nargs : - WINDOWSIZE64 + sizeof (int64_t) * 6; + WINDOWSIZE64 + sizeof (int64_t) * nargs : + WINDOWSIZE64 + sizeof (int64_t) * 6; sp = PSTACK_ALIGN64(sp); ret = sp + WINDOWSIZE32 + sizeof (int32_t); } else { sp -= (nargs > 6)? - WINDOWSIZE32 + sizeof (int32_t) * (1 + nargs) : - WINDOWSIZE32 + sizeof (int32_t) * (1 + 6); + WINDOWSIZE32 + sizeof (int32_t) * (1 + nargs) : + WINDOWSIZE32 + sizeof (int32_t) * (1 + 6); sp = PSTACK_ALIGN32(sp); ret = sp + WINDOWSIZE64 + sizeof (int32_t); } diff --git a/usr/src/uts/common/sys/elf_386.h b/usr/src/uts/common/sys/elf_386.h index cac257feb5..2ac67c8db2 100644 --- a/usr/src/uts/common/sys/elf_386.h +++ b/usr/src/uts/common/sys/elf_386.h @@ -23,15 +23,13 @@ * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T * All Rights Reserved * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ELF_386_H #define _SYS_ELF_386_H -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */ - #ifdef __cplusplus extern "C" { #endif @@ -85,6 +83,52 @@ extern "C" { #define SHN_BEFORE 0xff00 #define SHN_AFTER 0xff01 +/* + * There are consumers of this file that want to include elf defines for + * all architectures. This is a problem for the defines below, because + * while they are architecture specific they have common names. Hence to + * prevent attempts to redefine these variables we'll check if any of + * the other elf architecture header files have been included. If + * they have then we'll just stick with the existing definitions. + */ +#if !defined(_SYS_ELF_MACH_COMMON) +#define _SYS_ELF_MACH_COMMON +#define _SYS_ELF_MACH_386 + +/* + * Plt and Got information; the first few .got and .plt entries are reserved + * PLT[0] jump to dynamic linker + * GOT[0] address of _DYNAMIC + */ +#define M_PLT_INSSIZE 6 /* single plt instruction size */ +#define M_PLT_XNumber 1 /* PLT[0] reserved */ +#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ +#define M_GOT_XLINKMAP 1 /* got index for link map */ +#define M_GOT_XRTLD 2 /* got index for rtbinder */ +#define M_GOT_XNumber 3 /* reserved no. of got entries */ + +#define M32_WORD_ALIGN 4 +#define M32_PLT_ENTSIZE 16 /* plt entry size in bytes */ +#define M32_PLT_ALIGN M32_WORD_ALIGN /* alignment of .plt section */ +#define M32_GOT_ENTSIZE 4 /* got entry size in bytes */ +#define M32_PLT_RESERVSZ (M_PLT_XNumber * \ + M32_PLT_ENTSIZE) /* first plt reserved */ + + +/* + * Make common alias for the 32/64 bit specific defines based on _ELF64 + */ +#if !defined(_ELF64) +/* architecture common defines */ +#define M_WORD_ALIGN M32_WORD_ALIGN +#define M_PLT_ENTSIZE M32_PLT_ENTSIZE +#define M_PLT_ALIGN M32_PLT_ALIGN +#define M_PLT_RESERVSZ M32_PLT_RESERVSZ +#define M_GOT_ENTSIZE M32_GOT_ENTSIZE +#endif /* !_ELF64 */ + +#endif /* !_SYS_ELF_MACH_COMMON */ + #ifdef __cplusplus } #endif diff --git a/usr/src/uts/common/sys/elf_SPARC.h b/usr/src/uts/common/sys/elf_SPARC.h index 63554a2aa5..976242e961 100644 --- a/usr/src/uts/common/sys/elf_SPARC.h +++ b/usr/src/uts/common/sys/elf_SPARC.h @@ -23,15 +23,13 @@ * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T * All Rights Reserved * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ELF_SPARC_H #define _SYS_ELF_SPARC_H -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */ - #ifdef __cplusplus extern "C" { #endif @@ -176,6 +174,82 @@ extern "C" { #define STO_SPARC_REGISTER_G6 0x6 /* register %g6 */ #define STO_SPARC_REGISTER_G7 0x7 /* register %g7 */ +/* + * There are consumers of this file that want to include elf defines for + * all architectures. This is a problem for the defines below, because + * while they are architecture specific they have common names. Hence to + * prevent attempts to redefine these variables we'll check if any of + * the other elf architecture header files have been included. If + * they have then we'll just stick with the existing definitions. + */ +#if !defined(_SYS_ELF_MACH_COMMON) +#define _SYS_ELF_MACH_COMMON + +/* + * Plt and Got information; the first few .got and .plt entries are reserved + * PLT[0] jump to dynamic linker + * GOT[0] address of _DYNAMIC + */ +#define M_PLT_INSSIZE 4 /* single plt instruction size */ +#define M_PLT_XNumber 4 /* reserved no. of plt entries */ +#define M_GOT_XDYNAMIC 0 /* got index for _DYNAMIC */ +#define M_GOT_XNumber 1 /* reserved no. of got entries */ + +/* + * ELF32 bit PLT constants + */ +#define M32_WORD_ALIGN 4 +#define M32_PLT_ENTSIZE 12 /* plt entry size in bytes */ +#define M32_PLT_ALIGN M_WORD_ALIGN /* alignment of .plt section */ +#define M32_GOT_ENTSIZE 4 /* got entry size in bytes */ +#define M32_GOT_MAXSMALL 2048 /* maximum no. of small gots */ +#define M32_PLT_RESERVSZ (M_PLT_XNumber * \ + M32_PLT_ENTSIZE) /* first 4 plt's reserved */ + +/* + * ELF64 bit PLT constants + */ +#define M64_WORD_ALIGN 8 +#define M64_PLT_ENTSIZE 32 /* plt entry size in bytes */ +#define M64_PLT_ALIGN 256 /* alignment of .plt section */ +#define M64_GOT_ENTSIZE 8 /* got entry size in bytes */ +#define M64_GOT_MAXSMALL 1024 /* maximum no. of small gots */ +#define M64_PLT_RESERVSZ (M_PLT_XNumber * \ + M64_PLT_ENTSIZE) /* first 4 plt's reserved */ + +#define M64_PLT_NEARPLTS 0x8000 /* # of NEAR PLTS we can have */ +#define M64_PLT_FENTSIZE 24 /* size of far plt is 6 instructions */ + /* x 4bytes */ +#define M64_PLT_PSIZE 8 /* size of PLTP pointer */ +#define M64_PLT_FBLKCNTS 160 /* # of plts in far PLT blocks */ +#define M64_PLT_FBLOCKSZ (M64_PLT_FBLKCNTS *\ + M64_PLT_ENTSIZE) /* size of far PLT block */ + + +/* + * Make common alias for the 32/64 bit specific defines based on _ELF64 + */ +#ifdef _ELF64 +/* architecture common defines */ +#define M_WORD_ALIGN M64_WORD_ALIGN +#define M_PLT_ENTSIZE M64_PLT_ENTSIZE +#define M_PLT_ALIGN M64_PLT_ALIGN +#define M_PLT_RESERVSZ M64_PLT_RESERVSZ +#define M_GOT_ENTSIZE M64_GOT_ENTSIZE +/* sparc specific defines */ +#define M_GOT_MAXSMALL M64_GOT_MAXSMALL +#else /* !_ELF64 */ +/* architecture common defines */ +#define M_WORD_ALIGN M32_WORD_ALIGN +#define M_PLT_ENTSIZE M32_PLT_ENTSIZE +#define M_PLT_ALIGN M32_PLT_ALIGN +#define M_PLT_RESERVSZ M32_PLT_RESERVSZ +#define M_GOT_ENTSIZE M32_GOT_ENTSIZE +/* sparc specific defines */ +#define M_GOT_MAXSMALL M32_GOT_MAXSMALL +#endif /* !_ELF64 */ + +#endif /* !_SYS_ELF_MACH_COMMON */ #ifdef __cplusplus } diff --git a/usr/src/uts/common/sys/elf_amd64.h b/usr/src/uts/common/sys/elf_amd64.h index f22c0d8cd6..263ea1bc51 100644 --- a/usr/src/uts/common/sys/elf_amd64.h +++ b/usr/src/uts/common/sys/elf_amd64.h @@ -20,14 +20,14 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_ELF_AMD64_H #define _SYS_ELF_AMD64_H -#pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/elf_386.h> #ifdef __cplusplus extern "C" { @@ -127,14 +127,44 @@ extern "C" { #define SHF_AMD64_LARGE 0x10000000 #define SHF_X86_64_LARGE SHF_AMD64_LARGE -#define SHF_ORDERED 0x40000000 -#define SHF_EXCLUDE 0x80000000 -#define SHN_BEFORE 0xff00 -#define SHN_AFTER 0xff01 #define SHN_AMD64_LCOMMON 0xff02 #define SHN_X86_64_LCOMMON SHN_AMD64_LCOMMON +/* + * There are consumers of this file that want to include elf defines for + * all architectures. This is a problem for the defines below, because + * while they are architecture specific they have common names. Hence to + * prevent attempts to redefine these variables we'll check if any of + * the other elf architecture header files have been included. If + * they have then we'll just stick with the existing definitions. + */ +#if defined(_SYS_ELF_MACH_386) + +/* + * Plt and Got information; the first few .got and .plt entries are reserved + * PLT[0] jump to dynamic linker + * GOT[0] address of _DYNAMIC + */ +#define M64_WORD_ALIGN 8 +#define M64_PLT_ENTSIZE M32_PLT_ENTSIZE +#define M64_PLT_ALIGN M64_WORD_ALIGN /* alignment of .plt section */ +#define M64_GOT_ENTSIZE 8 /* got entry size in bytes */ +#define M64_PLT_RESERVSZ M32_PLT_RESERVSZ + +/* + * Make common alias for the 32/64 bit specific defines based on _ELF64 + */ +#if defined(_ELF64) +/* architecture common defines */ +#define M_WORD_ALIGN M64_WORD_ALIGN +#define M_PLT_ENTSIZE M64_PLT_ENTSIZE +#define M_PLT_ALIGN M64_PLT_ALIGN +#define M_PLT_RESERVSZ M64_PLT_RESERVSZ +#define M_GOT_ENTSIZE M64_GOT_ENTSIZE +#endif /* _ELF64 */ + +#endif /* _SYS_ELF_MACH_386 */ #ifdef __cplusplus } diff --git a/usr/src/uts/common/sys/machelf.h b/usr/src/uts/common/sys/machelf.h index 6f2bfa17a0..da54df92c9 100644 --- a/usr/src/uts/common/sys/machelf.h +++ b/usr/src/uts/common/sys/machelf.h @@ -20,20 +20,18 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_MACHELF_H #define _SYS_MACHELF_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif -#if defined(__amd64) +#if defined(__amd64) || (defined(__i386) && defined(_ELF64)) #include <sys/elf_amd64.h> #elif defined(__i386) #include <sys/elf_386.h> |