summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/include/i386/machdep_x86.h24
-rw-r--r--usr/src/cmd/sgs/include/sparc/machdep_sparc.h50
-rw-r--r--usr/src/lib/libproc/amd64/Pisadep.c10
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.c7
-rw-r--r--usr/src/lib/libproc/common/Pcore.c11
-rw-r--r--usr/src/lib/libproc/common/Psymtab.c101
-rw-r--r--usr/src/lib/libproc/common/Psymtab_machelf32.c249
-rw-r--r--usr/src/lib/libproc/common/libproc.h1
-rw-r--r--usr/src/lib/libproc/i386/Pisadep.c10
-rw-r--r--usr/src/lib/libproc/sparc/Pisadep.c14
-rw-r--r--usr/src/lib/libproc/sparcv9/Pisadep.c45
-rw-r--r--usr/src/uts/common/sys/elf_386.h50
-rw-r--r--usr/src/uts/common/sys/elf_SPARC.h80
-rw-r--r--usr/src/uts/common/sys/elf_amd64.h42
-rw-r--r--usr/src/uts/common/sys/machelf.h6
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>