summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_gelf.c39
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_gelf.h1
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_kproc.c6
-rw-r--r--usr/src/cmd/sgs/librtld_db/Makefile.com5
-rw-r--r--usr/src/cmd/sgs/librtld_db/amd64/Makefile3
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/_rtld_db.h72
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/librtld_db.msg12
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/llib-lrtld_db7
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/mapfile-vers18
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/mapfile-vers.6435
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/rd_elf.c156
-rw-r--r--usr/src/cmd/sgs/librtld_db/common/rtld_db.c28
-rw-r--r--usr/src/cmd/sgs/librtld_db/sparcv9/Makefile3
-rw-r--r--usr/src/head/link.h9
-rw-r--r--usr/src/head/rtld_db.h32
-rw-r--r--usr/src/lib/brand/lx/librtld_db/Makefile5
-rw-r--r--usr/src/lib/brand/lx/librtld_db/Makefile.com42
-rw-r--r--usr/src/lib/brand/lx/librtld_db/amd64/Makefile9
-rw-r--r--usr/src/lib/brand/lx/librtld_db/amd64/mapfile-vers32
-rw-r--r--usr/src/lib/brand/lx/librtld_db/common/lx_librtld_db.c428
-rw-r--r--usr/src/lib/brand/lx/librtld_db/common/mapfile-vers17
-rw-r--r--usr/src/lib/brand/lx/librtld_db/i386/Makefile10
-rw-r--r--usr/src/lib/libproc/common/Psymtab_machelf32.c26
23 files changed, 693 insertions, 302 deletions
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_gelf.c b/usr/src/cmd/mdb/common/mdb/mdb_gelf.c
index ade3da21cf..4bf43aec25 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_gelf.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_gelf.c
@@ -468,6 +468,45 @@ gelf_dyn_lookup(mdb_gelf_file_t *gf, GElf_Xword tag)
return ((GElf_Xword)-1L);
}
+void
+mdb_gelf_dyns_set(mdb_gelf_file_t *gf, void *dyns, size_t dyns_sz)
+{
+ size_t ndyns, i, dyn_size;
+ caddr_t dp;
+ GElf_Dyn *gdp;
+
+ if (gf->gf_dyns != NULL) {
+ /* Free the existing dyn entries */
+ free(gf->gf_dyns);
+ gf->gf_dyns = NULL;
+ gf->gf_ndyns = 0;
+ }
+
+ if (gf->gf_ehdr.e_ident[EI_CLASS] == ELFCLASS32)
+ dyn_size = sizeof (Elf32_Dyn);
+ else
+ dyn_size = sizeof (Elf64_Dyn);
+
+ ndyns = dyns_sz / dyn_size;
+ gf->gf_dyns = mdb_zalloc(sizeof (GElf_Dyn) * ndyns, UM_SLEEP);
+ gf->gf_ndyns = ndyns;
+
+ dp = dyns;
+ gdp = gf->gf_dyns;
+
+ if (gf->gf_ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
+ for (i = 0; i < ndyns; i++, dp += dyn_size, gdp++) {
+ /* LINTED - alignment */
+ (void) gelf32_to_dyn((Elf32_Dyn *)dp, gdp);
+ }
+ } else {
+ for (i = 0; i < ndyns; i++, dp += dyn_size, gdp++) {
+ /* LINTED - alignment */
+ (void) gelf64_to_dyn((Elf64_Dyn *)dp, gdp);
+ }
+ }
+}
+
static GElf_Dyn *
gelf_dyns_init(mdb_gelf_file_t *gf, size_t dyn_size,
GElf_Dyn *(*elf2gelf)(const void *, GElf_Dyn *))
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_gelf.h b/usr/src/cmd/mdb/common/mdb/mdb_gelf.h
index 4f9d5a95d4..a2baa4cfff 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_gelf.h
+++ b/usr/src/cmd/mdb/common/mdb/mdb_gelf.h
@@ -94,6 +94,7 @@ typedef struct mdb_gelf_dsym {
extern int mdb_gelf_check(mdb_io_t *, Elf32_Ehdr *, GElf_Half);
extern mdb_gelf_file_t *mdb_gelf_create(mdb_io_t *, GElf_Half, int);
extern void mdb_gelf_destroy(mdb_gelf_file_t *);
+extern void mdb_gelf_dyns_set(mdb_gelf_file_t *, void *, size_t);
extern void mdb_gelf_ehdr_to_gehdr(Ehdr *, GElf_Ehdr *);
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kproc.c b/usr/src/cmd/mdb/common/mdb/mdb_kproc.c
index 6adda9dbc6..41e57b60b5 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_kproc.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_kproc.c
@@ -182,6 +182,8 @@ kp_file_create(mdb_tgt_t *t, kp_map_t *kpm, GElf_Half etype)
{
kp_file_t *kpf = mdb_zalloc(sizeof (kp_file_t), UM_SLEEP);
kp_data_t *kp = t->t_data;
+ size_t dyns_sz;
+ void *dyns;
kpf->kpf_fio = kp_io_create(t, kpm);
kpf->kpf_map = kpm;
@@ -198,6 +200,10 @@ kp_file_create(mdb_tgt_t *t, kp_map_t *kpm, GElf_Half etype)
mdb_dprintf(MDB_DBG_TGT, "loading symbols for %s\n",
kpm->kpm_map.map_name);
+ if ((kp->kp_rap != NULL) && (rd_get_dyns(kp->kp_rap,
+ kpf->kpf_text_base, &dyns, &dyns_sz) == RD_OK))
+ mdb_gelf_dyns_set(kpf->kpf_file, dyns, dyns_sz);
+
kpf->kpf_dynsym = mdb_gelf_symtab_create_dynamic(kpf->kpf_file,
MDB_TGT_DYNSYM);
diff --git a/usr/src/cmd/sgs/librtld_db/Makefile.com b/usr/src/cmd/sgs/librtld_db/Makefile.com
index 5a87d8d2f9..318433264d 100644
--- a/usr/src/cmd/sgs/librtld_db/Makefile.com
+++ b/usr/src/cmd/sgs/librtld_db/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -74,5 +74,8 @@ ROOTFS_LINKS64= $(ROOTFS_LIBDIR64)/$(LIBLINKS)
$(ROOTFS_DYNLIB) := FILEMODE= 755
$(ROOTFS_DYNLIB64) := FILEMODE= 755
+pics/rd_elf.o := CERRWARN += -erroff=E_END_OF_LOOP_CODE_NOT_REACHED
+pics/rd_elf64.o := CERRWARN += -erroff=E_END_OF_LOOP_CODE_NOT_REACHED
+
$(VAR_POUND_1)$(ROOTFS_LIBDIR)/$(LINTLIBSRC): ../common/$(LINTLIBSRC)
$(VAR_POUND_1)$(INS.file) ../common/$(LINTLIBSRC)
diff --git a/usr/src/cmd/sgs/librtld_db/amd64/Makefile b/usr/src/cmd/sgs/librtld_db/amd64/Makefile
index 598eee444b..90593524fd 100644
--- a/usr/src/cmd/sgs/librtld_db/amd64/Makefile
+++ b/usr/src/cmd/sgs/librtld_db/amd64/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +37,7 @@ SGSMSGTARG += $(SGSMSGINTEL)
LINTFLAGS64 += $(VAR_LINTFLAGS64)
CPPFLAGS += -D_SYSCALL32
CONVLIBDIR = $(CONVLIBDIR64)
+DYNFLAGS += -M../common/mapfile-vers.64
.KEEP_STATE:
diff --git a/usr/src/cmd/sgs/librtld_db/common/_rtld_db.h b/usr/src/cmd/sgs/librtld_db/common/_rtld_db.h
index 0f513c1d32..da4a058372 100644
--- a/usr/src/cmd/sgs/librtld_db/common/_rtld_db.h
+++ b/usr/src/cmd/sgs/librtld_db/common/_rtld_db.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +39,60 @@
extern "C" {
#endif
+/*
+ * Brand helper libraries must name their ops vector using this macro.
+ */
+#ifdef _LP64
+#ifdef _ELF64
+#define RTLD_DB_BRAND_OPS rtld_db_brand_ops64
+#else /* !_ELF64 */
+#define RTLD_DB_BRAND_OPS rtld_db_brand_ops32
+#endif /* !_ELF64 */
+#else /* !_LP64 */
+#define RTLD_DB_BRAND_OPS rtld_db_brand_ops32
+#endif /* !_LP64 */
+
+/*
+ * State kept for brand helper libraries
+ *
+ * All librtld_db brand plugin libraries need to specify a Lmid_t value
+ * that controls how link map ids are assigned to native solaris objects
+ * (as pointed to by the processes aux vectors) which are enumerated by
+ * librtld_db. In most cases this value will either be LM_ID_NONE or
+ * LM_ID_BRAND.
+ *
+ * If LM_ID_NONE is specified in the structure below, then when native solaris
+ * objects are enumerated by librtld_db, their link map id values will match
+ * the link map ids assigned to those objects by the solaris linker within
+ * the target process.
+ *
+ * If LM_ID_BRAND is specified in the structure below, then when native solaris
+ * objects are enumerated by librtld_db, their link map id value will be
+ * explicity set to LM_ID_BRAND, regardless of the link map ids assigned to
+ * those objects by the solaris linker within the target process.
+ *
+ * In all cases the librtld_db brand plugin library can report any link
+ * map id value that it wants for objects that it enumerates via it's
+ * rho_loadobj_iter() entry point.
+ */
+typedef struct __rd_helper_data *rd_helper_data_t;
+typedef struct rd_helper_ops {
+ Lmid_t rho_lmid;
+ rd_helper_data_t (*rho_init)(rd_agent_t *,
+ struct ps_prochandle *);
+ void (*rho_fini)(rd_helper_data_t);
+ int (*rho_loadobj_iter)(rd_helper_data_t,
+ rl_iter_f *, void *);
+ rd_err_e (*rho_get_dyns)(rd_helper_data_t,
+ psaddr_t, void **, size_t *);
+} rd_helper_ops_t;
+
+typedef struct rd_helper {
+ void *rh_dlhandle;
+ rd_helper_ops_t *rh_ops;
+ rd_helper_data_t rh_data;
+} rd_helper_t;
+
struct rd_agent {
mutex_t rd_mutex;
struct ps_prochandle *rd_psp; /* prochandle pointer */
@@ -76,26 +130,36 @@ extern int rtld_db_logging;
extern rd_err_e rd_binder_exit_addr(struct rd_agent *, const char *,
psaddr_t *);
-extern rd_err_e _rd_reset32(struct rd_agent *);
+
extern rd_err_e _rd_event_enable32(rd_agent_t *, int);
extern rd_err_e _rd_event_getmsg32(rd_agent_t *, rd_event_msg_t *);
+extern rd_err_e _rd_get_dyns32(struct rd_agent *,
+ psaddr_t, Dyn **, size_t *);
+extern rd_err_e _rd_get_ehdr32(struct rd_agent *,
+ psaddr_t, Ehdr *, uint_t *);
extern rd_err_e _rd_objpad_enable32(struct rd_agent *, size_t);
extern rd_err_e _rd_loadobj_iter32(rd_agent_t *, rl_iter_f *, void *);
+extern rd_err_e _rd_reset32(struct rd_agent *);
extern rd_err_e find_dynamic_ent32(struct rd_agent *, psaddr_t,
Xword, Dyn *);
-
extern rd_err_e plt32_resolution(rd_agent_t *, psaddr_t, lwpid_t,
psaddr_t, rd_plt_info_t *);
+extern rd_err_e validate_rdebug32(struct rd_agent *rap);
#ifdef _LP64
-extern rd_err_e _rd_reset64(struct rd_agent *);
extern rd_err_e _rd_event_enable64(rd_agent_t *, int);
extern rd_err_e _rd_event_getmsg64(rd_agent_t *, rd_event_msg_t *);
+extern rd_err_e _rd_get_dyns64(struct rd_agent *,
+ psaddr_t, Elf64_Dyn **, size_t *);
+extern rd_err_e _rd_get_ehdr64(struct rd_agent *,
+ psaddr_t, Elf64_Ehdr *, uint_t *);
extern rd_err_e _rd_objpad_enable64(struct rd_agent *, size_t);
extern rd_err_e _rd_loadobj_iter64(rd_agent_t *, rl_iter_f *, void *);
+extern rd_err_e _rd_reset64(struct rd_agent *);
extern rd_err_e find_dynamic_ent64(struct rd_agent *, psaddr_t,
Xword, Elf64_Dyn *);
extern rd_err_e plt64_resolution(rd_agent_t *, psaddr_t, lwpid_t,
psaddr_t, rd_plt_info_t *);
+extern rd_err_e validate_rdebug64(struct rd_agent *rap);
#endif
#ifdef __cplusplus
diff --git a/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg b/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg
index a68b417490..97f3e77dbf 100644
--- a/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg
+++ b/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg
@@ -20,10 +20,11 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
+#
# Message file for cmd/sgs/librtld_db.
@@ -75,13 +76,15 @@
@ MSG_DB_READFAIL_2 "rtld_db: rpr: read of 0x%llx failed"
@ MSG_DB_READFAIL_3 "rtld_db: roe: read of 0x%llx failed"
@ MSG_DB_READFAIL_4 "rtld_db: fde: read of 0x%llx failed"
+@ MSG_DB_READFAIL_5 "rtld_db: ge: read of 0x%llx failed"
+@ MSG_DB_READFAIL_6 "rtld_db: gd: read of 0x%llx failed"
@ MSG_DB_WRITEFAIL_1 "rtld_db: ree: write of 0x%llx failed"
@ MSG_DB_WRITEFAIL_2 "rtld_db: roe: write of 0x%llx failed"
@ MSG_DB_UNFNDSYM "rtld_db: rbea: unable to find sym: %s"
@ MSG_DB_NODYNDEBUG "rtld_db: fde: no %lld found in .dynamic"
@ MSG_DB_FINDDYNAMIC "rtld_db: fde: DYNAMIC entry found tag: %d found. \
val: 0x%llx"
-@ MSG_DB_HELPER_PREFIX "/usr/lib/brand/"
+@ MSG_DB_HELPER_PREFIX "/usr/lib/brand"
@@ -99,7 +102,7 @@
@ MSG_DB_RDEVENTGETMSG "rtld_db: rd_event_getmsg(dmodel=%d, type=%d, \
state=%d)"
@ MSG_DB_RDOBJPADE "rtld_db: rd_objpad_enable(padsize=0x%llx)"
-@ MSG_DB_64BIT_PREFIX "64/";
+@ MSG_DB_64BIT_PREFIX "64/"
@ MSG_DB_BRAND_HELPERPATH_PREFIX "%s/%s/%s/%s%s_librtld_db.so.1"
@ MSG_DB_BRAND_HELPERPATH "%s/%s/%s%s_librtld_db.so.1"
@ MSG_DB_HELPERNOOPS "rtld_db: helper lib loaded but ops not preset"
@@ -122,4 +125,5 @@
@ MSG_SYM_DLACT "rtld_db_dlactivity"
@ MSG_SYM_RTBIND "elf_rtbndr"
@ MSG_SYM_DYNAMIC "_DYNAMIC"
-@ MSG_SYM_BRANDOPS "rtld_db_brand_ops"
+@ MSG_SYM_BRANDOPS32 "rtld_db_brand_ops32"
+@ MSG_SYM_BRANDOPS64 "rtld_db_brand_ops64"
diff --git a/usr/src/cmd/sgs/librtld_db/common/llib-lrtld_db b/usr/src/cmd/sgs/librtld_db/common/llib-lrtld_db
index f54aa47e17..15bf89cbec 100644
--- a/usr/src/cmd/sgs/librtld_db/common/llib-lrtld_db
+++ b/usr/src/cmd/sgs/librtld_db/common/llib-lrtld_db
@@ -22,9 +22,9 @@
/* PROTOLIB1 */
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- */
+ */
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -45,6 +45,5 @@ rd_agent_t * rd_new(struct ps_prochandle *);
rd_err_e rd_objpad_enable(struct rd_agent *, size_t);
rd_err_e rd_plt_resolution(rd_agent_t *, psaddr_t, lwpid_t,
psaddr_t, rd_plt_info_t *);
-void rd_fix_phdrs(struct rd_agent *, Elf32_Dyn *, size_t,
- uintptr_t);
+rd_err_e rd_get_dyns(rd_agent_t *, psaddr_t, void **, size_t *);
rd_err_e rd_reset(struct rd_agent *);
diff --git a/usr/src/cmd/sgs/librtld_db/common/mapfile-vers b/usr/src/cmd/sgs/librtld_db/common/mapfile-vers
index 0739202216..9735d7e0df 100644
--- a/usr/src/cmd/sgs/librtld_db/common/mapfile-vers
+++ b/usr/src/cmd/sgs/librtld_db/common/mapfile-vers
@@ -1,7 +1,4 @@
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
@@ -21,7 +18,13 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
# ident "%Z%%M% %I% %E% SMI"
+#
SUNW_1.1 {
global:
@@ -37,12 +40,19 @@ SUNW_1.1 {
rd_new;
rd_objpad_enable;
rd_plt_resolution;
- rd_fix_phdrs;
rd_reset;
local:
*;
};
+SUNWprivate_1.1 {
+ global:
+ _rd_get_dyns32;
+ _rd_get_ehdr32;
+ _rd_loadobj_iter32;
+ rd_get_dyns;
+ validate_rdebug32;
+};
#Externally defined symbols
{
diff --git a/usr/src/cmd/sgs/librtld_db/common/mapfile-vers.64 b/usr/src/cmd/sgs/librtld_db/common/mapfile-vers.64
new file mode 100644
index 0000000000..5432883c53
--- /dev/null
+++ b/usr/src/cmd/sgs/librtld_db/common/mapfile-vers.64
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUNWprivate_1.1 {
+ global:
+ _rd_get_dyns64;
+ _rd_get_ehdr64;
+ _rd_loadobj_iter64;
+ validate_rdebug64;
+};
diff --git a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
index e427f966e7..99ad5312e5 100644
--- a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
+++ b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,24 +44,30 @@
*/
#ifdef _LP64
#ifdef _ELF64
-#define _rd_reset32 _rd_reset64
#define _rd_event_enable32 _rd_event_enable64
#define _rd_event_getmsg32 _rd_event_getmsg64
+#define _rd_get_dyns32 _rd_get_dyns64
+#define _rd_get_ehdr32 _rd_get_ehdr64
#define _rd_objpad_enable32 _rd_objpad_enable64
#define _rd_loadobj_iter32 _rd_loadobj_iter64
+#define _rd_reset32 _rd_reset64
#define find_dynamic_ent32 find_dynamic_ent64
+#define validate_rdebug32 validate_rdebug64
#define TList List
#define TListnode Listnode
+#define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS64
#else /* ELF32 */
#define Rt_map Rt_map32
#define Rtld_db_priv Rtld_db_priv32
#define TList List32
#define TListnode Listnode32
#define Lm_list Lm_list32
+#define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS32
#endif /* _ELF64 */
#else /* _LP64 */
#define TList List
#define TListnode Listnode
+#define MSG_SYM_BRANDOPS MSG_SYM_BRANDOPS32
#endif /* _LP64 */
/*
@@ -73,8 +79,8 @@
typedef ps_err_e (*ps_pbrandname_fp_t)(struct ps_prochandle *,
char *, size_t);
-static rd_err_e
-validate_rdebug(struct rd_agent *rap)
+rd_err_e
+validate_rdebug32(struct rd_agent *rap)
{
struct ps_prochandle *php = rap->rd_psp;
psaddr_t db_privp;
@@ -168,15 +174,6 @@ find_dynamic_ent32(struct rd_agent *rap, psaddr_t dynaddr,
extern char rtld_db_helper_path[MAXPATHLEN];
-#ifndef _ELF64
-void
-rd_fix_phdrs(struct rd_agent *rap, Elf32_Dyn *dp, size_t sz, uintptr_t a)
-{
- if (rap->rd_helper.rh_ops != NULL)
- rap->rd_helper.rh_ops->rho_fix_phdrs(rap, dp, sz, a);
-}
-#endif
-
rd_err_e
_rd_reset32(struct rd_agent *rap)
{
@@ -231,7 +228,7 @@ _rd_reset32(struct rd_agent *rap)
rap->rd_rdebug = (uintptr_t)auxvp->a_un.a_ptr;
LOG(ps_plog(MSG_ORIG(MSG_DB_FLDDATA),
rap->rd_rdebug));
- rc = validate_rdebug(rap);
+ rc = validate_rdebug32(rap);
break;
}
auxvp++;
@@ -258,7 +255,7 @@ _rd_reset32(struct rd_agent *rap)
rap->rd_rdebug = symaddr;
LOG(ps_plog(MSG_ORIG(MSG_DB_SYMRDEBUG),
EC_ADDR(symaddr)));
- rc = validate_rdebug(rap);
+ rc = validate_rdebug32(rap);
}
}
@@ -280,7 +277,7 @@ _rd_reset32(struct rd_agent *rap)
return (rc);
}
rap->rd_rdebug = dyn.d_un.d_ptr;
- rc = validate_rdebug(rap);
+ rc = validate_rdebug32(rap);
if (rc != RD_OK) {
LOG(ps_plog(MSG_ORIG(MSG_DB_INITFAILED)));
return (rc);
@@ -288,17 +285,19 @@ _rd_reset32(struct rd_agent *rap)
}
/*
- * If we are debugging a branded executable, load the appropriate helper
- * library, and call its initialization routine.
+ * If we are debugging a branded executable, load the appropriate
+ * helper library, and call its initialization routine. Being unable
+ * to load the helper library is not a critical error. (Hopefully
+ * we'll still be able to access some objects in the target.)
*/
ps_pbrandname = (ps_pbrandname_fp_t)dlsym(RTLD_PROBE, "ps_pbrandname");
- if ((ps_pbrandname != NULL) &&
+ while ((ps_pbrandname != NULL) &&
(ps_pbrandname(php, brandname, MAXPATHLEN) == PS_OK)) {
const char *isa = "";
-#ifdef __amd64
+#ifdef _LP64
isa = MSG_ORIG(MSG_DB_64BIT_PREFIX);
-#endif /* __amd64 */
+#endif /* _LP64 */
if (rtld_db_helper_path[0] != '\0')
(void) snprintf(brandlib, MAXPATHLEN,
@@ -312,28 +311,36 @@ _rd_reset32(struct rd_agent *rap)
MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa,
brandname);
- if ((rap->rd_helper.rh_dlhandle = dlopen(brandlib,
- RTLD_LAZY | RTLD_LOCAL)) == NULL) {
+ rap->rd_helper.rh_dlhandle = dlopen(brandlib,
+ RTLD_LAZY | RTLD_LOCAL);
+ if (rap->rd_helper.rh_dlhandle == NULL) {
LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADFAILED),
brandlib));
- return (RD_ERR);
+ break;
}
- if ((rap->rd_helper.rh_ops = dlsym(rap->rd_helper.rh_dlhandle,
- MSG_ORIG(MSG_SYM_BRANDOPS))) == NULL) {
+ rap->rd_helper.rh_ops = dlsym(rap->rd_helper.rh_dlhandle,
+ MSG_ORIG(MSG_SYM_BRANDOPS));
+ if (rap->rd_helper.rh_ops == NULL) {
LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERNOOPS),
brandlib));
- return (RD_ERR);
+ (void) dlclose(rap->rd_helper.rh_dlhandle);
+ rap->rd_helper.rh_dlhandle = NULL;
+ break;
}
- rap->rd_helper.rh_data = rap->rd_helper.rh_ops->rho_init(php);
+ rap->rd_helper.rh_data = rap->rd_helper.rh_ops->rho_init(rap,
+ php);
if (rap->rd_helper.rh_data == NULL) {
LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERINITFAILED)));
(void) dlclose(rap->rd_helper.rh_dlhandle);
rap->rd_helper.rh_dlhandle = NULL;
rap->rd_helper.rh_ops = NULL;
- } else
- LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADED), brandname));
+ break;
+ }
+
+ LOG(ps_plog(MSG_ORIG(MSG_DB_HELPERLOADED), brandname));
+ break;
}
if ((rap->rd_flags & RDF_FL_COREFILE) == 0) {
@@ -367,6 +374,85 @@ _rd_reset32(struct rd_agent *rap)
}
rd_err_e
+_rd_get_ehdr32(struct rd_agent *rap,
+ psaddr_t addr, Ehdr *ehdr, uint_t *phnum)
+{
+ struct ps_prochandle *php = rap->rd_psp;
+ Shdr shdr;
+
+ if (ps_pread(php, addr, ehdr, sizeof (*ehdr)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5), EC_ADDR(addr)));
+ return (RD_ERR);
+ }
+ if (phnum == NULL)
+ return (RD_OK);
+
+ if (ehdr->e_phnum != PN_XNUM) {
+ *phnum = ehdr->e_phnum;
+ return (RD_OK);
+ }
+
+ /* deal with elf extended program headers */
+ if ((ehdr->e_shoff == 0) || (ehdr->e_shentsize < sizeof (shdr)))
+ return (RD_ERR);
+
+ addr += ehdr->e_shoff;
+ if (ps_pread(php, addr, &shdr, sizeof (shdr)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_5), EC_ADDR(addr)));
+ return (RD_ERR);
+ }
+
+ if (shdr.sh_info == 0)
+ return (RD_ERR);
+
+ *phnum = shdr.sh_info;
+ return (RD_OK);
+}
+
+rd_err_e
+_rd_get_dyns32(rd_agent_t *rap, psaddr_t addr, Dyn **dynpp, size_t *dynpp_sz)
+{
+ struct ps_prochandle *php = rap->rd_psp;
+ rd_err_e err;
+ uint_t phnum;
+ Ehdr ehdr;
+ Phdr phdr;
+ Dyn *dynp;
+ int i;
+
+ /* We only need to muck with dyn elements for ET_DYN objects */
+ if ((err = _rd_get_ehdr32(rap, addr, &ehdr, &phnum)) != RD_OK)
+ return (err);
+
+ for (i = 0; i < phnum; i++) {
+ psaddr_t a = addr + ehdr.e_phoff + (i * ehdr.e_phentsize);
+ if (ps_pread(php, a, &phdr, sizeof (phdr)) != PS_OK) {
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6), EC_ADDR(a)));
+ return (RD_ERR);
+ }
+ if (phdr.p_type == PT_DYNAMIC)
+ break;
+ }
+ if (i == phnum)
+ return (RD_ERR);
+
+ if ((dynp = malloc(phdr.p_filesz)) == NULL)
+ return (RD_ERR);
+ if (ehdr.e_type == ET_DYN)
+ phdr.p_vaddr += addr;
+ if (ps_pread(php, phdr.p_vaddr, dynp, phdr.p_filesz) != PS_OK) {
+ free(dynp);
+ LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_6),
+ EC_ADDR(phdr.p_vaddr)));
+ return (RD_ERR);
+ }
+
+ *dynpp = dynp;
+ *dynpp_sz = phdr.p_filesz;
+ return (RD_OK);
+}
+
+rd_err_e
_rd_event_enable32(rd_agent_t *rap, int onoff)
{
struct ps_prochandle *php = rap->rd_psp;
@@ -502,8 +588,10 @@ iter_map(rd_agent_t *rap, unsigned long ident, psaddr_t lmaddr,
lobj.rl_base = (psaddr_t)ADDR(&rmap);
lobj.rl_flags = 0;
lobj.rl_refnameaddr = (psaddr_t)REFNAME(&rmap);
- if (rap->rd_helper.rh_dlhandle != NULL)
- lobj.rl_lmident = LM_ID_BRAND;
+ if ((rap->rd_helper.rh_ops != NULL) &&
+ (rap->rd_helper.rh_ops->rho_lmid != LM_ID_NONE))
+ lobj.rl_lmident =
+ rap->rd_helper.rh_ops->rho_lmid;
else
lobj.rl_lmident = ident;
@@ -679,8 +767,8 @@ _rd_loadobj_iter32(rd_agent_t *rap, rl_iter_f *cb, void *client_data)
return (rc);
if (rap->rd_helper.rh_ops != NULL)
- return (rap->rd_helper.rh_ops->rho_loadobj_iter(rap->rd_psp, cb,
- client_data, rap->rd_helper.rh_data));
+ return (rap->rd_helper.rh_ops->rho_loadobj_iter(
+ rap->rd_helper.rh_data, cb, client_data));
return (RD_OK);
}
diff --git a/usr/src/cmd/sgs/librtld_db/common/rtld_db.c b/usr/src/cmd/sgs/librtld_db/common/rtld_db.c
index a0324c6107..53f90f9c60 100644
--- a/usr/src/cmd/sgs/librtld_db/common/rtld_db.c
+++ b/usr/src/cmd/sgs/librtld_db/common/rtld_db.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,6 +110,23 @@ rd_ctl(int cmd, void *arg)
}
rd_err_e
+rd_get_dyns(rd_agent_t *rap, psaddr_t addr, void **dynpp, size_t *dynpp_sz)
+{
+ if (rap->rd_helper.rh_ops != NULL)
+ return (rap->rd_helper.rh_ops->rho_get_dyns(
+ rap->rd_helper.rh_data, addr, dynpp, dynpp_sz));
+
+#ifdef _LP64
+ if (rap->rd_dmodel == PR_MODEL_LP64)
+ return (_rd_get_dyns64(rap,
+ addr, (Elf64_Dyn **)dynpp, dynpp_sz));
+ else
+#endif
+ return (_rd_get_dyns32(rap,
+ addr, (Dyn **)dynpp, dynpp_sz));
+}
+
+rd_err_e
rd_reset(struct rd_agent *rap)
{
rd_err_e err;
@@ -151,7 +168,10 @@ rd_new(struct ps_prochandle *php)
rap->rd_psp = php;
(void) mutex_init(&rap->rd_mutex, USYNC_THREAD, 0);
if (rd_reset(rap) != RD_OK) {
- (void) dlclose(rap->rd_helper.rh_dlhandle);
+ if (rap->rd_helper.rh_dlhandle != NULL) {
+ rap->rd_helper.rh_ops->rho_fini(rap->rd_helper.rh_data);
+ (void) dlclose(rap->rd_helper.rh_dlhandle);
+ }
free(rap);
LOG(ps_plog(MSG_ORIG(MSG_DB_RESETFAIL)));
return ((rd_agent_t *)0);
@@ -165,6 +185,10 @@ void
rd_delete(rd_agent_t *rap)
{
LOG(ps_plog(MSG_ORIG(MSG_DB_RDDELETE), rap));
+ if (rap->rd_helper.rh_dlhandle != NULL) {
+ rap->rd_helper.rh_ops->rho_fini(rap->rd_helper.rh_data);
+ (void) dlclose(rap->rd_helper.rh_dlhandle);
+ }
free(rap);
}
diff --git a/usr/src/cmd/sgs/librtld_db/sparcv9/Makefile b/usr/src/cmd/sgs/librtld_db/sparcv9/Makefile
index 001502facb..de9be4eee9 100644
--- a/usr/src/cmd/sgs/librtld_db/sparcv9/Makefile
+++ b/usr/src/cmd/sgs/librtld_db/sparcv9/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +37,7 @@ SGSMSGTARG += $(SGSMSGSPARCV9)
LINTFLAGS64 += $(VAR_LINTFLAGS64)
CPPFLAGS += -D_SYSCALL32
CONVLIBDIR = $(CONVLIBDIR64)
+DYNFLAGS += -M../common/mapfile-vers.64
.KEEP_STATE:
diff --git a/usr/src/head/link.h b/usr/src/head/link.h
index c4f2dd8e94..5948108b37 100644
--- a/usr/src/head/link.h
+++ b/usr/src/head/link.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -114,11 +114,10 @@ extern void ld_section64();
*/
#define LM_ID_BASE 0x00
#define LM_ID_LDSO 0x01
-#define LM_ID_BRAND 0x02 /* marks branded objs in rd_loadobj_t */
-
-#define LM_ID_NUM 3
-
+#define LM_ID_NUM 2
+#define LM_ID_BRAND 0xfd /* brand emulation linkmap objs */
+#define LM_ID_NONE 0xfe /* no link map specified */
#define LM_ID_NEWLM 0xff /* create a new link-map */
/*
diff --git a/usr/src/head/rtld_db.h b/usr/src/head/rtld_db.h
index 52575a3bd3..c442087237 100644
--- a/usr/src/head/rtld_db.h
+++ b/usr/src/head/rtld_db.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -161,27 +161,6 @@ typedef struct rd_plt_info {
unsigned int pi_flags;
} rd_plt_info_t;
-/*
- * State kept for brand helper libraries
- */
-typedef struct rd_helper_ops {
- void *(*rho_init)(struct ps_prochandle *);
- int (*rho_loadobj_iter)(struct ps_prochandle *, rl_iter_f *cb,
- void *client_data, void *helper_data);
- void (*rho_fix_phdrs)(struct rd_agent *, Elf32_Dyn *, size_t,
- psaddr_t addr);
-} rd_helper_ops_t;
-
-typedef struct rd_helper {
- rd_helper_ops_t *rh_ops;
- void *rh_data;
- void *rh_dlhandle;
-} rd_helper_t;
-
-/*
- * Brand helper libraries must name their ops vector using this macro.
- */
-#define RTLD_DB_BRAND_OPS rtld_db_brand_ops
/*
* Values for pi_flags
@@ -211,10 +190,9 @@ extern rd_agent_t *rd_new(struct ps_prochandle *);
extern rd_err_e rd_objpad_enable(struct rd_agent *, size_t);
extern rd_err_e rd_plt_resolution(rd_agent_t *, psaddr_t, lwpid_t,
psaddr_t, rd_plt_info_t *);
-extern void rd_fix_phdrs(struct rd_agent *, Elf32_Dyn *,
- size_t, uintptr_t);
+extern rd_err_e rd_get_dyns(rd_agent_t *, psaddr_t, void **, size_t *);
extern rd_err_e rd_reset(struct rd_agent *);
-#else
+#else /* !__STDC__ */
extern void rd_delete();
extern char *rd_errstr();
extern rd_err_e rd_event_addr();
@@ -227,9 +205,9 @@ extern void rd_log();
extern rd_agent_t *rd_new();
extern rd_err_e rd_objpad_enable();
extern rd_err_e rd_plt_resolution();
-extern void rd_fix_phdrs();
+extern rd_err_e rd_get_dyns();
extern rd_err_e rd_reset();
-#endif
+#endif /* !__STDC__ */
#ifdef __cplusplus
}
diff --git a/usr/src/lib/brand/lx/librtld_db/Makefile b/usr/src/lib/brand/lx/librtld_db/Makefile
index f1ac26d7d5..2fc0a818f6 100644
--- a/usr/src/lib/brand/lx/librtld_db/Makefile
+++ b/usr/src/lib/brand/lx/librtld_db/Makefile
@@ -18,8 +18,9 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -27,7 +28,7 @@
default: all
-include ../../../Makefile.lib
+include $(SRC)/lib/Makefile.lib
SUBDIRS = $(MACH)
$(BUILD64)SUBDIRS += $(MACH64)
diff --git a/usr/src/lib/brand/lx/librtld_db/Makefile.com b/usr/src/lib/brand/lx/librtld_db/Makefile.com
index 8c723ad86b..202cc0fe7b 100644
--- a/usr/src/lib/brand/lx/librtld_db/Makefile.com
+++ b/usr/src/lib/brand/lx/librtld_db/Makefile.com
@@ -18,8 +18,9 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -28,32 +29,55 @@
LIBRARY = lx_librtld_db.a
VERS = .1
COBJS = lx_librtld_db.o
-OBJECTS = $(COBJS)
+OBJECTS = $(COBJS) $(COBJS64)
-include ../../../../Makefile.lib
+include $(SRC)/lib/Makefile.lib
include ../../Makefile.lx
CSRCS = $(COBJS:%o=../common/%c)
SRCS = $(CSRCS)
SRCDIR = ../common
-UTSBASE = ../../../../../uts
+UTSBASE = $(SRC)/uts
+#
+# ATTENTION:
+# Librtl_db brand plugin libraries should NOT directly invoke any
+# libproc.so interfaces or be linked against libproc. If a librtl_db
+# brand plugin library uses libproc.so interfaces then it may break
+# any other librtld_db consumers (like mdb) that tries to attach
+# to a branded process. The only safe interfaces that the a librtld_db
+# brand plugin library can use to access a target process are the
+# proc_service(3PROC) apis.
+#
+DYNFLAGS += $(VERSREF) -M../common/mapfile-vers
LIBS = $(DYNLIB)
-LDLIBS += -lc -lproc
+LDLIBS += -lc -lrtld_db
CFLAGS += $(CCVERBOSE)
CPPFLAGS += -D_REENTRANT -I../ -I$(UTSBASE)/common/brand/lx \
- -I../../../../../cmd/sgs/librtld_db/common \
- -I../../../../../cmd/sgs/include \
- -I../../../../../cmd/sgs/include/$(MACH)
+ -I$(SRC)/cmd/sgs/librtld_db/common \
+ -I$(SRC)/cmd/sgs/include \
+ -I$(SRC)/cmd/sgs/include/$(MACH)
ROOTLIBDIR = $(ROOT)/usr/lib/brand/lx
ROOTLIBDIR64 = $(ROOT)/usr/lib/brand/lx/$(MACH64)
+#
+# The top level Makefiles define define TEXT_DOMAIN. But librtld_db.so.1
+# isn't internationalized and this library won't be either. The only
+# messages that this library can generate are messages used for debugging
+# the operation of the library itself.
+#
+DTEXTDOM =
+
.KEEP_STATE:
all: $(LIBS)
lint: lintcheck
-include ../../../../Makefile.targ
+pics/%64.o: ../common/%.c
+ $(COMPILE.c) -D_ELF64 $(PICFLAGS) -o $@ $<
+ $(POST_PROCESS_O)
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/brand/lx/librtld_db/amd64/Makefile b/usr/src/lib/brand/lx/librtld_db/amd64/Makefile
index f2cbdd0616..4e32e6e622 100644
--- a/usr/src/lib/brand/lx/librtld_db/amd64/Makefile
+++ b/usr/src/lib/brand/lx/librtld_db/amd64/Makefile
@@ -18,17 +18,16 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
-# lib/brand/lx/librtld_db/amd64/Makefile
-
-ISASRCDIR=.
-ASFLAGS += -P -D_ASM
+# This is a 64-bit build, and as such needs 64-bit ELF support
+COBJS64 = lx_librtld_db64.o
include ../Makefile.com
include $(SRC)/lib/Makefile.lib.64
diff --git a/usr/src/lib/brand/lx/librtld_db/amd64/mapfile-vers b/usr/src/lib/brand/lx/librtld_db/amd64/mapfile-vers
new file mode 100644
index 0000000000..76415578d6
--- /dev/null
+++ b/usr/src/lib/brand/lx/librtld_db/amd64/mapfile-vers
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+SUNWprivate_1.1 {
+ global:
+ rtld_db_brand_ops64;
+};
diff --git a/usr/src/lib/brand/lx/librtld_db/common/lx_librtld_db.c b/usr/src/lib/brand/lx/librtld_db/common/lx_librtld_db.c
index 4be5ee9a84..7d17789755 100644
--- a/usr/src/lib/brand/lx/librtld_db/common/lx_librtld_db.c
+++ b/usr/src/lib/brand/lx/librtld_db/common/lx_librtld_db.c
@@ -35,51 +35,92 @@
#include <proc_service.h>
#include <rtld_db.h>
#include <synch.h>
+
#include <sys/lx_brand.h>
-static void *lx_ldb_client_init(struct ps_prochandle *);
-static int lx_ldb_iter(struct ps_prochandle *, rl_iter_f *, void *, void *);
-static void lx_ldb_fix_phdr(struct rd_agent *, Elf32_Dyn *, size_t,
- psaddr_t);
-
-struct rd_agent {
- mutex_t rd_mutex;
- struct ps_prochandle *rd_psp; /* prochandle pointer */
- psaddr_t rd_rdebug; /* rtld r_debug */
- psaddr_t rd_preinit; /* rtld_db_preinit */
- psaddr_t rd_postinit; /* rtld_db_postinit */
- psaddr_t rd_dlact; /* rtld_db_dlact */
- psaddr_t rd_tbinder; /* tail of binder */
- psaddr_t rd_rtlddbpriv; /* rtld rtld_db_priv */
- ulong_t rd_flags; /* flags */
- ulong_t rd_rdebugvers; /* rtld_db_priv.vers */
- int rd_dmodel; /* data model */
- rd_helper_t rd_helper; /* private to helper */
-};
+/*
+ * ATTENTION:
+ * Librtl_db brand plugin libraries should NOT directly invoke any
+ * libproc.so interfaces or be linked against libproc. If a librtl_db
+ * brand plugin library uses libproc.so interfaces then it may break
+ * any other librtld_db consumers (like mdb) that tries to attach
+ * to a branded process. The only safe interfaces that the a librtld_db
+ * brand plugin library can use to access a target process are the
+ * proc_service(3PROC) apis.
+ */
+
+/*
+ * M_DATA comes from some streams header file but is also redifined in
+ * _rtld_db.h, so nuke the old streams definition here.
+ */
+#ifdef M_DATA
+#undef M_DATA
+#endif /* M_DATA */
+
+/*
+ * For 32-bit versions of this library, this file get's compiled once.
+ * For 64-bit versions of this library, this file get's compiled twice,
+ * once with _ELF64 defined and once without. The expectation is that
+ * the 64-bit version of the library can properly deal with both 32-bit
+ * and 64-bit elf files, hence in the 64-bit library there are two copies
+ * of all the interfaces in this file, one set named *32 and one named *64.
+ *
+ * This also means that we need to be careful when declaring local pointers
+ * that point to objects in another processes address space, since these
+ * pointers may not match the current processes pointer width. Basically,
+ * we should avoid using data types that change size between 32 and 64 bit
+ * modes like: long, void *, uintprt_t, caddr_t, psaddr_t, size_t, etc.
+ * Instead we should declare all pointers as uint32_t. Then when we
+ * are compiled to deal with 64-bit targets we'll re-define uint32_t
+ * to be a uint64_t.
+ *
+ * Finally, one last importante note. All the 64-bit elf file code
+ * is never used and can't be tested. This is because we don't actually
+ * support 64-bit Linux processes yet. The reason that we have it here
+ * is because we want to support debugging 32-bit elf targets with the
+ * 64-bit version of this library, so we need to have a 64-bit version
+ * of this library. But a 64-bit version of this library is expected
+ * to provide debugging interfaces for both 32 and 64-bit elf targets.
+ * So we provide the 64-bit elf target interfaces, but they will never
+ * be invoked and are untested. If we ever add support for 64-bit elf
+ * Linux processes, we'll need to verify that this code works correctly
+ * for those targets.
+ */
+#ifdef _LP64
+#ifdef _ELF64
+#define lx_ldb_get_dyns32 lx_ldb_get_dyns64
+#define lx_ldb_init32 lx_ldb_init64
+#define lx_ldb_fini32 lx_ldb_fini64
+#define lx_ldb_loadobj_iter32 lx_ldb_loadobj_iter64
+#define lx_ldb_getauxval32 lx_ldb_getauxval64
+#define lx_elf_props32 lx_elf_props64
+#define _rd_get_dyns32 _rd_get_dyns64
+#define _rd_get_ehdr32 _rd_get_ehdr64
+#define uint32_t uint64_t
+#define Elf32_Dyn Elf64_Dyn
+#define Elf32_Ehdr Elf64_Ehdr
+#define Elf32_Phdr Elf64_Phdr
+#endif /* _ELF64 */
+#endif /* _LP64 */
+
+/* Included from usr/src/cmd/sgs/librtld_db/common */
+#include <_rtld_db.h>
typedef struct lx_rd {
- struct ps_prochandle *lr_php; /* prochandle of target */
- uint32_t lr_rdebug; /* address of lx r_debug */
- uint32_t lr_exec; /* base address of main executable */
+ rd_agent_t *lr_rap;
+ struct ps_prochandle *lr_php; /* proc handle pointer */
+ uint32_t lr_rdebug; /* address of lx r_debug */
+ uint32_t lr_exec; /* base address of executable */
} lx_rd_t;
-rd_helper_ops_t RTLD_DB_BRAND_OPS = {
- lx_ldb_client_init,
- lx_ldb_iter,
- lx_ldb_fix_phdr
-};
-
-struct lx_link_map
-{
+typedef struct lx_link_map {
uint32_t lxm_addr; /* Base address shared object is loaded at. */
uint32_t lxm_name; /* Absolute file name object was found in. */
uint32_t lxm_ld; /* Dynamic section of the shared object. */
- uint32_t lxm_next; /* Chain of loaded objects. */
- uint32_t lxm_prev;
-};
+ uint32_t lxm_next; /* Chain of loaded objects. */
+} lx_link_map_t;
-struct lx_r_debug
-{
+typedef struct lx_r_debug {
int r_version; /* Version number for this protocol. */
uint32_t r_map; /* Head of the chain of loaded objects. */
@@ -93,7 +134,23 @@ struct lx_r_debug
uint32_t r_brk;
r_state_e r_state; /* defined the same way between lx/solaris */
uint32_t r_ldbase; /* Base address the linker is loaded at. */
-};
+} lx_r_debug_t;
+
+static uint32_t
+lx_ldb_getauxval32(struct ps_prochandle *php, int type)
+{
+ const auxv_t *auxvp = NULL;
+
+ if (ps_pauxv(php, &auxvp) != PS_OK)
+ return ((uint32_t)-1);
+
+ while (auxvp->a_type != AT_NULL) {
+ if (auxvp->a_type == type)
+ return ((uint32_t)(uintptr_t)auxvp->a_un.a_ptr);
+ auxvp++;
+ }
+ return ((uint32_t)-1);
+}
/*
* A key difference between the linux linker and ours' is that the linux
@@ -115,103 +172,111 @@ struct lx_r_debug
* DT_NEEDED section. For all matching sections, we subtract the segment
* base address to get back to relative addresses.
*/
-static void
-lx_ldb_fix_phdr(struct rd_agent *rap, Elf32_Dyn *dp, size_t size,
- psaddr_t addr)
+static rd_err_e
+lx_ldb_get_dyns32(rd_helper_data_t rhd,
+ psaddr_t addr, void **dynpp, size_t *dynpp_sz)
{
- struct ps_prochandle *php = rap->rd_psp;
+ lx_rd_t *lx_rd = (lx_rd_t *)rhd;
+ rd_agent_t *rap = lx_rd->lr_rap;
+ Elf32_Ehdr ehdr;
+ Elf32_Dyn *dynp = NULL;
+ size_t dynp_sz;
+ uint_t ndyns;
int i;
- int strsz = 0;
- uint32_t strtab_p = NULL;
- char *strtab;
- /* Make sure addr matches the current byte size */
- addr = (uint32_t)addr;
+ ps_plog("lx_ldb_get_dyns: invoked for object at 0x%p", addr);
- /*
- * First we need to find the address of the string table.
- */
- for (i = 0; i < size / sizeof (Elf32_Dyn); i++) {
- if (dp[i].d_tag == DT_STRTAB)
- strtab_p = dp[i].d_un.d_ptr;
- if (dp[i].d_tag == DT_STRSZ)
- strsz = dp[i].d_un.d_val;
- }
- if (strtab_p == NULL) {
- ps_plog("lx_librtld_db: couldn't find strtab");
- return;
- }
- if (strsz == 0) {
- ps_plog("lx_librtld_db: couldn't find strsz");
- return;
+ /* Read in a copy of the ehdr */
+ if (_rd_get_ehdr32(rap, addr, &ehdr, NULL) != RD_OK) {
+ ps_plog("lx_ldb_get_dyns: _rd_get_ehdr() failed");
+ return (RD_ERR);
}
- if ((strtab = malloc(strsz)) == NULL)
- return;
- if (Pread(php, strtab, strsz, strtab_p) != strsz) {
- ps_plog("lx_librtld_db: couldn't read strtab at 0x%p",
- strtab_p);
- free(strtab);
- return;
+ /* read out the PT_DYNAMIC elements for this object */
+ if (_rd_get_dyns32(rap, addr, &dynp, &dynp_sz) != RD_OK) {
+ ps_plog("lx_ldb_get_dyns: _rd_get_dyns() failed");
+ return (RD_ERR);
}
/*
- * ELF binaries may have more than one DT_NEEDED entry - we must
- * check them all. The linux linker segment also needs to be fixed,
- * but it doesn't have a DT_NEEDED entry. Instead, look for a
- * matching DT_SONAME.
+ * From here on out if we encounter an error we'll just return
+ * success and pass back the unmolested dynamic elements that
+ * we've already obtained.
*/
- for (i = 0; i < size / sizeof (Elf32_Dyn); i++) {
- if (dp[i].d_tag == DT_SONAME &&
- strncmp(strtab + dp[i].d_un.d_ptr, LX_LINKER_NAME,
- sizeof (LX_LINKER_NAME)) == 0)
- break;
-
- if (dp[i].d_tag != DT_NEEDED)
- continue;
+ *dynpp = dynp;
+ *dynpp_sz = dynp_sz;
+ ndyns = dynp_sz / sizeof (Elf32_Dyn);
+
+ /* If this isn't a dynamic object, there's nothing left todo */
+ if (ehdr.e_type != ET_DYN) {
+ ps_plog("lx_ldb_get_dyns: done: not a shared object");
+ return (RD_OK);
+ }
- if (strncmp(strtab + dp[i].d_un.d_ptr,
- LX_LINKER_NAME, sizeof (LX_LINKER_NAME)) == 0 ||
- strncmp(strtab + dp[i].d_un.d_ptr, LX_LIBC_NAME,
- sizeof (LX_LIBC_NAME)) == 0)
+ /*
+ * Before we blindly start changing dynamic section addresses
+ * we need to figure out if the current object that we're looking
+ * at is a linux object or a solaris object. To do this first
+ * we need to find the string tab dynamic section element.
+ */
+ for (i = 0; i < ndyns; i++) {
+ if (dynp[i].d_tag == DT_STRTAB)
break;
}
- free(strtab);
- if (i == size / sizeof (Elf32_Dyn)) {
- /*
- * This is not a linux mapping, so we have nothing left to do.
- */
- ps_plog("lx_librtld_db: "
- "0x%p doesn't appear to be an lx object", addr);
- return;
+ if (i == ndyns) {
+ ps_plog("lx_ldb_get_dyns: "
+ "failed to find string tab in the dynamic section");
+ return (RD_OK);
}
/*
- * The linux linker added the segment's base address to a bunch of the
- * dynamic section addresses. Fix them back to their original, on-disk
- * format so Solaris understands them.
+ * Check if the strtab value looks like an offset or an address.
+ * It's an offset if the value is less then the base address that
+ * the object is loaded at, or if the value is less than the offset
+ * of the section headers in the same elf object. This check isn't
+ * perfect, but in practice it's good enough.
*/
- for (i = 0; i < size / sizeof (Elf32_Dyn); i++) {
- switch (dp[i].d_tag) {
- case DT_INIT:
- case DT_FINI:
+ if ((dynp[i].d_un.d_ptr < addr) ||
+ (dynp[i].d_un.d_ptr < ehdr.e_shoff)) {
+ ps_plog("lx_ldb_get_dyns: "
+ "doesn't appear to be an lx object");
+ return (RD_OK);
+ }
+
+ /*
+ * This seems to be a a linux object, so we'll patch up the dynamic
+ * section addresses
+ */
+ ps_plog("lx_ldb_get_dyns: "
+ "patching up lx object dynamic section addresses");
+ for (i = 0; i < ndyns; i++) {
+ switch (dynp[i].d_tag) {
+ case DT_PLTGOT:
case DT_HASH:
case DT_STRTAB:
case DT_SYMTAB:
+ case DT_RELA:
+ case DT_REL:
case DT_DEBUG:
- case DT_PLTGOT:
case DT_JMPREL:
- case DT_REL:
- case DT_VERNEED:
case DT_VERSYM:
- if (dp[i].d_un.d_val > addr) {
- dp[i].d_un.d_ptr -= addr;
+ if (dynp[i].d_un.d_val > addr) {
+ dynp[i].d_un.d_ptr -= addr;
}
break;
default:
break;
}
}
+ return (RD_OK);
+}
+
+static void
+lx_ldb_fini32(rd_helper_data_t rhd)
+{
+ lx_rd_t *lx_rd = (lx_rd_t *)rhd;
+ ps_plog("lx_ldb_fini: cleaning up lx helper");
+ free(lx_rd);
}
/*
@@ -224,64 +289,64 @@ lx_ldb_fix_phdr(struct rd_agent *rap, Elf32_Dyn *dp, size_t size,
* address of the Elf header, and from there we can easily get to the DT_DEBUG
* entry.
*/
-static void *
-lx_ldb_client_init(struct ps_prochandle *php)
+static rd_helper_data_t
+lx_ldb_init32(rd_agent_t *rap, struct ps_prochandle *php)
{
- lx_rd_t *rd = calloc(sizeof (lx_rd_t), 1);
- uint32_t phdr_addr, ehdr_addr, dp_addr;
- Elf32_Dyn *dp;
+ lx_rd_t *lx_rd;
+ uint32_t addr, phdr_addr, dyn_addr;
+ Elf32_Dyn *dyn;
Elf32_Phdr phdr, *ph, *phdrs;
Elf32_Ehdr ehdr;
- int i, dp_count;
+ int i, dyn_count;
- rd->lr_rdebug = 0;
-
- if (rd == NULL) {
- ps_plog("lx_ldb_client_init: cannot allocate memory");
+ lx_rd = calloc(sizeof (lx_rd_t), 1);
+ if (lx_rd == NULL) {
+ ps_plog("lx_ldb_init: cannot allocate memory");
return (NULL);
}
+ lx_rd->lr_rap = rap;
+ lx_rd->lr_php = php;
- phdr_addr = Pgetauxval(php, AT_SUN_BRAND_LX_PHDR);
+ phdr_addr = lx_ldb_getauxval32(php, AT_SUN_BRAND_LX_PHDR);
if (phdr_addr == (uint32_t)-1) {
- ps_plog("lx_ldb_client_init: no LX_PHDR found in aux vector");
+ ps_plog("lx_ldb_init: no LX_PHDR found in aux vector");
return (NULL);
}
- ps_plog("lx_ldb_client_init: found LX_PHDR auxv phdr at: 0x%p",
+ ps_plog("lx_ldb_init: found LX_PHDR auxv phdr at: 0x%p",
phdr_addr);
if (ps_pread(php, phdr_addr, &phdr, sizeof (phdr)) != PS_OK) {
- ps_plog("lx_ldb_client_init: couldn't read phdr at 0x%p",
+ ps_plog("lx_ldb_init: couldn't read phdr at 0x%p",
phdr_addr);
- free(rd);
+ free(lx_rd);
return (NULL);
}
/* The ELF headher should be before the program header in memory */
- rd->lr_exec = ehdr_addr = phdr_addr - phdr.p_offset;
- if (ps_pread(php, ehdr_addr, &ehdr, sizeof (ehdr)) !=
- PS_OK) {
- ps_plog("lx_ldb_client_init: couldn't read ehdr at 0x%p",
- rd->lr_exec);
- free(rd);
+ lx_rd->lr_exec = addr = phdr_addr - phdr.p_offset;
+ if (ps_pread(php, addr, &ehdr, sizeof (ehdr)) != PS_OK) {
+ ps_plog("lx_ldb_init: couldn't read ehdr at 0x%p",
+ lx_rd->lr_exec);
+ free(lx_rd);
return (NULL);
}
- ps_plog("lx_ldb_client_init: read ehdr at: 0x%p", ehdr_addr);
+ ps_plog("lx_ldb_init: read ehdr at: 0x%p", addr);
if ((phdrs = malloc(ehdr.e_phnum * ehdr.e_phentsize)) == NULL) {
- ps_plog("lx_ldb_client_init: couldn't alloc phdrs memory");
- free(rd);
+ ps_plog("lx_ldb_init: couldn't alloc phdrs memory");
+ free(lx_rd);
return (NULL);
}
if (ps_pread(php, phdr_addr, phdrs, ehdr.e_phnum * ehdr.e_phentsize) !=
PS_OK) {
- ps_plog("lx_ldb_client_init: couldn't read phdrs at 0x%p",
+ ps_plog("lx_ldb_init: couldn't read phdrs at 0x%p",
phdr_addr);
- free(rd);
+ free(lx_rd);
free(phdrs);
return (NULL);
}
- ps_plog("lx_ldb_client_init: read %d phdrs at: 0x%p",
+ ps_plog("lx_ldb_init: read %d phdrs at: 0x%p",
ehdr.e_phnum, phdr_addr);
for (i = 0, ph = phdrs; i < ehdr.e_phnum; i++,
@@ -291,51 +356,51 @@ lx_ldb_client_init(struct ps_prochandle *php)
break;
}
if (i == ehdr.e_phnum) {
- ps_plog("lx_ldb_client_init: no PT_DYNAMIC in executable");
- free(rd);
+ ps_plog("lx_ldb_init: no PT_DYNAMIC in executable");
+ free(lx_rd);
free(phdrs);
return (NULL);
}
- ps_plog("lx_ldb_client_init: found PT_DYNAMIC phdr[%d] at: 0x%p",
+ ps_plog("lx_ldb_init: found PT_DYNAMIC phdr[%d] at: 0x%p",
i, (phdr_addr + ((char *)ph - (char *)phdrs)));
- if ((dp = malloc(ph->p_filesz)) == NULL) {
- ps_plog("lx_ldb_client_init: couldn't alloc for PT_DYNAMIC");
- free(rd);
+ if ((dyn = malloc(ph->p_filesz)) == NULL) {
+ ps_plog("lx_ldb_init: couldn't alloc for PT_DYNAMIC");
+ free(lx_rd);
free(phdrs);
return (NULL);
}
- dp_addr = ehdr_addr + ph->p_offset;
- dp_count = ph->p_filesz / sizeof (Elf32_Dyn);
- if (ps_pread(php, dp_addr, dp, ph->p_filesz) != PS_OK) {
- ps_plog("lx_ldb_client_init: couldn't read dynamic at 0x%p",
- dp_addr);
- free(rd);
+ dyn_addr = addr + ph->p_offset;
+ dyn_count = ph->p_filesz / sizeof (Elf32_Dyn);
+ if (ps_pread(php, dyn_addr, dyn, ph->p_filesz) != PS_OK) {
+ ps_plog("lx_ldb_init: couldn't read dynamic at 0x%p",
+ dyn_addr);
+ free(lx_rd);
free(phdrs);
- free(dp);
+ free(dyn);
return (NULL);
}
- ps_plog("lx_ldb_client_init: read %d dynamic headers at: 0x%p",
- dp_count, dp_addr);
+ ps_plog("lx_ldb_init: read %d dynamic headers at: 0x%p",
+ dyn_count, dyn_addr);
- for (i = 0; i < dp_count; i++) {
- if (dp[i].d_tag == DT_DEBUG) {
- rd->lr_rdebug = dp[i].d_un.d_ptr;
+ for (i = 0; i < dyn_count; i++) {
+ if (dyn[i].d_tag == DT_DEBUG) {
+ lx_rd->lr_rdebug = dyn[i].d_un.d_ptr;
break;
}
}
free(phdrs);
- free(dp);
+ free(dyn);
- if (rd->lr_rdebug == 0) {
- ps_plog("lx_ldb_client_init: no DT_DEBUG found in exe");
- free(rd);
+ if (lx_rd->lr_rdebug == 0) {
+ ps_plog("lx_ldb_init: no DT_DEBUG found in exe");
+ free(lx_rd);
return (NULL);
}
- ps_plog("lx_ldb_client_init: found DT_DEBUG: 0x%p", rd->lr_rdebug);
+ ps_plog("lx_ldb_init: found DT_DEBUG: 0x%p", lx_rd->lr_rdebug);
- return (rd);
+ return ((rd_helper_data_t)lx_rd);
}
/*
@@ -343,7 +408,7 @@ lx_ldb_client_init(struct ps_prochandle *php)
* the proper link map ID.
*/
static size_t
-lx_elf_props(struct ps_prochandle *php, uint32_t addr, psaddr_t *data_addr)
+lx_elf_props32(struct ps_prochandle *php, uint32_t addr, psaddr_t *data_addr)
{
Elf32_Ehdr ehdr;
Elf32_Phdr *phdrs, *ph;
@@ -399,20 +464,20 @@ lx_elf_props(struct ps_prochandle *php, uint32_t addr, psaddr_t *data_addr)
}
static int
-lx_ldb_iter(struct ps_prochandle *php, rl_iter_f *cb, void *client_data,
- void *rd_addr)
+lx_ldb_loadobj_iter32(rd_helper_data_t rhd, rl_iter_f *cb, void *client_data)
{
- lx_rd_t *lx_rd = (lx_rd_t *)rd_addr;
- struct lx_r_debug r_debug;
- struct lx_link_map map;
+ lx_rd_t *lx_rd = (lx_rd_t *)rhd;
+ struct ps_prochandle *php = lx_rd->lr_php;
+ lx_r_debug_t r_debug;
+ lx_link_map_t map;
uint32_t p = NULL;
int rc;
rd_loadobj_t exec;
if ((rc = ps_pread(php, (psaddr_t)lx_rd->lr_rdebug, &r_debug,
sizeof (r_debug))) != PS_OK) {
- ps_plog("lx_ldb_iter: Couldn't read linux r_debug at 0x%p",
- rd_addr);
+ ps_plog("lx_ldb_loadobj_iter: "
+ "Couldn't read linux r_debug at 0x%p", lx_rd->lr_rdebug);
return (rc);
}
@@ -427,22 +492,23 @@ lx_ldb_iter(struct ps_prochandle *php, rl_iter_f *cb, void *client_data,
* the AT_EXECNAME entry instead.
*/
if ((rc = ps_pread(php, (psaddr_t)p, &map, sizeof (map))) != PS_OK) {
- ps_plog("lx_ldb_iter: Couldn't read linux link map at 0x%p",
- p);
+ ps_plog("lx_ldb_loadobj_iter: "
+ "Couldn't read linux link map at 0x%p", p);
return (rc);
}
bzero(&exec, sizeof (exec));
exec.rl_base = lx_rd->lr_exec;
exec.rl_dynamic = map.lxm_ld;
- exec.rl_nameaddr = Pgetauxval(php, AT_SUN_EXECNAME);
+ exec.rl_nameaddr = lx_ldb_getauxval32(php, AT_SUN_EXECNAME);
exec.rl_lmident = LM_ID_BASE;
exec.rl_bend = exec.rl_base +
- lx_elf_props(php, lx_rd->lr_exec, &exec.rl_data_base);
+ lx_elf_props32(php, lx_rd->lr_exec, &exec.rl_data_base);
if ((*cb)(&exec, client_data) == 0) {
- ps_plog("lx_ldb_iter: client callb failed for executable");
+ ps_plog("lx_ldb_loadobj_iter: "
+ "client callb failed for executable");
return (PS_ERR);
}
@@ -451,8 +517,8 @@ lx_ldb_iter(struct ps_prochandle *php, rl_iter_f *cb, void *client_data,
if ((rc = ps_pread(php, (psaddr_t)p, &map, sizeof (map))) !=
PS_OK) {
- ps_plog("lx_ldb_iter: Couldn't read lk map at %p",
- p);
+ ps_plog("lx_ldb_loadobj_iter: "
+ "Couldn't read lk map at %p", p);
return (rc);
}
@@ -476,20 +542,34 @@ lx_ldb_iter(struct ps_prochandle *php, rl_iter_f *cb, void *client_data,
*/
obj.rl_bend = map.lxm_addr +
- lx_elf_props(php, map.lxm_addr, &obj.rl_data_base);
+ lx_elf_props32(php, map.lxm_addr, &obj.rl_data_base);
obj.rl_padstart = obj.rl_base;
obj.rl_padend = obj.rl_bend;
obj.rl_dynamic = map.lxm_ld;
obj.rl_tlsmodid = 0;
- ps_plog("lx_ldb_iter: 0x%p to 0x%p",
+ ps_plog("lx_ldb_loadobj_iter: 0x%p to 0x%p",
obj.rl_base, obj.rl_bend);
if ((*cb)(&obj, client_data) == 0) {
- ps_plog("lx_ldb_iter: Client callback failed on %s",
- map.lxm_name);
+ ps_plog("lx_ldb_loadobj_iter: "
+ "Client callback failed on %s", map.lxm_name);
return (rc);
}
}
return (RD_OK);
}
+
+/*
+ * Librtld_db plugin linkage struct.
+ *
+ * When we get loaded by librtld_db, it will look for the symbol below
+ * to find our plugin entry points.
+ */
+rd_helper_ops_t RTLD_DB_BRAND_OPS = {
+ LM_ID_BRAND,
+ lx_ldb_init32,
+ lx_ldb_fini32,
+ lx_ldb_loadobj_iter32,
+ lx_ldb_get_dyns32
+};
diff --git a/usr/src/lib/brand/lx/librtld_db/common/mapfile-vers b/usr/src/lib/brand/lx/librtld_db/common/mapfile-vers
index e3c40016b3..e460725681 100644
--- a/usr/src/lib/brand/lx/librtld_db/common/mapfile-vers
+++ b/usr/src/lib/brand/lx/librtld_db/common/mapfile-vers
@@ -20,14 +20,27 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
+#
{
global:
- rtld_db_brand_ops;
+ rtld_db_brand_ops32;
local:
*;
};
+
+#Externally defined symbols
+{
+ global:
+ ps_pauxv = NODIRECT PARENT;
+ ps_pdmodel = NODIRECT PARENT;
+ ps_pglobal_lookup = NODIRECT PARENT;
+ ps_pglobal_sym = NODIRECT PARENT;
+ ps_plog = NODIRECT PARENT;
+ ps_pread = NODIRECT PARENT;
+ ps_pwrite = NODIRECT PARENT;
+};
diff --git a/usr/src/lib/brand/lx/librtld_db/i386/Makefile b/usr/src/lib/brand/lx/librtld_db/i386/Makefile
index e85d3fc08a..b5f780c072 100644
--- a/usr/src/lib/brand/lx/librtld_db/i386/Makefile
+++ b/usr/src/lib/brand/lx/librtld_db/i386/Makefile
@@ -18,17 +18,13 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
+#ident "%Z%%M% %I% %E% SMI"
#
-# lib/brand/lx/librtld_db/i386/Makefile
-
-ISASRCDIR=.
-
-ASFLAGS += -P -D_ASM
include ../Makefile.com
diff --git a/usr/src/lib/libproc/common/Psymtab_machelf32.c b/usr/src/lib/libproc/common/Psymtab_machelf32.c
index dc6ba18a59..704e41547c 100644
--- a/usr/src/lib/libproc/common/Psymtab_machelf32.c
+++ b/usr/src/lib/libproc/common/Psymtab_machelf32.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -255,25 +255,19 @@ fake_elf32(struct ps_prochandle *P, file_info_t *fptr, uintptr_t addr,
Off off;
size_t pltsz = 0, pltentsz;
-
if (ehdr->e_type == ET_DYN)
phdr->p_vaddr += addr;
- if ((dp = malloc(phdr->p_filesz)) == NULL)
- goto bad;
-
- if (Pread(P, dp, phdr->p_filesz, phdr->p_vaddr) != phdr->p_filesz)
- goto bad;
-
-#ifndef _ELF64
- /*
- * Allow librtld_db the opportunity to "fix" the program
- * headers, if it needs to, before we process them.
- */
- if (P->rap != NULL && ehdr->e_type == ET_DYN) {
- rd_fix_phdrs(P->rap, dp, phdr->p_filesz, addr);
+ if (P->rap != NULL) {
+ if (rd_get_dyns(P->rap, addr, (void **)&dp, NULL) != RD_OK)
+ goto bad;
+ } else {
+ if ((dp = malloc(phdr->p_filesz)) == NULL)
+ goto bad;
+ if (Pread(P, dp, phdr->p_filesz, phdr->p_vaddr) !=
+ phdr->p_filesz)
+ goto bad;
}
-#endif
/*
* Iterate over the items in the dynamic section, grabbing