# # 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 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" # include $(SRC)/cmd/sgs/Makefile.sub # # 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 (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2016 RackTop Systems. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # LIBRARY = liblddbg.a VERS = .4 COMOBJS = args.o audit.o basic.o debug.o \ syminfo.o tls.o COMOBJS32 = bindings32.o cap32.o dlfcns32.o dynamic32.o \ elf32.o entry32.o files32.o got32.o \ libs32.o map32.o move32.o phdr32.o \ relocate32.o sections32.o segments32.o shdr32.o \ statistics32.o support32.o syms32.o unused32.o \ util32.o version32.o COMOBJS64 = bindings64.o cap64.o dlfcns64.o dynamic64.o \ elf64.o entry64.o files64.o got64.o \ libs64.o map64.o move64.o phdr64.o \ relocate64.o sections64.o segments64.o shdr64.o \ statistics64.o support64.o syms64.o unused64.o \ util64.o version64.o BLTOBJ = msg.o SGSCOMMONOBJ = alist.o OBJECTS = $(BLTOBJ) $(COMOBJS) $(COMOBJS32) $(COMOBJS64) $(SGSCOMMONOBJ) include $(SRC)/lib/Makefile.lib include $(SRC)/lib/Makefile.rootfs include $(SRC)/cmd/sgs/Makefile.com LIBS = $(DYNLIB) # Hammerhead: removed stale COMPATLINKS/COMPATLINKS64 overrides. # Makefile.rootfs sets correct COMPATLINKS for flattened layout. SRCDIR = $(SGSHOME)/liblddbg MAPFILEDIR = $(SRCDIR)/common CERRWARN += -Wno-unused-value CERRWARN += $(CNOWARN_UNINIT) CERRWARN += -Wno-parentheses CPPFLAGS += -I$(SRC)/lib/libc/inc DYNFLAGS += $(VERSREF) '-R$$ORIGIN' # Hammerhead: -ldl needed because libconv (static archive) contains demangle.o # which calls dlopen/dlsym for C++ symbol demangling LDLIBS += $(CONVLIBDIR) -lconv -ldl -lc BLTDEFS = msg.h BLTDATA = msg.c BLTMESG = $(SGSMSGDIR)/liblddbg BLTFILES = $(BLTDEFS) $(BLTDATA) $(BLTMESG) SGSMSGCOM = $(SRCDIR)/common/liblddbg.msg SGSMSGALL = $(SGSMSGCOM) SGSMSGTARG = $(SGSMSGCOM) SGSMSGFLAGS += -h $(BLTDEFS) -d $(BLTDATA) -m $(BLTMESG) -n liblddbg_msg CHKSRCS = $(COMOBJS32:%32.o=$(SRCDIR)/common/%.c) LIBSRCS = $(COMOBJS:%.o=$(SRCDIR)/common/%.c) \ $(SGSCOMMONOBJ:%.o=$(SGSCOMMON)/%.c) $(BLTDATA) CLEANFILES += $(BLTFILES) CLOBBERFILES += $(DYNLIB) $(LIBLINKS) # # 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 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2016 RackTop Systems. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # pics/%.o: $(SRCDIR)/common/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) pics/%.o: $(SGSCOMMON)/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) pics/%32.o: $(SRCDIR)/common/%.c $(COMPILE.c) -o $@ $< $(POST_PROCESS_O) pics/%64.o: $(SRCDIR)/common/%.c $(COMPILE.c) -D_ELF64 -o $@ $< $(POST_PROCESS_O) $(LIBLINKS): -$(RM) $@; $(SYMLINK) $(DYNLIB) $@ $(PICS): pics include $(SRC)/lib/Makefile.targ # Derived source and header files (messaging). catalog: $(BLTMESG) chkmsg: $(LIBSRCS) $(CHKSRCS) sh $(CHKMSG) $(CHKMSGFLAGS) $(LIBSRCS) $(CHKSRCS) # Hammerhead: Ensure messages directory exists, use grouped target syntax $(SGSMSGDIR): $(MKDIR) -p $@ $(BLTDEFS) $(BLTDATA) $(BLTMESG) &: $(SGSMSGALL) | $(SGSMSGDIR) $(SGSMSG) $(SGSMSGFLAGS) $(SGSMSGALL) # # 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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # include ../Makefile.com CONVLIBDIR = $(CONVLIBDIR64) .KEEP_STATE: $(ROOTFS_DYNLIB64) : FILEMODE= 755 all: $(DYNLIB) $(LIBLINKS) install: all $(ROOTLIBS64) $(ROOTCOMPATLINKS64) include ../Makefile.targ include $(SRC)/Makefile.master.64 /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _DEBUG_DOT_H #define _DEBUG_DOT_H #include #include #ifdef __cplusplus extern "C" { #endif /* * Debugging is enabled by various tokens (see debug.c) that result in an * internal bit mask (d_class) being initialized. Each debugging function is * appropriate for one or more of the classes specified by the bit mask. Each * debugging function validates whether it is appropriate for the present * classes before printing anything. */ #define DBG_NOTCLASS(c) !(dbg_desc->d_class & (c)) #define DBG_C_ARGS 0x00000001 #define DBG_C_AUDITING 0x00000002 #define DBG_C_BASIC 0x00000004 #define DBG_C_BINDINGS 0x00000008 #define DBG_C_CAP 0x00000010 #define DBG_C_DEMANGLE 0x00000020 #define DBG_C_ENTRY 0x00000040 #define DBG_C_FILES 0x00000080 #define DBG_C_GOT 0x00000100 #define DBG_C_INIT 0x00000200 #define DBG_C_LIBS 0x00000400 #define DBG_C_MAP 0x00000800 #define DBG_C_MOVE 0x00001000 #define DBG_C_RELOC 0x00002000 #define DBG_C_SECTIONS 0x00004000 #define DBG_C_SEGMENTS 0x00008000 #define DBG_C_STATS 0x00010000 #define DBG_C_STRTAB 0x00020000 #define DBG_C_SUPPORT 0x00040000 #define DBG_C_SYMBOLS 0x00080000 #define DBG_C_TLS 0x00100000 #define DBG_C_UNUSED 0x00200000 #define DBG_C_VERSIONS 0x00400000 #define DBG_C_DL 0x00800000 #define DBG_C_ALL 0xffffffff typedef struct { const char *o_name; /* command line argument name */ uint_t o_class; /* associated class for this name */ uint_t o_extra; /* associated extra for this name */ } DBG_options; #define AL_CNT_DEBUG 4 /* * Some Dbg_*() format strings differ depending on whether they are used for * 32-bit or 64-bit values. */ #if defined(_ELF64) #define MSG_EDATA_TITLE MSG_EDATA_TITLE_64 #define MSG_EDATA_ENTRY MSG_EDATA_ENTRY_64 #else #define MSG_EDATA_TITLE MSG_EDATA_TITLE_32 #define MSG_EDATA_ENTRY MSG_EDATA_ENTRY_32 #endif /* * Some Elf_*() format strings differ depending on whether they are used for * 32-bit or 64-bit values. */ #if defined(_ELF64) #define MSG_DL_IPHDR_ADDR MSG_DL_IPHDR_ADDR_64 #define MSG_DL_IPHDR_PHDR MSG_DL_IPHDR_PHDR_64 #define MSG_GOT_TITLE MSG_GOT_TITLE_64 #define MSG_GOT_ENTRY_RE MSG_GOT_ENTRY_RE_64 #define MSG_GOT_ENTRY_NR MSG_GOT_ENTRY_NR_64 #define MSG_GOT_COLUMNS1 MSG_GOT_COLUMNS1_64 #define MSG_GOT_COLUMNS2 MSG_GOT_COLUMNS2_64 #define MSG_GOT_FORMAT1 MSG_GOT_FORMAT1_64 #define MSG_GOT_FORMAT2 MSG_GOT_FORMAT2_64 #define MSG_PHD_VADDR MSG_PHD_VADDR_64 #define MSG_PHD_PADDR MSG_PHD_PADDR_64 #define MSG_PHD_FILESZ MSG_PHD_FILESZ_64 #define MSG_PHD_OFFSET MSG_PHD_OFFSET_64 #define MSG_REL_EFSA_TITLE MSG_REL_EFSA_TITLE_64 #define MSG_REL_EFLA_TITLE MSG_REL_EFLA_TITLE_64 #define MSG_REL_EFSN_TITLE MSG_REL_EFSN_TITLE_64 #define MSG_REL_EFLN_TITLE MSG_REL_EFLN_TITLE_64 #define MSG_REL_EFSA_ENTRY MSG_REL_EFSA_ENTRY_64 #define MSG_REL_EFLA_ENTRY MSG_REL_EFLA_ENTRY_64 #define MSG_REL_EFSN_ENTRY MSG_REL_EFSN_ENTRY_64 #define MSG_REL_EFLN_ENTRY MSG_REL_EFLN_ENTRY_64 #define MSG_REL_RT_APLREG MSG_REL_RT_APLREG_64 #define MSG_REL_RT_APLVAL MSG_REL_RT_APLVAL_64 #define MSG_REL_RTA_TITLE MSG_REL_RTA_TITLE_64 #define MSG_REL_RTN_TITLE MSG_REL_RTN_TITLE_64 #define MSG_REL_RTV_TITLE MSG_REL_RTV_TITLE_64 #define MSG_REL_RTA_ENTRY MSG_REL_RTA_ENTRY_64 #define MSG_REL_RTN_ENTRY MSG_REL_RTN_ENTRY_64 #define MSG_REL_LDSA_TITLE MSG_REL_LDSA_TITLE_64 #define MSG_REL_LDSN_TITLE MSG_REL_LDSN_TITLE_64 #define MSG_REL_LDSA_ENTRY MSG_REL_LDSA_ENTRY_64 #define MSG_REL_LDSN_ENTRY MSG_REL_LDSN_ENTRY_64 #define MSG_REL_LDSV_TITLE MSG_REL_LDSV_TITLE_64 #define MSG_REL_LDSV_ENTRY MSG_REL_LDSV_ENTRY_64 #define MSG_REL_LDLA_TITLE MSG_REL_LDLA_TITLE_64 #define MSG_REL_LDLN_TITLE MSG_REL_LDLN_TITLE_64 #define MSG_REL_LDLA_ENTRY MSG_REL_LDLA_ENTRY_64 #define MSG_REL_LDLN_ENTRY MSG_REL_LDLN_ENTRY_64 #define MSG_REL_LDLV_TITLE MSG_REL_LDLV_TITLE_64 #define MSG_REL_LDLV_ENTRY MSG_REL_LDLV_ENTRY_64 #define MSG_SHD_ADDR MSG_SHD_ADDR_64 #define MSG_SHD_SIZE MSG_SHD_SIZE_64 #define MSG_SHD_OFFSET MSG_SHD_OFFSET_64 #define MSG_SHD_OFFSET_ENT MSG_SHD_OFFSET_ENT_64 #define MSG_SHD_ALIGN MSG_SHD_ALIGN_64 #define MSG_SHD_LINK MSG_SHD_LINK_64 #define MSG_SYM_EFS_ENTRY MSG_SYM_EFS_ENTRY_64 #define MSG_SYM_EFL_ENTRY MSG_SYM_EFL_ENTRY_64 #define MSG_SYM_EFS_TITLE MSG_SYM_EFS_TITLE_64 #define MSG_SYM_EFL_TITLE MSG_SYM_EFL_TITLE_64 #define MSG_SYM_LDS_TITLE MSG_SYM_LDS_TITLE_64 #define MSG_SYM_LDL_TITLE MSG_SYM_LDL_TITLE_64 #else #define MSG_DL_IPHDR_ADDR MSG_DL_IPHDR_ADDR_32 #define MSG_DL_IPHDR_PHDR MSG_DL_IPHDR_PHDR_32 #define MSG_GOT_TITLE MSG_GOT_TITLE_32 #define MSG_GOT_ENTRY_RE MSG_GOT_ENTRY_RE_32 #define MSG_GOT_ENTRY_NR MSG_GOT_ENTRY_NR_32 #define MSG_GOT_COLUMNS1 MSG_GOT_COLUMNS1_32 #define MSG_GOT_COLUMNS2 MSG_GOT_COLUMNS2_32 #define MSG_GOT_FORMAT1 MSG_GOT_FORMAT1_32 #define MSG_GOT_FORMAT2 MSG_GOT_FORMAT2_32 #define MSG_PHD_VADDR MSG_PHD_VADDR_32 #define MSG_PHD_PADDR MSG_PHD_PADDR_32 #define MSG_PHD_FILESZ MSG_PHD_FILESZ_32 #define MSG_PHD_OFFSET MSG_PHD_OFFSET_32 #define MSG_REL_EFSA_TITLE MSG_REL_EFSA_TITLE_32 #define MSG_REL_EFLA_TITLE MSG_REL_EFLA_TITLE_32 #define MSG_REL_EFSN_TITLE MSG_REL_EFSN_TITLE_32 #define MSG_REL_EFLN_TITLE MSG_REL_EFLN_TITLE_32 #define MSG_REL_EFSA_ENTRY MSG_REL_EFSA_ENTRY_32 #define MSG_REL_EFLA_ENTRY MSG_REL_EFLA_ENTRY_32 #define MSG_REL_EFSN_ENTRY MSG_REL_EFSN_ENTRY_32 #define MSG_REL_EFLN_ENTRY MSG_REL_EFLN_ENTRY_32 #define MSG_REL_RT_APLREG MSG_REL_RT_APLREG_32 #define MSG_REL_RT_APLVAL MSG_REL_RT_APLVAL_32 #define MSG_REL_RTA_TITLE MSG_REL_RTA_TITLE_32 #define MSG_REL_RTN_TITLE MSG_REL_RTN_TITLE_32 #define MSG_REL_RTV_TITLE MSG_REL_RTV_TITLE_32 #define MSG_REL_RTA_ENTRY MSG_REL_RTA_ENTRY_32 #define MSG_REL_RTN_ENTRY MSG_REL_RTN_ENTRY_32 #define MSG_REL_LDSA_TITLE MSG_REL_LDSA_TITLE_32 #define MSG_REL_LDSN_TITLE MSG_REL_LDSN_TITLE_32 #define MSG_REL_LDSA_ENTRY MSG_REL_LDSA_ENTRY_32 #define MSG_REL_LDSN_ENTRY MSG_REL_LDSN_ENTRY_32 #define MSG_REL_LDSV_TITLE MSG_REL_LDSV_TITLE_32 #define MSG_REL_LDSV_ENTRY MSG_REL_LDSV_ENTRY_32 #define MSG_REL_LDLA_TITLE MSG_REL_LDLA_TITLE_32 #define MSG_REL_LDLN_TITLE MSG_REL_LDLN_TITLE_32 #define MSG_REL_LDLA_ENTRY MSG_REL_LDLA_ENTRY_32 #define MSG_REL_LDLN_ENTRY MSG_REL_LDLN_ENTRY_32 #define MSG_REL_LDLV_TITLE MSG_REL_LDLV_TITLE_32 #define MSG_REL_LDLV_ENTRY MSG_REL_LDLV_ENTRY_32 #define MSG_SHD_ADDR MSG_SHD_ADDR_32 #define MSG_SHD_SIZE MSG_SHD_SIZE_32 #define MSG_SHD_OFFSET MSG_SHD_OFFSET_32 #define MSG_SHD_OFFSET_ENT MSG_SHD_OFFSET_ENT_32 #define MSG_SHD_ALIGN MSG_SHD_ALIGN_32 #define MSG_SHD_LINK MSG_SHD_LINK_32 #define MSG_SYM_EFS_ENTRY MSG_SYM_EFS_ENTRY_32 #define MSG_SYM_EFL_ENTRY MSG_SYM_EFL_ENTRY_32 #define MSG_SYM_EFS_TITLE MSG_SYM_EFS_TITLE_32 #define MSG_SYM_EFL_TITLE MSG_SYM_EFL_TITLE_32 #define MSG_SYM_LDS_TITLE MSG_SYM_LDS_TITLE_32 #define MSG_SYM_LDL_TITLE MSG_SYM_LDL_TITLE_32 #endif #define INDEX_STR_SIZE 10 /* * Buffer used by dbg_isec_name() to format input section * names. The size was selected to satisfy two opposing * constraints: * - To be large enough to handle the largest C++ mangled name. * Although we can malloc buffers, we don't want that to happen. * - To be small enough on the thread stack to not cause problems. */ typedef char dbg_isec_name_buf_t[INDEX_STR_SIZE + 2048]; #if defined(_ELF64) #define dbg_fmt_isec_name dbg64_fmt_isec_name #define dbg_fmt_isec_name2 dbg64_fmt_isec_name2 #else #define dbg_fmt_isec_name dbg32_fmt_isec_name #define dbg_fmt_isec_name2 dbg32_fmt_isec_name2 #endif extern const char *dbg_fmt_isec_name(Is_desc *, dbg_isec_name_buf_t, char **); extern const char *dbg_fmt_isec_name2(const char *, Word, dbg_isec_name_buf_t, char **); #ifdef __cplusplus } #endif #endif /* _DEBUG_DOT_H */ /* * 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 (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ #include #include "_debug.h" #include "msg.h" void Dbg_args_option(Lm_list *lml, int ndx, int c, char *optarg) { if (DBG_NOTCLASS(DBG_C_ARGS)) return; if (optarg) dbg_print(lml, MSG_INTL(MSG_ARG_OPTARG), ndx, c, optarg); else dbg_print(lml, MSG_INTL(MSG_ARG_OPTION), ndx, c); } void Dbg_args_str2chr(Lm_list *lml, int ndx, const char *opt, int c) { if (DBG_NOTCLASS(DBG_C_ARGS)) return; dbg_print(lml, MSG_INTL(MSG_ARG_STR2CHR), ndx, opt, c); } void Dbg_args_Wldel(Lm_list *lml, int ndx, const char *opt) { if (DBG_NOTCLASS(DBG_C_ARGS)) return; dbg_print(lml, MSG_INTL(MSG_ARG_WLDEL), ndx, opt); } void Dbg_args_file(Lm_list *lml, int ndx, char *file) { if (DBG_NOTCLASS(DBG_C_ARGS)) return; dbg_print(lml, MSG_INTL(MSG_ARG_FILE), ndx, file); } /* * 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 (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. */ #include #include #include "_debug.h" #include "msg.h" #include "libld.h" void Dbg_audit_lib(Rt_map *clmp, const char *lib, int type) { Lm_list *clml = LIST(clmp); const char *str; if (DBG_NOTCLASS(DBG_C_AUDITING)) return; Dbg_util_nl(clml, DBG_NL_STD); switch (type) { case DBG_AUD_PRELOAD: str = MSG_ORIG(MSG_AUD_PRELOAD); break; case DBG_AUD_GLOBAL: str = MSG_ORIG(MSG_AUD_GLOBAL); break; case DBG_AUD_LOCAL: /* FALLTHROUGH */ default: str = MSG_ORIG(MSG_STR_EMPTY); } dbg_print(clml, MSG_INTL(MSG_AUD_LIB), lib, NAME(clmp), str); } void Dbg_audit_interface(Lm_list *lml, const char *lib, const char *interface) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; dbg_print(lml, MSG_INTL(MSG_AUD_INTERFACE), lib, interface); } void Dbg_audit_version(Lm_list *lml, const char *lib, uint_t overs, uint_t nvers) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; dbg_print(lml, MSG_INTL(MSG_AUD_VERSION), lib, overs, nvers); } void Dbg_audit_activity(Lm_list *lml, const char *lib, const char *obj, uint_t flags) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_AUDITING)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_ACTIVITY), lib, obj, conv_la_activity(flags, CONV_FMT_ALT_DEFAULT, &inv_buf)); } void Dbg_audit_preinit(Lm_list *lml, const char *lib, const char *obj) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_PREINIT), lib, obj); } void Dbg_audit_objsearch(Lm_list *lml, int call, const char *lib, const char *oobj, uint_t flags, const char *nobj) { Conv_la_search_buf_t la_search_buf; if (DBG_NOTCLASS(DBG_C_AUDITING)) return; if (call == DBG_AUD_CALL) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_OBJSEARCH), lib, oobj, conv_la_search(flags, &la_search_buf)); } else { if (nobj) dbg_print(lml, MSG_INTL(MSG_AUD_OBJSEARCH_R), lib, oobj, nobj); else dbg_print(lml, MSG_INTL(MSG_AUD_OBJSEARCH_S), lib, oobj); } } void Dbg_audit_objfilter(Lm_list *lml, int call, const char *lib, const char *filter, const char *filtee, const char *ref) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; if (call == DBG_AUD_CALL) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_OBJFILTER), lib, filter, filtee, ref); } else dbg_print(lml, MSG_INTL(MSG_AUD_OBJFILTER_R), lib, filter); } void Dbg_audit_objopen(Lm_list *lml, int call, const char *lib, const char *obj, uint_t flags, Boolean ignore) { Conv_la_bind_buf_t la_bind_buf; if (DBG_NOTCLASS(DBG_C_AUDITING)) return; if (call == DBG_AUD_CALL) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_OBJOPEN), lib, obj); } else { if (ignore) dbg_print(lml, MSG_INTL(MSG_AUD_OBJOPEN_RI), lib, obj, conv_la_bind(flags, &la_bind_buf)); else dbg_print(lml, MSG_INTL(MSG_AUD_OBJOPEN_R), lib, obj, conv_la_bind(flags, &la_bind_buf)); } } void Dbg_audit_objclose(Lm_list *lml, const char *lib, const char *obj) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_OBJCLOSE), lib, obj); } void Dbg_audit_symbind(Lm_list *lml, int call, const char *lib, const char *name, Addr value, uint_t flags) { Conv_la_symbind_buf_t la_symbind_buf; if (DBG_NOTCLASS(DBG_C_AUDITING)) return; if (call == DBG_AUD_CALL) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_SYMBIND), lib, name, EC_XWORD(value), conv_la_symbind(flags, &la_symbind_buf)); } else { dbg_print(lml, MSG_INTL(MSG_AUD_SYMBIND_R), lib, name, EC_XWORD(value), conv_la_symbind(flags, &la_symbind_buf)); } } void Dbg_audit_pltenter(Lm_list *lml, int call, const char *lib, const char *name, Addr value) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; if (call == DBG_AUD_CALL) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_AUD_PLTENTER), lib, name, EC_XWORD(value)); } else { dbg_print(lml, MSG_INTL(MSG_AUD_PLTENTER_R), lib, name, EC_XWORD(value)); } } void Dbg_audit_pltexit(Lm_list *lml, const char *lib, const char *name) { if (DBG_NOTCLASS(DBG_C_AUDITING)) return; dbg_print(lml, MSG_INTL(MSG_AUD_PLTEXIT), lib, name); } void Dbg_audit_skip(Lm_list *lml, const char *name, const char *lmid) { if (DBG_NOTCLASS(DBG_C_AUDITING | DBG_C_FILES)) return; dbg_print(lml, MSG_INTL(MSG_AUD_SKIP), name, lmid); } void Dbg_audit_terminate(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_FILES)) return; dbg_print(lml, MSG_INTL(MSG_AUD_TERM), name); } void Dbg_audit_ignore(Rt_map *lmp) { if (DBG_NOTCLASS(DBG_C_AUDITING | DBG_C_FILES)) return; dbg_print(LIST(lmp), MSG_INTL(MSG_AUD_IGNORE), NAME(lmp)); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include "_debug.h" #include "msg.h" /* * This file contains a number of simple title interfaces, that give a basic * trace of a link-edit. These interfaces cross several functional boundaries, * but are consolidated here to ensure consistent use of the DBG_C_BASIC and * DBG_NOTTIME macros. */ void Dbg_basic_collect(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_COLLECT)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_basic_create(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_CREATE)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_basic_files(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_FILES)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_basic_finish(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_FINISHED)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_basic_options(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_OPTIONS)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_basic_relocate(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_RELOCATE)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_basic_validate(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_BASIC) && DBG_NOTTIME()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_BASIC_VALIDATE)); Dbg_util_nl(lml, DBG_NL_STD); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include "_debug.h" #include "msg.h" void Dbg_bind_plt_summary(Lm_list *lml, Half mach, Word pltcnt21d, Word pltcnt24d, Word pltcntu32, Word pltcntu44, Word pltcntfull, Word pltcntfar) { Word plttotal = pltcnt21d + pltcnt24d + pltcntu32 + pltcntu44 + pltcntfull + pltcntfar; if (DBG_NOTCLASS(DBG_C_BINDINGS)) return; switch (mach) { case EM_SPARC: dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARC), EC_WORD(pltcnt21d), EC_WORD(pltcnt24d), EC_WORD(pltcntfull), EC_WORD(plttotal)); break; case EM_SPARCV9: dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARCV9), EC_WORD(pltcnt21d), EC_WORD(pltcnt24d), EC_WORD(pltcntu32), EC_WORD(pltcntu44), EC_WORD(pltcntfull), EC_WORD(pltcntfar), EC_WORD(plttotal)); break; default: dbg_print(lml, MSG_INTL(MSG_BND_PSUM_DEFAULT), EC_WORD(plttotal)); break; }; } static const char *pltbindtypes[PLT_T_NUM] = { MSG_ORIG(MSG_STR_EMPTY), /* PLT_T_NONE */ MSG_ORIG(MSG_PLT_21D), /* PLT_T_21D */ MSG_ORIG(MSG_PLT_24D), /* PLT_T_24D */ MSG_ORIG(MSG_PLT_U32), /* PLT_T_U32 */ MSG_ORIG(MSG_PLT_U44), /* PLT_T_U44 */ MSG_ORIG(MSG_PLT_FULL), /* PLT_T_FULL */ MSG_ORIG(MSG_PLT_FAR) /* PLT_T_FAR */ }; #define BINFOSZ MSG_BINFO_START_SIZE + \ MSG_BINFO_DIRECT_SIZE + MSG_BINFO_SEP_SIZE + \ MSG_BINFO_INTERPOSE_SIZE + MSG_BINFO_SEP_SIZE + \ MSG_BINFO_COPYREF_SIZE + MSG_BINFO_SEP_SIZE + \ MSG_BINFO_FILTEE_SIZE + MSG_BINFO_SEP_SIZE + \ MSG_BINFO_PLTADDR_SIZE + \ CONV_INV_BUFSIZE + MSG_BINFO_END_SIZE void Dbg_bind_global(Rt_map *flmp, Addr fabs, Off foff, Xword pltndx, Pltbindtype pbtype, Rt_map *tlmp, Addr tabs, Off toff, const char *sym, uint_t binfo) { /* * MSG_ORIG(MSG_BINFO_DIRECT) * MSG_ORIG(MSG_BINFO_INTERPOSE) * MSG_ORIG(MSG_BINFO_COPYREF) * MSG_ORIG(MSG_BINFO_FILTEE) * MSG_ORIG(MSG_BINFO_PLTADDR) */ static char binfostr[BINFOSZ]; static Val_desc vda[] = { { DBG_BINFO_DIRECT, MSG_BINFO_DIRECT }, { DBG_BINFO_INTERPOSE, MSG_BINFO_INTERPOSE }, { DBG_BINFO_COPYREF, MSG_BINFO_COPYREF }, { DBG_BINFO_FILTEE, MSG_BINFO_FILTEE }, { DBG_BINFO_PLTADDR, MSG_BINFO_PLTADDR }, { 0, 0 } }; static CONV_EXPN_FIELD_ARG conv_arg = { binfostr, sizeof (binfostr), NULL, 0, 0, MSG_ORIG(MSG_BINFO_START), MSG_ORIG(MSG_BINFO_SEP), MSG_ORIG(MSG_BINFO_END) }; const char *ffile = NAME(flmp); const char *tfile = NAME(tlmp); Lm_list *lml = LIST(flmp); if (DBG_NOTCLASS(DBG_C_BINDINGS)) return; if (DBG_NOTDETAIL()) { dbg_print(lml, MSG_INTL(MSG_BND_BASIC), ffile, tfile, Dbg_demangle_name(sym)); return; } /* * Determine if this binding has any associated information, such as * interposition, direct binding, copy-relocations, etc. */ binfo &= ~DBG_BINFO_FOUND; binfo &= DBG_BINFO_MSK; if (binfo) { conv_arg.oflags = conv_arg.rflags = binfo; (void) conv_expn_field(&conv_arg, vda, 0); } else { binfostr[0] = '\0'; } if (pltndx != (Xword)-1) { const char *pltstring; if (pbtype < PLT_T_NUM) pltstring = pltbindtypes[pbtype]; else pltstring = pltbindtypes[PLT_T_NONE]; /* * Called from a plt offset. */ dbg_print(lml, MSG_INTL(MSG_BND_PLT), ffile, EC_ADDR(fabs), EC_OFF(foff), EC_XWORD(pltndx), pltstring, tfile, EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), binfostr); } else if ((fabs == 0) && (foff == 0)) { /* * Called from a dlsym(). We're not performing a relocation, * but are handing the address of the symbol back to the user. */ dbg_print(lml, MSG_INTL(MSG_BND_DLSYM), ffile, tfile, EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), binfostr); } else { /* * Standard relocation. */ dbg_print(lml, MSG_INTL(MSG_BND_DEFAULT), ffile, EC_ADDR(fabs), EC_OFF(foff), tfile, EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), binfostr); } } void Dbg_bind_reject(Rt_map *flmp, Rt_map *tlmp, const char *sym, int why) { static Msg reason[DBG_BNDREJ_NUM + 1] = { MSG_BNDREJ_DIRECT, /* MSG_INTL(MSG_BNDREJ_DIRECT) */ MSG_BNDREJ_GROUP, /* MSG_INTL(MSG_BNDREJ_GROUP) */ MSG_BNDREJ_SINGLE /* MSG_INTL(MSG_BNDREJ_SINGLE) */ }; if (DBG_NOTCLASS(DBG_C_BINDINGS)) return; dbg_print(LIST(flmp), MSG_INTL(MSG_BND_REJECT), NAME(flmp), NAME(tlmp), sym, MSG_INTL(reason[why])); } void Dbg_bind_weak(Rt_map *flmp, Addr fabs, Addr frel, const char *sym) { Lm_list *lml = LIST(flmp); const char *ffile = NAME(flmp); if (DBG_NOTCLASS(DBG_C_BINDINGS)) return; if (DBG_NOTDETAIL()) dbg_print(lml, MSG_INTL(MSG_BND_WEAK_1), ffile, Dbg_demangle_name(sym)); else dbg_print(lml, MSG_INTL(MSG_BND_WEAK_2), ffile, EC_ADDR(fabs), EC_ADDR(frel), Dbg_demangle_name(sym)); } #if defined(_ELF64) void Dbg_bind_pltpad_to(Rt_map *lmp, Addr pltpad, const char *dfile, const char *sname) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), NAME(lmp), dfile, sname); } void Dbg_bind_pltpad_from(Rt_map *lmp, Addr pltpad, const char *sname) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), NAME(lmp), sname); } #endif /* * 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 (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2022 Oxide Computer Company */ #include #include #include #include #include "msg.h" #include "_debug.h" void Dbg_cap_candidate(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_FILES)) return; dbg_print(lml, MSG_INTL(MSG_CAP_CANDIDATE), name); } void Dbg_cap_filter(Lm_list *lml, const char *dir, Rt_map *flmp) { if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); if (flmp) dbg_print(lml, MSG_INTL(MSG_CAP_FILTER_1), dir, NAME(flmp)); else dbg_print(lml, MSG_INTL(MSG_CAP_FILTER_2), dir); } void Dbg_cap_identical(Lm_list *lml, const char *file1, const char *file2) { if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_FILES)) return; dbg_print(lml, MSG_INTL(MSG_CAP_IDENTICAL), file1, file2); } void Dbg_cap_val(Lm_list *lml, Syscapset *sys, Syscapset *alt, Half mach) { Conv_cap_val_buf_t cap_val_buf; if ((sys->sc_plat == NULL) && (sys->sc_mach == NULL) && (sys->sc_hw_2 == 0) && (sys->sc_hw_1 == 0) && (sys->sc_sf_1 == 0)) return; Dbg_util_nl(lml, DBG_NL_FRC); /* * Print any capabilities in precedence order. */ if (sys->sc_plat) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_PLAT), sys->sc_plat); } if (sys->sc_mach) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_MACH), sys->sc_mach); } if (sys->sc_hw_3) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_3), conv_cap_val_hw3(sys->sc_hw_3, mach, 0, &cap_val_buf.cap_val_hw3_buf)); } if (sys->sc_hw_2) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_2), conv_cap_val_hw2(sys->sc_hw_2, mach, 0, &cap_val_buf.cap_val_hw2_buf)); } if (sys->sc_hw_1) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_HW_1), conv_cap_val_hw1(sys->sc_hw_1, mach, 0, &cap_val_buf.cap_val_hw1_buf)); } if (sys->sc_sf_1) { dbg_print(lml, MSG_INTL(MSG_CAP_SYS_SF_1), conv_cap_val_sf1(sys->sc_sf_1, mach, 0, &cap_val_buf.cap_val_sf1_buf)); } if (alt != sys) { Dbg_util_nl(lml, DBG_NL_FRC); if (alt->sc_plat != sys->sc_plat) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_PLAT), alt->sc_plat); } if (alt->sc_mach != sys->sc_mach) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_MACH), alt->sc_mach); } if (alt->sc_hw_3 != sys->sc_hw_3) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_3), conv_cap_val_hw3(alt->sc_hw_3, mach, 0, &cap_val_buf.cap_val_hw3_buf)); } if (alt->sc_hw_2 != sys->sc_hw_2) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_2), conv_cap_val_hw2(alt->sc_hw_2, mach, 0, &cap_val_buf.cap_val_hw2_buf)); } if (alt->sc_hw_1 != sys->sc_hw_1) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_HW_1), conv_cap_val_hw1(alt->sc_hw_1, mach, 0, &cap_val_buf.cap_val_hw1_buf)); } if (alt->sc_sf_1 != sys->sc_sf_1) { dbg_print(lml, MSG_INTL(MSG_CAP_ALT_SF_1), conv_cap_val_sf1(alt->sc_sf_1, mach, 0, &cap_val_buf.cap_val_sf1_buf)); } } Dbg_util_nl(lml, DBG_NL_FRC); } /* * This version takes a pointer to a Capmask, and will report the exclusion * bits if they exist. */ void Dbg_cap_ptr_entry(Lm_list *lml, dbg_state_t dbg_state, Xword tag, const char *ptr) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_CAP)) return; dbg_print(lml, MSG_INTL(MSG_CAP_SEC_ENTRY), Dbg_state_str(dbg_state), conv_cap_tag(tag, 0, &inv_buf), ptr); } /* * This version takes a pointer to a CapMask, and will report the exclusion * bits if they exist. */ void Dbg_cap_val_entry(Lm_list *lml, dbg_state_t dbg_state, Xword tag, Xword val, Half mach) { Conv_inv_buf_t inv_buf; Conv_cap_val_buf_t cap_val_buf; if (DBG_NOTCLASS(DBG_C_CAP)) return; dbg_print(lml, MSG_INTL(MSG_CAP_SEC_ENTRY), Dbg_state_str(dbg_state), conv_cap_tag(tag, 0, &inv_buf), conv_cap_val(tag, val, mach, 0, &cap_val_buf)); } void Dbg_cap_sec_title(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_CAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_CAP_SEC_TITLE), name); } void Dbg_cap_mapfile_title(Lm_list *lml, Lineno lineno) { if (DBG_NOTCLASS(DBG_C_MAP | DBG_C_CAP)) return; dbg_print(lml, MSG_INTL(MSG_MAP_CAP), EC_LINENO(lineno)); } void Dbg_cap_id(Lm_list *lml, Lineno lineno, const char *oid, const char *nid) { Dbg_cap_mapfile_title(lml, lineno); Dbg_cap_ptr_entry(lml, DBG_STATE_CURRENT, CA_SUNW_ID, oid); Dbg_cap_ptr_entry(lml, DBG_STATE_NEW, CA_SUNW_ID, nid); Dbg_cap_ptr_entry(lml, DBG_STATE_RESOLVED, CA_SUNW_ID, nid); } void Dbg_cap_post_title(Lm_list *lml, int *title) { if (DBG_NOTCLASS(DBG_C_CAP)) return; Dbg_util_nl(lml, DBG_NL_STD); if ((*title)++ == 0) dbg_print(lml, MSG_INTL(MSG_CAP_POST_TITLE)); } void Elf_cap_title(Lm_list *lml) { dbg_print(lml, MSG_INTL(MSG_CAP_ELF_TITLE)); } void Elf_cap_entry(Lm_list *lml, Cap *cap, int ndx, const char *str, size_t str_size, Half mach) { Conv_inv_buf_t inv_buf; Conv_cap_val_buf_t cap_val_buf; char index[INDEX_STR_SIZE]; (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_FMT_INDEX), ndx); switch (cap->c_tag) { case CA_SUNW_PLAT: case CA_SUNW_MACH: case CA_SUNW_ID: /* If offset is in range, format as a string */ if (str && (cap->c_un.c_ptr < str_size)) { str += cap->c_un.c_ptr; break; } /*FALLTHROUGH*/ default: /* Format numerically */ str = conv_cap_val(cap->c_tag, cap->c_un.c_val, mach, 0, &cap_val_buf); } dbg_print(lml, MSG_INTL(MSG_CAP_ELF_ENTRY), index, conv_cap_tag(cap->c_tag, 0, &inv_buf), str); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include <_debug.h> #include /* * Define a debug descriptor. Note, although this provides the default * definition to which most users bind, ld.so.1 must provide its own definition, * and thus interposition is expected. This item should be defined NODIRECT. */ static Dbg_desc _dbg_desc = { 0, 0, NULL, { 0, 0 }, { 0, 0 } }; Dbg_desc *dbg_desc = &_dbg_desc; int _Dbg_cnt = 0; /* * Debugging initialization and processing. The dbg_options[] array defines * a set of option strings that can be specified using the -D flag or from an * environment variable. For each option, a class is enabled in the d_class * bit mask, or an extra flag is enabled in the d_extra bit mask. */ static DBG_options _Dbg_options[] = { /* Options accepted by both linkers */ {MSG_ORIG(MSG_TOK_DETAIL), 0, DBG_E_DETAIL}, {MSG_ORIG(MSG_TOK_LONG), 0, DBG_E_LONG}, {MSG_ORIG(MSG_TOK_HELP), 0, DBG_E_HELP}, {MSG_ORIG(MSG_TOK_TTIME), 0, DBG_E_TTIME}, {MSG_ORIG(MSG_TOK_DTIME), 0, DBG_E_DTIME}, {MSG_ORIG(MSG_TOK_ALL), DBG_C_ALL & ~DBG_C_DEMANGLE, 0}, {MSG_ORIG(MSG_TOK_BASIC), DBG_C_BASIC, 0}, {MSG_ORIG(MSG_TOK_CAP), DBG_C_CAP, 0}, {MSG_ORIG(MSG_TOK_DEMANGLE), DBG_C_DEMANGLE, 0}, {MSG_ORIG(MSG_TOK_FILES), DBG_C_FILES, 0}, {MSG_ORIG(MSG_TOK_LIBS), DBG_C_LIBS, 0}, {MSG_ORIG(MSG_TOK_MOVE), DBG_C_MOVE, 0}, {MSG_ORIG(MSG_TOK_RELOC), DBG_C_RELOC, 0}, {MSG_ORIG(MSG_TOK_SYMBOLS), DBG_C_SYMBOLS, 0}, {MSG_ORIG(MSG_TOK_TLS), DBG_C_TLS, 0}, {MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0}, {MSG_ORIG(MSG_TOK_VERSIONS), DBG_C_VERSIONS, 0}, {NULL, 0, 0}, }; static DBG_options _Dbg_options_ld[] = { /* ld only options */ {MSG_ORIG(MSG_TOK_CLASS), 0, DBG_E_SNAME | DBG_E_CLASS}, {MSG_ORIG(MSG_TOK_FULLNAME), 0, DBG_E_SNAME | DBG_E_FNAME}, {MSG_ORIG(MSG_TOK_NAME), 0, DBG_E_SNAME}, {MSG_ORIG(MSG_TOK_ARGS), DBG_C_ARGS, 0}, {MSG_ORIG(MSG_TOK_ENTRY), DBG_C_ENTRY, 0}, {MSG_ORIG(MSG_TOK_GOT), DBG_C_GOT, 0}, {MSG_ORIG(MSG_TOK_MAP), DBG_C_MAP, 0}, {MSG_ORIG(MSG_TOK_SECTIONS), DBG_C_SECTIONS, 0}, {MSG_ORIG(MSG_TOK_SEGMENTS), DBG_C_SEGMENTS, 0}, {MSG_ORIG(MSG_TOK_STATS), DBG_C_STATS, 0}, {MSG_ORIG(MSG_TOK_STRTAB), DBG_C_STRTAB, 0}, {MSG_ORIG(MSG_TOK_SUPPORT), DBG_C_SUPPORT, 0}, {NULL, 0, 0}, }; static DBG_options _Dbg_options_rtld[] = { /* ld.so.1 only options */ {MSG_ORIG(MSG_TOK_AUDIT), DBG_C_AUDITING, 0}, {MSG_ORIG(MSG_TOK_BINDINGS), DBG_C_BINDINGS, 0}, {MSG_ORIG(MSG_TOK_DL), DBG_C_DL, 0}, {MSG_ORIG(MSG_TOK_INIT), DBG_C_INIT, 0}, {NULL, 0, 0}, }; /* * Compare name to the options found in optarr. If one matches, * update *dbp and return TRUE. Otherwise, FALSE. */ static Boolean process_options(const char *name, Boolean set, Dbg_desc *dbp, DBG_options *optarr) { DBG_options *opt; for (opt = optarr; opt->o_name != NULL; opt++) { if (strcmp(name, opt->o_name) != 0) continue; if (set == TRUE) { if (opt->o_class) dbp->d_class |= opt->o_class; if (opt->o_extra) dbp->d_extra |= opt->o_extra; } else { if (opt->o_class) dbp->d_class &= ~(opt->o_class); if (opt->o_extra) dbp->d_extra &= ~(opt->o_extra); } return (TRUE); } return (FALSE); } /* * Provide a debugging usage message */ void Dbg_help(void) { Dbg_util_nl(0, DBG_NL_STD); dbg_print(0, MSG_INTL(MSG_USE_R1_A)); dbg_print(0, MSG_INTL(MSG_USE_R1_B)); dbg_print(0, MSG_INTL(MSG_USE_R1_C)); dbg_print(0, MSG_INTL(MSG_USE_R1_D)); dbg_print(0, MSG_INTL(MSG_USE_R1_E)); dbg_print(0, MSG_INTL(MSG_USE_R1_F)); dbg_print(0, MSG_INTL(MSG_USE_R1_G)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_R2_A)); dbg_print(0, MSG_INTL(MSG_USE_R2_B)); dbg_print(0, MSG_INTL(MSG_USE_R2_C)); dbg_print(0, MSG_INTL(MSG_USE_R2_D)); dbg_print(0, MSG_INTL(MSG_USE_R2_E)); dbg_print(0, MSG_INTL(MSG_USE_R2_F)); dbg_print(0, MSG_INTL(MSG_USE_R2_G)); dbg_print(0, MSG_INTL(MSG_USE_R2_H)); dbg_print(0, MSG_INTL(MSG_USE_R2_I)); dbg_print(0, MSG_INTL(MSG_USE_R2_J)); dbg_print(0, MSG_INTL(MSG_USE_R2_K)); dbg_print(0, MSG_INTL(MSG_USE_R2_L)); dbg_print(0, MSG_INTL(MSG_USE_R2_M)); dbg_print(0, MSG_INTL(MSG_USE_R2_N)); dbg_print(0, MSG_INTL(MSG_USE_R2_O)); dbg_print(0, MSG_INTL(MSG_USE_R2_P)); dbg_print(0, MSG_INTL(MSG_USE_R2_Q)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_R2_R)); dbg_print(0, MSG_INTL(MSG_USE_R2_S)); dbg_print(0, MSG_INTL(MSG_USE_R2_T)); dbg_print(0, MSG_INTL(MSG_USE_R2_U)); dbg_print(0, MSG_INTL(MSG_USE_R2_V)); dbg_print(0, MSG_INTL(MSG_USE_R2_W)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_R3_A)); dbg_print(0, MSG_INTL(MSG_USE_R3_B)); dbg_print(0, MSG_INTL(MSG_USE_R3_C)); dbg_print(0, MSG_INTL(MSG_USE_R3_D)); dbg_print(0, MSG_INTL(MSG_USE_R3_E)); dbg_print(0, MSG_INTL(MSG_USE_R3_F)); dbg_print(0, MSG_INTL(MSG_USE_R3_G)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_R3_H)); dbg_print(0, MSG_INTL(MSG_USE_R3_F)); dbg_print(0, MSG_INTL(MSG_USE_R3_I)); dbg_print(0, MSG_INTL(MSG_USE_R3_J)); dbg_print(0, MSG_INTL(MSG_USE_R3_K)); dbg_print(0, MSG_INTL(MSG_USE_R3_L)); dbg_print(0, MSG_INTL(MSG_USE_R3_M)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_R3_N)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_HDR_DCT)); dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); dbg_print(0, MSG_INTL(MSG_USE_R4_A)); dbg_print(0, MSG_INTL(MSG_USE_R4_B)); dbg_print(0, MSG_INTL(MSG_USE_R4_B2)); dbg_print(0, MSG_INTL(MSG_USE_R4_C)); dbg_print(0, MSG_INTL(MSG_USE_R4_C2)); dbg_print(0, MSG_INTL(MSG_USE_R4_C3)); dbg_print(0, MSG_INTL(MSG_USE_R4_D)); dbg_print(0, MSG_INTL(MSG_USE_R4_E)); dbg_print(0, MSG_INTL(MSG_USE_R4_E2)); dbg_print(0, MSG_INTL(MSG_USE_R4_E3)); dbg_print(0, MSG_INTL(MSG_USE_R4_F)); dbg_print(0, MSG_INTL(MSG_USE_R4_F2)); dbg_print(0, MSG_INTL(MSG_USE_R4_F3)); dbg_print(0, MSG_INTL(MSG_USE_R4_F4)); dbg_print(0, MSG_INTL(MSG_USE_R4_F5)); dbg_print(0, MSG_INTL(MSG_USE_R4_F6)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); dbg_print(0, MSG_INTL(MSG_USE_R5_A)); dbg_print(0, MSG_INTL(MSG_USE_R5_A2)); dbg_print(0, MSG_INTL(MSG_USE_R5_A3)); dbg_print(0, MSG_INTL(MSG_USE_R5_A4)); dbg_print(0, MSG_INTL(MSG_USE_R5_A5)); dbg_print(0, MSG_INTL(MSG_USE_R5_A6)); dbg_print(0, MSG_INTL(MSG_USE_R5_A7)); dbg_print(0, MSG_INTL(MSG_USE_R5_A8)); dbg_print(0, MSG_INTL(MSG_USE_R5_A9)); dbg_print(0, MSG_INTL(MSG_USE_R5_A0)); dbg_print(0, MSG_INTL(MSG_USE_R5_B)); dbg_print(0, MSG_INTL(MSG_USE_R5_C)); dbg_print(0, MSG_INTL(MSG_USE_R5_D)); dbg_print(0, MSG_INTL(MSG_USE_R5_E)); dbg_print(0, MSG_INTL(MSG_USE_R5_F)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); dbg_print(0, MSG_INTL(MSG_USE_R6_A)); dbg_print(0, MSG_INTL(MSG_USE_R6_B)); dbg_print(0, MSG_INTL(MSG_USE_R6_C)); dbg_print(0, MSG_INTL(MSG_USE_R6_C2)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_HDR_CST)); dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); dbg_print(0, MSG_INTL(MSG_USE_R7_A)); dbg_print(0, MSG_INTL(MSG_USE_R7_B)); dbg_print(0, MSG_INTL(MSG_USE_R7_C)); dbg_print(0, MSG_INTL(MSG_USE_R7_D)); dbg_print(0, MSG_INTL(MSG_USE_R7_E)); dbg_print(0, MSG_INTL(MSG_USE_R7_F)); dbg_print(0, MSG_INTL(MSG_USE_R7_F2)); dbg_print(0, MSG_INTL(MSG_USE_R7_G)); dbg_print(0, MSG_INTL(MSG_USE_R7_H)); dbg_print(0, MSG_INTL(MSG_USE_R7_I)); dbg_print(0, MSG_INTL(MSG_USE_R7_I2)); dbg_print(0, MSG_INTL(MSG_USE_R7_J)); dbg_print(0, MSG_INTL(MSG_USE_R7_K)); dbg_print(0, MSG_INTL(MSG_USE_R7_K2)); dbg_print(0, MSG_INTL(MSG_USE_R7_L)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); dbg_print(0, MSG_INTL(MSG_USE_R8_A)); dbg_print(0, MSG_INTL(MSG_USE_R8_B)); dbg_print(0, MSG_INTL(MSG_USE_R8_B2)); dbg_print(0, MSG_INTL(MSG_USE_R8_C)); dbg_print(0, MSG_INTL(MSG_USE_R8_D)); Dbg_util_nl(0, DBG_NL_FRC); dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); dbg_print(0, MSG_INTL(MSG_USE_R9_A)); dbg_print(0, MSG_INTL(MSG_USE_R9_B)); dbg_print(0, MSG_INTL(MSG_USE_R9_C)); dbg_print(0, MSG_INTL(MSG_USE_R9_D)); dbg_print(0, MSG_INTL(MSG_USE_R9_E)); dbg_print(0, MSG_INTL(MSG_USE_R9_F)); dbg_print(0, MSG_INTL(MSG_USE_R9_F2)); dbg_print(0, MSG_INTL(MSG_USE_R9_G)); dbg_print(0, MSG_INTL(MSG_USE_R9_H)); dbg_print(0, MSG_INTL(MSG_USE_R9_H2)); dbg_print(0, MSG_INTL(MSG_USE_R9_I)); Dbg_util_nl(0, DBG_NL_FRC); } /* * Provide a debugging message showing the version of the linker package */ void Dbg_version(void) { Dbg_util_nl(0, DBG_NL_STD); dbg_print(0, MSG_ORIG(MSG_STR_LDVER), link_ver_string); Dbg_util_nl(0, DBG_NL_STD); } /* * Messaging support - funnel everything through dgettext() as this provides * the real binding to libc. */ const char * _liblddbg_msg(Msg mid) { return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid))); } /* * Given a name starting with "lmid", finish processing it. Return TRUE * if a valid lmid token was seen, and FALSE for any error. * * exit: * On failure, returns FALSE, indicating a syntax error * * On success: * - Appropriate flags in dbg->d_extra have been set * - Any link-map list names specified have been added to * d_list, for the rtld dbg_print() to compare against * link-map list names. * - TRUE is returned. */ static Boolean process_lmid(char *name, Dbg_desc *dbp) { /* * "lmid" can have an optional argument. Allowed values are "all", * "alt[0-9]+", "base", or "ldso". Alt has a variable ending, but * we can use process_options() to handle the other three. */ static DBG_options options_lmid[] = { {MSG_ORIG(MSG_TOK_LMID_ALL), 0, DBG_E_LMID_ALL}, {MSG_ORIG(MSG_TOK_LMID_BASE), 0, DBG_E_LMID_BASE}, {MSG_ORIG(MSG_TOK_LMID_LDSO), 0, DBG_E_LMID_LDSO}, {NULL, 0, 0}, }; Dbg_desc tmp_db; const char *lmid_opt; /* If it's a plain "lmid", we can set the flag and return now */ if (name[MSG_TOK_LMID_SIZE] == '\0') { dbp->d_extra |= DBG_E_LMID; return (TRUE); } /* If there's no value, its an error */ if (conv_strproc_extract_value(name, MSG_TOK_LMID_SIZE, CONV_SPEXV_F_UCASE, &lmid_opt) == 0) return (FALSE); /* * ALL, BASE, or LDSO? */ tmp_db.d_extra = 0; if (process_options(lmid_opt, TRUE, &tmp_db, options_lmid)) { /* * If BASE, and we haven't already seen it, add it to the * rtld name matching list. For the others, setting the * e_extra bit suffices. */ if (((tmp_db.d_extra & DBG_E_LMID_BASE) != 0) && ((dbp->d_extra & DBG_E_LMID_BASE) == 0) && (aplist_append(&dbp->d_list, MSG_ORIG(MSG_TOK_LMID_BASE), AL_CNT_DEBUG) == NULL)) return (FALSE); /* Add the resulting flags into the callers descriptor */ dbp->d_extra |= DBG_E_LMID | tmp_db.d_extra; return (TRUE); } /* * ALT? */ if (strncmp(lmid_opt, MSG_ORIG(MSG_TOK_LMID_ALT), MSG_TOK_LMID_ALT_SIZE) == 0) { const char *tail = lmid_opt + MSG_TOK_LMID_ALT_SIZE; /* 'ALT' without a # means "all alternative link-map lists" */ if (*tail == '\0') { dbp->d_extra |= DBG_E_LMID | DBG_E_LMID_ALT; return (TRUE); } /* * It is ALT[0-9]+. Make sure the characters following 'ALT' * are numbers, and then add it to the rtld name matching list. */ for (; *tail; tail++) if ((*tail < '0') || (*tail > '9')) return (FALSE); if (aplist_append(&dbp->d_list, lmid_opt, AL_CNT_DEBUG) == NULL) return (FALSE); dbp->d_extra |= DBG_E_LMID; return (TRUE); } /* It's nothing we recognize */ return (FALSE); } /* * Validate and enable the appropriate debugging classes. * * entry: * string - String to be analyzed for debugging options * dbp - Pointer to debug descriptor to be initialized * outfile_ret - NULL, or pointer to receive result of 'output=' * token. A NULL value means that the 'output=' token * is not accepted. A non-NULL value means that it is. * * exit: * On failure, False (0) is returned. * * On success, string has been parsed, and the descriptor referenced * by dbp has been initialized. If outfile is non-NULL, *outfile will * be set to NULL if the 'output=' token is not present, and to the * user supplied string otherwise. True (1) is returned. */ int Dbg_setup(dbg_setup_caller_t caller, const char *string, Dbg_desc *dbp, const char **outfile) { char *name, *_name; /* buffer in which to perform */ /* strtok_r() operations. */ char *lasts; const char *delimit = MSG_ORIG(MSG_STR_DELIMIT); /* * Clear the help flags --- these items only apply for a single * call to Dbg_setup(). */ dbp->d_extra &= ~(DBG_E_HELP | DBG_E_HELP_EXIT); if ((_name = (char *)malloc(strlen(string) + 1)) == NULL) return (0); (void) strcpy(_name, string); if (outfile) *outfile = NULL; /* No output file yet */ /* * The token should be of the form "-Dtok,tok,tok,...". Separate the * pieces and build up the appropriate mask, unrecognized options are * flagged. */ if ((name = strtok_r(_name, delimit, &lasts)) != NULL) { do { Boolean set; /* Remove leading and trailing whitespace */ name = conv_strproc_trim(name); if (name[0] == '!') { set = FALSE; name++; } else set = TRUE; if (*name == '\0') continue; /* Skip null token */ /* * First, determine if the token represents a class or * extra. */ if (process_options(name, set, dbp, _Dbg_options)) continue; switch (caller) { case DBG_CALLER_LD: /* ld only tokens */ if (process_options(name, set, dbp, _Dbg_options_ld)) continue; break; case DBG_CALLER_RTLD: /* rtld only tokens */ if (process_options(name, set, dbp, _Dbg_options_rtld)) continue; break; } /* The remaining options do not accept negation */ if (!set) { dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name); continue; } /* * Is it an 'output=' token? This item is a special * case because it depends on the presence of * a non-NULL outfile argument, and because the * part following the '=' is variable. */ if ((outfile != NULL) && strncmp(name, MSG_ORIG(MSG_TOK_OUTFILE), MSG_TOK_OUTFILE_SIZE) == 0) { if (conv_strproc_extract_value(name, MSG_TOK_OUTFILE_SIZE, 0, outfile)) continue; } /* * Only the rtld "lmid" token is left. */ if ((caller == DBG_CALLER_RTLD) && (strncmp(name, MSG_ORIG(MSG_TOK_LMID), MSG_TOK_LMID_SIZE) == 0) && process_lmid(name, dbp)) continue; /* If we make it here, the token is not understood */ dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name); } while ((name = strtok_r(NULL, delimit, &lasts)) != NULL); } /* * If the debug help option was specified and this is the only debug * class, return an indication that the user should exit. */ if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) && (dbp->d_class == 0)) dbp->d_extra |= DBG_E_HELP_EXIT; return (1); } /* * Define our own printing routine. This provides a basic fallback, as ld(1) * and ld.so.1(1) provide their own routines that augment their diagnostic * output, and direct the output to stderr. This item should be defined * NODIRECT. */ /* PRINTFLIKE2 */ void dbg_print(Lm_list *lml, const char *format, ...) { va_list ap; #if defined(lint) /* * The lml argument is only meaningful for diagnostics sent to ld.so.1. * Supress the lint error by making a dummy assignment. */ lml = 0; #endif va_start(ap, format); (void) vprintf(format, ap); (void) printf(MSG_ORIG(MSG_STR_NL)); va_end(ap); } /* * Return an internationalized state transition string. These are used by * various debugging output. */ const char * Dbg_state_str(dbg_state_t type) { static const Msg state[DBG_STATE_NUM] = { MSG_STR_ADD, /* MSG_INTL(MSG_STR_ADD) */ MSG_STR_CURRENT, /* MSG_INTL(MSG_STR_CURRENT) */ MSG_STR_EXCLUDE, /* MSG_INTL(MSG_STR_EXCLUDE) */ MSG_STR_IGNORE, /* MSG_INTL(MSG_STR_IGNORE) */ MSG_STR_MOD_BEFORE, /* MSG_INTL(MSG_STR_MOD_BEFORE) */ MSG_STR_MOD_AFTER, /* MSG_INTL(MSG_STR_MOD_AFTER) */ MSG_STR_NEW, /* MSG_INTL(MSG_STR_NEW) */ MSG_STR_NEW_IMPLICIT, /* MSG_INTL(MSG_STR_NEW_IMPLICIT) */ MSG_STR_RESET, /* MSG_INTL(MSG_STR_RESET) */ MSG_STR_ORIGINAL, /* MSG_INTL(MSG_STR_ORIGINAL) */ MSG_STR_RESOLVED, /* MSG_INTL(MSG_STR_RESOLVED) */ }; #if DBG_STATE_NUM != (DBG_STATE_RESOLVED + 1) #error DBG_SEG_NUM has changed. Update segtype[] #endif assert(type < DBG_STATE_NUM); return (MSG_INTL(state[type])); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include "msg.h" #include "_debug.h" #include "libld.h" void Dbg_dl_iphdr_enter(Rt_map *clmp, u_longlong_t cnt_map, u_longlong_t cnt_unmap) { Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_DL)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_ENTER), NAME(clmp)); dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_MAPCNT), cnt_map, cnt_unmap); } void Dbg_dl_iphdr_callback(Lm_list *lml, struct dl_phdr_info *info) { if (DBG_NOTCLASS(DBG_C_DL)) return; dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_CALLBACK)); dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_NAME), info->dlpi_name); dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_ADDR), EC_ADDR(info->dlpi_addr)); dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_PHDR), EC_ADDR(CAST_PTRINT(Addr, info->dlpi_phdr)), EC_WORD(info->dlpi_phnum)); } void Dbg_dl_iphdr_mapchange(Lm_list *lml, u_longlong_t cnt_map, u_longlong_t cnt_unmap) { if (DBG_NOTCLASS(DBG_C_DL)) return; dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_MAPCNG)); dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_MAPCNT), cnt_map, cnt_unmap); } void Dbg_dl_iphdr_unmap_ret(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_DL)) return; dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_UNMAP)); } void Dbg_dl_dlopen(Rt_map *clmp, const char *name, int *in_nfavl, int mode) { Conv_dl_mode_buf_t dl_mode_buf; Lm_list *lml = LIST(clmp); const char *retry; if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_DL)) return; /* * The core functionality of dlopen() can be called twice. The first * attempt can be affected by path names that exist in the "not-found" * AVL tree. Should a "not-found" path name be found, a second attempt * is made to locate the required file (in_nfavl is NULL). This fall- * back provides for file system changes while a process executes. */ if (in_nfavl) retry = MSG_ORIG(MSG_STR_EMPTY); else retry = MSG_INTL(MSG_STR_RETRY); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_DLOPEN), name, NAME(clmp), retry, conv_dl_mode(mode, 0, &dl_mode_buf)); } void Dbg_dl_dlclose(Rt_map *clmp, const char *name, int flag) { const char *str; Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_DL)) return; if (flag == DBG_DLCLOSE_IGNORE) str = MSG_INTL(MSG_STR_IGNORE); else str = MSG_ORIG(MSG_STR_EMPTY); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_DLCLOSE), name, NAME(clmp), str); } void Dbg_dl_dldump(Rt_map *clmp, const char *ipath, const char *opath, int flags) { Conv_dl_flag_buf_t dl_flag_buf; Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_DL)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_DLDUMP), ipath, NAME(clmp), opath ? opath : MSG_INTL(MSG_STR_NULL), conv_dl_flag(flags, 0, &dl_flag_buf)); } void Dbg_dl_dlerror(Rt_map *clmp, const char *str) { Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_DL)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_DLERROR), NAME(clmp), str ? str : MSG_INTL(MSG_STR_NULL)); } void Dbg_dl_dladdr(Rt_map *clmp, void *addr) { Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_DL)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_DLADDR), NAME(clmp), EC_NATPTR(addr)); } void Dbg_dl_dlsym(Rt_map *clmp, const char *sym, int *in_nfavl, const char *next, int type) { const char *str, *retry, *from = NAME(clmp); Lm_list *lml = LIST(clmp); static const Msg dlsym_msg[DBG_DLSYM_NUM] = { MSG_STR_EMPTY, /* MSG_ORIG(MSG_STR_EMPTY) */ MSG_DLSYM_NEXT, /* MSG_ORIG(MSG_DLSYM_NEXT) */ MSG_DLSYM_DEFAULT, /* MSG_ORIG(MSG_DLSYM_DEFAULT) */ MSG_DLSYM_SELF, /* MSG_ORIG(MSG_DLSYM_SELF) */ MSG_DLSYM_PROBE, /* MSG_ORIG(MSG_DLSYM_PROBE) */ MSG_DLSYM_SINGLETON /* MSG_ORIG(MSG_DLSYM_SINGLETON) */ }; #if DBG_DLSYM_NUM != (DBG_DLSYM_SINGLETON + 1) #error DBG_DLSYM_NUM has grown #endif if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_DL)) return; /* * The core functionality of dlsym() can be called twice. The first * attempt can be affected by path names that exist in the "not-found" * AVL tree. Should a "not-found" path name be found, a second attempt * is made to locate the required file (in_nfavl is NULL). This fall- * back provides for file system changes while a process executes. */ if (in_nfavl) retry = MSG_ORIG(MSG_STR_EMPTY); else retry = MSG_INTL(MSG_STR_RETRY); if (type >= DBG_DLSYM_NUM) type = 0; str = MSG_ORIG(dlsym_msg[type]); Dbg_util_nl(lml, DBG_NL_STD); if (next == 0) dbg_print(lml, MSG_INTL(MSG_DLSYM_1), Dbg_demangle_name(sym), from, retry, str); else dbg_print(lml, MSG_INTL(MSG_DLSYM_2), Dbg_demangle_name(sym), from, next, retry, str); } void Dbg_dl_dlinfo(Rt_map *clmp, const char *name, int request, void *addr) { Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_DL)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_DL_DLINFO), NAME(clmp), name, conv_dl_info(request), EC_NATPTR(addr)); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include <_debug.h> #include /* * Print out the dynamic section entries. */ void Elf_dyn_title(Lm_list *lml) { dbg_print(lml, MSG_INTL(MSG_DYN_TITLE)); } void Elf_dyn_entry(Lm_list *lml, Dyn *dyn, int ndx, const char *name, uchar_t osabi, Half mach) { Conv_inv_buf_t inv_buf; char index[INDEX_STR_SIZE]; (void) snprintf(index, sizeof (index), MSG_ORIG(MSG_FMT_INDEX), ndx); dbg_print(lml, MSG_INTL(MSG_DYN_ENTRY), index, conv_dyn_tag(dyn->d_tag, osabi, mach, 0, &inv_buf), EC_XWORD(dyn->d_un.d_val), name); } /* * Variant of Elf_dyn_entry() specifically for DT_NULL. Handles the * case of multiple adjacent DT_NULL entries by displaying them on * a single line using an index range instead of a single index. */ void Elf_dyn_null_entry(Lm_list *lml, Dyn *dyn, int start_ndx, int end_ndx) { Conv_inv_buf_t inv_buf; char index[2 * INDEX_STR_SIZE]; if (start_ndx == end_ndx) { Elf_dyn_entry(lml, dyn, start_ndx, MSG_ORIG(MSG_STR_EMPTY), ELFOSABI_NONE, 0); } else { (void) snprintf(index, sizeof (index), MSG_ORIG(MSG_FMT_INDEX_RANGE), start_ndx, end_ndx); dbg_print(lml, MSG_INTL(MSG_DYN_ENTRY), index, conv_dyn_tag(DT_NULL, ELFOSABI_NONE, 0, 0, &inv_buf), EC_XWORD(dyn->d_un.d_val), MSG_ORIG(MSG_STR_EMPTY)); } } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include <_debug.h> #include #include void Elf_ehdr(Lm_list *lml, Ehdr *ehdr, Shdr *shdr0) { Conv_inv_buf_t inv_buf1, inv_buf2; Conv_ehdr_flags_buf_t flags_buf; Conv_sec_flags_buf_t sec_flags_buf; Byte *byte = &(ehdr->e_ident[0]); const char *flgs; int xshdr = 0; uchar_t osabi = ehdr->e_ident[EI_OSABI]; Half mach = ehdr->e_machine; dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); dbg_print(lml, MSG_INTL(MSG_ELF_HEADER)); dbg_print(lml, MSG_ORIG(MSG_ELF_MAGIC), byte[EI_MAG0], (byte[EI_MAG1] ? byte[EI_MAG1] : '0'), (byte[EI_MAG2] ? byte[EI_MAG2] : '0'), (byte[EI_MAG3] ? byte[EI_MAG3] : '0')); dbg_print(lml, MSG_ORIG(MSG_ELF_CLASS), conv_ehdr_class(ehdr->e_ident[EI_CLASS], 0, &inv_buf1), conv_ehdr_data(ehdr->e_ident[EI_DATA], 0, &inv_buf2)); dbg_print(lml, MSG_ORIG(MSG_ELF_OSABI), conv_ehdr_osabi(ehdr->e_ident[EI_OSABI], 0, &inv_buf1), conv_ehdr_abivers(ehdr->e_ident[EI_OSABI], ehdr->e_ident[EI_ABIVERSION], CONV_FMT_DECIMAL, &inv_buf2)); dbg_print(lml, MSG_ORIG(MSG_ELF_MACHINE), conv_ehdr_mach(mach, 0, &inv_buf1), conv_ehdr_vers(ehdr->e_version, 0, &inv_buf2)); dbg_print(lml, MSG_ORIG(MSG_ELF_TYPE), conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf1)); /* * Line up the flags differently depending on whether we received a * numeric (e.g. "0x200") or text representation (e.g. * "[ EF_SPARC_SUN_US1 ]"). */ flgs = conv_ehdr_flags(mach, ehdr->e_flags, 0, &flags_buf); if (flgs[0] == '[') dbg_print(lml, MSG_ORIG(MSG_ELF_FLAGS_FMT), flgs); else dbg_print(lml, MSG_ORIG(MSG_ELF_FLAGS), flgs); /* * The e_shnum, e_shstrndx and e_phnum entries may have a different * meaning if extended sections exist. */ if (ehdr->e_shstrndx == SHN_XINDEX) { dbg_print(lml, MSG_ORIG(MSG_ELFX_ESIZE), EC_ADDR(ehdr->e_entry), ehdr->e_ehsize); xshdr++; } else dbg_print(lml, MSG_ORIG(MSG_ELF_ESIZE), EC_ADDR(ehdr->e_entry), ehdr->e_ehsize, ehdr->e_shstrndx); if (ehdr->e_shnum == 0) { dbg_print(lml, MSG_ORIG(MSG_ELFX_SHOFF), EC_OFF(ehdr->e_shoff), ehdr->e_shentsize); xshdr++; } else dbg_print(lml, MSG_ORIG(MSG_ELF_SHOFF), EC_OFF(ehdr->e_shoff), ehdr->e_shentsize, ehdr->e_shnum); if (ehdr->e_phnum == PN_XNUM) { dbg_print(lml, MSG_ORIG(MSG_ELFX_PHOFF), EC_OFF(ehdr->e_phoff), ehdr->e_phentsize); xshdr++; } else dbg_print(lml, MSG_ORIG(MSG_ELF_PHOFF), EC_OFF(ehdr->e_phoff), ehdr->e_phentsize, ehdr->e_phnum); if ((xshdr == 0) || (shdr0 == NULL)) return; /* * If we have Extended ELF headers - print shdr[0]. */ dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); dbg_print(lml, MSG_ORIG(MSG_SHD0_TITLE)); dbg_print(lml, MSG_ORIG(MSG_SHD0_ADDR), EC_ADDR(shdr0->sh_addr), conv_sec_flags(osabi, mach, shdr0->sh_flags, 0, &sec_flags_buf)); dbg_print(lml, MSG_ORIG(MSG_SHD0_SIZE), EC_XWORD(shdr0->sh_size), conv_sec_type(osabi, mach, shdr0->sh_type, 0, &inv_buf1)); dbg_print(lml, MSG_ORIG(MSG_SHD0_OFFSET), EC_OFF(shdr0->sh_offset), EC_XWORD(shdr0->sh_entsize)); dbg_print(lml, MSG_ORIG(MSG_SHD0_LINK), EC_WORD(shdr0->sh_link), EC_WORD(shdr0->sh_info)); dbg_print(lml, MSG_ORIG(MSG_SHD0_ALIGN), EC_XWORD(shdr0->sh_addralign)); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include "msg.h" #include "_debug.h" #include "libld.h" /* * Print out a single `entry descriptor' entry. */ void Dbg_ent_entry(Lm_list *lml, uchar_t osabi, Half mach, Ent_desc *enp) { union { Conv_inv_buf_t inv; Conv_sec_flags_buf_t sec_flags; Conv_ent_flags_buf_t ent_flags; Conv_ent_files_flags_buf_t ent_files_flags; } buf; Aliste idx; Ent_desc_file *edfp; if (enp->ec_name != NULL) dbg_print(lml, MSG_ORIG(MSG_ECR_NAME), enp->ec_name); dbg_print(lml, MSG_ORIG(MSG_ECR_FLAGS), conv_ent_flags(enp->ec_flags, &buf.ent_flags)); dbg_print(lml, MSG_ORIG(MSG_ECR_IS_NAME), (enp->ec_is_name ? enp->ec_is_name : MSG_INTL(MSG_STR_NULL)), conv_sec_flags(osabi, mach, enp->ec_attrmask, 0, &buf.sec_flags)); dbg_print(lml, MSG_ORIG(MSG_ECR_SEGMENT), (enp->ec_segment->sg_name ? enp->ec_segment->sg_name : MSG_INTL(MSG_STR_NULL)), conv_sec_flags(osabi, mach, enp->ec_attrbits, 0, &buf.sec_flags)); dbg_print(lml, MSG_ORIG(MSG_ECR_NDX), EC_WORD(enp->ec_ordndx), conv_sec_type(osabi, mach, enp->ec_type, 0, &buf.inv)); if (enp->ec_files) { dbg_print(lml, MSG_ORIG(MSG_ECR_FILES)); for (ALIST_TRAVERSE(enp->ec_files, idx, edfp)) dbg_print(lml, MSG_ORIG(MSG_ECR_FILE), conv_ent_files_flags(edfp->edf_flags, 0, &buf.ent_files_flags), edfp->edf_name); } } /* * Print out all `entrance descriptor' entries. */ void Dbg_ent_print(Lm_list *lml, uchar_t osabi, Half mach, APlist *alp) { Ent_desc *enp; Aliste ndx; if (DBG_NOTCLASS(DBG_C_ENTRY)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_ECR_TITLE)); for (APLIST_TRAVERSE(alp, ndx, enp)) { dbg_print(lml, MSG_INTL(MSG_ECR_DESC), EC_WORD(ndx)); Dbg_ent_entry(lml, osabi, mach, enp); } } /* * 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 (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2022 Oxide Computer Company */ #include #include #include #include #include #include #include #include #include #include "msg.h" #include "_debug.h" void Dbg_file_analyze(Rt_map *lmp) { Conv_dl_mode_buf_t dl_mode_buf; Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_ANALYZE), NAME(lmp), conv_dl_mode(MODE(lmp), 1, &dl_mode_buf)); } void Dbg_file_mmapobj(Lm_list *lml, const char *name, mmapobj_result_t *ompp, uint_t onum) { mmapobj_result_t *mpp; uint_t mnum; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ), name, onum); for (mnum = 0, mpp = ompp; mnum < onum; mnum++, mpp++) { const char *str; uint_t type = MR_GET_TYPE(mpp->mr_flags); if (type == MR_PADDING) str = MSG_ORIG(MSG_MR_PADDING); else if (type == MR_HDR_ELF) str = MSG_ORIG(MSG_MR_HDR_ELF); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_1), mnum, EC_NATPTR(mpp->mr_addr), EC_OFF(mpp->mr_fsize), str); dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_2), EC_OFF(mpp->mr_offset), EC_OFF(mpp->mr_msize)); } Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_elf(Lm_list *lml, const char *name, Addr addr, size_t size, const char *lmid, Aliste lmco) { const char *str; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (addr == 0) str = MSG_INTL(MSG_STR_TEMPORARY); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_FIL_ELF), name, str); dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size)); dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco)); } void Dbg_file_ldso(Rt_map *lmp, char **envp, auxv_t *auxv, const char *lmid, Aliste lmco) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_LDSO), PATHNAME(lmp)); dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(ADDR(lmp)), EC_OFF(MSIZE(lmp))); dbg_print(lml, MSG_INTL(MSG_FIL_DATA_EA), EC_NATPTR(envp), EC_NATPTR(auxv)); dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_prot(Rt_map *lmp, int prot) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_PROT), NAME(lmp), (prot ? '+' : '-')); } void Dbg_file_delete(Rt_map *lmp) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_DELETE), NAME(lmp)); } static int hdl_title = 0; static Msg hdl_str = 0; void Dbg_file_hdl_title(int type) { static const Msg titles[] = { MSG_FIL_HDL_CREATE, /* MSG_INTL(MSG_FIL_HDL_CREATE) */ MSG_FIL_HDL_ADD, /* MSG_INTL(MSG_FIL_HDL_ADD) */ MSG_FIL_HDL_DELETE, /* MSG_INTL(MSG_FIL_HDL_DELETE) */ MSG_FIL_HDL_ORPHAN, /* MSG_INTL(MSG_FIL_HDL_ORPHAN) */ MSG_FIL_HDL_REINST, /* MSG_INTL(MSG_FIL_HDL_REINST) */ }; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; /* * Establish a binding title for later use in Dbg_file_hdl_action. */ if (type <= DBG_HDL_REINST) { hdl_str = titles[type]; hdl_title = 1; } else { hdl_str = 0; hdl_title = 0; } } void Dbg_file_hdl_collect(Grp_hdl *ghp, const char *name) { Conv_grphdl_flags_buf_t grphdl_flags_buf; Lm_list *lml = ghp->gh_ownlml; const char *str; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; if (ghp->gh_ownlmp) str = NAME(ghp->gh_ownlmp); else str = MSG_INTL(MSG_STR_ORPHAN); if (hdl_title) { hdl_title = 0; Dbg_util_nl(lml, DBG_NL_STD); } if (name) dbg_print(lml, MSG_INTL(MSG_FIL_HDL_RETAIN), str, name); else dbg_print(lml, MSG_INTL(MSG_FIL_HDL_COLLECT), str, conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf)); } void Dbg_file_hdl_action(Grp_hdl *ghp, Rt_map *lmp, int type, uint_t flags) { Conv_grpdesc_flags_buf_t grpdesc_flags_buf; const char *mode, *group; Lm_list *lml = LIST(lmp); Msg str; static const Msg fmt[] = { MSG_FIL_DEP_ADD, /* MSG_INTL(MSG_FIL_DEP_ADD) */ MSG_FIL_DEP_UPDATE, /* MSG_INTL(MSG_FIL_DEP_UPDATE) */ MSG_FIL_DEP_DELETE, /* MSG_INTL(MSG_FIL_DEP_DELETE) */ MSG_FIL_DEP_REMOVE, /* MSG_INTL(MSG_FIL_DEP_REMOVE) */ MSG_FIL_DEP_REMAIN, /* MSG_INTL(MSG_FIL_DEP_REMAIN) */ MSG_FIL_DEP_ORPHAN, /* MSG_INTL(MSG_FIL_DEP_ORPHAN) */ MSG_FIL_DEP_REINST, /* MSG_INTL(MSG_FIL_DEP_REINST) */ }; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; if (hdl_title) { Dbg_util_nl(lml, DBG_NL_STD); if (hdl_str) { Conv_grphdl_flags_buf_t grphdl_flags_buf; const char *name; /* * Protect ourselves in case this handle has no * originating owner. */ if (ghp->gh_ownlmp) name = NAME(ghp->gh_ownlmp); else name = MSG_INTL(MSG_STR_UNKNOWN); dbg_print(lml, MSG_INTL(hdl_str), name, conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf), EC_NATPTR(ghp)); } hdl_title = 0; } /* * Establish a binding descriptor format string. */ if (type > DBG_DEP_REINST) return; str = fmt[type]; if (((type == DBG_DEP_ADD) || (type == DBG_DEP_UPDATE)) && flags) group = conv_grpdesc_flags(flags, &grpdesc_flags_buf); else group = MSG_ORIG(MSG_STR_EMPTY); if ((MODE(lmp) & (RTLD_GLOBAL | RTLD_NODELETE)) == (RTLD_GLOBAL | RTLD_NODELETE)) mode = MSG_ORIG(MSG_MODE_GLOBNODEL); else if (MODE(lmp) & RTLD_GLOBAL) mode = MSG_ORIG(MSG_MODE_GLOB); else if (MODE(lmp) & RTLD_NODELETE) mode = MSG_ORIG(MSG_MODE_NODEL); else mode = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(str), NAME(lmp), mode, group); } void Dbg_file_bind_entry(Lm_list *lml, Bnd_desc *bdp) { Conv_bnd_type_buf_t bnd_type_buf; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; /* * Print the dependency together with the modes of the binding. */ Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_BND_ADD), NAME(bdp->b_caller)); dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE), NAME(bdp->b_depend), conv_bnd_type(bdp->b_flags, &bnd_type_buf)); } void Dbg_file_bindings(Rt_map *lmp, int flag) { Conv_bnd_obj_buf_t bnd_obj_buf; Conv_bnd_type_buf_t bnd_type_buf; const char *str; Rt_map *tlmp; Lm_list *lml = LIST(lmp); int next = 0; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; if (flag & RT_SORT_REV) str = MSG_ORIG(MSG_SCN_INIT); else str = MSG_ORIG(MSG_SCN_FINI); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_DEP_TITLE), str, conv_bnd_obj(lml->lm_flags, &bnd_obj_buf)); /* LINTED */ for (tlmp = lmp; tlmp; tlmp = (Rt_map *)NEXT(tlmp)) { Bnd_desc *bdp; Aliste idx; /* * For .init processing, only collect objects that have been * relocated and haven't already been collected. * For .fini processing, only collect objects that have had * their .init collected, and haven't already been .fini * collected. */ if (flag & RT_SORT_REV) { if ((FLAGS(tlmp) & (FLG_RT_RELOCED | FLG_RT_INITCLCT)) != FLG_RT_RELOCED) continue; } else { if ((flag & RT_SORT_DELETE) && ((FLAGS(tlmp) & FLG_RT_DELETE) == 0)) continue; if (((FLAGS(tlmp) & (FLG_RT_INITCLCT | FLG_RT_FINICLCT)) == FLG_RT_INITCLCT) == 0) continue; } if (next++) Dbg_util_nl(lml, DBG_NL_STD); if (DEPENDS(tlmp) == NULL) dbg_print(lml, MSG_INTL(MSG_FIL_DEP_NONE), NAME(tlmp)); else { dbg_print(lml, MSG_INTL(MSG_FIL_DEP_ENT), NAME(tlmp)); for (APLIST_TRAVERSE(DEPENDS(tlmp), idx, bdp)) { dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE), NAME(bdp->b_depend), conv_bnd_type(bdp->b_flags, &bnd_type_buf)); } } } Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_bindings_done(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); } void Dbg_file_lazyload(Rt_map *clmp, const char *fname, const char *sname) { Lm_list *lml = LIST(clmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_LAZYLOAD), fname, NAME(clmp), Dbg_demangle_name(sname)); } void Dbg_file_preload(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_PRELOAD), name); } void Dbg_file_needed(Rt_map *lmp, const char *name) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_NEEDED), name, NAME(lmp)); } void Dbg_file_filter(Lm_list *lml, const char *filter, const char *filtee, int config) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); if (config) dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_1), filter, filtee); else dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_2), filter, filtee); } void Dbg_file_filtee(Lm_list *lml, const char *filter, const char *filtee, int audit) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); if (audit) dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_3), filtee); else if (filter) dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_1), filtee, filter); else dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_2), filtee); } void Dbg_file_fixname(Lm_list *lml, const char *oname, const char *nname) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_FIXNAME), oname, nname); } void Dbg_file_output(Ofl_desc *ofl) { const char *prefix = MSG_ORIG(MSG_PTH_OBJECT); char *oname, *nname, *ofile; int fd; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; /* * Obtain the present input object filename for concatenation to the * prefix name. */ oname = (char *)ofl->ofl_name; if ((ofile = strrchr(oname, '/')) == NULL) ofile = oname; else ofile++; /* * Concatenate the prefix with the object filename, open the file and * write out the present Elf memory image. As this is debugging we * ignore all errors. */ if ((nname = malloc(strlen(prefix) + strlen(ofile) + 1)) != 0) { (void) strcpy(nname, prefix); (void) strcat(nname, ofile); if ((fd = open(nname, O_RDWR | O_CREAT | O_TRUNC, 0666)) != -1) { (void) write(fd, ofl->ofl_nehdr, ofl->ofl_size); (void) close(fd); } free(nname); } } void Dbg_file_config_dis(Lm_list *lml, const char *config, int features) { Conv_config_feat_buf_t config_feat_buf; const char *str; if (features == 0) return; switch (features & ~CONF_FEATMSK) { case DBG_CONF_IGNORE: str = MSG_INTL(MSG_FIL_CONFIG_ERR_1); break; case DBG_CONF_VERSION: str = MSG_INTL(MSG_FIL_CONFIG_ERR_2); break; case DBG_CONF_PRCFAIL: str = MSG_INTL(MSG_FIL_CONFIG_ERR_3); break; case DBG_CONF_CORRUPT: str = MSG_INTL(MSG_FIL_CONFIG_ERR_4); break; case DBG_CONF_ABIMISMATCH: str = MSG_INTL(MSG_FIL_CONFIG_ERR_5); break; default: str = conv_config_feat(features, &config_feat_buf); break; } Dbg_util_nl(lml, DBG_NL_FRC); dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG_ERR), config, str); Dbg_util_nl(lml, DBG_NL_FRC); } void Dbg_file_config_obj(Lm_list *lml, const char *dir, const char *file, const char *config) { char *name, _name[PATH_MAX]; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (file) { (void) snprintf(_name, PATH_MAX, MSG_ORIG(MSG_FMT_PATH), dir, file); name = _name; } else name = (char *)dir; dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG), name, config); } void Dbg_file_del_rescan(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_DEL_RESCAN)); } void Dbg_file_mode_promote(Rt_map *lmp, int mode) { Conv_dl_mode_buf_t dl_mode_buf; Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_PROMOTE), NAME(lmp), conv_dl_mode(mode, 0, &dl_mode_buf)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_deferred(Lm_list *lml, const char *oname, const char *nname) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_DEFERRED), oname, nname); } void Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco) { Lm_cntl *lmc; Aliste off; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_CNTL_TITLE), EC_XWORD(flmco), EC_XWORD(tlmco)); for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) { Rt_map *lmp; /* LINTED */ for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) dbg_print(lml, MSG_ORIG(MSG_CNTL_ENTRY), EC_XWORD(off), NAME(lmp)); } Dbg_util_nl(lml, DBG_NL_STD); } /* * Report archive rescan operation. * argv_start_ndx, argv_end_ndx - Index range of command line arguments * from which archives are to be reprocessed. */ void Dbg_file_ar_rescan(Lm_list *lml, int argv_start_ndx, int argv_end_ndx) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_AR_RESCAN), argv_start_ndx, argv_end_ndx); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_ar(Lm_list *lml, const char *name, Boolean again) { const char *str; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (again) str = MSG_INTL(MSG_STR_AGAIN); else str = MSG_ORIG(MSG_STR_EMPTY); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_ARCHIVE), name, str); } void Dbg_file_generic(Lm_list *lml, Ifl_desc *ifl) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_BASIC), ifl->ifl_name, conv_ehdr_type(ifl->ifl_ehdr->e_ident[EI_OSABI], ifl->ifl_ehdr->e_type, 0, &inv_buf)); } #if SGS_REJ_NUM != (SGS_REJ_HWCAP_3 + 1) #error SGS_REJ_NUM has changed #endif static const Msg reject[SGS_REJ_NUM] = { MSG_STR_EMPTY, MSG_REJ_MACH, /* MSG_INTL(MSG_REJ_MACH) */ MSG_REJ_CLASS, /* MSG_INTL(MSG_REJ_CLASS) */ MSG_REJ_DATA, /* MSG_INTL(MSG_REJ_DATA) */ MSG_REJ_TYPE, /* MSG_INTL(MSG_REJ_TYPE) */ MSG_REJ_BADFLAG, /* MSG_INTL(MSG_REJ_BADFLAG) */ MSG_REJ_MISFLAG, /* MSG_INTL(MSG_REJ_MISFLAG) */ MSG_REJ_VERSION, /* MSG_INTL(MSG_REJ_VERSION) */ MSG_REJ_HAL, /* MSG_INTL(MSG_REJ_HAL) */ MSG_REJ_US3, /* MSG_INTL(MSG_REJ_US3) */ MSG_REJ_STR, /* MSG_INTL(MSG_REJ_STR) */ MSG_REJ_UNKFILE, /* MSG_INTL(MSG_REJ_UNKFILE) */ MSG_REJ_UNKCAP, /* MSG_INTL(MSG_REJ_UNKCAP) */ MSG_REJ_HWCAP_1, /* MSG_INTL(MSG_REJ_HWCAP_1) */ MSG_REJ_SFCAP_1, /* MSG_INTL(MSG_REJ_SFCAP_1) */ MSG_REJ_MACHCAP, /* MSG_INTL(MSG_REJ_MACHCAP) */ MSG_REJ_PLATCAP, /* MSG_INTL(MSG_REJ_PLATCAP) */ MSG_REJ_HWCAP_2, /* MSG_INTL(MSG_REJ_HWCAP_2) */ MSG_REJ_ARCHIVE, /* MSG_INTL(MSG_REJ_ARCHIVE) */ MSG_REJ_KMOD, /* MSG_INTL(MSG_REJ_KMOD) */ MSG_REJ_HWCAP_3 /* MSG_INTL(MSG_REJ_HWCAP_3) */ }; void Dbg_file_rejected(Lm_list *lml, Rej_desc *rej, Half mach) { Conv_reject_desc_buf_t rej_buf; if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(reject[rej->rej_type]), rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN), conv_reject_desc(rej, &rej_buf, mach)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_reuse(Lm_list *lml, const char *nname, const char *oname) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_REUSE), nname, oname); } void Dbg_file_skip(Lm_list *lml, const char *oname, const char *nname) { if (DBG_NOTCLASS(DBG_C_FILES)) return; if (oname && strcmp(nname, oname)) dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_1), nname, oname); else dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_2), nname); } void Dbg_file_modified(Lm_list *lml, const char *obj, const char *oname, const char *nname, int ofd, int nfd, Elf *oelf, Elf *nelf) { const char *str; if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_SUPPORT)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_MODIFIED), oname, obj); if (nname != oname) dbg_print(lml, MSG_INTL(MSG_FIL_NAMECHANGE), nname); if (nfd != ofd) { if (nfd == -1) str = MSG_INTL(MSG_FIL_IGNORE); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_FIL_FDCHANGE), ofd, nfd, str); } if (nelf != oelf) { if (nelf == 0) str = MSG_INTL(MSG_FIL_IGNORE); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_FIL_ELFCHANGE), EC_NATPTR(oelf), EC_NATPTR(nelf), str); } Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_file_cleanup(Lm_list *lml, const char *name, Aliste lmco) { if (DBG_NOTCLASS(DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_FIL_CLEANUP), name, EC_XWORD(lmco)); } /* * 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. */ #include #include "_debug.h" #include "msg.h" #include "libld.h" static int Dbg_got_compare(Gottable *gtp1, Gottable *gtp2) { Gotndx *gnp1 = >p1->gt_gndx; Gotndx *gnp2 = >p2->gt_gndx; if (gnp1->gn_gotndx > gnp2->gn_gotndx) return (1); if (gnp1->gn_gotndx < gnp2->gn_gotndx) return (-1); return (0); } void Dbg_got_display(Ofl_desc *ofl, Off goff, int stage, Word m_got_xnumber, size_t m_got_entsize) { Lm_list *lml = ofl->ofl_lml; Gottable *gtp = ofl->ofl_gottable; Word gotndx; Xword *gptr; if (DBG_NOTCLASS(DBG_C_GOT)) return; if (ofl->ofl_gotcnt == m_got_xnumber) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_GOT_INFO), EC_WORD(ofl->ofl_gotcnt)); if (DBG_NOTDETAIL()) return; qsort((char *)gtp, ofl->ofl_gotcnt, sizeof (Gottable), (int(*)(const void *, const void *))Dbg_got_compare); if (stage == 0) dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS1)); else dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS2)); gptr = (Xword *)ofl->ofl_osgot->os_outdata->d_buf; for (gotndx = 0; gotndx < ofl->ofl_gotcnt; gotndx++, gtp++, gptr++) { Sym_desc *sdp = gtp->gt_sym; const char *refstr, *name; Gotndx *gnp = >p->gt_gndx; Lword gotaddval; Off off = goff + (gotndx * m_got_entsize); char index[INDEX_STR_SIZE]; (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX), EC_SWORD(gnp->gn_gotndx)); if (sdp == 0) refstr = MSG_ORIG(MSG_STR_EMPTY); else if (sdp->sd_flags & FLG_SY_SMGOT) refstr = MSG_ORIG(MSG_GOT_SMALL_PIC); else refstr = MSG_ORIG(MSG_GOT_BIG_PIC); if (sdp == 0) name = MSG_ORIG(MSG_STR_EMPTY); else if (sdp->sd_name) name = Dbg_demangle_name(sdp->sd_name); else name = MSG_INTL(MSG_STR_UNKNOWN); if (stage == 0) gotaddval = gnp->gn_addend; else gotaddval = *gptr; if ((sdp == 0) || (sdp->sd_sym->st_shndx == SHN_UNDEF) || (sdp->sd_file == 0)) { dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT1), index, refstr, EC_OFF(off), EC_XWORD(gotaddval), name); } else { dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT2), index, refstr, EC_OFF(off), EC_XWORD(gotaddval), sdp->sd_file->ifl_name, name); } } } void Elf_got_title(Lm_list *lml) { dbg_print(lml, MSG_INTL(MSG_GOT_TITLE)); } void Elf_got_entry(Lm_list *lml, Sword ndx, Addr addr, Xword value, Half mach, uchar_t ei_target_data, uchar_t ei_host_data, Word type, void *reloc, const char *name) { Rela *rela; Rel *rel; const char *str; Conv_inv_buf_t inv_buf; char index[INDEX_STR_SIZE]; (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX), EC_SWORD(ndx)); /* * Got sections are SHT_PROGBITS, and are therefore not xlated by * libelf. If the target system has a different byte order than * the system displaying the data, swap the bytes so they are * presented properly. */ if (ei_target_data != ei_host_data) value = BSWAP_XWORD(value); if (reloc) { if (type == SHT_RELA) { rela = (Rela *)reloc; str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info, mach), 0, &inv_buf); } else { rel = (Rel *)reloc; str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info, mach), 0, &inv_buf); } if (name) name = Elf_demangle_name(name); else name = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_RE), index, EC_ADDR(addr), EC_XWORD(value), str, name); } else dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_NR), index, EC_ADDR(addr), EC_XWORD(value)); } # # 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 (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2022 Oxide Computer Company # @ _START_ # Message file for cmd/sgs/liblddbg. @ MSG_ID_LIBLDDBG # Usage messages @ MSG_USE_UNRECOG "warning: unrecognized debug option (try help): %s" @ MSG_USE_CNTNEGOPT "warning: ignoring non-negatable debug option: %s" @ MSG_USE_HDR_DCT "Display Control Tokens:" @ MSG_USE_HDR_CST "Category Selection Tokens:" @ MSG_USE_HDR_BOTH " [ld and ld.so.1]" @ MSG_USE_HDR_RTLD " [ld.so.1 only]" @ MSG_USE_HDR_LD " [ld only]" # TRANSLATION_NOTE - Use the following output in the C locale as reference 1. # # The runtime linker and link-editor support a shared debugging # facility. Options are selected via a comma separated list of tokens, # each of which specifies a display option or a category for which # information is desired. Many tokens apply to both linker components, # while some are specific to one or the other. Diagnostics are printed, # one per line, with a standard prefix prepended to each one. Diagnostic # output is sent to stderr unless otherwise redirected. # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. @ MSG_USE_R1_A "The runtime linker and link-editor support a \ shared debugging" @ MSG_USE_R1_B "facility. Options are selected via a comma separated list \ of tokens," @ MSG_USE_R1_C "each of which specifies a display option or a category \ for which" @ MSG_USE_R1_D "information is desired. Many tokens apply to both linker \ components," @ MSG_USE_R1_E "while some are specific to one or the other. Diagnostics \ are printed," @ MSG_USE_R1_F "one per line, with a standard prefix prepended to each one. \ Diagnostic" # TRANSLATION_NOTE -- do not translate "stderr" @ MSG_USE_R1_G "output is sent to stderr unless otherwise redirected." # TRANSLATION_NOTE - End of reference 1 # TRANSLATION_NOTE - Use the following output in the C locale as reference 2. # # Runtime Linking (ld.so.1): # Diagnostics that trace the runtime linking of an application # can be enabled via the LD_DEBUG environment variable: # LD_DEBUG=token1,token2 app ... # In addition to the "output" token described below, diagnostic # output from the runtime linker can be redirected to an output # file using the additional environment variable: # LD_DEBUG_OUTPUT=file # If the "output" token and LD_DEBUG_OUTPUT are both specified, # the file specified by LD_DEBUG_OUTPUT is used. If LD_DEBUG_OUTPUT # is used, the output file name is suffixed with the process id. # An output file specified via the "output" token is used as # specified, without a process id suffix. Use of the "output" # token with programs that call fork() results in each process # writing debug output to the same file. The debug output will be # jumbled and incomplete. LD_DEBUG_OUTPUT should be used in such # cases to direct debug output for each process to a unique file. # # All runtime linker diagnostics are prepended with the process # id. If thread capabilities are enabled for the process, the # thread id is also shown. All Solaris applications are thread # capable, and a single threaded application may use threads via # the libraries it links to. Diagnostics from such applications # reference thread id 1. # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. @ MSG_USE_R2_A "Runtime Linking (ld.so.1):" @ MSG_USE_R2_B " Diagnostics that trace the runtime linking \ of an application" # TRANSLATION_NOTE -- do not translate "LD_DEBUG" @ MSG_USE_R2_C " can be enabled via the LD_DEBUG environment variable:" # TRANSLATION_NOTE -- do not translate "LD_DEBUG" @ MSG_USE_R2_D " LD_DEBUG=token1,token2 app ..." # TRANSLATION_NOTE -- do not translate "output" @ MSG_USE_R2_E " In addition to the \"output\" token described \ below, diagnostic" @ MSG_USE_R2_F " output from the runtime linker can be redirected to \ an output" @ MSG_USE_R2_G " file using the additional environment variable:" # TRANSLATION_NOTE -- do not translate "LD_DEBUG_OUTPUT" @ MSG_USE_R2_H " LD_DEBUG_OUTPUT=file" # TRANSLATION_NOTE -- do not translate "output" or "LD_DEBUG_OUTPUT" @ MSG_USE_R2_I " If the \"output\" token and LD_DEBUG_OUTPUT are \ both specified," # TRANSLATION_NOTE -- do not translate "LD_DEBUG_OUTPUT" @ MSG_USE_R2_J " the file specified by LD_DEBUG_OUTPUT is used. \ If LD_DEBUG_OUTPUT" @ MSG_USE_R2_K " is used, the output file name is suffixed with \ the process id." # TRANSLATION_NOTE -- do not translate "output" @ MSG_USE_R2_L " An output file specified via the \"output\" token \ is used as" # TRANSLATION_NOTE -- do not translate "output" @ MSG_USE_R2_M " specified, without a process id suffix. Use \ of the \"output\"" # TRANSLATION_NOTE -- do not translate "fork" @ MSG_USE_R2_N " token with programs that call fork() results in \ each process" @ MSG_USE_R2_O " writing debug output to the same file. The debug \ output will be" @ MSG_USE_R2_P " jumbled and incomplete. LD_DEBUG_OUTPUT should be \ used in such" @ MSG_USE_R2_Q " cases to direct debug output for each process to \ a unique file." @ MSG_USE_R2_R " All runtime linker diagnostics are prepended with \ the process" @ MSG_USE_R2_S " id. If thread capabilities are enabled for the \ process, the" @ MSG_USE_R2_T " thread id is also shown. All Solaris applications are \ thread" @ MSG_USE_R2_U " capable, and a single threaded application may \ use threads via" @ MSG_USE_R2_V " the libraries it links to. Diagnostics from such \ applications" @ MSG_USE_R2_W " reference thread id 1." # TRANSLATION_NOTE - End of reference 2 # TRANSLATION_NOTE - Use the following output in the C locale as reference 3. # # Link-Editing (ld): # Diagnostics that trace the link-editing of an application are # enabled using the -D option: # ld -Dtoken1,token2 -o prog ... # As compiler drivers may assign -D a different meaning, the # LD_OPTIONS environment variable is often used: # LD_OPTIONS=-Dtoken1,token2 cc -o prog ... # # The position of -D on the link-edit command line is significant. # Diagnostics are enabled when a debug token is first encountered, # and can be switched off by prepending the token with "!". # # Diagnostic output can be directed to a file using the "output" # token, The output file is used as specified, without a process # id suffix. # # All link-editor diagnostics are prepended with the string "debug". # # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. @ MSG_USE_R3_A " Link-Editing (ld):" @ MSG_USE_R3_B " Diagnostics that trace the link-editing of an \ application are" @ MSG_USE_R3_C " enabled using the -D option:" @ MSG_USE_R3_D " ld -Dtoken1,token2 -o prog ..." @ MSG_USE_R3_E " As compiler drivers may assign -D a different meaning, the" # TRANSLATION_NOTE -- do not translate "LD_OPTIONS" @ MSG_USE_R3_F " LD_OPTIONS environment variable is often used:" # TRANSLATION_NOTE -- do not translate "LD_OPTIONS" @ MSG_USE_R3_G " LD_OPTIONS=-Dtoken1,token2 cc -o prog ..." @ MSG_USE_R3_H " The position of -D on the link-edit command line \ is significant." @ MSG_USE_R3_I " Diagnostics are enabled when a debug token is \ first encountered," @ MSG_USE_R3_J " and can be switched off by prepending the token \ with \"!\"." # TRANSLATION_NOTE -- do not translate "output" @ MSG_USE_R3_K " Diagnostic output can be directed to a file using \ the \"output\"" @ MSG_USE_R3_L " token, The output file is used as specified, \ without a process" @ MSG_USE_R3_M " id suffix." # TRANSLATION_NOTE -- do not translate "debug" @ MSG_USE_R3_N " All link-editor diagnostics are prepended with the \ string \"debug\"." # TRANSLATION_NOTE - End of reference 3 # TRANSLATION_NOTE - Use the following output in the C locale as reference 4. # # demangle show C++ symbol names in their demangled form # detail provide more information in conjunction with # other options # dtime prepend a time delta to diagnostics. The value # appears as seconds.fraction, and represents # the elapsed time since that last diagnostic. # long display long object names without truncation # output=file debug output is sent to the named file # instead of stderr. If file is empty (\"\"), # following output will be sent to stderr. # ttime prepend a time stamp to diagnostics. The value # appears as seconds.fraction, and represents # the time since entering ld or ld.so.1. # Note, all diagnostics induce a probe affect, # which should be taken into account when # interpreting dtime and ttime information. # # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. # TRANSLATION_NOTE -- do not translate the first token "demangle". @ MSG_USE_R4_A " demangle show C++ symbol names in their \ demangled form" # TRANSLATION_NOTE -- do not translate the first token "detail". @ MSG_USE_R4_B " detail provide more information in \ conjunction with" @ MSG_USE_R4_B2 " other options" # TRANSLATION_NOTE -- do not translate the first token "dtime". @ MSG_USE_R4_C " dtime prepend a time delta to diagnostics. \ The value" @ MSG_USE_R4_C2 " appears as seconds.fraction, and \ represents" @ MSG_USE_R4_C3 " the elapsed time since that last \ diagnostic." # TRANSLATION_NOTE -- do not translate the first token "long". @ MSG_USE_R4_D " long display long object names without \ truncation" # TRANSLATION_NOTE -- do not translate the first token "output". @ MSG_USE_R4_E " output=file debug output is sent to the \ named file" @ MSG_USE_R4_E2 " instead of stderr. If file is \ empty (\"\")," @ MSG_USE_R4_E3 " following output will be \ sent to stderr." # TRANSLATION_NOTE -- do not translate the first token "ttime". @ MSG_USE_R4_F " ttime prepend a time stamp to diagnostics. \ The value" @ MSG_USE_R4_F2 " appears as seconds.fraction, and \ represents" @ MSG_USE_R4_F3 " the time since entering ld or \ ld.so.1." @ MSG_USE_R4_F4 " Note all diagnostics induce a \ probe affect," @ MSG_USE_R4_F5 " which should be taken into \ account when" @ MSG_USE_R4_F6 " interpreting dtime and ttime \ information." # TRANSLATION_NOTE - End of reference 4 # TRANSLATION_NOTE - Use the following output in the C locale as reference 5. # # lmid[=name] prepend link-map list id to diagnostics, and # optionally filter the lists: By default, # diagnostics are produced for all link-map # lists except that of the runtime linker # (ldso), without identification. "lmid" causes # the link-map list id to be prepended. # "name" limits diagnostics to the named # link-map list. Additional "lmid" tokens # can specify multiple link-map lists. # Valid names are: # all all link-map lists except ldso # alt all alternative link-map lists # alt[0-9]+ specific alternative link-map list # base the base, or main, link-map list # ldso the runtime linker link-map list # # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. # TRANSLATION_NOTE -- do not translate the first token "lmid". @ MSG_USE_R5_A " lmid[=name] prepend link-map list id to \ diagnostics, and" @ MSG_USE_R5_A2 " optionally filter the lists: By \ default," @ MSG_USE_R5_A3 " diagnostics are produced for all \ link-map" @ MSG_USE_R5_A4 " lists except that of the runtime \ linker" @ MSG_USE_R5_A5 " (ldso), without identification. \ \"lmid\" causes" # TRANSLATION_NOTE -- do not translate "name" @ MSG_USE_R5_A6 " the link-map list id to be prepended." @ MSG_USE_R5_A7 " \"name\" limits diagnostics to the \ named" @ MSG_USE_R5_A8 " link-map list. Additional \"lmid\" \ tokens" @ MSG_USE_R5_A9 " can specify multiple link-map \ lists." @ MSG_USE_R5_A0 " Valid names are:" # TRANSLATION_NOTE -- do not translate the token "all". @ MSG_USE_R5_B " all all link-map lists \ except ldso" # TRANSLATION_NOTE -- do not translate the token "alt". @ MSG_USE_R5_C " alt all alternative \ link-map lists" # TRANSLATION_NOTE -- do not translate the token "alt". @ MSG_USE_R5_D " alt[0-9]+ specific alt \ link-map list" # TRANSLATION_NOTE -- do not translate the token "base". @ MSG_USE_R5_E " base base (main) \ link-map list" @ MSG_USE_R5_F " ldso runtime linker \ link-map list " # TRANSLATION_NOTE - End of reference 5 # TRANSLATION_NOTE - Use the following output in the C locale as reference 6. # # name prepend output file basename to diagnostics # fullname prepend full output file name to diagnostics # class prepend output file elfclass (32/64) to # diagnostics # # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. # TRANSLATION_NOTE -- do not translate the first token "name". @ MSG_USE_R6_A " name prepend output file basename \ to diagnostics" # TRANSLATION_NOTE -- do not translate the first token "fullname". @ MSG_USE_R6_B " fullname prepend full output file name \ to diagnostics" # TRANSLATION_NOTE -- do not translate the first token "class". @ MSG_USE_R6_C " class prepend output file elfclass \ (32/64) to" @ MSG_USE_R6_C2 " diagnostics" # TRANSLATION_NOTE - End of reference 6 # TRANSLATION_NOTE - Use the following output in the C locale as reference 7. # # all display information for all categories # basic basic trace information/warnings # cap platform/machine/hardware/software capabilities # files input file processing (files and libraries) # help this help message # libs library search paths; detail flag shows # actual library lookup (-l) processing # move move sections # reloc relocations # symbols symbol tables; detail flag shows internal # symbol table addition and resolution (ld only) # tls thread local storage (TLS) # unused unused/unreferenced files; detail flag # shows unused sections (ld only) # versions ELF versioning # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. # TRANSLATION_NOTE -- do not translate the first token "all". @ MSG_USE_R7_A " all display information for \ all categories" # TRANSLATION_NOTE -- do not translate the first token "basic". @ MSG_USE_R7_B " basic basic trace information/warnings" # TRANSLATION_NOTE -- do not translate the first token "cap". @ MSG_USE_R7_C " cap platform/machine/hardware/software \ capabilities" # TRANSLATION_NOTE -- do not translate the first token "files". @ MSG_USE_R7_D " files input file processing (files \ and libraries)" # TRANSLATION_NOTE -- do not translate the first token "help". @ MSG_USE_R7_E " help this help message" # TRANSLATION_NOTE -- do not translate the first token "libs". @ MSG_USE_R7_F " libs library search paths; detail \ flag shows" @ MSG_USE_R7_F2 " actual library lookup (-l) \ processing" # TRANSLATION_NOTE -- do not translate the first token "move". @ MSG_USE_R7_G " move move sections" # TRANSLATION_NOTE -- do not translate the first token "reloc". @ MSG_USE_R7_H " reloc relocations" # TRANSLATION_NOTE -- do not translate the first token "symbols". @ MSG_USE_R7_I " symbols symbol tables; detail flag shows \ internal" @ MSG_USE_R7_I2 " symbol table addition/resolution \ (ld only)" # TRANSLATION_NOTE -- do not translate the first token "tls". @ MSG_USE_R7_J " tls thread local storage (TLS)" # TRANSLATION_NOTE -- do not translate the first token "unused". @ MSG_USE_R7_K " unused unused/unreferenced files; \ detail flag" @ MSG_USE_R7_K2 " shows unused sections (ld only)" # TRANSLATION_NOTE -- do not translate the first token "versions". @ MSG_USE_R7_L " versions ELF versioning" # TRANSLATION_NOTE - End of reference 7 # TRANSLATION_NOTE - Use the following output in the C locale as reference 8. # # audit runtime link-audit processing # bindings symbol binding; detail flag shows # absolute:relative addresses # callback user supplied code executed by ld.so.1 # (i.e. dl_iterate_phdr) # init init and fini processing # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. # TRANSLATION_NOTE -- do not translate the first token "audit". @ MSG_USE_R8_A " audit runtime link-audit processing" # TRANSLATION_NOTE -- do not translate the first token "bindings". @ MSG_USE_R8_B " bindings symbol binding; detail flag shows" @ MSG_USE_R8_B2 " absolute:relative addresses" # TRANSLATION_NOTE -- do not translate the first token "dl". @ MSG_USE_R8_C " dl user calls to the dl*() family" # TRANSLATION_NOTE -- do not translate the first token "init". @ MSG_USE_R8_D " init init and fini processing" # TRANSLATION_NOTE - End of reference 8 # TRANSLATION_NOTE - Use the following output in the C locale as reference 9. # # args input arguments # entry entrance criteria descriptors # got GOT symbol information # map mapfile processing # sections input sections # segments output segments and address/offset processing; # detail flag shows associated sections # statistics symbol table and relocation statistics # strtab string table compression statistics; # detail flag shows layout of string tables # support support libraries # TRANSLATION_NOTE - The next series of messages makes the above output in C # locale. # TRANSLATION_NOTE -- do not translate the first token "args". @ MSG_USE_R9_A " args input arguments" # TRANSLATION_NOTE -- do not translate the first token "entry". @ MSG_USE_R9_B " entry entrance criteria descriptors" # TRANSLATION_NOTE -- do not translate the first token "got". @ MSG_USE_R9_C " got GOT symbol information" # TRANSLATION_NOTE -- do not translate the first token "map". @ MSG_USE_R9_D " map mapfile processing" # TRANSLATION_NOTE -- do not translate the first token "sections". @ MSG_USE_R9_E " sections input sections" # TRANSLATION_NOTE -- do not translate the first token "segments". @ MSG_USE_R9_F " segments output segments and address/offset \ processing;" @ MSG_USE_R9_F2 " detail flag shows associated \ sections" # TRANSLATION_NOTE -- do not translate the first token "statistics". @ MSG_USE_R9_G " statistics symbol table and relocation \ statistics" # TRANSLATION_NOTE -- do not translate the first token "strtab". @ MSG_USE_R9_H " strtab string table compression statistics;" @ MSG_USE_R9_H2 " detail flag shows layout of \ string tables" # TRANSLATION_NOTE -- do not translate the first token "support". @ MSG_USE_R9_I " support support libraries" # TRANSLATION_NOTE - End of reference 9 # Basic processing (ld). @ MSG_BASIC_COLLECT "collect relocations" @ MSG_BASIC_CREATE "create output image" @ MSG_BASIC_FILES "process files" @ MSG_BASIC_FINISHED "processing finished" @ MSG_BASIC_OPTIONS "process options" @ MSG_BASIC_RELOCATE "relocate output image" @ MSG_BASIC_VALIDATE "validating symbols" # Argument messages @ MSG_ARG_OPTION "arg[%d]\toption=-%c" @ MSG_ARG_OPTARG "arg[%d]\toption=-%c: option-argument: %s" @ MSG_ARG_STR2CHR "arg[%d]\toption=-%s: translated: new option=-%c" @ MSG_ARG_WLDEL "arg[%d]\toption=-W%s: translated: prefix -Wl,: \ removed" @ MSG_ARG_FILE "arg[%d]\tfile=%s" # Bindings messages # NOTE: these are used by appcert(1) and lari(1), use care when changing. @ MSG_BND_BASIC "binding file=%s to file=%s: symbol '%s'" @ MSG_BND_PLT "binding file=%s (%#llx:%#llx) at plt[%lld]:%s to \ file=%s (%#llx:%#llx): symbol '%s'%s" @ MSG_BND_DLSYM "binding file=%s (dlsym) to file=%s \ (%#llx:%#llx): symbol '%s'%s" @ MSG_BND_DEFAULT "binding file=%s (%#llx:%#llx) to file=%s \ (%#llx:%#llx): symbol '%s'%s" @ MSG_BND_WEAK_1 "binding file=%s to 0x0 (undefined weak): symbol '%s'" @ MSG_BND_WEAK_2 "binding file=%s (%#llx:%#llx) to 0x0 \ (undefined weak): symbol '%s'" # NOTE: the rejected message is used by lari(1), use care when changing. This # message is formatted to conform to the pattern used by the MSG_BINFO messages. @ MSG_BND_REJECT "binding file=%s to file=%s: symbol '%s' \ (rejected: %s)" @ MSG_BNDREJ_DIRECT "attempt to directly bind to a NODIRECT definition" @ MSG_BNDREJ_GROUP "attempt to bind within a group to a NODIRECT \ definition" @ MSG_BNDREJ_SINGLE "attempt to bind to a SINGLETON definition without \ following default search model" @ MSG_BND_PLTPAD_TO " pltpad: %#llx: file=%s bound to file=%s: \ symbol '%s'" @ MSG_BND_PLTPAD_FROM " pltpad: %#llx: bound from file=%s: symbol '%s'" @ MSG_BND_PSUM_SPARCV9 "Summary of PLT types bound: 21d=%d, 24d=%d, u32=%d, \ u44=%d, full=%d, far=%d, Total=%d" @ MSG_BND_PSUM_SPARC "Summary of PLT types bound: 21d=%d, 24d=%d, \ full=%d, Total=%d" @ MSG_BND_PSUM_DEFAULT "Summary of PLT types bound: total=%d" # Relocation messages @ MSG_REL_GENERATE "generating input relocations: section=%s" @ MSG_REL_COLLECT "collecting input relocations: section=%s, file=%s" @ MSG_REL_ACTIVE "performing active relocations" @ MSG_REL_CREATING "creating output relocations" @ MSG_REL_START "relocation processing: file=%s%s" @ MSG_REL_FINISH "relocation processing: file=%s; finished%s" @ MSG_REL_NONE "relocation processing: file=%s%s; nothing to do" @ MSG_REL_PLT " (plt processing only)" @ MSG_REL_FAIL " (failed)" @ MSG_REL_BADROFFSET "" @ MSG_REL_TRANSITION "relocation: %s: section=%s; input from file=%s; \ offset=0x%llx; symbol=%s; transitioned to: %s" @ MSG_REL_DISCARDED "relocation against discarded section=%s from file=%s; \ relocation type=%s offset=0x%llx; relocation discarded" @ MSG_REL_COPY "copy data from file=%s to file=%s: symbol '%s'%s" @ MSG_REL_SLOPPYCOMDAT "the following relocation references a discarded \ section; relocation redirected to section %s in \ file %s" # Entrance criteria messages @ MSG_ECR_TITLE "Segment Entrance Criteria Descriptor List" @ MSG_ECR_DESC "entrance descriptor[%u]" # Elf Data (section) messages # TRANSLATION_NOTE - the following two entries provide for a series of one or # more standard 32-bit Elf_Data entries that align with the initial title. @ MSG_EDATA_TITLE_32 " addr type size offset al file" @ MSG_EDATA_ENTRY_32 " %3s %#10llx %-5s %#10llx %#8llx %2lld %s %s%s" # TRANSLATION_NOTE - the following two entries provide for a series of one or # more standard 64-bit Elf_Data entries that align with the initial title. @ MSG_EDATA_TITLE_64 " addr type \ size offset al file" @ MSG_EDATA_ENTRY_64 " %3s %#18llx %-5s %#18llx %#16llx %2lld %s %s%s" @ MSG_EDATA_IGNSCN " (section ignored)" # File messages @ MSG_FIL_BASIC "file=%s [ %s ]" @ MSG_FIL_ARCHIVE "file=%s [ archive ] %s" @ MSG_FIL_SKIP_1 "file=%s; skipped: already processed as %s" @ MSG_FIL_SKIP_2 "file=%s; skipped: already processed" @ MSG_FIL_REUSE "file=%s; reusing: originally processed as %s" @ MSG_FIL_PROT "file=%s; modifying memory protections (%c PROT_WRITE)" @ MSG_FIL_DELETE "file=%s; deleting" @ MSG_FIL_CLEANUP "file=%s; loading failed: cleaning up lmco 0x%llx" @ MSG_FIL_LAZYLOAD "file=%s; lazy loading from file=%s: symbol=%s" @ MSG_FIL_PRELOAD "file=%s; preloading" @ MSG_FIL_NEEDED "file=%s; needed by %s" @ MSG_FIL_FILTER_1 "file=%s; filter for %s (configuration definition)" @ MSG_FIL_FILTER_2 "file=%s; filter for %s" @ MSG_FIL_FILTEE_2 "file=%s; filtee processing failed" @ MSG_FIL_FILTEE_3 "file=%s; filtee skipped (auditor directed)" @ MSG_FIL_FIXNAME "file=%s; required name=%s" @ MSG_FIL_PROMOTE "file=%s; promoting mode to %s" @ MSG_FIL_DEFERRED "file=%s; deferred dependency exchanged for file=%s" @ MSG_FIL_ELF "file=%s [ ELF ]; generating link map%s" @ MSG_FIL_LDSO "file=%s [ ELF ]" # NOTE: these are used by lari(1), use care when changing. @ MSG_FIL_ANALYZE "file=%s; analyzing %s" @ MSG_FIL_FILTEE_1 "file=%s; filtered by %s" @ MSG_FIL_CONFIG "file=%s [ ELF ]; configuration alternate found: %s" @ MSG_FIL_DATA_AS " addr: %#18llx size: %#18llx" @ MSG_FIL_DATA_LL " lmid: %18.18s lmco: %#18llx" @ MSG_FIL_DATA_EA " envp: %#18llx auxv: %#18llx" @ MSG_FIL_MMAPOBJ "file=%s mmapobj entries=%d" @ MSG_FIL_MMAPOBJ_1 " [%d]: addr: %#18llx fsize: %#18llx %s" @ MSG_FIL_MMAPOBJ_2 " offset: %#17llx msize: %#18llx" @ MSG_FIL_BND_ADD "file=%s; add binding to:" @ MSG_FIL_BND_FILE " file=%s %s" @ MSG_FIL_DEP_TITLE "processing %s dependencies %s:" @ MSG_FIL_DEP_NONE " file=%s; has no dependencies" @ MSG_FIL_DEP_ENT " file=%s; depends on:" @ MSG_FIL_DEP_ADD " file=%s; object added %s %s" @ MSG_FIL_DEP_UPDATE " file=%s; object updated %s %s" @ MSG_FIL_DEP_DELETE " file=%s; object deleting %s" @ MSG_FIL_DEP_REMOVE " file=%s; object removed from handle %s" @ MSG_FIL_DEP_REMAIN " file=%s; object must remain on handle %s" @ MSG_FIL_DEP_ORPHAN " file=%s; object remains on orphan handle %s" @ MSG_FIL_DEP_REINST " file=%s; object reinstated %s" @ MSG_FIL_HDL_CREATE "handle=%s; creating %s 0x%llx:" @ MSG_FIL_HDL_ADD "handle=%s; adding dependent objects %s:" @ MSG_FIL_HDL_DELETE "handle=%s; inspecting for deletion:" @ MSG_FIL_HDL_ORPHAN "handle=%s; deletion cannot be completed: moving to \ orphan list:" @ MSG_FIL_HDL_REINST "handle=%s; reinstating from orphan list:" @ MSG_FIL_HDL_COLLECT "handle=%s; collected for possible removal %s" @ MSG_FIL_HDL_RETAIN "handle=%s; externally referenced from %s: handle \ retained" @ MSG_FIL_DEL_RESCAN "pending deletions; rescanning orphan list for \ available deletions" @ MSG_FIL_AR_RESCAN "rescanning archives from args[%d-%d]; additional \ members may satisfy prior extractions" @ MSG_FIL_CONFIG_ERR "configuration file=%s: %s" @ MSG_FIL_CONFIG_ERR_1 "ignored (configuration building)" @ MSG_FIL_CONFIG_ERR_2 "invalid version" @ MSG_FIL_CONFIG_ERR_3 "unable to process file" @ MSG_FIL_CONFIG_ERR_4 "corrupt or truncated file" @ MSG_FIL_CONFIG_ERR_5 "incompatible ELF class, byte order, or machine \ architecture" @ MSG_FIL_MODIFIED "file=%s; open modified by support library: %s" @ MSG_FIL_NAMECHANGE " name changed to: %s" @ MSG_FIL_FDCHANGE " file descriptor changed from: %d to: %d %s" @ MSG_FIL_ELFCHANGE " ELF descriptor changed from: 0x%llx to: 0x%llx %s" @ MSG_FIL_IGNORE " (file will be ignored)" @ MSG_CNTL_TITLE "control list processing complete: moving lmco 0x%llx \ to lmco 0x%llx" @ MSG_REJ_MACH "file=%s; rejected: wrong machine type: %s" @ MSG_REJ_CLASS "file=%s; rejected: wrong ELF class: %s" @ MSG_REJ_DATA "file=%s; rejected: wrong ELF data format: %s" @ MSG_REJ_TYPE "file=%s; rejected: bad ELF type: %s" @ MSG_REJ_BADFLAG "file=%s; rejected: bad ELF flags value: %s" @ MSG_REJ_MISFLAG "file=%s; rejected: mismatched ELF flags value: %s" @ MSG_REJ_VERSION "file=%s; rejected: mismatched ELF/lib version: %s" @ MSG_REJ_HAL "file=%s; rejected: HAL R1 extensions required" @ MSG_REJ_US3 "file=%s; rejected: Sun UltraSPARC III extensions \ required" @ MSG_REJ_STR "obj=%s; rejected: %s" @ MSG_REJ_UNKFILE "obj=%s; rejected: unknown file type" @ MSG_REJ_UNKCAP "obj=%s; rejected: unknown capability: %d" @ MSG_REJ_HWCAP_1 "obj=%s; rejected: hardware capability (CA_SUNW_HW_1) \ unsupported: %s" @ MSG_REJ_SFCAP_1 "obj=%s; rejected: software capability (CA_SUNW_SF_1) \ unsupported: %s" @ MSG_REJ_MACHCAP "obj=%s; rejected: machine capability (CA_SUNW_MACH) \ unsupported: %s" @ MSG_REJ_PLATCAP "obj=%s; rejected: platform capability (CA_SUNW_PLAT) \ unsupported: %s" @ MSG_REJ_HWCAP_2 "obj=%s; rejected: hardware capability (CA_SUNW_HW_2) \ unsupported: %s" @ MSG_REJ_ARCHIVE "obj=%s; rejected: archive unsed incorrectly" @ MSG_REJ_KMOD "obj=%s; rejected: kernel module" @ MSG_REJ_HWCAP_3 "obj=%s; rejected: hardware capability (CA_SUNW_HW_3) \ unsupported: %s" # Libs messages @ MSG_LIB_INITPATH "Library Search Paths (initial)" @ MSG_LIB_UPPATH "Library Search Paths (-L updated)" @ MSG_LIB_LOPT "find lib=-l%s; path=%s" @ MSG_LIB_REQUIRED "find lib=%s; path=%s (required by %s)" @ MSG_LIB_LDLIBPATH " search path=%s (LD_LIBRARY_PATH)" @ MSG_LIB_LDLIBPATHC " search path=%s (configuration LD_LIBRARY_PATH - %s)" @ MSG_LIB_RUNPATH " search path=%s (RUNPATH/RPATH from file %s)" @ MSG_LIB_DEFAULT " search path=%s (default)" @ MSG_LIB_DEFAULTC " search path=%s (configuration default - %s)" @ MSG_LIB_TDEFAULT " search path=%s (trusted default)" @ MSG_LIB_TDEFAULTC " search path=%s (trusted configuration default - %s)" @ MSG_LIB_LIBPATH " search path=%s (LIBPATH or -YP)" @ MSG_LIB_YPATH " search path=%s replaces path=%s (-Y%c)" @ MSG_LIB_FIND "find object=%s; searching" @ MSG_LIB_TRYING " trying path=%s%s" @ MSG_LIB_ALTER " trying path=%s (auditor returned alternative)" @ MSG_LIB_SKIP " skip path=%s (auditor directed)" @ MSG_LIB_IGNORE " ignore path=%s (insecure directory name)" @ MSG_LIB_INUSE " use path=%s (implicitly secure, as directory \ has already provided dependencies)" # Mapfile messages @ MSG_MAP_MAPFILE "mapfile=%s; version=%d (%s)" @ MSG_MAP_SEG "segment directive; line=%llu; %s" @ MSG_MAP_SEG_ORDER "segment order directive; line=%llu; list_cnt=%lld; %s" @ MSG_MAP_CAP "capability directive; line=%llu" @ MSG_MAP_EC "entrance criteria; line=%llu; added" @ MSG_MAP_OS_ORDER "output section ordering; line=%llu; segment=%s \ section=%s; index=%d" @ MSG_MAP_HDR_NOALLOC "header noalloc directive; line=%llu; first loadable \ segment will not contain ELF and program headers" @ MSG_MAP_SYM_SCOPE "symbol scope definition" @ MSG_MAP_SYM_SIZE "size-symbol directive; line=%llu; segment=%s; \ symbol=%s; %s" @ MSG_MAP_SYM_VER_1 "%s, %s; symbol=%s (%s)" @ MSG_MAP_SYM_VER_2 "%s; symbol=%s (%s)" @ MSG_MAP_DV "depend versions directive; line=%llu, object=%s" @ MSG_MAP_DV_ENTRY "%12.12s %s; line=%llu" @ MSG_MAP_SORT_TITLE "mapfile additions: segment sorting required" @ MSG_MAP_SORT_TITLE_O "before:" @ MSG_MAP_SORT_TITLE_S "after:" @ MSG_MAP_POST_TITLE "mapfile post processing" @ MSG_MAP_ENT_ORD_TITLE "set entrance criteria input section sort keys; \ segment=%s" @ MSG_MAP_ID_ADD "%s: %lld: enter conditional expression id: %s" @ MSG_MAP_ID_CLEAR "%s: %lld: delete conditional expression id: %s" @ MSG_MAP_PASS "%s: %lld: input enabled by %s" @ MSG_MAP_NOPASS "%s: %lld: input disabled by %s" # Move messages @ MSG_MOVE_FILE "file=%s processing move data" @ MSG_MOVE_TITLE1 " i/o offset size repeat stride \ value with respect to" @ MSG_MOVE_TITLE2 " i/o address size repeat stride \ value with respect to" @ MSG_MOVE_ENTRYIN " in %#10llx %6d %6d %6d %#16llx %s" @ MSG_MOVE_ENTRYOUT " out %#10llx %6d %6d %6d %#16llx %s" @ MSG_MOVE_EXPAND " %#10llx %#16llx (expanded)" @ MSG_MOVE_ADJEXPAND "for symbol=%s roffset: new=0x%llx" @ MSG_MOVE_ADJMOVE "for symbol=%s roffset: from=0x%llx, to=0x%llx" @ MSG_MOVE_OUTSCTADJ "adjusting addend for symbol=%s" @ MSG_MOVE_PAREXPN "expanding symbol=%s into .data: %s" @ MSG_MOVE_OUTMOVE "copying move entries for symbol=%s into .SUNW_move" @ MSG_MOVE_INPUT "collecting move entries: file=%s" @ MSG_MOVE_BAD "move %lld offset invalid: %s: offset=0x%llx \ lies outside memory image; move discarded" # Section header messages @ MSG_SHD_MODIFIED "section=%s; section header modified by support \ library: %s" @ MSG_SHD_ORIG " original:" @ MSG_SHD_NEW " new:" # TRANSLATION_NOTE - The following two items are used following a number in # the MSG_SHD_OFFSET_ENT_XX format strings below. For example "1 entry" # or "23 entries". # @ MSG_SHD_ENTRY_1 "entry" @ MSG_SHD_ENTRY_N "entries" # Section messages @ MSG_SEC_BACKING "mapfile symbol definitions: create backing storage:" @ MSG_SEC_INPUT "section=%s; input from file=%s" @ MSG_SEC_INPUT_GEN "section=%s" @ MSG_SEC_INPUT_GENSTR "section=%s; input generated merged string section" @ MSG_SEC_ADDED "section=%s; added to segment=%s" @ MSG_SEC_CREATED "section=%s; added to segment=%s (created)" @ MSG_SEC_REDIRECTED "section=%s; redirected to section=%s" @ MSG_SEC_DISCARDED "section=%s; input from file=%s; \ discarded in favor of section=%s; file=%s" @ MSG_SEC_GNU_COMDAT_1 "section=%s; identified as COMDAT with \ relaxed relocations enabled" @ MSG_SEC_GNU_COMDAT_2 "section=%s; identified as COMDAT" @ MSG_SEC_GNU_COMDAT_3 "section=%s; relaxed relocations enabled" @ MSG_SEC_GRP_DEFINE "section=%s; input from file=%s; defines %s\ group: signature symbol: %s" @ MSG_SEC_GRP_MEMBER "section=%s; input from file=%s; member of %s\ group: signature symbol: %s" @ MSG_SEC_GRP_DISCARDED "section=%s; input from file=%s; discarded in \ favor of group: signature symbol: %s: file=%s" @ MSG_SEC_STRMERGE_DISCARDED "section=%s; input from file=%s; \ discarded in favor of generated merged string section" @ MSG_SEC_STRMERGE_UNSUP "section=%s; input from file=%s; sh_addralign=%lld; \ sh_entsize=%lld; unable to merge sections with this \ size and alignment" @ MSG_SEC_STRTAB_STND "strtab=%s; full size: %lld; uncompressed" @ MSG_SEC_STRTAB_COMP "strtab=%s; full size: %lld; compressed down to: %lld" @ MSG_SEC_GENSTR_COMP "section=%s (generated merged string section); \ full size: %lld; compressed down to: %lld" @ MSG_SEC_STRTAB_HD "strtab=%s; compression information [%d buckets]:" @ MSG_SEC_STRTAB_BCKT " bucket[%d]:" @ MSG_SEC_STRTAB_MSTR " [%lld] %s " @ MSG_SEC_STRTAB_SUFSTR " [%lld] %s " # Unused messages @ MSG_USD_SEC "section=%s; size=0x%llx; input from file=%s; \ unused: does not satisfy any references%s" @ MSG_USD_SECDISCARD "; discarded" @ MSG_USD_FILE "file=%s unused: does not satisfy any references" @ MSG_USD_NEEDSTR "file=%s unused: unable to determine use" @ MSG_USD_UNREF "file=%s unreferenced: unused dependency of %s" @ MSG_USD_FILECYCLIC "file=%s unused: cyclic group [%d] member: \ unreferenced outside of group" @ MSG_USD_LCINTERFACE "file=%s unused interface [%s]: using interface \ from previously loaded object: file=%s" @ MSG_USD_LDLIBPATH " search path=%s unused: LD_LIBRARY_PATH entry" @ MSG_DUP_LDLIBPATH " search path=%s unused: (duplicate) LD_LIBRARY_PATH \ entry" @ MSG_USD_LDLIBPATHC " search path=%s unused: configuration \ LD_LIBRARY_PATH entry - %s" @ MSG_DUP_LDLIBPATHC " search path=%s unused: (duplicate) configuration \ LD_LIBRARY_PATH entry - %s" @ MSG_USD_RUNPATH " search path=%s unused: RUNPATH/RPATH from file %s" # Segment messages @ MSG_SEG_DESC_INUSE "Program Header / Segment Descriptor List (in use)" @ MSG_SEG_DESC_AVAIL "Program Header / Segment Descriptor List (available)" # Support messages @ MSG_SUP_REQ "support object request=%s (%s)" @ MSG_SUP_REQ_ENV "supplied via SGS_SUPPORT" @ MSG_SUP_REQ_CMD "supplied via -S" @ MSG_SUP_ROUTINE " support object=%s: provides routine %s" @ MSG_SUP_CALLING_1 " calling routine=%s (%s)" @ MSG_SUP_CALLING_2 " calling routine=%s (%s) %s=%s" @ MSG_SUP_VNONE " unloading object=%s: version=LD_SUP_VNONE" @ MSG_SUP_OUTFILE "output file" @ MSG_SUP_INFILE "input file" @ MSG_SUP_INSEC "input section" @ MSG_SUP_SEC "section" # Symbol strings @ MSG_SYM_AR_FILE "symbol table processing; input file=%s [ archive ] %s" @ MSG_SYM_AR_SKIP "file=%s, symbol=%s, skipped" @ MSG_SYM_AR_CHECK "file=%s(%s), symbol=%s, checking for tentative or \ restricted visibility override" @ MSG_SYM_AR_RESOLVE "file=%s(%s), symbol=%s, resolves undefined or \ tentative symbol" @ MSG_SYM_AR_FORCE "file=%s(%s), forced extraction" @ MSG_SYM_SPECIAL "symbol table processing; building special symbols" @ MSG_SYM_PROCESS "symbol table processing; input file=%s [ %s ]" @ MSG_SYM_FINAL "symbol table processing; final update" @ MSG_SYM_INDEX "symbol table processing; determining section \ symbol's index" @ MSG_SYM_BSS "symbol table processing; assigning to bss \ (possible copy relocations)" @ MSG_SYM_REDUCED "symbol table processing; reducing global symbols" @ MSG_SYM_RETAINING "symbol table processing; retaining local symbols" @ MSG_SYM_VERSION "symbol table processing; adding version symbols" @ MSG_SYM_CAPABILITIES "symbol table processing; adding local capabilities \ symbols" @ MSG_SYM_BASIC "symbol[%d]=%s" @ MSG_SYM_ADDING "symbol[%d]=%s (global); adding" @ MSG_SYM_SECTION "symbol[%d]=%s (section); segment=%s" @ MSG_SYM_RESOLVING "symbol[%d]=%s (global); resolving [%d][%d]" @ MSG_SYM_UPDATE "symbol=%s; updated" @ MSG_SYM_CREATE "symbol=%s; creating" @ MSG_SYM_REDUCING "symbol=%s; reducing to local" @ MSG_SYM_ELIMINATING "symbol=%s; eliminating" @ MSG_SYM_NOTELIMINATE "symbol=%s; not eliminated: referenced by \ section=%s, entry[%d]" @ MSG_SYM_DISCARD_SEC "symbol=%s; discarded: originates from unused or \ discarded section=%s from file=%s" @ MSG_SYM_DISCARD_FILE "symbol=%s; discarded: originates from unused or \ discarded file=%s" @ MSG_SYM_DISCARD_DUP "symbol[%d]=%s; discarded duplicate: originates from \ file=%s" @ MSG_SYM_WRAP "symbol[%d]=%s renamed to %s (-z wrap)" @ MSG_SYM_CAP_ORIG "symbol[%d]=%s converting to symbol capability \ (-z symbolcap)" @ MSG_SYM_CAP_LOCAL "symbol[%d]=%s creating local capability \ (-z symbolcap)" @ MSG_SYM_COPY_DST "symbol=%s; copy destination: alignment: 0x%x" @ MSG_SYM_COPY_REF "symbol=%s; copy reference" @ MSG_SYM_LOOKUP "symbol=%s; lookup in file=%s [ %s ]" @ MSG_DLSYM_1 "symbol=%s; dlsym() called from file=%s %s %s" @ MSG_DLSYM_2 "symbol=%s; dlsym() called from file=%s; starting \ at file=%s %s %s" @ MSG_CAP_SYM_DEFAULT " symbol=%s[%u]: capability family default" @ MSG_CAP_SYM_USED " symbol=%s[%u]: used" @ MSG_CAP_SYM_CANDIDATE " symbol=%s[%u]: capability candidate" @ MSG_CAP_SYM_REJECTED " symbol=%s[%u]: capability rejected" @ MSG_CAP_SYM_HW_1 " symbol=%s[%u]: capability specific \ (CA_SUNW_HW_1): [ %s ]" @ MSG_CAP_SYM_SF_1 " symbol=%s[%u]: capability specific \ (CA_SUNW_SF_1): [ %s ]" @ MSG_CAP_SYM_MACH " symbol=%s[%u]: capability specific \ (CA_SUNW_MACH): [ %s ]" @ MSG_CAP_SYM_PLAT " symbol=%s[%u]: capability specific \ (CA_SUNW_PLAT): [ %s ]" @ MSG_CAP_SYM_HW_2 " symbol=%s[%u]: capability specific \ (CA_SUNW_HW_2): [ %s ]" @ MSG_CAP_SYM_HW_3 " symbol=%s[%u]: capability specific \ (CA_SUNW_HW_3): [ %s ]" @ MSG_SYM_LAZY_RESCAN "rescanning for lazy dependencies for symbol: %s" @ MSG_SYM_DUPSORTADDR "section %s: symbol '%s' and symbol '%s' have the \ same address: %#llx" @ MSG_SYM_IGNGNUVER "symbol=%s; hash index=%d; version=%d; skipping \ symbol with GNU version hidden bit set in file=%s" # Syminfo string @ MSG_SYMINFO_INFO "syminfo information" # Version strings @ MSG_VER_AVAIL_1 "version availability: file=%s" @ MSG_VER_AVAIL_2 " available version selected from" @ MSG_VER_DEF_TITLE "version definition processing: file=%s" @ MSG_VER_NEED_TITLE "version needed processing: file=%s" @ MSG_VER_NOINTERFACE "version definition has no interface symbols: %s" # SHF_ORDERED related messages. Token used is sections. @ MSG_ORD_SORT_BEFORE "section=%s; requires output section reordering:" @ MSG_ORD_SORT_AFTER "section=%s; output section reordered:" @ MSG_ORD_HDR_1 " number of SHN_BEGIN=%u, ordered=%u, default=%u, \ SHN_AFTER=%u" @ MSG_ORD_TITLE_1 " %s=SHN_BEGIN: section=%s from %s" @ MSG_ORD_TITLE_2 " %s=SHN_AFTER: section=%s from %s" @ MSG_ORD_TITLE_3 " sort key=%u: section=%s from %s, %s=%s" @ MSG_ORD_ERR_TITLE "the SHF_ORDERED section %s from %s has \ an error; flag ignored" @ MSG_ORD_ERR_INFORANGE " the sh_info field is out of range" @ MSG_ORD_ERR_ORDER " the section pointed by sh_info is an ordered section" @ MSG_ORD_ERR_LINKRANGE " the sh_link field is out of range" @ MSG_ORD_ERR_FLAGS " the sh_flag is incorrect" @ MSG_ORD_ERR_CYCLIC " the sh_link is cyclic" @ MSG_ORD_ERR_LINKINV " a section pointed to by sh_link has an error" # Link-Auditing Messages @ MSG_AUD_LIB "auditor %s: required by: %s %s" @ MSG_AUD_INTERFACE "auditor %s: provides interface: %s" @ MSG_AUD_VERSION "auditor %s: la_version(): %d: returned %d" @ MSG_AUD_ACTIVITY "auditor %s: la_activity(): %s %s" @ MSG_AUD_PREINIT "auditor %s: la_preinit(): %s" @ MSG_AUD_OBJFILTER "auditor %s: la_objfilter(): %s: filtee=%s [ %s ]" @ MSG_AUD_OBJFILTER_R "auditor %s: la_objfilter(): %s: returned 0 (filtee \ ignored)" @ MSG_AUD_OBJOPEN "auditor %s: la_objopen(): %s" @ MSG_AUD_OBJOPEN_R "auditor %s: la_objopen(): %s: returned %s" @ MSG_AUD_OBJOPEN_RI "auditor %s: la_objopen(): %s: returned %s (flags \ ignored)" @ MSG_AUD_OBJSEARCH "auditor %s: la_objsearch(): %s %s" @ MSG_AUD_OBJSEARCH_R "auditor %s: la_objsearch(): %s: alternative path \ returned: %s" @ MSG_AUD_OBJSEARCH_S "auditor %s: la_objsearch(): %s: alternative path \ returned: 0 (path skipped)" @ MSG_AUD_OBJCLOSE "auditor %s: la_objclose(): %s" @ MSG_AUD_SYMBIND "auditor %s: la_symbind(): %s: value: 0x%llx %s" @ MSG_AUD_SYMBIND_R "auditor %s: la_symbind(): %s: returned value: \ 0x%llx %s" @ MSG_AUD_PLTENTER "auditor %s: la_pltenter(): %s: value: 0x%llx" @ MSG_AUD_PLTENTER_R "auditor %s: la_pltenter(): %s: returned value: 0x%llx" @ MSG_AUD_PLTEXIT "auditor %s: la_pltexit(): %s" @ MSG_AUD_IGNORE "file=%s; global auditing request ignored: object \ did not initiate process" @ MSG_AUD_SKIP "file=%s; skipped: using auditor from %s" @ MSG_AUD_TERM "file=%s; auditor has indicated path should be skipped" # GOT Messages @ MSG_GOT_INFO "Global Offset Table information: (%u entries)" # TRANSLATION_NOTE # Do not translate .init or .fini, they represent reserved section names. @ MSG_UTL_INIT "calling .init (%s): %s" @ MSG_UTL_FINI "calling .fini: %s" @ MSG_UTL_ARRAY "calling %s[%d]:0x%llx: %s" @ MSG_UTL_TRANS "transferring control: %s" @ MSG_UTL_INTOOLATE "loading after relocation has started: interposition \ request (DF_1_INTERPOSE) ignored: %s" @ MSG_UTL_EDGE_TITLE_I "traversing %s dependency edge for interposer:" @ MSG_UTL_EDGE_TITLE_S "traversing %s dependency edge:" @ MSG_UTL_EDGE_START " node (%d): file=%s" @ MSG_UTL_EDGE_IN " node (%d): file=%s: referenced by %s %s" @ MSG_UTL_EDGE_OUT " node (%d): file=%s; cyclic dependency on %s" @ MSG_UTL_COLLECT " [%d] %s; collecting %s section" @ MSG_UTL_SORT "from sorted order" @ MSG_UTL_PEND "pending" @ MSG_UTL_DYN "dynamically triggered" @ MSG_UTL_DONE "done" @ MSG_UTL_DBNOTIFY "notify debugger: event: %s state: %s" @ MSG_UTL_SCC_TITLE " cycle detected - sorting cyclic dependencies in %s" @ MSG_UTL_SCC_SUBI "reverse load-order" @ MSG_UTL_SCC_SUBF "load-order" @ MSG_UTL_LCINTERFACE "file=%s; provides interface [%s]: 0x%llx" # Generic strings @ MSG_STR_IGNORE "ignored" @ MSG_STR_ENTERED "entered" @ MSG_STR_ORIGINAL "original" @ MSG_STR_EXCLUDE "exclude" @ MSG_STR_RESET "reset" @ MSG_STR_IN " in" @ MSG_STR_OUT "out" @ MSG_STR_ACT "act" @ MSG_STR_CURRENT "current" @ MSG_STR_ADD "add" @ MSG_STR_OLD "old" @ MSG_STR_NEW "new" @ MSG_STR_NEW_IMPLICIT "new (implicit)" @ MSG_STR_RESOLVED "resolved" @ MSG_STR_ADDING "adding" @ MSG_STR_UP_1 "updating" @ MSG_STR_UP_2 "updated" @ MSG_STR_ALLOW "allow" @ MSG_STR_REQUIRE "require" @ MSG_STR_MOD_BEFORE "modify (before)" @ MSG_STR_MOD_AFTER "modify (after)" @ MSG_STR_UNKNOWN "" @ MSG_STR_ORPHAN "" @ MSG_STR_UNUSED "(unused)" @ MSG_STR_AGAIN "(again)" @ MSG_STR_NULL "(null)" @ MSG_STR_ALTER " (alternate)" @ MSG_STR_COPYZERO " (copy zero's unnecessary)" @ MSG_STR_TEMPORARY " (temporary)" @ MSG_STR_RETRY " (retry) " # TLS related messages @ MSG_TLS_STATBLOCK1 "static TLS module: [%ld] %s" @ MSG_TLS_STATBLOCK2 "static TLS reservation: in use %#llx: \ additional backup: %#llx" @ MSG_TLS_STATBLOCK3 "static TLS requirement: [%ld] %s: size %#llx: \ satisfied from backup reservation: remaining %#llx" @ MSG_TLS_MODENT1 " block: %#18llx soff: %#10llx flags: %#llx \ %s" @ MSG_TLS_MODENT2 " filesz: %#18llx memsz: %#10llx modid: %lld" @ MSG_TLS_MODACT "%s TLS module: %s" @ MSG_TLS_ADD "add" @ MSG_TLS_REMOVE "remove" # Statistics related messages @ MSG_STATS_AR "archive %s: count=%d, used=%d (%d%%)" @ MSG_STATS_GENERAL "General Statistics:" @ MSG_STATS_FILES " Input files: relocatables=%lld \ shared objects=%lld archives=%lld" @ MSG_STATS_SYMBOLS_OUT " Symbols output: globals=%-10lld locals=%lld" @ MSG_STATS_SYMBOLS_IN " Symbols input: globals=%-10lld scoped=%-10lld \ eliminated=%lld" @ MSG_STATS_REL_OUT " Relocations output: records=%lld" @ MSG_STATS_REL_IN " Relocations input: records=%-10lld applied=%lld" @ MSG_STATS_REL_TICACHE " Relocation Cache" @ MSG_STATS_REL_TIACT "Active" @ MSG_STATS_REL_TIOUT "Output" @ MSG_STATS_REL_CACHE " %s: buffers=%d, used=%lld/%lld (%d%%), \ size=%lld%s" @ MSG_STATS_REL_ACACHE " Aux: buffers=%d, used=%lld/%lld (%d%%), \ size=%lld%s" # Capabilities messages @ MSG_CAP_SYS_HW_1 "hardware capabilities (CA_SUNW_HW_1) - %s" @ MSG_CAP_SYS_SF_1 "software capabilities (CA_SUNW_SF_1) - %s" @ MSG_CAP_SYS_MACH "machine capability (CA_SUNW_MACH) - %s" @ MSG_CAP_SYS_PLAT "platform capability (CA_SUNW_PLAT) - %s" @ MSG_CAP_SYS_HW_2 "hardware capabilities (CA_SUNW_HW_2) - %s" @ MSG_CAP_SYS_HW_3 "hardware capabilities (CA_SUNW_HW_3) - %s" @ MSG_CAP_ALT_HW_1 "alternative hardware capabilities (CA_SUNW_HW_1) - %s" @ MSG_CAP_ALT_SF_1 "alternative software capabilities (CA_SUNW_SF_1) - %s" @ MSG_CAP_ALT_MACH "alternative machine capability (CA_SUNW_MACH) - %s" @ MSG_CAP_ALT_PLAT "alternative platform capability (CA_SUNW_PLAT) - %s" @ MSG_CAP_ALT_HW_2 "alternative hardware capabilities (CA_SUNW_HW_2) - %s" @ MSG_CAP_ALT_HW_3 "alternative hardware capabilities (CA_SUNW_HW_3) - %s" @ MSG_CAP_SEC_TITLE "capabilities; input file=%s" @ MSG_CAP_SEC_ENTRY "%12.12s %-15.15s %s" @ MSG_CAP_CANDIDATE "obj=%s; capabilities candidate" @ MSG_CAP_POST_TITLE "capabilities post processing" @ MSG_CAP_FILTER_1 "dir=%s; capability directory filtered by %s" @ MSG_CAP_FILTER_2 "dir=%s; no capability objects found" @ MSG_CAP_IDENTICAL "obj=%s and obj=%s: have identical capabilities: both \ objects ignored" @ MSG_ELF_HEADER "ELF Header" # Capabilities entries. # TRANSLATION_NOTE - the following two entries provide for a series of one or # more capabilities table entries that align with the initial title. @ MSG_CAP_ELF_TITLE " index tag value" @ MSG_CAP_ELF_ENTRY "%10.10s %-15.15s %s" # Dynamic entries. # TRANSLATION_NOTE - the following two entries provide for a series of one or # more dynamic table entries that align with the initial title. @ MSG_DYN_TITLE " index tag value" @ MSG_DYN_ENTRY "%10.10s %-16.16s %-#16llx %s" # Symbol table entries. # TRANSLATION_NOTE - the following entries provide for a series of one or more # standard 32-bit symbol table entries that align with the initial title. @ MSG_SYM_EFS_TITLE_32 " index value size type bind \ oth ver shndx name" @ MSG_SYM_LDS_TITLE_32 " value size type bind \ oth ver shndx" @ MSG_SYM_EFS_ENTRY_32 "%10.10s %10.10s 0x%8.8x %4s %4s %2s %4s \ %-14.14s %s" # TRANSLATION_NOTE - the following entries provide for a series of one or more # long 32-bit symbol table entries that align with the initial title. @ MSG_SYM_EFL_TITLE_32 " index value size type bind \ oth ver shndx / name" @ MSG_SYM_LDL_TITLE_32 " value size type bind \ oth ver shndx" @ MSG_SYM_EFL_ENTRY_32 "%10.10s %10.10s 0x%8.8x %4s %4s %2s %4s \ %-14s %s" # TRANSLATION_NOTE - the following entries provide for a series of one or more # standard 64-bit symbol table entries that align with the initial title. @ MSG_SYM_EFS_TITLE_64 " index value size \ type bind oth ver shndx name" @ MSG_SYM_LDS_TITLE_64 " value size \ type bind oth ver shndx" @ MSG_SYM_EFS_ENTRY_64 "%10.10s %18.18s 0x%16.16llx %4s %4s %2s %4s \ %-14.14s %s" # TRANSLATION_NOTE - the following entries provide for a series of one or more # long 64-bit symbol table entries that align with the initial title. @ MSG_SYM_EFL_TITLE_64 " index value size \ type bind oth ver shndx / name" @ MSG_SYM_LDL_TITLE_64 " value size \ type bind oth ver shndx" @ MSG_SYM_EFL_ENTRY_64 "%10.10s %18.18s 0x%16.16llx %4s %4s %2s %4s \ %-14s %s" # Syminfo entries. # TRANSLATION_NOTE - the following two entries provide for a series of one or # more symbol information table entries that align with the initial title. @ MSG_SYMINFO_TITLE " index flags \ bound to symbol" @ MSG_SYMINFO_ENTRY "%10.10s %-8s %7s %-24s %s" @ MSG_SYMINFO_CAP "" @ MSG_SYMINFO_SELF "" @ MSG_SYMINFO_PARENT "" @ MSG_SYMINFO_EXTERN "" # Global offset table entries. # TRANSLATION_NOTE - the following two entries are used by elfdump(1), and # provide for a series of one or more 32-bit got table entries that align with # the initial title. @ MSG_GOT_TITLE_32 " index addr value \ pending relocation" @ MSG_GOT_ENTRY_RE_32 "%10.10s 0x%08llx 0x%08llx %-24s %s" @ MSG_GOT_ENTRY_NR_32 "%10.10s 0x%08llx 0x%08llx" # TRANSLATION_NOTE - the following two entries are used by elfdump(1), and # provide for a series of one or more 64-bit got table entries that align with # the initial title. @ MSG_GOT_TITLE_64 " index addr \ value pending relocation" @ MSG_GOT_ENTRY_RE_64 "%10.10s 0x%016llx 0x%016llx %-24s %s" @ MSG_GOT_ENTRY_NR_64 "%10.10s 0x%016llx 0x%016llx" # TRANSLATION_NOTE - the following three entries are used by ld(1), and provide # for a series of one or more 32-bit got table entries that align with one of # the initial titles. @ MSG_GOT_COLUMNS1_32 " index ref offset addend symbol" @ MSG_GOT_COLUMNS2_32 " index ref offset value symbol" @ MSG_GOT_FORMAT1_32 "%10.10s %3s 0x%08llx 0x%08llx %s" @ MSG_GOT_FORMAT2_32 "%10.10s %3s 0x%08llx 0x%08llx %s:%s" # TRANSLATION_NOTE - the following three entries are used by ld(1), and provide # for a series of one or more 64-bit got table entries that align with one of # the initial titles. @ MSG_GOT_COLUMNS1_64 " index ref offset \ addend symbol" @ MSG_GOT_COLUMNS2_64 " index ref offset \ value symbol" @ MSG_GOT_FORMAT1_64 "%10.10s %3s 0x%016llx 0x%016llx %s" @ MSG_GOT_FORMAT2_64 "%10.10s %3s 0x%016llx 0x%016llx %s:%s" # Version table entries. @ MSG_VER_DEF " index version dependency" @ MSG_VER_NEED " file version" @ MSG_VER_NEED_GNUVER " index file version" @ MSG_VER_LINE_1 "%10.10s %-26.26s %-20s %s" @ MSG_VER_LLINE_1 "%10s %-26s %-20s %s" @ MSG_VER_LINE_2 "%47s %s" @ MSG_VER_LINE_3 "%38s %-20s %s" @ MSG_VER_LINE_4 " %s" @ MSG_VER_LINE_5 " %-26.26s %s" @ MSG_VER_LLINE_5 " %-26s %s" # Relocation entries. # TRANSLATION_NOTE - the following strings are used by elfdump(1). These # strings provide for a series of one or more 32-bit relocation table entries, # using truncated section names, that align with one of the initial titles. @ MSG_REL_EFSA_TITLE_32 " type offset addend \ section symbol" @ MSG_REL_EFSN_TITLE_32 " type offset \ section symbol" @ MSG_REL_EFSA_ENTRY_32 " %-24s %#10llx %#10llx %-14.14s %s" @ MSG_REL_EFSN_ENTRY_32 " %-24s %#10llx %-14.14s %s" # TRANSLATION_NOTE - the following strings are used by elfdump(1). These # strings provide for a series of one or more 32-bit relocation table entries, # using long section names, that align with one of the initial titles. @ MSG_REL_EFLA_TITLE_32 " type offset addend \ section / symbol" @ MSG_REL_EFLN_TITLE_32 " type offset \ section / symbol" @ MSG_REL_EFLA_ENTRY_32 " %-24s %#10llx %#10llx %-14s %s" @ MSG_REL_EFLN_ENTRY_32 " %-24s %#10llx %-14s %s" # TRANSLATION_NOTE - the following strings are used by ld.so.1(1). These # strings provide for a series of one or more 32-bit relocation table entries, # that align with the initial titles. @ MSG_REL_RTA_TITLE_32 " type offset \ addend symbol" @ MSG_REL_RTN_TITLE_32 " type offset \ value symbol" @ MSG_REL_RTV_TITLE_32 " value" @ MSG_REL_RTA_ENTRY_32 " %5s %-24s %#10llx %#10llx %s %s" @ MSG_REL_RTN_ENTRY_32 " %5s %-24s %#10llx %s %s" @ MSG_REL_RT_APLVAL_32 " apply %#10llx %#10llx" @ MSG_REL_RT_APLREG_32 " apply %10.10s %#10llx" # TRANSLATION_NOTE - the following strings are used by ld(1). These strings # provide for a series of one or more 32-bit relocation table entries, using # truncated section names, that align with one of the initial titles. @ MSG_REL_LDSA_TITLE_32 " type \ offset addend section symbol" @ MSG_REL_LDSN_TITLE_32 " type \ offset section symbol" @ MSG_REL_LDSA_ENTRY_32 " %5s %-24s %#10llx %#10llx %-14.14s %s %s" @ MSG_REL_LDSN_ENTRY_32 " %5s %-24s %#10llx %-14.14s %s %s" @ MSG_REL_LDSV_TITLE_32 " type \ offset value section symbol" # TRANSLATION_NOTE - the following strings are used by ld(1). These strings # provide for a series of one or more 32-bit relocation table entries, using # long section names, that align with one of the initial titles. @ MSG_REL_LDLA_TITLE_32 " type \ offset addend section / symbol" @ MSG_REL_LDLN_TITLE_32 " type \ offset section / symbol" @ MSG_REL_LDLA_ENTRY_32 " %5s %-24s %#10llx %#10llx %-14s %s %s" @ MSG_REL_LDLN_ENTRY_32 " %5s %-24s %#10llx %-14s %s %s" @ MSG_REL_LDLV_TITLE_32 " type \ offset value section / symbol" # TRANSLATION_NOTE - the following strings are used by elfdump(1). These # strings provide for a series of one or more 64-bit relocation table entries, # using truncated section names, that align with one of the initial titles. @ MSG_REL_EFSA_TITLE_64 " type \ offset addend section symbol" @ MSG_REL_EFSN_TITLE_64 " type \ offset section symbol" @ MSG_REL_EFSA_ENTRY_64 " %-24s %#18llx %#18llx %-14.14s %s" @ MSG_REL_EFSN_ENTRY_64 " %-24s %#18llx %-14.14s %s" # TRANSLATION_NOTE - the following strings are used by elfdump(1). These # strings provide for a series of one or more 64-bit relocation table entries, # using long section names, that align with one of the initial titles. @ MSG_REL_EFLA_TITLE_64 " type \ offset addend section / symbol" @ MSG_REL_EFLN_TITLE_64 " type \ offset section / symbol" @ MSG_REL_EFLA_ENTRY_64 " %-24s %#18llx %#18llx %-14s %s" @ MSG_REL_EFLN_ENTRY_64 " %-24s %#18llx %-14s %s" # TRANSLATION_NOTE - the following strings are used by ld.so.1(1). These # strings provide for a series of one or more 64-bit relocation table entries, # that align with the initial titles. @ MSG_REL_RTA_TITLE_64 " type \ offset addend symbol" @ MSG_REL_RTN_TITLE_64 " type \ offset value symbol" @ MSG_REL_RTV_TITLE_64 " value" @ MSG_REL_RTA_ENTRY_64 " %5s %-24s %#18llx %#18llx %s %s" @ MSG_REL_RTN_ENTRY_64 " %5s %-24s %#18llx %s %s" @ MSG_REL_RT_APLVAL_64 " apply %#18llx %#18llx" @ MSG_REL_RT_APLREG_64 " apply %18.18s %#18llx" # TRANSLATION_NOTE - the following strings are used by ld(1). These strings # provide for a series of one or more 64-bit relocation table entries, using # truncated section names, that align with one of the initial titles. @ MSG_REL_LDSA_TITLE_64 " type \ offset addend section symbol" @ MSG_REL_LDSN_TITLE_64 " type \ offset section symbol" @ MSG_REL_LDSA_ENTRY_64 " %5s %-24s %#18llx %#18llx %-14.14s %s %s" @ MSG_REL_LDSN_ENTRY_64 " %5s %-24s %#18llx %-14.14s %s %s" @ MSG_REL_LDSV_TITLE_64 " type \ offset value section symbol" # TRANSLATION_NOTE - the following strings are used by ld(1). These strings # provide for a series of one or more 64-bit relocation table entries, using # long section names, that align with one of the initial titles. @ MSG_REL_LDLA_TITLE_64 " type \ offset addend section / symbol" @ MSG_REL_LDLN_TITLE_64 " type \ offset section / symbol" @ MSG_REL_LDLA_ENTRY_64 " %5s %-24s %#18llx %#18llx %-14s %s %s" @ MSG_REL_LDLN_ENTRY_64 " %5s %-24s %#18llx %-14s %s %s" @ MSG_REL_LDLV_TITLE_64 " type \ offset value section / symbol" # dl*() family messages @ MSG_DL_IPHDR_ENTER "dl_iterate_phdr() called from file=%s" @ MSG_DL_IPHDR_MAPCNG "dl_iterate_phdr() object map/unmap in callback" @ MSG_DL_IPHDR_UNMAP "dl_iterate_phdr() early return due to object unmap" @ MSG_DL_IPHDR_CALLBACK "dl_iterate_phdr() callback" @ MSG_DL_IPHDR_NAME " dlpi_name: %s" @ MSG_DL_IPHDR_MAPCNT " dlpi_adds: %-18llu dlpi_subs: %-18llu" @ MSG_DL_IPHDR_ADDR_32 " dlpi_addr: %#-10llx" @ MSG_DL_IPHDR_PHDR_32 " dlpi_phdr: %#-10llx dlpi_phnum: %u" @ MSG_DL_IPHDR_ADDR_64 " dlpi_addr: %#-18llx" @ MSG_DL_IPHDR_PHDR_64 " dlpi_phdr: %#-18llx dlpi_phnum: %u" @ MSG_DL_DLCLOSE "file=%s; dlclose() called from file=%s %s" @ MSG_DL_DLDUMP "file=%s; dldump() called from file=%s: dumping to \ file=%s %s" @ MSG_DL_DLOPEN "file=%s; dlopen() called from file=%s %s %s" @ MSG_DL_DLADDR "dladdr() called from file=%s: %#llx" @ MSG_DL_DLERROR "dlerror() called from file=%s: %s" @ MSG_DL_DLINFO "dlinfo() called from file=%s: handle=%s, request=%s, \ user data=%#llx" @ _END_ # Debug enabling tokens (for now these are untranslated) @ MSG_TOK_ALL "all" @ MSG_TOK_ARGS "args" @ MSG_TOK_BINDINGS "bindings" @ MSG_TOK_DL "dl" @ MSG_TOK_CAP "cap" @ MSG_TOK_BASIC "basic" @ MSG_TOK_ENTRY "entry" @ MSG_TOK_FILES "files" @ MSG_TOK_HELP "help" @ MSG_TOK_INIT "init" @ MSG_TOK_LIBS "libs" @ MSG_TOK_MAP "map" @ MSG_TOK_RELOC "reloc" @ MSG_TOK_SECTIONS "sections" @ MSG_TOK_SEGMENTS "segments" @ MSG_TOK_SUPPORT "support" @ MSG_TOK_SYMBOLS "symbols" @ MSG_TOK_TLS "tls" @ MSG_TOK_VERSIONS "versions" @ MSG_TOK_AUDIT "audit" @ MSG_TOK_GOT "got" @ MSG_TOK_MOVE "move" @ MSG_TOK_DEMANGLE "demangle" @ MSG_TOK_STRTAB "strtab" @ MSG_TOK_STATS "statistics" @ MSG_TOK_UNUSED "unused" @ MSG_TOK_DETAIL "detail" @ MSG_TOK_LONG "long" @ MSG_TOK_NAME "name" @ MSG_TOK_FULLNAME "fullname" @ MSG_TOK_CLASS "class" @ MSG_TOK_LMID "lmid" @ MSG_TOK_TTIME "ttime" @ MSG_TOK_DTIME "dtime" @ MSG_TOK_OUTFILE "output" @ MSG_TOK_LMID_ALL "ALL" @ MSG_TOK_LMID_ALT "ALT" @ MSG_TOK_LMID_BASE "BASE" @ MSG_TOK_LMID_LDSO "LDSO" # The following strings represent reserved words, files, pathnames and symbols. # Reference to this strings is via the MSG_ORIG() macro, and thus no message # translation is required. @ MSG_STR_EMPTY "" @ MSG_STR_DELIMIT ",:" @ MSG_STR_COMDAT "COMDAT " @ MSG_SCN_GOT ".got" @ MSG_SCN_PLT ".plt" @ MSG_SCN_BSS ".bss" @ MSG_SCN_INIT ".init" @ MSG_SCN_FINI ".fini" @ MSG_SCN_INITARRAY ".initarray" @ MSG_SCN_FINIARRAY ".finiarray" @ MSG_SCN_PREINITARRAY ".preinitarray" @ MSG_SH_INFO "sh_info" @ MSG_SH_LINK "sh_link" @ MSG_UTL_SCC_ENTRY " [%d] %s" @ MSG_FMT_INDEX " [%d]" @ MSG_FMT_INDEX_RANGE " [%d-%d]" @ MSG_FMT_STR "%s" @ MSG_FMT_PATH "%s/%s" @ MSG_PTH_OBJECT "/tmp/ld.so-OBJECT-" @ MSG_SUNW_OST_SGS "SUNW_OST_SGS" # Entrance criteria messages @ MSG_ECR_NAME " ec_name: %s" @ MSG_ECR_FLAGS " ec_flags: %s" @ MSG_ECR_IS_NAME " ec_is_name: %-8s ec_attrmask: %s" @ MSG_ECR_SEGMENT " ec_segment: %-8s ec_attrbits: %s" @ MSG_ECR_NDX " ec_ordndx: %-8d ec_type: %s" @ MSG_ECR_FILES " ec_files:" @ MSG_ECR_FILE " %-21s %s" @ MSG_MAP_SORT_SEG " %s" @ MSG_MAP_SORT_SEG_NAME " %-20s %s" @ MSG_MAP_SORT_SEG_V " %-20s %-20s p_vaddr=0x%llx" @ MSG_MAP_SORT_SEG_O " %-20s %-20s order=%d" # Libs messages @ MSG_LIB_FILE " %s" # PLT binding methods @ MSG_PLT_21D "21d" @ MSG_PLT_24D "24d" @ MSG_PLT_U32 "u32" @ MSG_PLT_U44 "u44" @ MSG_PLT_FULL "full" @ MSG_PLT_FAR "far" # Segment messages @ MSG_SEG_DESC "segment[%d]" @ MSG_SEG_NAME " sg_name: %s" @ MSG_SEG_LENGTH " sg_length: %#llx" @ MSG_SEG_ROUND " sg_round: %#llx" @ MSG_SEG_ALIGN " sg_align: %#llx" @ MSG_SEG_FLAGS " sg_flags: %s" @ MSG_SEG_SIZESYM_TITLE " sg_sizesym:" @ MSG_SEG_SIZESYM " %s" @ MSG_SEG_IS_ORDER_TITLE " sg_is_order:" @ MSG_SEG_OS_ORDER_TITLE " sg_os_order:" @ MSG_SEG_LIST_ITEM " %s" # Section messages (used when expanding segment information) @ MSG_SEC_NAME " section[%d] os_name: %s" # Symbol strings @ MSG_SYM_GLOBAL "global" @ MSG_SYM_LOCAL "local" @ MSG_SYM_COPY "copy" @ MSG_DLSYM_NEXT "[ RTLD_NEXT ]" @ MSG_DLSYM_DEFAULT "[ RTLD_DEFAULT ]" @ MSG_DLSYM_SELF "[ RTLD_SELF ]" @ MSG_DLSYM_PROBE "[ RTLD_PROBE ]" @ MSG_DLSYM_SINGLETON "( singleton reference )" # Link-map mode strings @ MSG_MODE_GLOBNODEL "[ GLOBAL NODELETE ]" @ MSG_MODE_GLOB "[ GLOBAL ]" @ MSG_MODE_NODEL "[ NODELETE ]" # NOTE: these are used by lari(1), use care when changing. @ MSG_BINFO_START " (" @ MSG_BINFO_DIRECT "direct" @ MSG_BINFO_INTERPOSE "interpose" @ MSG_BINFO_COPYREF "copy-ref" @ MSG_BINFO_FILTEE "filtee" @ MSG_BINFO_PLTADDR "plt-addr" @ MSG_BINFO_END ")" @ MSG_BINFO_SEP "," # Utility messages @ MSG_UTL_EVNT_PREINIT "RD_PREINIT" @ MSG_UTL_EVNT_POSTINIT "RD_POSTINIT" @ MSG_UTL_EVNT_DLACT "RD_DLACTIVITY" @ MSG_UTL_STA_ADD "RT_ADD" @ MSG_UTL_STA_DELETE "RT_DELETE" @ MSG_UTL_STA_CONSIST "RT_CONSISTENT" # Version messages @ MSG_VER_SELECTED " SELECTED %-26.26s %s" @ MSG_VER_L_SELECTED " SELECTED %-26s %s" @ MSG_VER_ALL " ALL %-26.26s" @ MSG_VER_L_ALL " ALL %-26s" # Global offset table entries. @ MSG_GOT_INDEX " [%d]" @ MSG_GOT_SMALL_PIC "pic" @ MSG_GOT_BIG_PIC "PIC" @ MSG_CNTL_ENTRY " [0x%llx] %s" @ MSG_STR_NL "\n" @ MSG_STR_LDVER "Solaris Linkers: %s" @ MSG_FMT_INDEX " [%d]" @ MSG_FMT_ISEC_NAME "[%u]%s" @ MSG_FMT_MEMUNIT " (%lld%c)" @ MSG_SUNW_OST_SGS "SUNW_OST_SGS" @ MSG_ELF_MAGIC " ei_magic: { 0x%x, %c, %c, %c }" @ MSG_ELF_CLASS " ei_class: %-18s ei_data: %s" @ MSG_ELF_OSABI " ei_osabi: %-18s ei_abiversion: %s" @ MSG_ELF_MACHINE " e_machine: %-18s e_version: %s" @ MSG_ELF_TYPE " e_type: %s" @ MSG_ELF_FLAGS " e_flags: %18s" @ MSG_ELF_FLAGS_FMT " e_flags: %s" @ MSG_ELF_ESIZE " e_entry: %#18llx e_ehsize: %2d \ e_shstrndx: %d" @ MSG_ELFX_ESIZE " e_entry: %#18llx e_ehsize: %2d \ e_shstrndx: SHN_XINDEX (see shdr[0].sh_link)" @ MSG_ELF_SHOFF " e_shoff: %#18llx e_shentsize: %2d \ e_shnum: %d" @ MSG_ELFX_SHOFF " e_shoff: %#18llx e_shentsize: %2d \ e_shnum: 0 (see shdr[0].sh_size)" @ MSG_ELF_PHOFF " e_phoff: %#18llx e_phentsize: %2d \ e_phnum: %d" @ MSG_ELFX_PHOFF " e_phoff: %#18llx e_phentsize: %2d \ e_phnum: PN_XNUM (see shdr[0].sh_info)" # Shdr[0] messages @ MSG_SHD0_TITLE "Section Header[0]: (ELF Ehdr extensions)" @ MSG_SHD0_ADDR " sh_addr: %-6lld sh_flags: %s" @ MSG_SHD0_SIZE " sh_size: %-6lld (e_shnum) sh_type: %s" @ MSG_SHD0_OFFSET " sh_offset: %-6lld \ sh_entsize: %lld" @ MSG_SHD0_LINK " sh_link: %-6d (e_shstrndx) sh_info: \ %d (e_phnum)" @ MSG_SHD0_ALIGN " sh_addralign: %-6lld" # Section header messages @ MSG_SHD_ADDR_32 " sh_addr: %#-10llx sh_flags: %s" @ MSG_SHD_SIZE_32 " sh_size: %#-10llx sh_type: %s" @ MSG_SHD_OFFSET_32 " sh_offset: %#-10llx sh_entsize: %#llx" @ MSG_SHD_OFFSET_ENT_32 " sh_offset: %#-10llx sh_entsize: %#llx \ (%lld %s)" @ MSG_SHD_LINK_32 " sh_link: %-14s sh_info: %s" @ MSG_SHD_ALIGN_32 " sh_addralign: %#-10llx" @ MSG_SHD_ADDR_64 " sh_addr: %#-18llx sh_flags: %s" @ MSG_SHD_SIZE_64 " sh_size: %#-18llx sh_type: %s" @ MSG_SHD_OFFSET_64 " sh_offset: %#-18llx sh_entsize: %#llx" @ MSG_SHD_OFFSET_ENT_64 " sh_offset: %#-18llx sh_entsize: %#llx \ (%lld %s)" @ MSG_SHD_LINK_64 " sh_link: %-18s sh_info: %s" @ MSG_SHD_ALIGN_64 " sh_addralign: %#-18llx" # Program header messages @ MSG_PHD_VADDR_32 " p_vaddr: %#-10llx p_flags: %s" @ MSG_PHD_PADDR_32 " p_paddr: %#-10llx p_type: %s" @ MSG_PHD_FILESZ_32 " p_filesz: %#-10llx p_memsz: %#llx" @ MSG_PHD_OFFSET_32 " p_offset: %#-10llx p_align: %#llx" @ MSG_PHD_VADDR_64 " p_vaddr: %#-18llx p_flags: %s" @ MSG_PHD_PADDR_64 " p_paddr: %#-18llx p_type: %s" @ MSG_PHD_FILESZ_64 " p_filesz: %#-18llx p_memsz: %#llx" @ MSG_PHD_OFFSET_64 " p_offset: %#-18llx p_align: %#llx" # Syminfo formats @ MSG_SYMINFO_UNKFLAG "[0x%x]" # Lc_interface interface tags. @ MSG_CI_NULL "NULL" @ MSG_CI_VERSION "VERSION" @ MSG_CI_ATEXIT "ATEXIT" @ MSG_CI_LCMESSAGES "LCMESSAGES" @ MSG_CI_BIND_GUARD "BIND_GUARD" @ MSG_CI_BIND_CLEAR "BIND_CLEAR" @ MSG_CI_THR_SELF "THR_SELF" @ MSG_CI_TLS_MODADD "TLS_MODADD" @ MSG_CI_TLS_MODREM "TLS_MODREM" @ MSG_CI_TLS_STATMOD "TLS_STATMOD" @ MSG_CI_THRINIT "THRINIT" @ MSG_CI_CRITICAL "CRITICAL" # TLS information flags @ MSG_TLS_FLAG_STATIC "STATIC-TLS" # mmapobj() mr_flags. @ MSG_MR_PADDING "[ PADDING ]" @ MSG_MR_HDR_ELF "[ HDR_ELF ]" # audit originator @ MSG_AUD_PRELOAD "[ LD_AUDIT ]" @ MSG_AUD_GLOBAL "[ GLOBAL AUDIT ]" /* * 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 (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. */ #include "msg.h" #include "_debug.h" #include "libld.h" void Dbg_libs_audit(Lm_list *lml, const char *opath, const char *npath) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; if (npath == opath) return; if (npath == NULL) dbg_print(lml, MSG_INTL(MSG_LIB_SKIP), opath); else dbg_print(lml, MSG_INTL(MSG_LIB_ALTER), npath); } void Dbg_libs_find(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_LIB_FIND), name); } void Dbg_libs_found(Lm_list *lml, const char *path, int alter) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; dbg_print(lml, MSG_INTL(MSG_LIB_TRYING), path, alter ? MSG_INTL(MSG_STR_ALTER) : MSG_ORIG(MSG_STR_EMPTY)); } void Dbg_libs_insecure(Lm_list *lml, const char *path, int usable) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; if (usable) dbg_print(lml, MSG_INTL(MSG_LIB_INUSE), path); else dbg_print(lml, MSG_INTL(MSG_LIB_IGNORE), path); } static void Dbg_lib_dir_print(Lm_list *lml, APlist *libdir) { Aliste idx; char *cp; for (APLIST_TRAVERSE(libdir, idx, cp)) dbg_print(lml, MSG_ORIG(MSG_LIB_FILE), cp); } void Dbg_libs_init(Lm_list *lml, APlist *ulibdir, APlist *dlibdir) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; dbg_print(lml, MSG_INTL(MSG_LIB_INITPATH)); Dbg_lib_dir_print(lml, ulibdir); Dbg_lib_dir_print(lml, dlibdir); } void Dbg_libs_l(Lm_list *lml, const char *name, const char *path) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_LIB_LOPT), name, path); } void Dbg_libs_path(Lm_list *lml, const char *path, uint_t orig, const char *obj) { const char *fmt; uint_t search; if (path == NULL) return; if (DBG_NOTCLASS(DBG_C_LIBS)) return; search = orig & (LA_SER_LIBPATH | LA_SER_RUNPATH | LA_SER_DEFAULT | LA_SER_SECURE); switch (search) { case LA_SER_LIBPATH: if (orig & LA_SER_CONFIG) fmt = MSG_INTL(MSG_LIB_LDLIBPATHC); else fmt = MSG_INTL(MSG_LIB_LDLIBPATH); break; case LA_SER_RUNPATH: fmt = MSG_INTL(MSG_LIB_RUNPATH); break; case LA_SER_DEFAULT: if (orig & LA_SER_CONFIG) fmt = MSG_INTL(MSG_LIB_DEFAULTC); else fmt = MSG_INTL(MSG_LIB_DEFAULT); break; case LA_SER_SECURE: if (orig & LA_SER_CONFIG) fmt = MSG_INTL(MSG_LIB_TDEFAULTC); else fmt = MSG_INTL(MSG_LIB_TDEFAULT); break; default: return; } dbg_print(lml, fmt, path, obj); } void Dbg_libs_req(Lm_list *lml, const char *so_name, const char *ref_file, const char *name) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_LIB_REQUIRED), so_name, name, ref_file); } void Dbg_libs_update(Lm_list *lml, APlist *ulibdir, APlist *dlibdir) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; dbg_print(lml, MSG_INTL(MSG_LIB_UPPATH)); Dbg_lib_dir_print(lml, ulibdir); Dbg_lib_dir_print(lml, dlibdir); } void Dbg_libs_yp(Lm_list *lml, const char *path) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; dbg_print(lml, MSG_INTL(MSG_LIB_LIBPATH), path); } void Dbg_libs_ylu(Lm_list *lml, const char *path, const char *orig, int index) { if (DBG_NOTCLASS(DBG_C_LIBS)) return; dbg_print(lml, MSG_INTL(MSG_LIB_YPATH), path, orig, (index == YLDIR) ? 'L' : 'U'); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include "msg.h" #include "_debug.h" #include "libld.h" /* * Report change in input enable status caused by evaluating * $if/$elif control directives. */ void Dbg_map_pass(Lm_list *lml, Boolean enable, const char *file, Lineno lineno, const char *directive) { const char *fmt; if (DBG_NOTCLASS(DBG_C_MAP)) return; fmt = enable ? MSG_INTL(MSG_MAP_PASS) : MSG_INTL(MSG_MAP_NOPASS); dbg_print(lml, fmt, file, EC_LINENO(lineno), directive); } /* * Report entry/removal of boolean identifier from conditional expression * known values. */ void Dbg_map_cexp_id(Lm_list *lml, Boolean add, const char *file, Lineno lineno, const char *id) { const char *fmt; if (DBG_NOTCLASS(DBG_C_MAP)) return; fmt = add ? MSG_INTL(MSG_MAP_ID_ADD) : MSG_INTL(MSG_MAP_ID_CLEAR); dbg_print(lml, fmt, file, EC_LINENO(lineno), id); } void Dbg_map_version(Lm_list *lml, const char *version, const char *name, int scope) { const char *str, *scp; if (DBG_NOTCLASS(DBG_C_MAP | DBG_C_SYMBOLS)) return; str = MSG_INTL(MSG_MAP_SYM_SCOPE); if (scope) scp = MSG_ORIG(MSG_SYM_GLOBAL); else scp = MSG_ORIG(MSG_SYM_LOCAL); if (version) dbg_print(lml, MSG_INTL(MSG_MAP_SYM_VER_1), str, version, Dbg_demangle_name(name), scp); else dbg_print(lml, MSG_INTL(MSG_MAP_SYM_VER_2), str, Dbg_demangle_name(name), scp); } void Dbg_map_size_new(Lm_list *lml, const char *symname, const char *segname, Lineno lineno) { if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_SYM_SIZE), EC_LINENO(lineno), segname, Dbg_demangle_name(symname), MSG_INTL(MSG_STR_ADDING)); } void Dbg_map_size_old(Ofl_desc *ofl, Sym_desc *sdp, const char *segname, Lineno lineno) { Conv_inv_buf_t inv_buf; Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_SYM_SIZE), EC_LINENO(lineno), segname, sdp->sd_name, MSG_INTL(MSG_STR_UP_1)); if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_INTL(MSG_STR_UP_2), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_map_symbol(Ofl_desc *ofl, Sym_desc *sdp) { Conv_inv_buf_t inv_buf; Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_MAP | DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_INTL(MSG_STR_ENTERED), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } /* * Object version dependency. In the v1 syntax, this is the 'dash' operator. * In the v2 syntax, the DEPEND_VERSIONS directive. */ void Dbg_map_dv(Lm_list *lml, const char *obj_name, Lineno lineno) { if (DBG_NOTCLASS(DBG_C_MAP)) return; dbg_print(lml, MSG_INTL(MSG_MAP_DV), EC_LINENO(lineno), obj_name); } /* * Add a version to an object dependency */ void Dbg_map_dv_entry(Lm_list *lml, Lineno lineno, int require, const char *version) { const char *attr; if (DBG_NOTCLASS(DBG_C_MAP)) return; attr = require ? MSG_INTL(MSG_STR_REQUIRE) : MSG_INTL(MSG_STR_ALLOW); dbg_print(lml, MSG_INTL(MSG_MAP_DV_ENTRY), attr, version, EC_LINENO(lineno)); } void Dbg_map_sort_title(Lm_list *lml, Boolean orig) { if (DBG_NOTCLASS(DBG_C_MAP)) return; if (DBG_NOTDETAIL()) return; if (orig) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_SORT_TITLE)); dbg_print(lml, MSG_INTL(MSG_MAP_SORT_TITLE_O)); } else { dbg_print(lml, MSG_INTL(MSG_MAP_SORT_TITLE_S)); } } void Dbg_map_sort_seg(Lm_list *lml, uchar_t osabi, Half mach, Sg_desc *sgp) { const char *type_str; Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_MAP)) return; if (DBG_NOTDETAIL()) return; type_str = conv_phdr_type(osabi, mach, sgp->sg_phdr.p_type, 0, &inv_buf); if (sgp->sg_name) { if (sgp->sg_flags & FLG_SG_P_VADDR) { dbg_print(lml, MSG_ORIG(MSG_MAP_SORT_SEG_V), type_str, sgp->sg_name, EC_ADDR(sgp->sg_phdr.p_vaddr)); } else if (sgp->sg_flags & FLG_SG_ORDERED) { /* * All FLG_SG_ORDERED have adjacent sg_id values * that start at SGID_TEXT. Subtract out the base * in order to present the order values based at 0. */ dbg_print(lml, MSG_ORIG(MSG_MAP_SORT_SEG_O), type_str, sgp->sg_name, EC_WORD(sgp->sg_id - SGID_TEXT)); } else { dbg_print(lml, MSG_ORIG(MSG_MAP_SORT_SEG_NAME), type_str, sgp->sg_name); } } else { dbg_print(lml, MSG_ORIG(MSG_MAP_SORT_SEG), type_str); } } void Dbg_map_parse(Lm_list *lml, const char *file, int version) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_MAPFILE), file, EC_WORD(version), conv_mapfile_version(version, 0, &inv_buf)); } void Dbg_map_ent(Lm_list *lml, Ent_desc *enp, Ofl_desc *ofl, Lineno lineno) { if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_EC), EC_LINENO(lineno)); Dbg_ent_entry(lml, ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, enp); } void Dbg_map_ent_ord_title(Lm_list *lml, const char *segname) { if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_ENT_ORD_TITLE), segname); } void Dbg_map_seg_os_order(Lm_list *lml, Sg_desc *sgp, const char *sec_name, Word ndx, Lineno lineno) { if (DBG_NOTCLASS(DBG_C_MAP)) return; dbg_print(lml, MSG_INTL(MSG_MAP_OS_ORDER), EC_LINENO(lineno), sgp->sg_name, sec_name, EC_WORD(ndx)); } void Dbg_map_seg(Ofl_desc *ofl, dbg_state_t dbg_state, int ndx, Sg_desc *sgp, Lineno lineno) { Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_SEG), EC_LINENO(lineno), Dbg_state_str(dbg_state)); Dbg_seg_desc_entry(ofl->ofl_lml, ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, ndx, sgp, FALSE); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_map_seg_order(Ofl_desc *ofl, uchar_t osabi, Half mach, dbg_state_t dbg_state, Lineno lineno) { Lm_list *lml = ofl->ofl_lml; Aliste idx; Sg_desc *sgp; Conv_inv_buf_t inv_buf; const char *type_str; if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_SEG_ORDER), EC_LINENO(lineno), EC_XWORD(aplist_nitems(ofl->ofl_segs_order)), Dbg_state_str(dbg_state)); for (APLIST_TRAVERSE(ofl->ofl_segs_order, idx, sgp)) { type_str = conv_phdr_type(osabi, mach, sgp->sg_phdr.p_type, 0, &inv_buf); dbg_print(lml, MSG_ORIG(MSG_MAP_SORT_SEG_NAME), type_str, sgp->sg_name); } Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_map_post_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_POST_TITLE)); } void Dbg_map_hdr_noalloc(Lm_list *lml, Lineno lineno) { if (DBG_NOTCLASS(DBG_C_MAP)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MAP_HDR_NOALLOC), EC_LINENO(lineno)); } # # 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 (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. # # # Generic interface definition for usr/src/cmd/sgs/liblddbg. # # # MAPFILE HEADER START # # WARNING: STOP NOW. DO NOT MODIFY THIS FILE. # Object versioning must comply with the rules detailed in # # usr/src/lib/README.mapfiles # # You should not be making modifications here until you've read the most current # copy of that file. If you need help, contact a gatekeeper for guidance. # # MAPFILE HEADER END # $mapfile_version 2 SYMBOL_VERSION SUNWprivate_4.83 { global: dbg_desc { # interposed - ld.so.1(1) FLAGS = NODIRECT; ASSERT = { TYPE = OBJECT; SIZE = addrsize; }; }; dbg_print { # interposed - ld(1) and ld.so.1(1) FLAGS = NODIRECT; }; Dbg_args_file; Dbg_args_option; Dbg_args_str2chr; Dbg_args_Wldel; Dbg_audit_activity; Dbg_audit_ignore; Dbg_audit_interface; Dbg_audit_lib; Dbg_audit_objclose; Dbg_audit_objfilter; Dbg_audit_objopen; Dbg_audit_objsearch; Dbg_audit_pltenter; Dbg_audit_pltexit; Dbg_audit_preinit; Dbg_audit_symbind; Dbg_audit_skip; Dbg_audit_terminate; Dbg_audit_version; Dbg_basic_collect; Dbg_basic_create; Dbg_basic_files; Dbg_basic_finish; Dbg_basic_options; Dbg_basic_relocate; Dbg_basic_validate; Dbg_help; Dbg_setup; Dbg_state_str; Dbg_version; Dbg32_bind_global; Dbg64_bind_global; Dbg32_bind_plt_summary; Dbg64_bind_plt_summary; Dbg64_bind_pltpad_from; Dbg64_bind_pltpad_to; Dbg32_bind_reject; Dbg64_bind_reject; Dbg32_bind_weak; Dbg64_bind_weak; Dbg32_cap_candidate; Dbg64_cap_candidate; Dbg32_cap_filter; Dbg64_cap_filter; Dbg32_cap_id; Dbg64_cap_id; Dbg32_cap_identical; Dbg64_cap_identical; Dbg32_cap_mapfile_title; Dbg64_cap_mapfile_title; Dbg32_cap_post_title; Dbg64_cap_post_title; Dbg32_cap_ptr_entry; Dbg64_cap_ptr_entry; Dbg32_cap_sec_title; Dbg64_cap_sec_title; Dbg32_cap_val; Dbg64_cap_val; Dbg32_cap_val_entry; Dbg64_cap_val_entry; Dbg32_dl_dladdr; Dbg64_dl_dladdr; Dbg32_dl_dlclose; Dbg64_dl_dlclose; Dbg32_dl_dldump; Dbg64_dl_dldump; Dbg32_dl_dlerror; Dbg64_dl_dlerror; Dbg32_dl_dlinfo; Dbg64_dl_dlinfo; Dbg32_dl_dlopen; Dbg64_dl_dlopen; Dbg32_dl_dlsym; Dbg64_dl_dlsym; Dbg32_dl_iphdr_callback; Dbg64_dl_iphdr_callback; Dbg32_dl_iphdr_enter; Dbg64_dl_iphdr_enter; Dbg32_dl_iphdr_mapchange; Dbg64_dl_iphdr_mapchange; Dbg32_dl_iphdr_unmap_ret; Dbg64_dl_iphdr_unmap_ret; Dbg32_demangle_name; Dbg64_demangle_name; Dbg32_ent_print; Dbg64_ent_print; Dbg32_file_analyze; Dbg64_file_analyze; Dbg32_file_ar; Dbg64_file_ar; Dbg32_file_ar_rescan; Dbg64_file_ar_rescan; Dbg32_file_bind_entry; Dbg64_file_bind_entry; Dbg32_file_bindings; Dbg64_file_bindings; Dbg32_file_bindings_done; Dbg64_file_bindings_done; Dbg32_file_cntl; Dbg64_file_cntl; Dbg32_file_config_dis; Dbg64_file_config_dis; Dbg32_file_config_obj; Dbg64_file_config_obj; Dbg32_file_deferred; Dbg64_file_deferred; Dbg32_file_del_rescan; Dbg64_file_del_rescan; Dbg32_file_delete; Dbg64_file_delete; Dbg32_file_elf; Dbg64_file_elf; Dbg32_file_cleanup; Dbg64_file_cleanup; Dbg32_file_filtee; Dbg64_file_filtee; Dbg32_file_filter; Dbg64_file_filter; Dbg32_file_fixname; Dbg64_file_fixname; Dbg32_file_generic; Dbg64_file_generic; Dbg32_file_hdl_action; Dbg64_file_hdl_action; Dbg32_file_hdl_collect; Dbg64_file_hdl_collect; Dbg32_file_hdl_title; Dbg64_file_hdl_title; Dbg32_file_lazyload; Dbg64_file_lazyload; Dbg32_file_ldso; Dbg64_file_ldso; Dbg32_file_mmapobj; Dbg64_file_mmapobj; Dbg32_file_mode_promote; Dbg64_file_mode_promote; Dbg32_file_modified; Dbg64_file_modified; Dbg32_file_needed; Dbg64_file_needed; Dbg32_file_output; Dbg64_file_output; Dbg32_file_preload; Dbg64_file_preload; Dbg32_file_prot; Dbg64_file_prot; Dbg32_file_rejected; Dbg64_file_rejected; Dbg32_file_reuse; Dbg64_file_reuse; Dbg32_file_skip; Dbg64_file_skip; Dbg32_got_display; Dbg64_got_display; Dbg32_libs_audit; Dbg64_libs_audit; Dbg32_libs_find; Dbg64_libs_find; Dbg32_libs_found; Dbg64_libs_found; Dbg32_libs_insecure; Dbg64_libs_insecure; Dbg32_libs_init; Dbg64_libs_init; Dbg32_libs_l; Dbg64_libs_l; Dbg32_libs_path; Dbg64_libs_path; Dbg32_libs_req; Dbg64_libs_req; Dbg32_libs_update; Dbg64_libs_update; Dbg32_libs_yp; Dbg64_libs_yp; Dbg32_libs_ylu; Dbg64_libs_ylu; Dbg32_map_cexp_id; Dbg64_map_cexp_id; Dbg32_map_dv; Dbg64_map_dv; Dbg32_map_dv_entry; Dbg64_map_dv_entry; Dbg32_map_ent; Dbg64_map_ent; Dbg32_map_ent_ord_title; Dbg64_map_ent_ord_title; Dbg32_map_hdr_noalloc; Dbg64_map_hdr_noalloc; Dbg32_map_parse; Dbg64_map_parse; Dbg32_map_pass; Dbg64_map_pass; Dbg32_map_post_title; Dbg64_map_post_title; Dbg32_map_seg; Dbg64_map_seg; Dbg32_map_seg_order; Dbg64_map_seg_order; Dbg32_map_seg_os_order; Dbg64_map_seg_os_order; Dbg32_map_size_new; Dbg64_map_size_new; Dbg32_map_size_old; Dbg64_map_size_old; Dbg32_map_sort_seg; Dbg64_map_sort_seg; Dbg32_map_sort_title; Dbg64_map_sort_title; Dbg32_map_symbol; Dbg64_map_symbol; Dbg32_map_version; Dbg64_map_version; Dbg32_move_adjexpandreloc; Dbg64_move_adjexpandreloc; Dbg32_move_adjmovereloc; Dbg64_move_adjmovereloc; Dbg32_move_bad; Dbg64_move_bad; Dbg32_move_data; Dbg64_move_data; Dbg32_move_entry1; Dbg64_move_entry1; Dbg32_move_entry2; Dbg64_move_entry2; Dbg32_move_expand; Dbg64_move_expand; Dbg32_move_input; Dbg64_move_input; Dbg32_move_outmove; Dbg64_move_outmove; Dbg32_move_outsctadj; Dbg64_move_outsctadj; Dbg32_move_parexpn; Dbg64_move_parexpn; Dbg32_reloc_apply_reg; Dbg64_reloc_apply_reg; Dbg32_reloc_apply_val; Dbg64_reloc_apply_val; Dbg32_reloc_ars_entry; Dbg64_reloc_ars_entry; Dbg32_reloc_copy; Dbg64_reloc_copy; Dbg32_reloc_discard; Dbg64_reloc_discard; Dbg32_reloc_doact; Dbg64_reloc_doact; Dbg32_reloc_doact_title; Dbg64_reloc_doact_title; Dbg32_reloc_dooutrel; Dbg64_reloc_dooutrel; Dbg32_reloc_entry; Dbg64_reloc_entry; Dbg32_reloc_error; Dbg64_reloc_error; Dbg32_reloc_generate; Dbg64_reloc_generate; Dbg32_reloc_in; Dbg64_reloc_in; Dbg32_reloc_ors_entry; Dbg64_reloc_ors_entry; Dbg32_reloc_out; Dbg64_reloc_out; Dbg32_reloc_proc; Dbg64_reloc_proc; Dbg32_reloc_run; Dbg64_reloc_run; Dbg32_reloc_sloppycomdat; Dbg64_reloc_sloppycomdat; Dbg32_reloc_transition; Dbg64_reloc_transition; Dbg32_sec_added; Dbg64_sec_added; Dbg32_sec_backing; Dbg64_sec_backing; Dbg32_sec_created; Dbg64_sec_created; Dbg32_sec_discarded; Dbg64_sec_discarded; Dbg32_sec_genstr_compress; Dbg64_sec_genstr_compress; Dbg32_sec_group; Dbg64_sec_group; Dbg32_sec_gnu_comdat; Dbg64_sec_gnu_comdat; Dbg32_sec_in; Dbg64_sec_in; Dbg32_sec_order_error; Dbg64_sec_order_error; Dbg32_sec_order_list; Dbg64_sec_order_list; Dbg32_sec_redirected; Dbg64_sec_redirected; Dbg32_sec_strtab; Dbg64_sec_strtab; Dbg32_sec_unsup_strmerge; Dbg64_sec_unsup_strmerge; Dbg32_seg_entry; Dbg64_seg_entry; Dbg32_seg_list; Dbg64_seg_list; Dbg32_seg_os; Dbg64_seg_os; Dbg32_seg_title; Dbg64_seg_title; Dbg32_shdr_modified; Dbg64_shdr_modified; Dbg32_statistics_ar; Dbg64_statistics_ar; Dbg32_statistics_ld; Dbg64_statistics_ld; Dbg32_support_action; Dbg64_support_action; Dbg32_support_load; Dbg64_support_load; Dbg32_support_req; Dbg64_support_req; Dbg32_support_vnone; Dbg64_support_vnone; Dbg32_syminfo_entry; Dbg64_syminfo_entry; Dbg32_syminfo_title; Dbg64_syminfo_title; Dbg32_syms_ar_checking; Dbg64_syms_ar_checking; Dbg32_syms_ar_force; Dbg64_syms_ar_force; Dbg32_syms_ar_resolve; Dbg64_syms_ar_resolve; Dbg32_syms_ar_skip; Dbg64_syms_ar_skip; Dbg32_syms_ar_title; Dbg64_syms_ar_title; Dbg32_syms_cap_convert; Dbg64_syms_cap_convert; Dbg32_syms_cap_local; Dbg64_syms_cap_local; Dbg32_syms_cap_lookup; Dbg64_syms_cap_lookup; Dbg32_syms_cap_title; Dbg64_syms_cap_title; Dbg32_syms_copy_reloc; Dbg64_syms_copy_reloc; Dbg32_syms_created; Dbg64_syms_created; Dbg32_syms_discarded; Dbg64_syms_discarded; Dbg32_syms_dup_discarded; Dbg64_syms_dup_discarded; Dbg32_syms_dup_sort_addr; Dbg64_syms_dup_sort_addr; Dbg32_syms_entered; Dbg64_syms_entered; Dbg32_syms_entry; Dbg64_syms_entry; Dbg32_syms_global; Dbg64_syms_global; Dbg32_syms_ignore; Dbg64_syms_ignore; Dbg32_syms_ignore_gnuver; Dbg64_syms_ignore_gnuver; Dbg32_syms_lazy_rescan; Dbg64_syms_lazy_rescan; Dbg32_syms_lookup; Dbg64_syms_lookup; Dbg32_syms_new; Dbg64_syms_new; Dbg32_syms_old; Dbg64_syms_old; Dbg32_syms_process; Dbg64_syms_process; Dbg32_syms_reduce; Dbg64_syms_reduce; Dbg32_syms_resolved; Dbg64_syms_resolved; Dbg32_syms_resolving; Dbg64_syms_resolving; Dbg32_syms_sec_entry; Dbg64_syms_sec_entry; Dbg32_syms_sec_title; Dbg64_syms_sec_title; Dbg32_syms_spec_title; Dbg64_syms_spec_title; Dbg32_syms_updated; Dbg64_syms_updated; Dbg32_syms_up_title; Dbg64_syms_up_title; Dbg32_syms_wrap; Dbg64_syms_wrap; Dbg_tls_modactivity; Dbg_tls_static_block; Dbg_tls_static_resv; Dbg32_util_call_array; Dbg64_util_call_array; Dbg32_util_call_fini; Dbg64_util_call_fini; Dbg32_util_call_init; Dbg64_util_call_init; Dbg32_util_call_main; Dbg64_util_call_main; Dbg32_util_collect; Dbg64_util_collect; Dbg32_util_dbnotify; Dbg64_util_dbnotify; Dbg32_util_edge_in; Dbg64_util_edge_in; Dbg32_util_edge_out; Dbg64_util_edge_out; Dbg32_util_lcinterface; Dbg64_util_lcinterface; Dbg32_util_intoolate; Dbg64_util_intoolate; Dbg32_util_nl; Dbg64_util_nl; Dbg32_util_scc_entry; Dbg64_util_scc_entry; Dbg32_util_scc_title; Dbg64_util_scc_title; Dbg32_util_str; Dbg64_util_str; Dbg32_unused_file; Dbg64_unused_file; Dbg32_unused_lcinterface; Dbg64_unused_lcinterface; Dbg32_unused_path; Dbg64_unused_path; Dbg32_unused_sec; Dbg64_unused_sec; Dbg32_unused_unref; Dbg64_unused_unref; Dbg32_ver_avail_entry; Dbg64_ver_avail_entry; Dbg32_ver_avail_title; Dbg64_ver_avail_title; Dbg32_ver_def_title; Dbg64_ver_def_title; Dbg32_ver_desc_entry; Dbg64_ver_desc_entry; Dbg32_ver_need_done; Dbg64_ver_need_done; Dbg32_ver_need_entry; Dbg64_ver_need_entry; Dbg32_ver_need_title; Dbg64_ver_need_title; Dbg32_ver_nointerface; Dbg64_ver_nointerface; Dbg32_ver_symbol; Dbg64_ver_symbol; } SUNWprivate_3.23; # The following interfaces are used by various parts of the link-editors and # elfdump(1). The link-editors are always packaged together but there # seems to be a variety of old elfdump's lying around. elfdump only uses # this interface, and thus by separating in from the ever changing Dbg_* # interfaces we can provide a stable versioning environment for this utility. SYMBOL_VERSION SUNWprivate_3.23 { global: Elf_syminfo_entry; Elf_syminfo_title; Elf32_cap_entry; Elf64_cap_entry; Elf32_cap_title; Elf64_cap_title; Elf32_demangle_name; Elf64_demangle_name; Elf32_dyn_entry; Elf64_dyn_entry; Elf32_dyn_null_entry; Elf64_dyn_null_entry; Elf32_dyn_title; Elf64_dyn_title; Elf32_ehdr; Elf64_ehdr; Elf32_got_entry; Elf64_got_entry; Elf32_got_title; Elf64_got_title; Elf32_phdr; Elf64_phdr; Elf32_reloc_apply_reg; Elf64_reloc_apply_reg; Elf32_reloc_apply_val; Elf64_reloc_apply_val; Elf32_reloc_entry_1; Elf64_reloc_entry_1; Elf32_reloc_entry_2; Elf64_reloc_entry_2; Elf32_reloc_title; Elf64_reloc_title; Elf32_shdr; Elf64_shdr; Elf32_syms_table_title; Elf64_syms_table_title; Elf32_syms_table_entry; Elf64_syms_table_entry; Elf32_ver_def_title; Elf64_ver_def_title; Elf32_ver_line_1; Elf64_ver_line_1; Elf32_ver_line_2; Elf64_ver_line_2; Elf32_ver_line_3; Elf64_ver_line_3; Elf32_ver_line_4; Elf64_ver_line_4; Elf32_ver_line_5; Elf64_ver_line_5; Elf32_ver_need_title; Elf64_ver_need_title; local: *; }; /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include "msg.h" #include "_debug.h" #include "libld.h" void Dbg_move_data(Rt_map *lmp) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_MOVE)) return; dbg_print(lml, MSG_INTL(MSG_MOVE_FILE), NAME(lmp)); dbg_print(lml, MSG_INTL(MSG_MOVE_TITLE2)); } void Dbg_move_adjexpandreloc(Lm_list *lml, Xword offset, const char *name) { if (DBG_NOTCLASS(DBG_C_MOVE | DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_MOVE_ADJEXPAND), Dbg_demangle_name(name), EC_XWORD(offset)); } void Dbg_move_adjmovereloc(Lm_list *lml, Xword offset1, Xword offset2, const char *name) { if (DBG_NOTCLASS(DBG_C_MOVE | DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_MOVE_ADJMOVE), Dbg_demangle_name(name), EC_XWORD(offset1), EC_XWORD(offset2)); } void Dbg_move_outsctadj(Lm_list *lml, Sym_desc *sdp) { if (DBG_NOTCLASS(DBG_C_MOVE | DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_MOVE_OUTSCTADJ), Dbg_demangle_name(sdp->sd_name)); } void Dbg_move_parexpn(Lm_list *lml, const char *name, const char *reason) { if (DBG_NOTCLASS(DBG_C_MOVE)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MOVE_PAREXPN), name, reason); dbg_print(lml, MSG_INTL(MSG_MOVE_TITLE1)); } void Dbg_move_outmove(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_MOVE)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MOVE_OUTMOVE), name); dbg_print(lml, MSG_INTL(MSG_MOVE_TITLE1)); } void Dbg_move_expand(Lm_list *lml, Move *mv, Addr addr) { if (DBG_NOTCLASS(DBG_C_MOVE)) return; dbg_print(lml, MSG_INTL(MSG_MOVE_EXPAND), EC_ADDR(addr), EC_LWORD(mv->m_value)); } void Dbg_move_input(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_MOVE)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_MOVE_INPUT), name); dbg_print(lml, MSG_INTL(MSG_MOVE_TITLE1)); } void Dbg_move_entry1(Lm_list *lml, int which, Move *mv, Sym_desc *s) { const char *str; if (DBG_NOTCLASS(DBG_C_MOVE)) return; if (which) str = MSG_INTL(MSG_MOVE_ENTRYIN); else str = MSG_INTL(MSG_MOVE_ENTRYOUT); dbg_print(lml, str, EC_XWORD(mv->m_poffset), ELF_M_SIZE(mv->m_info), mv->m_repeat, mv->m_stride, EC_LWORD(mv->m_value), s->sd_name); } void Dbg_move_entry2(Lm_list *lml, Move *mv, Word st_name, const char *name) { const char *sname; if (DBG_NOTCLASS(DBG_C_MOVE)) return; if (st_name) sname = name; else sname = MSG_INTL(MSG_STR_UNKNOWN); dbg_print(lml, MSG_INTL(MSG_MOVE_ENTRYIN), EC_XWORD(mv->m_poffset), ELF_M_SIZE(mv->m_info), mv->m_repeat, mv->m_stride, EC_LWORD(mv->m_value), sname); } void Dbg_move_bad(Lm_list *lml, ulong_t num, const char *name, Addr addr) { if (DBG_NOTCLASS(DBG_C_MOVE)) return; dbg_print(lml, MSG_INTL(MSG_MOVE_BAD), EC_XWORD(num), name, EC_ADDR(addr)); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include <_debug.h> #include #include void Elf_phdr(Lm_list *lml, uchar_t osabi, Half mach, Phdr *phdr) { Conv_inv_buf_t inv_buf; Conv_phdr_flags_buf_t phdr_flags_buf; dbg_print(lml, MSG_ORIG(MSG_PHD_VADDR), EC_ADDR(phdr->p_vaddr), conv_phdr_flags(osabi, phdr->p_flags, 0, &phdr_flags_buf)); dbg_print(lml, MSG_ORIG(MSG_PHD_PADDR), EC_ADDR(phdr->p_paddr), conv_phdr_type(osabi, mach, phdr->p_type, 0, &inv_buf)); dbg_print(lml, MSG_ORIG(MSG_PHD_FILESZ), EC_XWORD(phdr->p_filesz), EC_XWORD(phdr->p_memsz)); dbg_print(lml, MSG_ORIG(MSG_PHD_OFFSET), EC_OFF(phdr->p_offset), EC_XWORD(phdr->p_align)); } /* * 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 (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. */ #include #include #include #include #include "_debug.h" #include "msg.h" void Dbg_reloc_apply_reg(Lm_list *lml, int caller, Half mach, Xword off, Xword value) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; /* * Print the actual relocation being applied to the specified output * section, the offset represents the actual relocation address, and the * value is the new data being written to that address. */ Elf_reloc_apply_reg(lml, caller, mach, off, value); } void Dbg_reloc_apply_val(Lm_list *lml, int caller, Xword off, Xword value) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; /* * Print the actual relocation being applied to the specified output * section, the offset represents the actual relocation address, and the * value is the new data being written to that address. */ Elf_reloc_apply_val(lml, caller, off, value); } void Dbg_reloc_error(Lm_list *lml, int caller, Half mach, Word type, void *reloc, const char *sname) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; Elf_reloc_entry_1(lml, caller, MSG_INTL(MSG_STR_IN), mach, type, reloc, NULL, sname, MSG_INTL(MSG_REL_BADROFFSET)); } void Dbg_reloc_run(Rt_map *lmp, uint_t rtype, int info, int dtype) { Lm_list *lml = LIST(lmp); const char *str, *name = NAME(lmp); if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (dtype == DBG_REL_FINISH) { if (info) str = MSG_ORIG(MSG_STR_EMPTY); else str = MSG_INTL(MSG_REL_FAIL); } else { if (info) str = MSG_INTL(MSG_REL_PLT); else str = MSG_ORIG(MSG_STR_EMPTY); } if (dtype == DBG_REL_START) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_REL_START), name, str); if (DBG_NOTDETAIL()) return; Elf_reloc_title(lml, ELF_DBG_RTLD, rtype); } else { if (dtype == DBG_REL_NONE) { dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); dbg_print(lml, MSG_INTL(MSG_REL_NONE), name, str); } else dbg_print(lml, MSG_INTL(MSG_REL_FINISH), name, str); Dbg_util_nl(lml, DBG_NL_STD); } } void Dbg_reloc_copy(Rt_map *dlmp, Rt_map *nlmp, const char *name, int zero) { const char *str; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; if (zero) str = MSG_INTL(MSG_STR_COPYZERO); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(LIST(dlmp), MSG_INTL(MSG_REL_COPY), NAME(dlmp), NAME(nlmp), name, str); } void Dbg_reloc_generate(Lm_list *lml, Os_desc *osp, Word type) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_REL_GENERATE), osp->os_name); if (DBG_NOTDETAIL()) return; Elf_reloc_title(lml, ELF_DBG_LD, type); } /* * Issue relocation collecting header message prior to listing * each relocation. * * entry: * lml - Link map control list * osp - If sh_info was non-NULL, output section to which * relocation applies. Otherwise NULL. * isp - If sh_info was non-NULL, input section to which * relocation applies. Otherwise NULL. * risp - Relocation section * * note: osp and isp must both be NULL, or both non-NULL. risp is never NULL. */ void Dbg_reloc_proc(Lm_list *lml, Os_desc *osp, Is_desc *isp, Is_desc *risp) { const char *str1, *str2; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (osp && osp->os_name) str1 = osp->os_name; else str1 = MSG_INTL(MSG_STR_NULL); if (isp && isp->is_file) str2 = isp->is_file->ifl_name; else if (risp && risp->is_file) str2 = risp->is_file->ifl_name; else str2 = MSG_INTL(MSG_STR_NULL); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_REL_COLLECT), str1, str2); if (DBG_NOTDETAIL()) return; Elf_reloc_title(lml, ELF_DBG_LD, risp->is_shdr->sh_type); } void Dbg_reloc_doact_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_REL_ACTIVE)); Elf_reloc_title(lml, ELF_DBG_LD_ACT, 0); } void Dbg_reloc_doact(Lm_list *lml, int caller, Half mach, Word type, Rel_desc *rdesc, Xword off, Xword value, rel_desc_sname_func_t rel_desc_sname_func) { Conv_inv_buf_t inv_buf; const char *secname; Os_desc *osp; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; osp = RELAUX_GET_OSDESC(rdesc); if (osp) { secname = osp->os_name; off += osp->os_shdr->sh_offset; } else secname = MSG_ORIG(MSG_STR_EMPTY); Elf_reloc_entry_2(lml, caller, MSG_ORIG(MSG_STR_EMPTY), type, conv_reloc_type(mach, rdesc->rel_rtype, 0, &inv_buf), off, value, secname, (*rel_desc_sname_func)(rdesc), MSG_ORIG(MSG_STR_EMPTY)); } void Dbg_reloc_dooutrel(Lm_list *lml, Word type) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_REL_CREATING)); Elf_reloc_title(lml, ELF_DBG_LD, type); } void Dbg_reloc_discard(Lm_list *lml, Half mach, Rel_desc *rsp) { dbg_isec_name_buf_t buf; char *alloc_mem; Conv_inv_buf_t inv_buf; Is_desc *isp; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; isp = rsp->rel_isdesc; dbg_print(lml, MSG_INTL(MSG_REL_DISCARDED), dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name, conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf), EC_OFF(rsp->rel_roffset)); if (alloc_mem != NULL) free(alloc_mem); } void Dbg_reloc_transition(Lm_list *lml, Half mach, Word rtype, Rel_desc *rsp, rel_desc_sname_func_t rel_desc_sname_func) { dbg_isec_name_buf_t buf; char *alloc_mem; Conv_inv_buf_t inv_buf1, inv_buf2; Is_desc *isp; if (DBG_NOTCLASS(DBG_C_RELOC)) return; isp = rsp->rel_isdesc; dbg_print(lml, MSG_INTL(MSG_REL_TRANSITION), conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf1), dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name, EC_OFF(rsp->rel_roffset), (*rel_desc_sname_func)(rsp), conv_reloc_type(mach, rtype, 0, &inv_buf2)); if (alloc_mem != NULL) free(alloc_mem); } void Dbg_reloc_out(Ofl_desc *ofl, int caller, Word type, void *reloc, const char *secname, const char *symname) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; Elf_reloc_entry_1(ofl->ofl_lml, caller, MSG_ORIG(MSG_STR_EMPTY), ofl->ofl_dehdr->e_machine, type, reloc, secname, symname, MSG_ORIG(MSG_STR_EMPTY)); } void Dbg_reloc_in(Lm_list *lml, int caller, Half mach, Word type, void *reloc, const char *secname, Word secndx, const char *symname) { dbg_isec_name_buf_t buf; char *alloc_mem; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; Elf_reloc_entry_1(lml, caller, MSG_INTL(MSG_STR_IN), mach, type, reloc, dbg_fmt_isec_name2(secname, secndx, buf, &alloc_mem), symname, MSG_ORIG(MSG_STR_EMPTY)); if (alloc_mem != NULL) free(alloc_mem); } /* * Used by ld when '-z relaxreloc' is in use and a relocation * is redirected to a kept section. * * entry: * lml - Link map control list * sdp - The replacement symbol to be used with the relocation, * which references the kept section. */ void Dbg_reloc_sloppycomdat(Lm_list *lml, Sym_desc *sdp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *nfname; if (DBG_NOTCLASS(DBG_C_RELOC) || DBG_NOTDETAIL()) return; nfname = (sdp && sdp->sd_file && sdp->sd_file->ifl_name) ? sdp->sd_file->ifl_name : MSG_INTL(MSG_STR_NULL); dbg_print(lml, MSG_INTL(MSG_REL_SLOPPYCOMDAT), dbg_fmt_isec_name(sdp->sd_isc, buf, &alloc_mem), nfname); if (alloc_mem != NULL) free(alloc_mem); } /* * Print a output relocation structure (Rel_desc). */ void Dbg_reloc_ors_entry(Lm_list *lml, int caller, Word type, Half mach, Rel_desc *orsp) { Conv_inv_buf_t inv_buf; const char *secname, *symname; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; if (orsp->rel_flags & (FLG_REL_GOT | FLG_REL_RFPTR1 | FLG_REL_RFPTR2)) { secname = MSG_ORIG(MSG_SCN_GOT); } else if (orsp->rel_flags & FLG_REL_PLT) { secname = MSG_ORIG(MSG_SCN_PLT); } else if (orsp->rel_flags & FLG_REL_BSS) { secname = MSG_ORIG(MSG_SCN_BSS); } else { Os_desc *osp = RELAUX_GET_OSDESC(orsp); secname = osp ? osp->os_name : MSG_INTL(MSG_STR_NULL); } /* * Register symbols can be relocated/initialized to a constant, which * is a special case where the symbol index is 0. */ if (orsp->rel_sym != NULL) symname = orsp->rel_sym->sd_name; else symname = MSG_ORIG(MSG_STR_EMPTY); Elf_reloc_entry_2(lml, caller, MSG_INTL(MSG_STR_OUT), type, conv_reloc_type(mach, orsp->rel_rtype, 0, &inv_buf), orsp->rel_roffset, orsp->rel_raddend, secname, symname, MSG_ORIG(MSG_STR_EMPTY)); } /* * Print a Active relocation structure (Rel_desc). */ void Dbg_reloc_ars_entry(Lm_list *lml, int caller, Word type, Half mach, Rel_desc *arsp) { Conv_inv_buf_t inv_buf; const char *secname; if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; if (arsp->rel_flags & (FLG_REL_GOT | FLG_REL_FPTR)) secname = MSG_ORIG(MSG_SCN_GOT); else secname = RELAUX_GET_OSDESC(arsp)->os_name; Elf_reloc_entry_2(lml, caller, MSG_INTL(MSG_STR_ACT), type, conv_reloc_type(mach, arsp->rel_rtype, 0, &inv_buf), arsp->rel_roffset, arsp->rel_raddend, secname, arsp->rel_sym->sd_name, MSG_ORIG(MSG_STR_EMPTY)); } void Dbg_reloc_entry(Lm_list *lml, const char *prestr, Half mach, Word type, void *reloc, const char *secname, const char *symname, const char *poststr) { /* * Register relocations can use a constant initializer, in which case * the associated symbol is 0. */ if (symname == NULL) symname = MSG_ORIG(MSG_STR_EMPTY); Elf_reloc_entry_1(lml, ELF_DBG_LD, prestr, mach, type, reloc, secname, symname, poststr); } #if defined(_ELF64) void Dbg64_pltpad_to(Lm_list *lml, const char *file, Addr pltpad, const char *dfile, const char *symname) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), file, dfile, symname); } void Dbg64_pltpad_from(Lm_list *lml, const char *file, const char *sname, Addr pltpad) { if (DBG_NOTCLASS(DBG_C_RELOC)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), file, Dbg_demangle_name(sname)); } #endif /* * Relocation output can differ depending on the caller and the type of * relocation record. However, the final diagnostic is maintained here so * that the various message strings remain consistent. * * elfdump: * type offset addend section symbol * X X X X X (Rela) * * type offset section symbol * X X X X (Rel) * * Note, it could be argued that the section name output with elfdump(1) is * unnecessary, as the table itself is identified with a title that reveals * the section name. However, the output does provide for grep(1)'ing for * individual entries and obtaining the section name with this type of input. * * ld.so.1: * (prestr) type offset addend symbol * value * in X X X X (Rela) * apply X X * * (prestr) type offset value symbol * in X X X (Rel) * apply X X * * ld: * (prestr) type offset addend section symbol * in X X X X X (Rela) * act X X X X * out X X X X * * (prestr) type offset section symbol * in X X X X (Rel) * act X X X X * out X X X X * * Both Rela and Rel active relocations are printed as: * * type offset value section symbol * X X X X X */ void Elf_reloc_title(Lm_list *lml, int caller, Word type) { if (caller == ELF_DBG_ELFDUMP) { if (type == SHT_RELA) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_EFSA_TITLE)); else dbg_print(lml, MSG_INTL(MSG_REL_EFLA_TITLE)); } else { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_EFSN_TITLE)); else dbg_print(lml, MSG_INTL(MSG_REL_EFLN_TITLE)); } return; } if (caller == ELF_DBG_RTLD) { if (type == SHT_RELA) { dbg_print(lml, MSG_INTL(MSG_REL_RTA_TITLE)); dbg_print(lml, MSG_INTL(MSG_REL_RTV_TITLE)); } else dbg_print(lml, MSG_INTL(MSG_REL_RTN_TITLE)); return; } if (caller == ELF_DBG_LD) { if (type == SHT_RELA) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_LDSA_TITLE)); else dbg_print(lml, MSG_INTL(MSG_REL_LDLA_TITLE)); } else { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_LDSN_TITLE)); else dbg_print(lml, MSG_INTL(MSG_REL_LDLN_TITLE)); } return; } if (caller == ELF_DBG_LD_ACT) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_LDSV_TITLE)); else dbg_print(lml, MSG_INTL(MSG_REL_LDLV_TITLE)); return; } } void Elf_reloc_entry_2(Lm_list *lml, int caller, const char *prestr, Word type, const char *typestr, Addr off, Sxword add, const char *secname, const char *symname, const char *poststr) { if (symname) symname = Elf_demangle_name(symname); else symname = MSG_ORIG(MSG_STR_EMPTY); if (caller == ELF_DBG_ELFDUMP) { if (type == SHT_RELA) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_EFSA_ENTRY), typestr, EC_OFF(off), EC_SXWORD(add), secname, symname); else dbg_print(lml, MSG_INTL(MSG_REL_EFLA_ENTRY), typestr, EC_OFF(off), EC_SXWORD(add), secname, symname); } else { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_EFSN_ENTRY), typestr, EC_OFF(off), secname, symname); else dbg_print(lml, MSG_INTL(MSG_REL_EFLN_ENTRY), typestr, EC_OFF(off), secname, symname); } return; } if (caller == ELF_DBG_RTLD) { if (type == SHT_RELA) dbg_print(lml, MSG_INTL(MSG_REL_RTA_ENTRY), prestr, typestr, EC_OFF(off), EC_SXWORD(add), symname, poststr); else dbg_print(lml, MSG_INTL(MSG_REL_RTN_ENTRY), prestr, typestr, EC_OFF(off), symname, poststr); return; } if (caller == ELF_DBG_LD) { if (type == SHT_RELA) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_LDSA_ENTRY), prestr, typestr, EC_OFF(off), EC_SXWORD(add), secname, symname, poststr); else dbg_print(lml, MSG_INTL(MSG_REL_LDLA_ENTRY), prestr, typestr, EC_OFF(off), EC_SXWORD(add), secname, symname, poststr); } else { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_LDSN_ENTRY), prestr, typestr, EC_OFF(off), secname, symname, poststr); else dbg_print(lml, MSG_INTL(MSG_REL_LDLN_ENTRY), prestr, typestr, EC_OFF(off), secname, symname, poststr); } return; } if (caller == ELF_DBG_LD_ACT) { longlong_t value = EC_SXWORD(add); /* * The following diagnostics are used to create active * relocation output. A "value" field is specified in the * same column as a RELA addend. * * We have to work around an issue caused by the use of a * common format string to handle both the 32-bit and 64-bit * cases. 'add' is a signed value. In the ELFCLASS32 case * where add is a 32-bit value, the EC_SXWORD() macro widens * it to a 64-bit signed value, which will cause sign extension * in the upper 32-bits. As we are displaying the value in hex, * this causes our 32-bit value to be displayed with 16 hex * digits instead of 8, as would be appropriate for ELFCLASS32. * * The solution is to mask off the unwanted bits before * formatting the value. The use of 'longlong_t' instead of * Elf64_Sxword (used by the EC_SXWORD macro) is for the * benefit of lint. */ #if !defined(_ELF64) value &= 0xffffffff; #endif if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_REL_LDSA_ENTRY), prestr, typestr, EC_OFF(off), value, secname, symname, poststr); else dbg_print(lml, MSG_INTL(MSG_REL_LDLA_ENTRY), prestr, typestr, EC_OFF(off), value, secname, symname, poststr); } } void Elf_reloc_entry_1(Lm_list *lml, int caller, const char *prestr, Half mach, Word type, void *reloc, const char *secname, const char *symname, const char *poststr) { Conv_inv_buf_t inv_buf; Addr off; Sxword add; const char *str; if (type == SHT_RELA) { Rela *rela = (Rela *)reloc; str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info, mach), 0, &inv_buf); off = rela->r_offset; add = rela->r_addend; } else { Rel *rel = (Rel *)reloc; str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info, mach), 0, &inv_buf); off = rel->r_offset; add = 0; } Elf_reloc_entry_2(lml, caller, prestr, type, str, off, add, secname, symname, poststr); } /* * Display any applied relocations. Presently, these are only called from * ld.so.1, but the interfaces are maintained here to insure consistency with * other relocation diagnostics. */ void Elf_reloc_apply_val(Lm_list *lml, int caller, Xword offset, Xword value) { if (caller == ELF_DBG_RTLD) dbg_print(lml, MSG_INTL(MSG_REL_RT_APLVAL), EC_XWORD(offset), EC_XWORD(value)); } void Elf_reloc_apply_reg(Lm_list *lml, int caller, Half mach, Xword offset, Xword value) { Conv_inv_buf_t inv_buf; if (caller == ELF_DBG_RTLD) dbg_print(lml, MSG_INTL(MSG_REL_RT_APLREG), conv_sym_value(mach, STT_SPARC_REGISTER, offset, &inv_buf), EC_XWORD(value)); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include "msg.h" #include "_debug.h" #include "libld.h" #include "_string_table.h" /* * Format an input section descriptor name for output, in the format * [ndx]name * If possible, a user supplied fixed size buffer is used. Failing that, * dynamic memory is allocated, which must be freed by the caller. * * entry: * [dbg_fmt_isec_name2]: name, scnndx - Name and section index * [dbg_fmt_isec_name]: isp - Input section descriptor giving name * and index. * * buf - Caller supplied buffer * alloc_mem - Address of pointer to be set to address of allocated * memory, or NULL if no memory is allocated. * * exit: * A pointer to the formatted string is returned. If the supplied buffer * was sufficient, *alloc_mem is set to NULL. If memory was allocated, * *alloc_mem references it. The caller must free this memory after use. */ const char * dbg_fmt_isec_name2(const char *name, Word scnndx, dbg_isec_name_buf_t buf, char **alloc_mem) { int cnt; /* * If the section index is 0, it's not a real section. * Just use the name as is. */ if (scnndx == 0) { *alloc_mem = NULL; return (name); } /* Format into the fixed buffer */ cnt = snprintf(buf, sizeof (dbg_isec_name_buf_t), MSG_ORIG(MSG_FMT_ISEC_NAME), EC_WORD(scnndx), name); /* * If the name was too long, try to allocate a dynamic buffer. * Failing that, fall through and use the clipped one already * formatted into buf, as that's better than nothing. */ if ((cnt >= sizeof (dbg_isec_name_buf_t)) && ((*alloc_mem = malloc(cnt + 1)) != NULL)) { (void) snprintf(*alloc_mem, cnt + 1, MSG_ORIG(MSG_FMT_ISEC_NAME), EC_WORD(scnndx), name); return (*alloc_mem); } /* Return the caller supplied buffer */ *alloc_mem = NULL; return (buf); } const char * dbg_fmt_isec_name(Is_desc *isp, dbg_isec_name_buf_t buf, char **alloc_mem) { return (dbg_fmt_isec_name2(isp->is_name, isp->is_scnndx, buf, alloc_mem)); } void Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp) { uint_t cnt; if (DBG_NOTCLASS(DBG_C_STRTAB)) return; if (!osp) return; Dbg_util_nl(lml, DBG_NL_STD); if (stp->st_flags & FLG_STTAB_COMPRESS) dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_COMP), osp->os_name, EC_XWORD(stp->st_fullstrsize), EC_XWORD(stp->st_strsize)); else dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_STND), osp->os_name, EC_XWORD(stp->st_fullstrsize)); if ((DBG_NOTDETAIL()) || ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)) return; dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_HD), osp->os_name, stp->st_hbckcnt); for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) { Str_hash *strhash = stp->st_hashbcks[cnt]; if (strhash == NULL) continue; dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_BCKT), cnt); while (strhash) { size_t stroff = strhash->hi_mstr->sm_strlen - strhash->hi_strlen; if (stroff == 0) { dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_MSTR), EC_XWORD(strhash->hi_refcnt), strhash->hi_mstr->sm_str); } else { dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_SUFSTR), EC_XWORD(strhash->hi_refcnt), &strhash->hi_mstr->sm_str[stroff], strhash->hi_mstr->sm_str); } strhash = strhash->hi_next; } } } void Dbg_sec_genstr_compress(Lm_list *lml, const char *os_name, Xword raw_size, Xword merge_size) { if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; dbg_print(lml, MSG_INTL(MSG_SEC_GENSTR_COMP), os_name, EC_XWORD(raw_size), EC_XWORD(merge_size)); } void Dbg_sec_unsup_strmerge(Lm_list *lml, Is_desc *isp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *str; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; /* * We can only merge string table sections with single byte * (char) characters. For any other (wide) character types, * issue a message so the user will understand why these * sections are not being picked up. */ if ((isp->is_shdr->sh_entsize > 1) || (isp->is_shdr->sh_addralign > 1)) { str = (isp->is_file != NULL) ? isp->is_file->ifl_name : MSG_INTL(MSG_STR_NULL); dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_UNSUP), dbg_fmt_isec_name(isp, buf, &alloc_mem), str, EC_XWORD(isp->is_shdr->sh_addralign), EC_XWORD(isp->is_shdr->sh_entsize)); if (alloc_mem != NULL) free(alloc_mem); } } void Dbg_sec_backing(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SEC_BACKING)); } void Dbg_sec_in(Lm_list *lml, Is_desc *isp) { if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; if (isp->is_flags & FLG_IS_GNSTRMRG) { /* * This section was generated because we have 1 or * more SHF_MERGE|SHF_STRINGS input sections that we * wish to merge. This new section will ultimately * end up replacing those sections once it has been filled * with their strings (merged and compressed) and relocations * have been redirected. */ dbg_print(lml, MSG_INTL(MSG_SEC_INPUT_GENSTR), isp->is_name); } else if (isp->is_file == NULL) { /* Generated input section */ dbg_print(lml, MSG_INTL(MSG_SEC_INPUT_GEN), isp->is_name); } else { /* Standard input section */ dbg_isec_name_buf_t buf; char *alloc_mem; dbg_print(lml, MSG_INTL(MSG_SEC_INPUT), dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name); if (alloc_mem != NULL) free(alloc_mem); } } void Dbg_sec_added(Lm_list *lml, Os_desc *osp, Sg_desc *sgp) { if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; dbg_print(lml, MSG_INTL(MSG_SEC_ADDED), osp->os_name, (sgp->sg_name ? sgp->sg_name : MSG_INTL(MSG_STR_NULL))); } void Dbg_sec_created(Lm_list *lml, Os_desc *osp, Sg_desc *sgp) { if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; dbg_print(lml, MSG_INTL(MSG_SEC_CREATED), osp->os_name, (sgp->sg_name ? sgp->sg_name : MSG_INTL(MSG_STR_NULL))); } void Dbg_sec_discarded(Lm_list *lml, Is_desc *isp, Is_desc *disp) { if (DBG_NOTCLASS(DBG_C_SECTIONS | DBG_C_UNUSED)) return; if ((isp->is_flags & FLG_IS_INSTRMRG) && (disp->is_flags & FLG_IS_GNSTRMRG)) { /* * This SHF_MERGE|SHF_STRINGS input section is being * discarded in favor of the generated merged string section. */ dbg_isec_name_buf_t buf; char *alloc_mem; dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_DISCARDED), dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name); if (alloc_mem != NULL) free(alloc_mem); } else { /* Generic section discard */ dbg_isec_name_buf_t buf1, buf2; char *alloc_mem1, *alloc_mem2; dbg_print(lml, MSG_INTL(MSG_SEC_DISCARDED), dbg_fmt_isec_name(isp, buf1, &alloc_mem1), isp->is_file->ifl_name, dbg_fmt_isec_name(disp, buf2, &alloc_mem2), disp->is_file->ifl_name); if (alloc_mem1 != NULL) free(alloc_mem1); if (alloc_mem2 != NULL) free(alloc_mem2); } } void Dbg_sec_group(Lm_list *lml, Is_desc *isp, Group_desc *gdp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *comdat, *isp_str; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; if (gdp->gd_data[0] & GRP_COMDAT) comdat = MSG_ORIG(MSG_STR_COMDAT); else comdat = MSG_ORIG(MSG_STR_EMPTY); isp_str = dbg_fmt_isec_name(isp, buf, &alloc_mem); if (isp->is_shdr->sh_type == SHT_GROUP) { dbg_print(lml, MSG_INTL(MSG_SEC_GRP_DEFINE), isp_str, isp->is_file->ifl_name, comdat, gdp->gd_name); } else { dbg_print(lml, MSG_INTL(MSG_SEC_GRP_MEMBER), isp_str, isp->is_file->ifl_name, comdat, gdp->gd_name); } if (gdp->gd_oisc) { dbg_print(lml, MSG_INTL(MSG_SEC_GRP_DISCARDED), isp_str, isp->is_file->ifl_name, gdp->gd_name, gdp->gd_oisc->is_file->ifl_name); } if (alloc_mem != NULL) free(alloc_mem); } void Dbg_sec_order_list(Ofl_desc *ofl, int flag) { Os_desc *osp; Is_desc *isp1; Aliste idx1; Lm_list *lml = ofl->ofl_lml; const char *str; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); /* * If the flag == 0, then the routine is called before sorting. */ if (flag == 0) str = MSG_INTL(MSG_ORD_SORT_BEFORE); else str = MSG_INTL(MSG_ORD_SORT_AFTER); for (APLIST_TRAVERSE(ofl->ofl_ordered, idx1, osp)) { int os_isdescs_idx; Aliste idx2; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, str, osp->os_name); dbg_print(lml, MSG_INTL(MSG_ORD_HDR_1), EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_BEFORE])), EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_ORDERED])), EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_DEFAULT])), EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_AFTER]))); OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx2, isp1) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *isp1_str; Word link; Ifl_desc *ifl = isp1->is_file; Is_desc *isp2; const char *msg; /* * An output segment that requires ordering might have * as little as two sorted input sections. For example, * the crt's can provide a SHN_BEGIN and SHN_AFTER, and * only these two sections must be processed. Thus, if * a input section is unordered, move on. Diagnosing * any unsorted section can produce way too much noise. */ if ((isp1->is_flags & FLG_IS_ORDERED) == 0) continue; if (isp1->is_shdr->sh_flags & SHF_ORDERED) { link = isp1->is_shdr->sh_info; msg = MSG_ORIG(MSG_SH_INFO); } else { /* SHF_LINK_ORDER */ link = isp1->is_shdr->sh_link; msg = MSG_ORIG(MSG_SH_LINK); } isp1_str = dbg_fmt_isec_name(isp1, buf, &alloc_mem); if (link == SHN_BEFORE) { dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_1), msg, isp1_str, isp1->is_file->ifl_name); } else if (link == SHN_AFTER) { dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_2), msg, isp1_str, isp1->is_file->ifl_name); } else { isp2 = ifl->ifl_isdesc[link]; dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_3), EC_WORD(isp2->is_keyident), isp1_str, ifl->ifl_name, msg, isp2->is_name); } if (alloc_mem != NULL) free(alloc_mem); } } Dbg_util_nl(lml, DBG_NL_STD); } /* * Error message string table. */ static const Msg order_errors[] = { MSG_ORD_ERR_INFORANGE, /* MSG_INTL(MSG_ORD_ERR_INFORANGE) */ MSG_ORD_ERR_ORDER, /* MSG_INTL(MSG_ORD_ERR_ORDER) */ MSG_ORD_ERR_LINKRANGE, /* MSG_INTL(MSG_ORD_ERR_LINKRANGE) */ MSG_ORD_ERR_FLAGS, /* MSG_INTL(MSG_ORD_ERR_FLAGS) */ MSG_ORD_ERR_CYCLIC, /* MSG_INTL(MSG_ORD_ERR_CYCLIC) */ MSG_ORD_ERR_LINKINV /* MSG_INTL(MSG_ORD_ERR_LINKINV) */ }; void Dbg_sec_order_error(Lm_list *lml, Ifl_desc *ifl, Word ndx, int error) { dbg_isec_name_buf_t buf; char *alloc_mem; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; if (DBG_NOTDETAIL()) return; if (error == 0) return; dbg_print(lml, MSG_INTL(MSG_ORD_ERR_TITLE), dbg_fmt_isec_name(ifl->ifl_isdesc[ndx], buf, &alloc_mem), ifl->ifl_name); if (alloc_mem != NULL) free(alloc_mem); if (error) dbg_print(lml, MSG_INTL(order_errors[error - 1])); } void Dbg_sec_redirected(Lm_list *lml, Is_desc *isp, const char *nname) { dbg_isec_name_buf_t buf; char *alloc_mem; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; dbg_print(lml, MSG_INTL(MSG_SEC_REDIRECTED), dbg_fmt_isec_name(isp, buf, &alloc_mem), nname); if (alloc_mem != NULL) free(alloc_mem); } void Dbg_sec_gnu_comdat(Lm_list *lml, Is_desc *isp, Boolean comdat, Boolean relax) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *fmt; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; if (comdat && relax) fmt = MSG_INTL(MSG_SEC_GNU_COMDAT_1); else if (comdat) fmt = MSG_INTL(MSG_SEC_GNU_COMDAT_2); else fmt = MSG_INTL(MSG_SEC_GNU_COMDAT_3); dbg_print(lml, fmt, dbg_fmt_isec_name(isp, buf, &alloc_mem)); if (alloc_mem != NULL) free(alloc_mem); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include "msg.h" #include "_debug.h" #include "libld.h" /* * Print out a single `segment descriptor' entry. */ void Dbg_seg_desc_entry(Lm_list *lml, uchar_t osabi, Half mach, int ndx, Sg_desc *sgp, Boolean space_nl) { Conv_seg_flags_buf_t seg_flags_buf; Aliste idx; Sym_desc *sdp; if (space_nl) Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_ORIG(MSG_SEG_DESC), ndx); if (sgp->sg_name) dbg_print(lml, MSG_ORIG(MSG_SEG_NAME), sgp->sg_name); dbg_print(lml, MSG_ORIG(MSG_SEG_FLAGS), conv_seg_flags(sgp->sg_flags, &seg_flags_buf)); Elf_phdr(lml, osabi, mach, &sgp->sg_phdr); if (sgp->sg_flags & FLG_SG_P_ALIGN) dbg_print(lml, MSG_ORIG(MSG_SEG_ALIGN), EC_ADDR(sgp->sg_align)); if (sgp->sg_flags & FLG_SG_LENGTH) dbg_print(lml, MSG_ORIG(MSG_SEG_LENGTH), EC_ADDR(sgp->sg_length)); if (sgp->sg_flags & FLG_SG_ROUND) dbg_print(lml, MSG_ORIG(MSG_SEG_ROUND), EC_ADDR(sgp->sg_round)); if (aplist_nitems(sgp->sg_sizesym) > 0) { dbg_print(lml, MSG_ORIG(MSG_SEG_SIZESYM_TITLE)); for (APLIST_TRAVERSE(sgp->sg_sizesym, idx, sdp)) if (sdp->sd_name) dbg_print(lml, MSG_ORIG(MSG_SEG_SIZESYM), Dbg_demangle_name(sdp->sd_name)); } if (aplist_nitems(sgp->sg_is_order) > 0) { Aliste idx; Ent_desc *enp; dbg_print(lml, MSG_ORIG(MSG_SEG_IS_ORDER_TITLE)); for (APLIST_TRAVERSE(sgp->sg_is_order, idx, enp)) dbg_print(lml, MSG_ORIG(MSG_SEG_LIST_ITEM), enp->ec_name); } if (alist_nitems(sgp->sg_os_order) > 0) { Aliste idx; Sec_order *scop; dbg_print(lml, MSG_ORIG(MSG_SEG_OS_ORDER_TITLE)); for (ALIST_TRAVERSE(sgp->sg_os_order, idx, scop)) dbg_print(lml, MSG_ORIG(MSG_SEG_LIST_ITEM), scop->sco_secname); } if (space_nl) Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_seg_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_SEGMENTS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SEG_DESC_INUSE)); } void Dbg_seg_entry(Ofl_desc *ofl, int ndx, Sg_desc *sgp) { if (DBG_NOTCLASS(DBG_C_SEGMENTS)) return; Dbg_seg_desc_entry(ofl->ofl_lml, ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, ndx, sgp, TRUE); } /* * Print out the available segment descriptors. */ void Dbg_seg_list(Lm_list *lml, uchar_t osabi, Half mach, APlist *apl) { Aliste idx; Sg_desc *sgp; int ndx = 0; if (DBG_NOTCLASS(DBG_C_SEGMENTS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SEG_DESC_AVAIL)); for (APLIST_TRAVERSE(apl, idx, sgp)) Dbg_seg_desc_entry(lml, osabi, mach, ndx++, sgp, TRUE); } /* * Print the output section information. This includes the section header * information and the output elf buffer information. If the detail flag is * set, traverse the input sections displaying all the input buffers that * have been concatenated to form this output buffer. */ void Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx) { Conv_inv_buf_t inv_buf; Lm_list *lml = ofl->ofl_lml; Aliste idx; Is_desc *isp; Elf_Data *data; Shdr *shdr; const char *empty = MSG_ORIG(MSG_STR_EMPTY); int os_isdescs_idx; if (DBG_NOTCLASS(DBG_C_SEGMENTS)) return; dbg_print(lml, MSG_ORIG(MSG_SEC_NAME), ndx, osp->os_name); Elf_shdr(lml, ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, osp->os_shdr); dbg_print(lml, MSG_INTL(MSG_EDATA_TITLE)); shdr = osp->os_shdr; data = osp->os_outdata; dbg_print(lml, MSG_INTL(MSG_EDATA_ENTRY), MSG_INTL(MSG_STR_OUT), EC_ADDR(shdr->sh_addr), conv_elfdata_type(data->d_type, &inv_buf), EC_XWORD(data->d_size), EC_OFF(data->d_off), EC_XWORD(data->d_align), empty, empty, empty); if (DBG_NOTDETAIL()) return; OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx, isp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *file, *str; Addr addr; data = isp->is_indata; if (isp->is_flags & FLG_IS_DISCARD) { str = MSG_INTL(MSG_EDATA_IGNSCN); addr = 0; } else { str = empty; addr = (Addr)(shdr->sh_addr + data->d_off); } if (isp->is_file && isp->is_file->ifl_name) file = isp->is_file->ifl_name; else file = empty; dbg_print(lml, MSG_INTL(MSG_EDATA_ENTRY), MSG_INTL(MSG_STR_IN), EC_ADDR(addr), conv_elfdata_type(data->d_type, &inv_buf), EC_XWORD(data->d_size), EC_OFF(data->d_off), EC_XWORD(data->d_align), file, dbg_fmt_isec_name(isp, buf, &alloc_mem), str); if (alloc_mem != NULL) free(alloc_mem); } } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include <_debug.h> #include #include void Elf_shdr(Lm_list *lml, uchar_t osabi, Half mach, Shdr *shdr) { Conv_inv_buf_t inv_buf1, inv_buf2; Conv_sec_flags_buf_t sec_flags_buf; dbg_print(lml, MSG_ORIG(MSG_SHD_ADDR), EC_ADDR(shdr->sh_addr), conv_sec_flags(osabi, mach, shdr->sh_flags, 0, &sec_flags_buf)); dbg_print(lml, MSG_ORIG(MSG_SHD_SIZE), EC_XWORD(shdr->sh_size), conv_sec_type(osabi, mach, shdr->sh_type, 0, &inv_buf1)); if (shdr->sh_entsize == 0) { dbg_print(lml, MSG_ORIG(MSG_SHD_OFFSET), EC_OFF(shdr->sh_offset), EC_XWORD(shdr->sh_entsize)); } else { /* Provide an entry count */ Xword nelts = shdr->sh_size / shdr->sh_entsize; const char *entstr = (nelts == 1) ? MSG_INTL(MSG_SHD_ENTRY_1) : MSG_INTL(MSG_SHD_ENTRY_N); dbg_print(lml, MSG_ORIG(MSG_SHD_OFFSET_ENT), EC_OFF(shdr->sh_offset), EC_XWORD(shdr->sh_entsize), EC_XWORD(nelts), entstr); } dbg_print(lml, MSG_ORIG(MSG_SHD_LINK), conv_sec_linkinfo(shdr->sh_link, shdr->sh_flags, &inv_buf1), conv_sec_linkinfo(shdr->sh_info, shdr->sh_flags, &inv_buf2)); dbg_print(lml, MSG_ORIG(MSG_SHD_ALIGN), EC_XWORD(shdr->sh_addralign)); } void Dbg_shdr_modified(Lm_list *lml, const char *obj, uchar_t osabi, Half mach, Word ndx, Shdr *oshdr, Shdr *nshdr, const char *name) { dbg_isec_name_buf_t buf; char *alloc_mem; if (DBG_NOTCLASS(DBG_C_SECTIONS | DBG_C_SUPPORT)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SHD_MODIFIED), dbg_fmt_isec_name2(name, ndx, buf, &alloc_mem), obj); if (alloc_mem != NULL) free(alloc_mem); dbg_print(lml, MSG_INTL(MSG_SHD_ORIG)); Elf_shdr(lml, osabi, mach, oshdr); dbg_print(lml, MSG_INTL(MSG_SHD_NEW)); Elf_shdr(lml, osabi, mach, nshdr); Dbg_util_nl(lml, DBG_NL_STD); } /* * 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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ #include #include "_debug.h" #include "msg.h" #include "libld.h" static const char * fmt_human_units(size_t bytes, char *buf, size_t bufsize) { static int unit_arr[] = { 'K', 'M', 'G', 'T' }; int i, unit_ch; size_t unit_bytes = bytes; /* Convert to human readable units */ for (i = 0; i < sizeof (unit_arr) / sizeof (unit_arr[0]); i++) { if (unit_bytes < 1024) break; unit_ch = unit_arr[i]; unit_bytes /= 1024; } if (unit_bytes == bytes) buf[0] = '\0'; else (void) snprintf(buf, bufsize, MSG_ORIG(MSG_FMT_MEMUNIT), EC_XWORD(unit_bytes), unit_ch); return (buf); } /* * Generate a relocation cache statistics line for the active or * output relocation cache. * * entry: * ofl - output file descriptor * alp - One of ofl->ofl_actrels or ofl->ofl_outrels. */ static void rel_cache_statistics(Ofl_desc *ofl, const char *title, APlist *alp) { Lm_list *lml = ofl->ofl_lml; size_t desc_cnt = 0, desc_used = 0, bytes; Aliste idx; Rel_cachebuf *rcp; char unit_buf[CONV_INV_BUFSIZE + 10]; /* Sum the total memory allocated across all the buffers */ for (APLIST_TRAVERSE(alp, idx, rcp)) { desc_cnt += rcp->rc_end - rcp->rc_arr; desc_used += rcp->rc_free - rcp->rc_arr; } bytes = desc_cnt * sizeof (Rel_desc); dbg_print(lml, MSG_INTL(MSG_STATS_REL_CACHE), title, EC_WORD(aplist_nitems(alp)), EC_XWORD(desc_used), EC_XWORD(desc_cnt), (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt), EC_XWORD(bytes), fmt_human_units(bytes, unit_buf, sizeof (unit_buf))); } /* * Generate a statistics line for the auxiliary relocation descriptor cache. * * entry: * ofl - output file descriptor */ static void rel_aux_cache_statistics(Ofl_desc *ofl) { Rel_aux_cachebuf *racp; Lm_list *lml = ofl->ofl_lml; size_t desc_cnt = 0, desc_used = 0, bytes; Aliste idx; char unit_buf[CONV_INV_BUFSIZE + 10]; /* Sum the total memory allocated across all the buffers */ for (APLIST_TRAVERSE(ofl->ofl_relaux, idx, racp)) { desc_cnt += racp->rac_end - racp->rac_arr; desc_used += racp->rac_free - racp->rac_arr; } bytes = desc_cnt * sizeof (Rel_desc); dbg_print(lml, MSG_INTL(MSG_STATS_REL_ACACHE), EC_WORD(aplist_nitems(ofl->ofl_relaux)), EC_XWORD(desc_used), EC_XWORD(desc_cnt), (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt), EC_XWORD(bytes), fmt_human_units(bytes, unit_buf, sizeof (unit_buf))); } void Dbg_statistics_ld(Ofl_desc *ofl) { Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_STATS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_STATS_GENERAL)); if (ofl->ofl_objscnt || ofl->ofl_soscnt || ofl->ofl_arscnt) { dbg_print(lml, MSG_INTL(MSG_STATS_FILES), EC_XWORD(ofl->ofl_objscnt), EC_XWORD(ofl->ofl_soscnt), EC_XWORD(ofl->ofl_arscnt)); } if (ofl->ofl_locscnt || ofl->ofl_globcnt) { dbg_print(lml, MSG_INTL(MSG_STATS_SYMBOLS_OUT), EC_XWORD(ofl->ofl_globcnt), EC_XWORD(ofl->ofl_locscnt)); } if (ofl->ofl_entercnt || ofl->ofl_scopecnt || ofl->ofl_elimcnt) { dbg_print(lml, MSG_INTL(MSG_STATS_SYMBOLS_IN), EC_XWORD(ofl->ofl_entercnt), EC_XWORD(ofl->ofl_scopecnt), EC_XWORD(ofl->ofl_elimcnt)); } dbg_print(lml, MSG_INTL(MSG_STATS_REL_OUT), EC_XWORD(ofl->ofl_outrels.rc_cnt)); dbg_print(lml, MSG_INTL(MSG_STATS_REL_IN), EC_XWORD(ofl->ofl_entrelscnt), EC_XWORD(ofl->ofl_actrels.rc_cnt)); dbg_print(lml, MSG_INTL(MSG_STATS_REL_TICACHE)); rel_cache_statistics(ofl, MSG_INTL(MSG_STATS_REL_TIOUT), ofl->ofl_outrels.rc_list); rel_cache_statistics(ofl, MSG_INTL(MSG_STATS_REL_TIACT), ofl->ofl_actrels.rc_list); rel_aux_cache_statistics(ofl); } void Dbg_statistics_ar(Ofl_desc *ofl) { Aliste idx; Ar_desc *adp; Elf_Arsym *arsym; Ar_aux *aux; Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_STATS | DBG_C_UNUSED)) return; Dbg_util_nl(lml, DBG_NL_STD); for (APLIST_TRAVERSE(ofl->ofl_ars, idx, adp)) { size_t poffset = 0; uint_t count = 0, used = 0; if ((adp->ad_flags & FLG_ARD_EXTRACT) == 0) { Dbg_unused_file(lml, adp->ad_name, 0, 0); continue; } if (DBG_NOTCLASS(DBG_C_STATS)) continue; arsym = adp->ad_start; aux = adp->ad_aux; while ((arsym != NULL) && (arsym->as_off != 0)) { /* * Assume that symbols from the same member file are * adjacent within the archive symbol table. */ if (poffset != arsym->as_off) { count++; poffset = arsym->as_off; if (aux->au_mem == FLG_ARMEM_PROC) used++; } aux++, arsym++; } if ((count == 0) || (used == 0)) continue; dbg_print(lml, MSG_INTL(MSG_STATS_AR), adp->ad_name, count, used, ((used * 100) / count)); } Dbg_util_nl(lml, DBG_NL_STD); } /* * 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. */ #include "msg.h" #include "_debug.h" void Dbg_support_req(Lm_list *lml, const char *define, int flag) { const char *str; if (DBG_NOTCLASS(DBG_C_SUPPORT)) return; switch (flag) { case DBG_SUP_ENVIRON: str = MSG_INTL(MSG_SUP_REQ_ENV); break; case DBG_SUP_CMDLINE: str = MSG_INTL(MSG_SUP_REQ_CMD); break; default: str = MSG_ORIG(MSG_STR_EMPTY); break; } dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); dbg_print(lml, MSG_INTL(MSG_SUP_REQ), define, str); } void Dbg_support_load(Lm_list *lml, const char *obj, const char *func) { if (DBG_NOTCLASS(DBG_C_SUPPORT)) return; dbg_print(lml, MSG_INTL(MSG_SUP_ROUTINE), obj, func); } void Dbg_support_vnone(Lm_list *lml, const char *obj) { if (DBG_NOTCLASS(DBG_C_SUPPORT)) return; dbg_print(lml, MSG_INTL(MSG_SUP_VNONE), obj); } void Dbg_support_action(Lm_list *lml, const char *obj, const char *func, Support_ndx ndx, const char *name) { const char *str; if (DBG_NOTCLASS(DBG_C_SUPPORT)) return; if (DBG_NOTDETAIL()) return; if (ndx == LDS_START) str = MSG_INTL(MSG_SUP_OUTFILE); else if ((ndx == LDS_OPEN) || (ndx == LDS_FILE)) str = MSG_INTL(MSG_SUP_INFILE); else if (ndx == LDS_INSEC) str = MSG_INTL(MSG_SUP_INSEC); else if (ndx == LDS_SEC) str = MSG_INTL(MSG_SUP_SEC); if ((ndx == LDS_ATEXIT) || (ndx == LDS_VERSION) || (ndx == LDS_INPUT_DONE)) dbg_print(lml, MSG_INTL(MSG_SUP_CALLING_1), func, obj); else dbg_print(lml, MSG_INTL(MSG_SUP_CALLING_2), func, obj, str, name); } /* * 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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #include #include #include #include void Elf_syminfo_title(Lm_list *lml) { dbg_print(lml, MSG_INTL(MSG_SYMINFO_TITLE)); } #define FLAGSZ 16 #define NDXSZ 10 void Elf_syminfo_entry(Lm_list *lml, Word ndx, Syminfo *sip, const char *name, const char *needed) { const char *bndstr = NULL, *str; char flagstr[FLAGSZ], sndxstr[NDXSZ], dndxstr[NDXSZ]; int flgndx = 0; Half flags = sip->si_flags; if (flags & SYMINFO_FLG_CAP) { bndstr = MSG_INTL(MSG_SYMINFO_CAP); flagstr[flgndx++] = 'S'; flags &= ~SYMINFO_FLG_CAP; } if (flags & SYMINFO_FLG_DIRECT) { if (bndstr == NULL) { if (sip->si_boundto == SYMINFO_BT_SELF) bndstr = MSG_INTL(MSG_SYMINFO_SELF); else if (sip->si_boundto == SYMINFO_BT_PARENT) bndstr = MSG_INTL(MSG_SYMINFO_PARENT); else bndstr = needed; } flagstr[flgndx++] = 'D'; flags &= ~SYMINFO_FLG_DIRECT; } else if (flags & SYMINFO_FLG_FILTER) { bndstr = needed; flagstr[flgndx++] = 'F'; flags &= ~SYMINFO_FLG_FILTER; } else if (flags & SYMINFO_FLG_AUXILIARY) { bndstr = needed; flagstr[flgndx++] = 'A'; flags &= ~SYMINFO_FLG_AUXILIARY; } else if (sip->si_boundto == SYMINFO_BT_EXTERN) bndstr = MSG_INTL(MSG_SYMINFO_EXTERN); else if (bndstr == NULL) bndstr = MSG_ORIG(MSG_STR_EMPTY); if (flags & SYMINFO_FLG_DIRECTBIND) { flagstr[flgndx++] = 'B'; flags &= ~SYMINFO_FLG_DIRECTBIND; } if (flags & SYMINFO_FLG_COPY) { flagstr[flgndx++] = 'C'; flags &= ~SYMINFO_FLG_COPY; } if (flags & SYMINFO_FLG_LAZYLOAD) { flagstr[flgndx++] = 'L'; flags &= ~SYMINFO_FLG_LAZYLOAD; } if (flags & SYMINFO_FLG_NOEXTDIRECT) { flagstr[flgndx++] = 'N'; flags &= ~SYMINFO_FLG_NOEXTDIRECT; } if (flags & SYMINFO_FLG_INTERPOSE) { flagstr[flgndx++] = 'I'; flags &= ~SYMINFO_FLG_INTERPOSE; } if (flags & SYMINFO_FLG_DEFERRED) { flagstr[flgndx++] = 'P'; flags &= ~SYMINFO_FLG_DEFERRED; } /* * Did we account for all of the flags? */ if (flags) (void) snprintf(&flagstr[flgndx], FLAGSZ - flgndx, MSG_ORIG(MSG_SYMINFO_UNKFLAG), flags); else flagstr[flgndx] = '\0'; /* * If we've bound to a dependency, determine the dynamic entry index. */ if (bndstr == needed) { (void) snprintf(dndxstr, NDXSZ, MSG_ORIG(MSG_FMT_INDEX), sip->si_boundto); str = dndxstr; } else str = MSG_ORIG(MSG_STR_EMPTY); (void) snprintf(sndxstr, NDXSZ, MSG_ORIG(MSG_FMT_INDEX), ndx); dbg_print(lml, MSG_INTL(MSG_SYMINFO_ENTRY), sndxstr, flagstr, str, bndstr, Elf_demangle_name(name)); } /* * 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 (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2022 Oxide Computer Company */ #include #include "msg.h" #include "_debug.h" #include "libld.h" void Dbg_syms_lookup(Rt_map *lmp, const char *name, const char *type) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_LOOKUP), Dbg_demangle_name(name), NAME(lmp), type); } static const Msg captype[DBG_CAP_HW_3 + 1] = { MSG_CAP_SYM_DEFAULT, /* MSG_INTL(MSG_CAP_SYM_DEFAULT) */ MSG_CAP_SYM_USED, /* MSG_INTL(MSG_CAP_SYM_USED) */ MSG_CAP_SYM_CANDIDATE, /* MSG_INTL(MSG_CAP_SYM_CANDIDATE) */ MSG_CAP_SYM_REJECTED, /* MSG_INTL(MSG_CAP_SYM_REJECTED) */ MSG_CAP_SYM_HW_1, /* MSG_INTL(MSG_CAP_SYM_HW_1) */ MSG_CAP_SYM_SF_1, /* MSG_INTL(MSG_CAP_SYM_SF_1) */ MSG_CAP_SYM_HW_2, /* MSG_INTL(MSG_CAP_SYM_HW_2) */ MSG_CAP_SYM_PLAT, /* MSG_INTL(MSG_CAP_SYM_PLAT) */ MSG_CAP_SYM_MACH, /* MSG_INTL(MSG_CAP_SYM_MACH) */ MSG_CAP_SYM_HW_3 /* MSG_INTL(MSG_CAP_SYM_HW_3) */ }; void Dbg_syms_cap_lookup(Rt_map *lmp, uint_t type, const char *name, uint_t ndx, Half mach, Syscapset *scapset) { Lm_list *lml = LIST(lmp); const char *str = NULL; Conv_cap_val_buf_t cap_val_buf; if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_SYMBOLS)) return; switch (type) { case DBG_CAP_HW_1: str = conv_cap_val_hw1(scapset->sc_hw_1, mach, 0, &cap_val_buf.cap_val_hw1_buf); break; case DBG_CAP_SF_1: str = conv_cap_val_sf1(scapset->sc_sf_1, mach, 0, &cap_val_buf.cap_val_sf1_buf); break; case DBG_CAP_HW_2: str = conv_cap_val_hw2(scapset->sc_hw_2, mach, 0, &cap_val_buf.cap_val_hw2_buf); break; case DBG_CAP_MACH: str = scapset->sc_mach; break; case DBG_CAP_PLAT: str = scapset->sc_plat; break; case DBG_CAP_HW_3: str = conv_cap_val_hw3(scapset->sc_hw_3, mach, 0, &cap_val_buf.cap_val_hw3_buf); break; } dbg_print(lml, MSG_INTL(captype[type]), Dbg_demangle_name(name), ndx, str); } void Dbg_syms_ignore_gnuver(Rt_map *lmp, const char *name, Word symndx, Versym verndx) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_IGNGNUVER), Dbg_demangle_name(name), EC_WORD(symndx), EC_HALF(verndx), NAME(lmp)); } void Dbg_syms_lazy_rescan(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_FILES)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_LAZY_RESCAN), Dbg_demangle_name(name)); } void Dbg_syms_ar_title(Lm_list *lml, const char *file, Boolean again) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_AR_FILE), file, again ? MSG_INTL(MSG_STR_AGAIN) : MSG_ORIG(MSG_STR_EMPTY)); } void Dbg_syms_ar_skip(Lm_list *lml, const char *archive, Elf_Arsym *arsym) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_AR_SKIP), archive, Dbg_demangle_name(arsym->as_name)); } void Dbg_syms_ar_checking(Lm_list *lml, const char *fname, const char *objname, Elf_Arsym *arsym) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_AR_CHECK), fname, objname, Dbg_demangle_name(arsym->as_name)); } void Dbg_syms_ar_resolve(Lm_list *lml, const char *fname, const char *objname, Elf_Arsym *arsym) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_AR_RESOLVE), fname, objname, Dbg_demangle_name(arsym->as_name)); } void Dbg_syms_ar_force(Lm_list *lml, const char *fname, const char *objname) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_AR_FORCE), fname, objname); } void Dbg_syms_spec_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_SPECIAL)); } void Dbg_syms_discarded(Lm_list *lml, Sym_desc *sdp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *file; if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_UNUSED)) return; if (DBG_NOTDETAIL()) return; if ((sdp->sd_file == NULL) || ((file = sdp->sd_file->ifl_name) == NULL)) file = MSG_INTL(MSG_STR_UNKNOWN); if (sdp->sd_isc) { dbg_print(lml, MSG_INTL(MSG_SYM_DISCARD_SEC), Dbg_demangle_name(sdp->sd_name), dbg_fmt_isec_name(sdp->sd_isc, buf, &alloc_mem), file); if (alloc_mem != NULL) free(alloc_mem); } else dbg_print(lml, MSG_INTL(MSG_SYM_DISCARD_FILE), Dbg_demangle_name(sdp->sd_name), file); } void Dbg_syms_dup_discarded(Lm_list *lml, Word ndx, Sym_desc *sdp) { const char *file; if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_UNUSED)) return; if (DBG_NOTDETAIL()) return; if ((sdp->sd_file == NULL) || ((file = sdp->sd_file->ifl_name) == NULL)) file = MSG_INTL(MSG_STR_UNKNOWN); dbg_print(lml, MSG_INTL(MSG_SYM_DISCARD_DUP), EC_WORD(ndx), Dbg_demangle_name(sdp->sd_name), file); } void Dbg_syms_entered(Ofl_desc *ofl, Sym *sym, Sym_desc *sdp) { Conv_inv_buf_t inv_buf; Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_INTL(MSG_STR_ENTERED), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_syms_process(Lm_list *lml, Ifl_desc *ifl) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_PROCESS), ifl->ifl_name, conv_ehdr_type(ifl->ifl_ehdr->e_ident[EI_OSABI], ifl->ifl_ehdr->e_type, 0, &inv_buf)); } void Dbg_syms_entry(Lm_list *lml, Word ndx, Sym_desc *sdp) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_BASIC), EC_WORD(ndx), Dbg_demangle_name(sdp->sd_name)); } void Dbg_syms_global(Lm_list *lml, Word ndx, const char *name) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_ADDING), EC_WORD(ndx), Dbg_demangle_name(name)); } void Dbg_syms_cap_convert(Ofl_desc *ofl, Word ndx, const char *name, Sym *sym) { if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_SYMBOLS)) return; dbg_print(ofl->ofl_lml, MSG_INTL(MSG_SYM_CAP_ORIG), EC_WORD(ndx), Dbg_demangle_name(name)); if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_ORIGINAL), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sym, 0, 0, NULL, MSG_ORIG(MSG_STR_EMPTY)); } void Dbg_syms_cap_local(Ofl_desc *ofl, Word ndx, const char *name, Sym *sym, Sym_desc *sdp) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_CAP | DBG_C_SYMBOLS)) return; dbg_print(ofl->ofl_lml, MSG_INTL(MSG_SYM_CAP_LOCAL), EC_WORD(ndx), Dbg_demangle_name(name)); if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_ENTERED), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_syms_wrap(Lm_list *lml, Word ndx, const char *orig_name, const char *name) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_WRAP), EC_WORD(ndx), Dbg_demangle_name(orig_name), Dbg_demangle_name(name)); } void Dbg_syms_sec_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_INDEX)); } void Dbg_syms_sec_entry(Lm_list *lml, Word ndx, Sg_desc *sgp, Os_desc *osp) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_SYM_SECTION), EC_WORD(ndx), osp->os_name, (*sgp->sg_name ? sgp->sg_name : MSG_INTL(MSG_STR_NULL))); } void Dbg_syms_up_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_FINAL)); Elf_syms_table_title(lml, ELF_DBG_LD); } void Dbg_syms_ignore(Ofl_desc *ofl, Sym_desc *sdp) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_IGNORE), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, 0, 0, NULL, MSG_INTL(MSG_STR_UNUSED)); } void Dbg_syms_old(Ofl_desc *ofl, Sym_desc *sdp) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_OLD), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, sdp->sd_name); } void Dbg_syms_new(Ofl_desc *ofl, Sym *sym, Sym_desc *sdp) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_NEW), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_syms_updated(Ofl_desc *ofl, Sym_desc *sdp, const char *name) { Conv_inv_buf_t inv_buf; Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_UPDATE), name); if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_ORIG(MSG_STR_EMPTY), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_syms_created(Lm_list *lml, const char *name) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_CREATE), Dbg_demangle_name(name)); } void Dbg_syms_resolving(Ofl_desc *ofl, Word ndx, const char *name, int row, int col, Sym *osym, Sym *nsym, Sym_desc *sdp, Ifl_desc *ifl) { Lm_list *lml = ofl->ofl_lml; uchar_t osabi = ofl->ofl_dehdr->e_ident[EI_OSABI]; Half mach = ofl->ofl_dehdr->e_machine; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; dbg_print(lml, MSG_INTL(MSG_SYM_RESOLVING), EC_WORD(ndx), Dbg_demangle_name(name), row, col); if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_OLD), osabi, mach, osym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, sdp->sd_file->ifl_name); Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_NEW), osabi, mach, nsym, 0, 0, NULL, ifl->ifl_name); } void Dbg_syms_resolved(Ofl_desc *ofl, Sym_desc *sdp) { Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_RESOLVED), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_syms_copy_reloc(Ofl_desc *ofl, Sym_desc *sdp, Word align) { static Boolean symbol_title = TRUE; Conv_inv_buf_t inv_buf; Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (symbol_title) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_BSS)); symbol_title = FALSE; } /* * Copy relocation symbols come in pairs, the original reference * (within a dependency), and the new destination (within the .bss of * the executable). The latter is accompanied with a computed * alignment. */ if (align) { dbg_print(lml, MSG_INTL(MSG_SYM_COPY_DST), Dbg_demangle_name(sdp->sd_name), EC_WORD(align)); } else { dbg_print(lml, MSG_INTL(MSG_SYM_COPY_REF), Dbg_demangle_name(sdp->sd_name)); } if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_ORIG(MSG_SYM_COPY), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, conv_def_tag(sdp->sd_ref, &inv_buf)); } void Dbg_syms_reduce(Ofl_desc *ofl, int which, Sym_desc *sdp, int idx, const char *sname) { static Boolean sym_reduce_title = TRUE; static Boolean sym_retain_title = TRUE; Boolean isfromglobal = (which == DBG_SYM_REDUCE_GLOBAL); Boolean isfromretain = (which == DBG_SYM_REDUCE_RETAIN); Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_VERSIONS)) return; if (sym_reduce_title && isfromglobal) { sym_reduce_title = FALSE; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_REDUCED)); } else if (sym_retain_title && isfromretain) { sym_retain_title = FALSE; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_RETAINING)); } if ((sdp->sd_flags & FLG_SY_ELIM) && isfromglobal) dbg_print(lml, MSG_INTL(MSG_SYM_ELIMINATING), Dbg_demangle_name(sdp->sd_name)); else if (isfromglobal) dbg_print(lml, MSG_INTL(MSG_SYM_REDUCING), Dbg_demangle_name(sdp->sd_name)); else dbg_print(lml, MSG_INTL(MSG_SYM_NOTELIMINATE), Dbg_demangle_name(sdp->sd_name), sname, idx); if (DBG_NOTDETAIL()) return; Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_ORIG(MSG_SYM_LOCAL), ofl->ofl_dehdr->e_ident[EI_OSABI], ofl->ofl_dehdr->e_machine, sdp->sd_sym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, sdp->sd_file->ifl_name); } void Dbg_syms_dup_sort_addr(Lm_list *lml, const char *secname, const char *symname1, const char *symname2, Addr addr) { if (DBG_NOTCLASS(DBG_C_SYMBOLS) || DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_SYM_DUPSORTADDR), secname, symname1, symname2, EC_ADDR(addr)); } void Dbg_syminfo_title(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYMINFO_INFO)); Elf_syminfo_title(lml); } void Dbg_syminfo_entry(Lm_list *lml, Word ndx, Syminfo *sip, Sym *sym, const char *strtab, Dyn *dyn) { const char *needed; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; if (sip->si_boundto < SYMINFO_BT_LOWRESERVE) needed = strtab + dyn[sip->si_boundto].d_un.d_val; else needed = 0; Elf_syminfo_entry(lml, ndx, sip, Dbg_demangle_name(strtab + sym->st_name), needed); } /* * Symbol table output can differ slightly depending on the caller. However, * the final diagnostic is maintained here so hat the various message strings * remain consistent * * elfdump: index value size type bind oth ver shndx name * ld: value size type bind oth ver shndx */ void Elf_syms_table_title(Lm_list *lml, int caller) { if (caller == ELF_DBG_ELFDUMP) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_SYM_EFS_TITLE)); else dbg_print(lml, MSG_INTL(MSG_SYM_EFL_TITLE)); return; } if (caller == ELF_DBG_LD) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_SYM_LDS_TITLE)); else dbg_print(lml, MSG_INTL(MSG_SYM_LDL_TITLE)); return; } } void Elf_syms_table_entry(Lm_list *lml, int caller, const char *prestr, uchar_t osabi, Half mach, Sym *sym, Versym verndx, int gnuver, const char *sec, const char *poststr) { Conv_inv_buf_t inv_buf1, inv_buf2, inv_buf3; Conv_inv_buf_t inv_buf4, inv_buf5, inv_buf6; uchar_t type = ELF_ST_TYPE(sym->st_info); uchar_t bind = ELF_ST_BIND(sym->st_info); const char *msg; if ((caller == ELF_DBG_ELFDUMP) || (caller == ELF_DBG_LD)) { if (DBG_NOTLONG()) msg = MSG_INTL(MSG_SYM_EFS_ENTRY); else msg = MSG_INTL(MSG_SYM_EFL_ENTRY); if (sec == NULL) sec = conv_sym_shndx(osabi, mach, sym->st_shndx, CONV_FMT_DECIMAL, &inv_buf6); dbg_print(lml, msg, prestr, conv_sym_value(mach, type, sym->st_value, &inv_buf1), sym->st_size, conv_sym_info_type(mach, type, 0, &inv_buf2), conv_sym_info_bind(bind, 0, &inv_buf3), conv_sym_other(sym->st_other, &inv_buf4), conv_ver_index(verndx, gnuver, &inv_buf5), sec, Elf_demangle_name(poststr)); } } void Dbg_syms_cap_title(Ofl_desc *ofl) { Lm_list *lml = ofl->ofl_lml; if (DBG_NOTCLASS(DBG_C_SYMBOLS)) return; if (DBG_NOTDETAIL()) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_CAPABILITIES)); Elf_syms_table_title(lml, ELF_DBG_LD); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include "msg.h" #include "_debug.h" #define FLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ MSG_TLS_FLAG_STATIC_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE static void Dbg_tls_modent(Lm_list *lml, TLS_modinfo * tmodent) { /* * MSG_ORIG(MSG_TLS_FLAG_STATIC) */ static char flagstr[FLAGSZ]; static Val_desc vda[] = { { TM_FLG_STATICTLS, MSG_TLS_FLAG_STATIC }, { 0, 0 } }; static CONV_EXPN_FIELD_ARG conv_arg = { flagstr, sizeof (flagstr) }; ulong_t flags; if ((flags = tmodent->tm_flags) != 0) { conv_arg.oflags = conv_arg.rflags = flags; (void) conv_expn_field(&conv_arg, vda, 0); } else { flagstr[0] = '\0'; } dbg_print(lml, MSG_INTL(MSG_TLS_MODENT1), EC_XWORD((uintptr_t)tmodent->tm_tlsblock), EC_XWORD(tmodent->tm_stattlsoffset), EC_XWORD(tmodent->tm_flags), flagstr); dbg_print(lml, MSG_INTL(MSG_TLS_MODENT2), EC_XWORD(tmodent->tm_filesz), EC_XWORD(tmodent->tm_memsz), EC_XWORD(tmodent->tm_modid)); } void Dbg_tls_static_block(Lm_list *lml, void *list, ulong_t size, ulong_t resv) { if (DBG_NOTCLASS(DBG_C_TLS)) return; Dbg_util_nl(lml, DBG_NL_STD); if (list) { ulong_t ndx; TLS_modinfo **tlsmodlist; tlsmodlist = (TLS_modinfo **)list; for (ndx = 0; tlsmodlist[ndx]; ndx++) { dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK1), ndx, tlsmodlist[ndx]->tm_modname); Dbg_tls_modent(lml, tlsmodlist[ndx]); Dbg_util_nl(lml, DBG_NL_STD); } } dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK2), EC_XWORD(size), EC_XWORD(resv)); } void Dbg_tls_static_resv(Rt_map *lmp, ulong_t size, ulong_t resv) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_TLS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK3), TLSMODID(lmp), NAME(lmp), EC_XWORD(size), EC_XWORD(resv)); } void Dbg_tls_modactivity(Lm_list *lml, void *vtlsmodent, uint_t flag) { const char *str; TLS_modinfo *tlsmodent; if (DBG_NOTCLASS(DBG_C_TLS)) return; if (flag == TM_FLG_MODADD) str = MSG_INTL(MSG_TLS_ADD); else str = MSG_INTL(MSG_TLS_REMOVE); tlsmodent = (TLS_modinfo *)vtlsmodent; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_TLS_MODACT), str, tlsmodent->tm_modname); Dbg_tls_modent(lml, tlsmodent); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include "msg.h" #include "_debug.h" #include "libld.h" void Dbg_unused_unref(Rt_map *lmp, const char *depend) { if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (DBG_NOTDETAIL()) return; dbg_print(LIST(lmp), MSG_INTL(MSG_USD_UNREF), NAME(lmp), depend); } void Dbg_unused_sec(Lm_list *lml, Is_desc *isp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *str; if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (DBG_NOTDETAIL()) return; /* * If the file from which this section originates hasn't been referenced * at all, skip this diagnostic, as it would have been covered under * Dbg_unused_file() called from ignore_section_processing(). */ if (isp->is_file && ((isp->is_file->ifl_flags & FLG_IF_FILEREF) == 0)) return; if (isp->is_flags & FLG_IS_DISCARD) str = MSG_INTL(MSG_USD_SECDISCARD); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_USD_SEC), dbg_fmt_isec_name(isp, buf, &alloc_mem), EC_XWORD(isp->is_shdr->sh_size), isp->is_file->ifl_name, str); if (alloc_mem != NULL) free(alloc_mem); } void Dbg_unused_file(Lm_list *lml, const char *name, int needstr, uint_t cycle) { if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (needstr) dbg_print(lml, MSG_INTL(MSG_USD_NEEDSTR), name); else if (cycle) dbg_print(lml, MSG_INTL(MSG_USD_FILECYCLIC), name, cycle); else dbg_print(lml, MSG_INTL(MSG_USD_FILE), name); } void Dbg_unused_path(Lm_list *lml, const char *path, uint_t orig, uint_t dup, const char *obj) { const char *fmt; if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (DBG_NOTDETAIL()) return; if (orig & LA_SER_LIBPATH) { if (orig & LA_SER_CONFIG) { if (dup) fmt = MSG_INTL(MSG_DUP_LDLIBPATHC); else fmt = MSG_INTL(MSG_USD_LDLIBPATHC); } else { if (dup) fmt = MSG_INTL(MSG_DUP_LDLIBPATH); else fmt = MSG_INTL(MSG_USD_LDLIBPATH); } } else if (orig & LA_SER_RUNPATH) { fmt = MSG_INTL(MSG_USD_RUNPATH); } else return; dbg_print(lml, fmt, path, obj); } /* * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2018 Jason King */ #include "msg.h" #include "_debug.h" #include "libld.h" /* * If any run-time linker debugging is being carried out always indicate the * fact and specify the point at which we transfer control to the main program. */ void Dbg_util_call_main(Rt_map *lmp) { Lm_list *lml = LIST(lmp); Dbg_util_nl(lml, DBG_NL_FRC); dbg_print(lml, MSG_INTL(MSG_UTL_TRANS), NAME(lmp)); Dbg_util_nl(lml, DBG_NL_FRC); } void Dbg_util_call_init(Rt_map *lmp, int flag) { Lm_list *lml = LIST(lmp); const char *str; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (flag == DBG_INIT_SORT) str = MSG_INTL(MSG_UTL_SORT); else if (flag == DBG_INIT_PEND) str = MSG_INTL(MSG_UTL_PEND); else if (flag == DBG_INIT_DYN) str = MSG_INTL(MSG_UTL_DYN); else str = MSG_INTL(MSG_UTL_DONE); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_UTL_INIT), str, NAME(lmp)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_util_intoolate(Rt_map *lmp) { Lm_list *lml = LIST(lmp); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_UTL_INTOOLATE), NAME(lmp)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_util_dbnotify(Lm_list *lml, rd_event_e event, r_state_e state) { const char *estr; const char *sstr; if (DBG_NOTCLASS(DBG_C_FILES)) return; if (DBG_NOTDETAIL()) return; switch (event) { case RD_PREINIT: estr = MSG_ORIG(MSG_UTL_EVNT_PREINIT); sstr = MSG_INTL(MSG_STR_NULL); break; case RD_POSTINIT: estr = MSG_ORIG(MSG_UTL_EVNT_POSTINIT); sstr = MSG_INTL(MSG_STR_NULL); break; case RD_DLACTIVITY: estr = MSG_ORIG(MSG_UTL_EVNT_DLACT); switch (state) { case RT_CONSISTENT: sstr = MSG_ORIG(MSG_UTL_STA_CONSIST); break; case RT_ADD: sstr = MSG_ORIG(MSG_UTL_STA_ADD); break; case RT_DELETE: sstr = MSG_ORIG(MSG_UTL_STA_DELETE); break; default: sstr = MSG_INTL(MSG_STR_NULL); break; } break; default: sstr = MSG_INTL(MSG_STR_NULL); estr = MSG_INTL(MSG_STR_UNKNOWN); break; } Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_UTL_DBNOTIFY), estr, sstr); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_util_call_array(Rt_map *lmp, void *addr, int ndx, Word shtype) { Lm_list *lml = LIST(lmp); const char *str; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (shtype == SHT_INIT_ARRAY) str = MSG_ORIG(MSG_SCN_INITARRAY); else if (shtype == SHT_FINI_ARRAY) str = MSG_ORIG(MSG_SCN_FINIARRAY); else str = MSG_ORIG(MSG_SCN_PREINITARRAY); dbg_print(lml, MSG_INTL(MSG_UTL_ARRAY), str, ndx, EC_NATPTR(addr), NAME(lmp)); } void Dbg_util_call_fini(Rt_map *lmp) { Lm_list *lml = LIST(lmp); if (DBG_NOTCLASS(DBG_C_INIT)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_UTL_FINI), NAME(lmp)); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_util_str(Lm_list *lml, const char *str) { Dbg_util_nl(lml, DBG_NL_STD); Dbg_util_nl(lml, DBG_NL_FRC); dbg_print(lml, MSG_ORIG(MSG_FMT_STR), str); Dbg_util_nl(lml, DBG_NL_FRC); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_util_scc_title(Lm_list *lml, int sec) { const char *_sec; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; if (sec) _sec = MSG_INTL(MSG_UTL_SCC_SUBI); else _sec = MSG_INTL(MSG_UTL_SCC_SUBF); Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_UTL_SCC_TITLE), _sec); } void Dbg_util_scc_entry(Rt_map *lmp, uint_t idx) { if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp)); } static int ectoggle = 0; void Dbg_util_edge_in(Lm_list *lml, Rt_map *clmp, uint_t flags, Rt_map *dlmp, int ndx, int flag) { Conv_bnd_type_buf_t bnd_type_buf; const char *str; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; if (flag & RT_SORT_REV) str = MSG_ORIG(MSG_SCN_INIT); else str = MSG_ORIG(MSG_SCN_FINI); if ((clmp == 0) || (ectoggle == 0)) Dbg_util_nl(lml, DBG_NL_STD); if (clmp == 0) { if (flag & RT_SORT_INTPOSE) dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_I), str); else dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_S), str); dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_START), ndx, NAME(dlmp)); } else dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_IN), ndx, NAME(dlmp), NAME(clmp), conv_bnd_type(flags, &bnd_type_buf)); ectoggle = 1; } void Dbg_util_edge_out(Rt_map *clmp, Rt_map *dlmp) { if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; dbg_print(LIST(clmp), MSG_INTL(MSG_UTL_EDGE_OUT), SORTVAL(clmp), NAME(clmp), NAME(dlmp)); } void Dbg_util_collect(Rt_map *lmp, int ndx, int flag) { Lm_list *lml = LIST(lmp); const char *str; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; if (flag & RT_SORT_REV) str = MSG_ORIG(MSG_SCN_INIT); else str = MSG_ORIG(MSG_SCN_FINI); if (ectoggle == 1) { Dbg_util_nl(lml, DBG_NL_STD); ectoggle = 0; } dbg_print(lml, MSG_INTL(MSG_UTL_COLLECT), ndx, NAME(lmp), str); } static const Msg tags[] = { MSG_CI_NULL, /* MSG_ORIG(MSG_CI_NULL) */ MSG_CI_VERSION, /* MSG_ORIG(MSG_CI_VERSION) */ MSG_CI_ATEXIT, /* MSG_ORIG(MSG_CI_ATEXIT) */ MSG_CI_LCMESSAGES, /* MSG_ORIG(MSG_CI_LCMESSAGES) */ MSG_CI_BIND_GUARD, /* MSG_ORIG(MSG_CI_BIND_GUARD) */ MSG_CI_BIND_CLEAR, /* MSG_ORIG(MSG_CI_BIND_CLEAR) */ MSG_CI_THR_SELF, /* MSG_ORIG(MSG_CI_THR_SELF) */ MSG_CI_TLS_MODADD, /* MSG_ORIG(MSG_CI_TLS_MODADD) */ MSG_CI_TLS_MODREM, /* MSG_ORIG(MSG_CI_TLS_MODREM) */ MSG_CI_TLS_STATMOD, /* MSG_ORIG(MSG_CI_TLS_STATMOD) */ MSG_CI_THRINIT, /* MSG_ORIG(MSG_CI_THRINIT) */ MSG_CI_CRITICAL /* MSG_ORIG(MSG_CI_CRITICAL) */ }; void Dbg_util_lcinterface(Rt_map *lmp, int tag, char *val) { const char *str; Conv_inv_buf_t inv_buf; if (DBG_NOTDETAIL()) return; if (tag < CI_MAX) str = MSG_ORIG(tags[tag]); else str = conv_invalid_val(&inv_buf, tag, 0); dbg_print(LIST(lmp), MSG_INTL(MSG_UTL_LCINTERFACE), NAME(lmp), str, EC_NATPTR(val)); } void Dbg_unused_lcinterface(Rt_map *nlmp, Rt_map *olmp, int tag) { const char *str; Conv_inv_buf_t inv_buf; if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (tag < CI_MAX) str = MSG_ORIG(tags[tag]); else str = conv_invalid_val(&inv_buf, tag, 0); dbg_print(LIST(nlmp), MSG_INTL(MSG_USD_LCINTERFACE), NAME(nlmp), str, NAME(olmp)); } /* * Generic new line generator. To prevent multiple newlines from being * generated, a flag is maintained in the global debug descriptor. This flag * is cleared by the callers dbg_print() function to indicate that a newline * (actually, any line) has been printed. Multiple newlines can be generated * using the DBG_NL_FRC flag. */ void Dbg_util_nl(Lm_list *lml, int flag) { if ((flag == DBG_NL_STD) && (dbg_desc->d_extra & DBG_E_STDNL)) return; dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); if (flag == DBG_NL_STD) dbg_desc->d_extra |= DBG_E_STDNL; } /* * Define name demanglers. */ const char * Dbg_demangle_name(const char *name) { static char *buf = NULL; if (DBG_NOTCLASS(DBG_C_DEMANGLE)) return (name); free(buf); buf = (char *)conv_demangle_name(name); if (buf == name) { buf = NULL; return (name); } return (buf); } const char * Elf_demangle_name(const char *name) { static char *buf = NULL; if (!DBG_ISDEMANGLE()) return (name); free(buf); buf = (char *)conv_demangle_name(name); if (buf == name) { buf = NULL; return (name); } return (buf); } /* * 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 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include "msg.h" #include "_debug.h" void Dbg_ver_avail_title(Lm_list *lml, const char *file) { if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_VER_AVAIL_1), file); dbg_print(lml, MSG_INTL(MSG_VER_AVAIL_2)); } void Dbg_ver_def_title(Lm_list *lml, const char *file) { if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_VER_DEF_TITLE), file); Elf_ver_def_title(lml); } void Dbg_ver_need_title(Lm_list *lml, const char *file) { if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_VER_NEED_TITLE), file); Elf_ver_need_title(lml, 0); } void Dbg_ver_need_entry(Lm_list *lml, Half cnt, const char *file, const char *version) { if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; if (cnt) Elf_ver_line_4(lml, version); else Elf_ver_line_5(lml, file, version); } void Dbg_ver_symbol(Lm_list *lml, const char *name) { static Boolean ver_symbol_title = TRUE; if (DBG_NOTCLASS(DBG_C_VERSIONS | DBG_C_SYMBOLS)) return; if (DBG_NOTCLASS(DBG_C_VERSIONS)) if (ver_symbol_title) { ver_symbol_title = FALSE; Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_SYM_VERSION)); } Dbg_syms_created(lml, name); } /* * This function doesn't test for any specific debugging category, thus it will * be generated for any debugging family. */ void Dbg_ver_nointerface(Lm_list *lml, const char *name) { Dbg_util_nl(lml, DBG_NL_STD); dbg_print(lml, MSG_INTL(MSG_VER_NOINTERFACE), name); Dbg_util_nl(lml, DBG_NL_STD); } void Dbg_ver_desc_entry(Lm_list *lml, Ver_desc *vdp) { Conv_ver_flags_buf_t ver_flags_buf; const char *dep; Ver_desc *_vdp, *__vdp; Aliste idx; char index[10]; if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; if (vdp->vd_deps) { _vdp = (Ver_desc *)vdp->vd_deps->apl_data[0]; dep = _vdp->vd_name; } else { _vdp = 0; dep = MSG_ORIG(MSG_STR_EMPTY); } (void) sprintf(index, MSG_ORIG(MSG_FMT_INDEX), vdp->vd_ndx); Elf_ver_line_1(lml, index, vdp->vd_name, dep, conv_ver_flags(vdp->vd_flags, 0, &ver_flags_buf)); /* * Loop through the dependency list in case there are more that one * dependency. */ for (APLIST_TRAVERSE(vdp->vd_deps, idx, __vdp)) { if (_vdp == __vdp) continue; Elf_ver_line_4(lml, __vdp->vd_name); } } void Dbg_ver_avail_entry(Lm_list *lml, Ver_index *vip, const char *select) { if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; if (select) { if (DBG_NOTLONG()) dbg_print(lml, MSG_ORIG(MSG_VER_SELECTED), vip->vi_name, select); else dbg_print(lml, MSG_ORIG(MSG_VER_L_SELECTED), vip->vi_name, select); } else { if (DBG_NOTLONG()) dbg_print(lml, MSG_ORIG(MSG_VER_ALL), vip->vi_name); else dbg_print(lml, MSG_ORIG(MSG_VER_L_ALL), vip->vi_name); } } void Elf_ver_def_title(Lm_list *lml) { dbg_print(lml, MSG_INTL(MSG_VER_DEF)); } /* * entry: * gnuver - If True (non-zero), the version rules used by the * GNU ld are assumed. If False (0), Solaris ld rules apply. */ void Elf_ver_need_title(Lm_list *lml, int gnuver) { if (gnuver) dbg_print(lml, MSG_INTL(MSG_VER_NEED_GNUVER)); else dbg_print(lml, MSG_INTL(MSG_VER_NEED)); } void Elf_ver_line_1(Lm_list *lml, const char *index, const char *name, const char *dep, const char *flags) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_VER_LINE_1), index, name, dep, flags); else dbg_print(lml, MSG_INTL(MSG_VER_LLINE_1), index, name, dep, flags); } void Elf_ver_line_2(Lm_list *lml, const char *name, const char *dep) { dbg_print(lml, MSG_INTL(MSG_VER_LINE_2), name, dep); } void Elf_ver_line_3(Lm_list *lml, const char *name, const char *dep, const char *flags) { dbg_print(lml, MSG_INTL(MSG_VER_LINE_3), name, dep, flags); } void Elf_ver_line_4(Lm_list *lml, const char *version) { dbg_print(lml, MSG_INTL(MSG_VER_LINE_4), version); } void Elf_ver_line_5(Lm_list *lml, const char *file, const char *version) { if (DBG_NOTLONG()) dbg_print(lml, MSG_INTL(MSG_VER_LINE_5), file, version); else dbg_print(lml, MSG_INTL(MSG_VER_LLINE_5), file, version); } /* * Called after final call to Dbg_ver_need() to inject final newline. */ void Dbg_ver_need_done(Lm_list *lml) { if (DBG_NOTCLASS(DBG_C_VERSIONS)) return; Dbg_util_nl(lml, DBG_NL_STD); }