summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorAli Bahrami <Ali.Bahrami@Sun.COM>2009-04-21 11:20:53 -0600
committerAli Bahrami <Ali.Bahrami@Sun.COM>2009-04-21 11:20:53 -0600
commite23c41c9edb2294649cde3d370ae755701f3f140 (patch)
tree60c791b2cccd65e5882b1936197d8de62d9632d7 /usr/src
parent14c261629a73309414a52b47437be9e4a39d037b (diff)
downloadillumos-gate-e23c41c9edb2294649cde3d370ae755701f3f140.tar.gz
6831285 linker LD_DEBUG support needs improvements
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.c511
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.msg16
-rw-r--r--usr/src/cmd/sgs/include/conv.h14
-rw-r--r--usr/src/cmd/sgs/include/debug.h52
-rw-r--r--usr/src/cmd/sgs/include/libld.h3
-rw-r--r--usr/src/cmd/sgs/libconv/Makefile.com6
-rw-r--r--usr/src/cmd/sgs/libconv/common/globals.c5
-rw-r--r--usr/src/cmd/sgs/libconv/common/globals_machelf.c1
-rw-r--r--usr/src/cmd/sgs/libconv/common/llib-lconv4
-rw-r--r--usr/src/cmd/sgs/libconv/common/strproc.c146
-rw-r--r--usr/src/cmd/sgs/libld/common/_libld.h7
-rw-r--r--usr/src/cmd/sgs/libld/common/args.c18
-rw-r--r--usr/src/cmd/sgs/libld/common/debug.c84
-rw-r--r--usr/src/cmd/sgs/libld/common/entry.c34
-rw-r--r--usr/src/cmd/sgs/libld/common/exit.c9
-rw-r--r--usr/src/cmd/sgs/libld/common/files.c3
-rw-r--r--usr/src/cmd/sgs/libld/common/ldmain.c5
-rw-r--r--usr/src/cmd/sgs/libld/common/libld.msg12
-rw-r--r--usr/src/cmd/sgs/libld/common/order.c46
-rw-r--r--usr/src/cmd/sgs/libld/common/place.c23
-rw-r--r--usr/src/cmd/sgs/libld/common/relocate.c16
-rw-r--r--usr/src/cmd/sgs/libld/common/sections.c2
-rw-r--r--usr/src/cmd/sgs/libld/common/support.c3
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/_debug.h70
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/debug.c505
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/liblddbg.msg652
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/llib-llddbg19
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/mapfile-vers3
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/relocate.c60
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/sections.c208
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/segments.c19
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/shdr.c10
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/syms.c10
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/unused.c11
-rw-r--r--usr/src/cmd/sgs/packages/Makefile.com6
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
-rw-r--r--usr/src/cmd/sgs/packages/common/admin45
-rw-r--r--usr/src/cmd/sgs/packages/common/checkinstall20
-rw-r--r--usr/src/cmd/sgs/packages/sparcv9/Makefile70
-rw-r--r--usr/src/cmd/sgs/packages/sparcv9/pkginfo.tmpl45
-rw-r--r--usr/src/cmd/sgs/packages/sparcv9/postremove53
-rw-r--r--usr/src/cmd/sgs/packages/sparcv9/preinstall50
-rw-r--r--usr/src/cmd/sgs/packages/sparcv9/prototype64
-rw-r--r--usr/src/cmd/sgs/rtld/amd64/amd64_elf.c2
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h2
-rw-r--r--usr/src/cmd/sgs/rtld/common/debug.c119
-rw-r--r--usr/src/cmd/sgs/rtld/common/elf.c6
-rw-r--r--usr/src/cmd/sgs/rtld/common/setup.c6
-rw-r--r--usr/src/cmd/sgs/rtld/common/util.c3
-rw-r--r--usr/src/cmd/sgs/rtld/i386/i386_elf.c4
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_elf.c2
-rw-r--r--usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c2
52 files changed, 2017 insertions, 1070 deletions
diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.c b/usr/src/cmd/sgs/elfdump/common/elfdump.c
index 454b256d2b..bfca5d7bdf 100644
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.c
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c
@@ -27,6 +27,7 @@
/*
* Dump an elf file.
*/
+#include <stddef.h>
#include <sys/elf_386.h>
#include <sys/elf_amd64.h>
#include <sys/elf_SPARC.h>
@@ -132,7 +133,59 @@ typedef struct {
Word symn; /* # of symbols */
} SYMTBL_STATE;
+/*
+ * A variable of this type is used to track information related to
+ * .eh_frame and .eh_frame_hdr sections across calls to unwind_eh_frame().
+ */
+typedef struct {
+ Word frame_cnt; /* # .eh_frame sections seen */
+ Word frame_ndx; /* Section index of 1st .eh_frame */
+ Word hdr_cnt; /* # .eh_frame_hdr sections seen */
+ Word hdr_ndx; /* Section index of 1st .eh_frame_hdr */
+ uint64_t frame_ptr; /* Value of FramePtr field from first */
+ /* .eh_frame_hdr section */
+ uint64_t frame_base; /* Data addr of 1st .eh_frame */
+} gnu_eh_state_t;
+
+/*
+ * C++ .exception_ranges entries make use of the signed ptrdiff_t
+ * type to record self-relative pointer values. We need a type
+ * for this that is matched to the ELFCLASS being processed.
+ */
+#if defined(_ELF64)
+ typedef int64_t PTRDIFF_T;
+#else
+ typedef int32_t PTRDIFF_T;
+#endif
+/*
+ * The Sun C++ ABI uses this struct to define each .exception_ranges
+ * entry. From the ABI:
+ *
+ * The field ret_addr is a self relative pointer to the start of the address
+ * range. The name was chosen because in the current implementation the range
+ * typically starts at the return address for a call site.
+ *
+ * The field length is the difference, in bytes, between the pc of the last
+ * instruction covered by the exception range and the first. When only a
+ * single call site is represented without optimization, this will equal zero.
+ *
+ * The field handler_addr is a relative pointer which stores the difference
+ * between the start of the exception range and the address of all code to
+ * catch exceptions and perform the cleanup for stack unwinding.
+ *
+ * The field type_block is a relative pointer which stores the difference
+ * between the start of the exception range and the address of an array used
+ * for storing a list of the types of exceptions which can be caught within
+ * the exception range.
+ */
+typedef struct {
+ PTRDIFF_T ret_addr;
+ Xword length;
+ PTRDIFF_T handler_addr;
+ PTRDIFF_T type_block;
+ Xword reserved;
+} exception_range_entry;
/*
* Focal point for verifying symbol names.
@@ -434,9 +487,26 @@ getphdr(Word phnum, Word *type_arr, Word type_cnt, const char *file, Elf *elf)
return (NULL);
}
+/*
+ * Display the contents of GNU/amd64 .eh_frame and .eh_frame_hdr
+ * sections.
+ *
+ * entry:
+ * cache - Cache of all section headers
+ * shndx - Index of .eh_frame or .eh_frame_hdr section to be displayed
+ * uphdr - NULL, or unwind program header associated with
+ * the .eh_frame_hdr section.
+ * ehdr - ELF header for file
+ * eh_state - Data used across calls to this routine. The
+ * caller should zero it before the first call, and
+ * pass it on every call.
+ * osabi - OSABI to use in displaying information
+ * file - Name of file
+ * flags - Command line option flags
+ */
static void
-unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
- const char *file, Elf *elf, uint_t flags)
+unwind_eh_frame(Cache *cache, Word shndx, Phdr *uphdr, Ehdr *ehdr,
+ gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
{
#if defined(_ELF64)
#define MSG_UNW_BINSRTAB2 MSG_UNW_BINSRTAB2_64
@@ -446,13 +516,253 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
#define MSG_UNW_BINSRTABENT MSG_UNW_BINSRTABENT_32
#endif
+ Cache *_cache = &cache[shndx];
+ Shdr *shdr = _cache->c_shdr;
+ uchar_t *data = (uchar_t *)(_cache->c_data->d_buf);
+ size_t datasize = _cache->c_data->d_size;
+ Conv_dwarf_ehe_buf_t dwarf_ehe_buf;
+ uint64_t ndx, frame_ptr, fde_cnt, tabndx;
+ uint_t vers, frame_ptr_enc, fde_cnt_enc, table_enc;
+ uint64_t initloc, initloc0;
+
+
+ /*
+ * Is this a .eh_frame_hdr?
+ */
+ if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
+ (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
+ MSG_SCN_FRMHDR_SIZE) == 0)) {
+ /*
+ * There can only be a single .eh_frame_hdr.
+ * Flag duplicates.
+ */
+ if (++eh_state->hdr_cnt > 1)
+ (void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTEHFRMHDR),
+ file, EC_WORD(shndx), _cache->c_name);
+
+ dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
+ ndx = 0;
+
+ vers = data[ndx++];
+ frame_ptr_enc = data[ndx++];
+ fde_cnt_enc = data[ndx++];
+ table_enc = data[ndx++];
+
+ dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
+
+ frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
+ ehdr->e_ident, shdr->sh_addr, ndx);
+ if (eh_state->hdr_cnt == 1) {
+ eh_state->hdr_ndx = shndx;
+ eh_state->frame_ptr = frame_ptr;
+ }
+
+ dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
+ conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
+ EC_XWORD(frame_ptr));
+
+ fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
+ ehdr->e_ident, shdr->sh_addr, ndx);
+
+ dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
+ conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
+ EC_XWORD(fde_cnt));
+ dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
+ conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
+ dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
+ dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
+
+ for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
+ initloc = dwarf_ehe_extract(data, &ndx, table_enc,
+ ehdr->e_ident, shdr->sh_addr, ndx);
+ /*LINTED:E_VAR_USED_BEFORE_SET*/
+ if ((tabndx != 0) && (initloc0 > initloc))
+ dbg_print(0, MSG_INTL(MSG_ERR_BADSORT),
+ file, _cache->c_name, EC_WORD(tabndx));
+ dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
+ EC_XWORD(initloc),
+ EC_XWORD(dwarf_ehe_extract(data, &ndx,
+ table_enc, ehdr->e_ident, shdr->sh_addr,
+ ndx)));
+ initloc0 = initloc;
+ }
+ } else { /* Display the .eh_frame section */
+ eh_state->frame_cnt++;
+ if (eh_state->frame_cnt == 1) {
+ eh_state->frame_ndx = shndx;
+ eh_state->frame_base = shdr->sh_addr;
+ } else if ((eh_state->frame_cnt > 1) &&
+ (ehdr->e_type != ET_REL)) {
+ Conv_inv_buf_t inv_buf;
+
+ (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
+ file, EC_WORD(shndx), _cache->c_name,
+ conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
+ }
+ dump_eh_frame(data, datasize, shdr->sh_addr,
+ ehdr->e_machine, ehdr->e_ident);
+ }
+
+ /*
+ * If we've seen the .eh_frame_hdr and the first .eh_frame section,
+ * compare the header frame_ptr to the address of the actual frame
+ * section to ensure the link-editor got this right. Note, this
+ * diagnostic is only produced when unwind information is explicitly
+ * asked for, as shared objects built with an older ld(1) may reveal
+ * this inconsistency. Although an inconsistency, it doesn't seem to
+ * have any adverse effect on existing tools.
+ */
+ if (((flags & FLG_MASK_SHOW) != FLG_MASK_SHOW) &&
+ (eh_state->hdr_cnt > 0) && (eh_state->frame_cnt > 0) &&
+ (eh_state->frame_ptr != eh_state->frame_base))
+ (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR),
+ file, EC_WORD(eh_state->hdr_ndx),
+ cache[eh_state->hdr_ndx].c_name,
+ EC_XWORD(eh_state->frame_ptr),
+ EC_WORD(eh_state->frame_ndx),
+ cache[eh_state->frame_ndx].c_name,
+ EC_XWORD(eh_state->frame_base));
+#undef MSG_UNW_BINSRTAB2
+#undef MSG_UNW_BINSRTABENT
+}
+
+/*
+ * Convert a self relative pointer into an address. A self relative
+ * pointer adds the address where the pointer resides to the offset
+ * contained in the pointer. The benefit is that the value of the
+ * pointer does not require relocation.
+ *
+ * entry:
+ * base_addr - Address of the pointer.
+ * delta - Offset relative to base_addr giving desired address
+ *
+ * exit:
+ * The computed address is returned.
+ *
+ * note:
+ * base_addr is an unsigned value, while ret_addr is signed. This routine
+ * used explicit testing and casting to explicitly control type
+ * conversion, and ensure that we handle the maximum possible range.
+ */
+static Addr
+srelptr(Addr base_addr, PTRDIFF_T delta)
+{
+ if (delta < 0)
+ return (base_addr - (Addr) (-delta));
+
+ return (base_addr + (Addr) delta);
+}
+
+/*
+ * Byte swap a PTRDIFF_T value.
+ */
+static PTRDIFF_T
+swap_ptrdiff(PTRDIFF_T value)
+{
+ PTRDIFF_T r;
+ uchar_t *dst = (uchar_t *)&r;
+ uchar_t *src = (uchar_t *)&value;
+
+ UL_ASSIGN_BSWAP_XWORD(dst, src);
+ return (r);
+}
+
+/*
+ * Display exception_range_entry items from the .exception_ranges section
+ * of a Sun C++ object.
+ */
+static void
+unwind_exception_ranges(Cache *_cache, const char *file, int do_swap)
+{
+ /*
+ * Translate a PTRDIFF_T self-relative address field of
+ * an exception_range_entry struct into an address.
+ *
+ * entry:
+ * exc_addr - Address of base of exception_range_entry struct
+ * cur_ent - Pointer to data in the struct to be translated
+ *
+ * _f - Field of struct to be translated
+ */
+#define SRELPTR(_f) \
+ srelptr(exc_addr + offsetof(exception_range_entry, _f), cur_ent->_f)
+
+#if defined(_ELF64)
+#define MSG_EXR_TITLE MSG_EXR_TITLE_64
+#define MSG_EXR_ENTRY MSG_EXR_ENTRY_64
+#else
+#define MSG_EXR_TITLE MSG_EXR_TITLE_32
+#define MSG_EXR_ENTRY MSG_EXR_ENTRY_32
+#endif
+
+ exception_range_entry scratch, *ent, *cur_ent = &scratch;
+ char index[MAXNDXSIZE];
+ Word i, nelts;
+ Addr addr, addr0, offset = 0;
+ Addr exc_addr = _cache->c_shdr->sh_addr;
+
+ dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
+ ent = (exception_range_entry *)(_cache->c_data->d_buf);
+ nelts = _cache->c_data->d_size / sizeof (exception_range_entry);
+
+ for (i = 0; i < nelts; i++, ent++) {
+ if (do_swap) {
+ /*
+ * Copy byte swapped values into the scratch buffer.
+ * The reserved field is not used, so we skip it.
+ */
+ scratch.ret_addr = swap_ptrdiff(ent->ret_addr);
+ scratch.length = BSWAP_XWORD(ent->length);
+ scratch.handler_addr = swap_ptrdiff(ent->handler_addr);
+ scratch.type_block = swap_ptrdiff(ent->type_block);
+ } else {
+ cur_ent = ent;
+ }
+
+ /*
+ * The table is required to be sorted by the address
+ * derived from ret_addr, to allow binary searching. Ensure
+ * that addresses grow monotonically.
+ */
+ addr = SRELPTR(ret_addr);
+ /*LINTED:E_VAR_USED_BEFORE_SET*/
+ if ((i != 0) && (addr0 > addr))
+ dbg_print(0, MSG_INTL(MSG_ERR_BADSORT),
+ file, _cache->c_name, EC_WORD(i));
+
+ (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
+ EC_XWORD(i));
+ dbg_print(0, MSG_INTL(MSG_EXR_ENTRY), index, EC_ADDR(offset),
+ EC_ADDR(addr), EC_ADDR(cur_ent->length),
+ EC_ADDR(SRELPTR(handler_addr)),
+ EC_ADDR(SRELPTR(type_block)));
+
+ addr0 = addr;
+ exc_addr += sizeof (exception_range_entry);
+ offset += sizeof (exception_range_entry);
+ }
+
+#undef SRELPTR
+#undef MSG_EXR_TITLE
+#undef MSG_EXR_ENTRY
+}
+
+/*
+ * Display information from unwind/exception sections:
+ *
+ * - GNU/amd64 .eh_frame and .eh_frame_hdr
+ * - Sun C++ .exception_ranges
+ *
+ */
+static void
+unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
+ const char *file, Elf *elf, uint_t flags)
+{
static Word phdr_types[] = { PT_SUNW_UNWIND, PT_SUNW_EH_FRAME };
- int frame_cnt = 0, hdr_cnt = 0, frame_ndx, hdr_ndx;
- uint64_t save_frame_ptr, save_frame_base;
- Conv_dwarf_ehe_buf_t dwarf_ehe_buf;
Word cnt;
Phdr *uphdr = NULL;
+ gnu_eh_state_t eh_state;
/*
* Historical background: .eh_frame and .eh_frame_hdr sections
@@ -468,31 +778,36 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
* other architectures in order to better support gcc-generated
* objects.
*
+ * .exception_ranges implement the same basic concepts, but
+ * were invented at Sun for the Sun C++ compiler.
+ *
* We match these sections by name, rather than section type,
* because they can come in as either SHT_AMD64_UNWIND, or as
- * SHT_PROGBITS, and because we need to distinquish between
- * the two types (.eh_frame and .eh_frame_hdr).
+ * SHT_PROGBITS, and because the type isn't enough to determine
+ * how they should be interprteted.
*/
+ /* Find the program header for .eh_frame_hdr if present */
if (phnum)
uphdr = getphdr(phnum, phdr_types,
sizeof (phdr_types) / sizeof (*phdr_types), file, elf);
+ /*
+ * eh_state is used to retain data used by unwind_eh_frame()
+ * accross calls.
+ */
+ bzero(&eh_state, sizeof (eh_state));
+
for (cnt = 1; cnt < shnum; cnt++) {
Cache *_cache = &cache[cnt];
Shdr *shdr = _cache->c_shdr;
- uchar_t *data;
- size_t datasize;
- uint64_t ndx, frame_ptr, fde_cnt, tabndx;
- uint_t vers, frame_ptr_enc, fde_cnt_enc, table_enc;
+ int is_exrange;
/*
- * Skip sections of the wrong type.
- *
- * On Solaris, these are SHT_AMD64_UNWIND for amd64,
- * and SHT_PROGBITS for other platforms. For Linux, and
- * presumably other operating systems that use the GNU
- * toolchain, SHT_PROGBITS is used on all platforms.
+ * Skip sections of the wrong type. On amd64, they
+ * can be SHT_AMD64_UNWIND. On all platforms, they
+ * can be SHT_PROGBITS (including amd64, if using
+ * the GNU compilers).
*
* Skip anything other than these two types. The name
* test below will thin out the SHT_PROGBITS that don't apply.
@@ -502,15 +817,22 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
continue;
/*
- * Only sections with names starting with .eh_frame or
- * .eh_frame_hdr are of interest. We do a prefix comparison,
- * allowing for naming conventions like .eh_frame.foo, hence
- * the use of strncmp() rather than strcmp(). This means that
- * we only really need to test for .eh_frame, as it's a
- * prefix of .eh_frame_hdr.
+ * Only sections with certain well known names are of interest.
+ * These are:
+ *
+ * .eh_frame - amd64/GNU-compiler unwind sections
+ * .eh_frame_hdr - Sorted table referencing .eh_frame
+ * .exception_ranges - Sun C++ unwind sections
+ *
+ * We do a prefix comparison, allowing for naming conventions
+ * like .eh_frame.foo, hence the use of strncmp() rather than
+ * strcmp(). This means that we only really need to test for
+ * .eh_frame, as it's a prefix of .eh_frame_hdr.
*/
- if (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRM),
- MSG_SCN_FRM_SIZE) != 0)
+ is_exrange = strncmp(_cache->c_name,
+ MSG_ORIG(MSG_SCN_EXRANGE), MSG_SCN_EXRANGE_SIZE) == 0;
+ if ((strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRM),
+ MSG_SCN_FRM_SIZE) != 0) && !is_exrange)
continue;
if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
@@ -522,105 +844,13 @@ unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name);
- data = (uchar_t *)(_cache->c_data->d_buf);
- datasize = _cache->c_data->d_size;
-
- /*
- * Is this a .eh_frame_hdr
- */
- if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
- (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
- MSG_SCN_FRMHDR_SIZE) == 0)) {
- /*
- * There can only be a single .eh_frame_hdr.
- * Flag duplicates.
- */
- if (++hdr_cnt > 1)
- (void) fprintf(stderr,
- MSG_INTL(MSG_ERR_MULTEHFRMHDR), file,
- EC_WORD(cnt), _cache->c_name);
-
- dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
- ndx = 0;
-
- vers = data[ndx++];
- frame_ptr_enc = data[ndx++];
- fde_cnt_enc = data[ndx++];
- table_enc = data[ndx++];
-
- dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
-
- frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
- ehdr->e_ident, shdr->sh_addr, ndx);
- if (hdr_cnt == 1) {
- hdr_ndx = cnt;
- save_frame_ptr = frame_ptr;
- }
-
- dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
- conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
- EC_XWORD(frame_ptr));
-
- fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
- ehdr->e_ident, shdr->sh_addr, ndx);
-
- dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
- conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
- EC_XWORD(fde_cnt));
- dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
- conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
- dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
- dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
-
- for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
- dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
- EC_XWORD(dwarf_ehe_extract(data, &ndx,
- table_enc, ehdr->e_ident, shdr->sh_addr,
- ndx)),
- EC_XWORD(dwarf_ehe_extract(data, &ndx,
- table_enc, ehdr->e_ident, shdr->sh_addr,
- ndx)));
- }
- } else { /* Display the .eh_frame section */
- frame_cnt++;
- if (frame_cnt == 1) {
- frame_ndx = cnt;
- save_frame_base = shdr->sh_addr;
- } else if ((frame_cnt > 1) &&
- (ehdr->e_type != ET_REL)) {
- Conv_inv_buf_t inv_buf;
-
- (void) fprintf(stderr,
- MSG_INTL(MSG_WARN_MULTEHFRM), file,
- EC_WORD(cnt), _cache->c_name,
- conv_ehdr_type(osabi, ehdr->e_type,
- 0, &inv_buf));
- }
- dump_eh_frame(data, datasize, shdr->sh_addr,
- ehdr->e_machine, ehdr->e_ident);
- }
-
- /*
- * If we've seen the .eh_frame_hdr and the first .eh_frame
- * section, compare the header frame_ptr to the address of the
- * actual frame section to ensure the link-editor got this
- * right. Note, this diagnostic is only produced when unwind
- * information is explicitly asked for, as shared objects built
- * with an older ld(1) may reveal this inconsistency. Although
- * an inconsistency, it doesn't seem to have any adverse effect
- * on existing tools.
- */
- if (((flags & FLG_MASK_SHOW) != FLG_MASK_SHOW) &&
- (hdr_cnt > 0) && (frame_cnt > 0) &&
- (save_frame_ptr != save_frame_base))
- (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR),
- file, EC_WORD(hdr_ndx), cache[hdr_ndx].c_name,
- EC_XWORD(save_frame_ptr), EC_WORD(frame_ndx),
- cache[frame_ndx].c_name, EC_XWORD(save_frame_base));
+ if (is_exrange)
+ unwind_exception_ranges(_cache, file,
+ _elf_sys_encoding() != ehdr->e_ident[EI_DATA]);
+ else
+ unwind_eh_frame(cache, cnt, uphdr, ehdr, &eh_state,
+ osabi, file, flags);
}
-
-#undef MSG_UNW_BINSRTAB2
-#undef MSG_UNW_BINSRTABENT
}
/*
@@ -4217,24 +4447,35 @@ regular(const char *file, int fd, Elf *elf, uint_t flags,
* Heuristic time: It is usually bad form
* to assume the meaning/format of a PROGBITS
* section based on its name. However, there
- * are exceptions: The ELF ABI specifies
- * .interp and .got sections by name. Existing
- * practice has similarly pinned down the
- * meaning of unwind sections (.eh_frame and
- * .eh_frame_hdr).
- *
- * Check for these special names.
+ * are ABI mandated exceptions. Check for
+ * these special names.
*/
+
+ /* The ELF ABI specifies .interp and .got */
if (strcmp(_cache->c_name,
- MSG_ORIG(MSG_ELF_INTERP)) == 0)
+ MSG_ORIG(MSG_ELF_INTERP)) == 0) {
flags |= FLG_SHOW_INTERP;
- else if (strcmp(_cache->c_name,
- MSG_ORIG(MSG_ELF_GOT)) == 0)
+ break;
+ }
+ if (strcmp(_cache->c_name,
+ MSG_ORIG(MSG_ELF_GOT)) == 0) {
flags |= FLG_SHOW_GOT;
- else if (strncmp(_cache->c_name,
+ break;
+ }
+ /*
+ * The GNU compilers, and amd64 ABI, define
+ * .eh_frame and .eh_frame_hdr. The Sun
+ * C++ ABI defines .exception_ranges.
+ */
+ if ((strncmp(_cache->c_name,
MSG_ORIG(MSG_SCN_FRM),
- MSG_SCN_FRM_SIZE) == 0)
+ MSG_SCN_FRM_SIZE) == 0) ||
+ (strncmp(_cache->c_name,
+ MSG_ORIG(MSG_SCN_EXRANGE),
+ MSG_SCN_EXRANGE_SIZE) == 0)) {
flags |= FLG_SHOW_UNWIND;
+ break;
+ }
break;
case SHT_SYMTAB:
diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
index 7b67746553..198b874bdf 100644
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
@@ -155,6 +155,7 @@
(1 expected)\n"
@ MSG_ERR_BADEHFRMPTR "%s: section[%d: %s] FramePtr (%#llx) does not match \
shdr[%d: %s].sh_addr (%#llx)\n"
+@ MSG_ERR_BADSORT "%s: %s: index[%d]: invalid sort order"
@ MSG_WARN_INVINTERP1 "%s: PT_INTERP header has no associated section\n"
@@ -173,6 +174,20 @@
@ MSG_INFO_LINUXOSABI "%s: %s object has Linux .note.ABI-tag section. \
Assuming %s\n"
+# exception_range_entry table entries.
+# TRANSLATION_NOTE - the following entries provide for a series of one or more
+# standard 32-bit and 64-bit .exception_ranges table entries that align with
+# the initial title.
+
+@ MSG_EXR_TITLE_32 " index offset ret_addr \
+ length handler type_blk"
+@ MSG_EXR_ENTRY_32 "%10.10s 0x%8.8llx 0x%8.8llx 0x%8.8llx 0x%8.8llx \
+ 0x%8.8llx"
+@ MSG_EXR_TITLE_64 " index offset ret_addr \
+ length handler type_blk"
+@ MSG_EXR_ENTRY_64 "%10.10s 0x%16.16llx 0x%16.16llx 0x%16.16llx \
+ 0x%16.16llx 0x%16.16llx"
+
# Elf Output Messages
@ MSG_ELF_SHDR "Section Header[%d]: sh_name: %s"
@@ -332,6 +347,7 @@
@ MSG_SCN_FRM ".eh_frame"
@ MSG_SCN_FRMHDR ".eh_frame_hdr"
+@ MSG_SCN_EXRANGE ".exception_ranges"
@ MSG_UNW_FRMHDR "Frame Header:"
@ MSG_UNW_FRMVERS " Version: %d"
diff --git a/usr/src/cmd/sgs/include/conv.h b/usr/src/cmd/sgs/include/conv.h
index f0d27cd587..28df496cd8 100644
--- a/usr/src/cmd/sgs/include/conv.h
+++ b/usr/src/cmd/sgs/include/conv.h
@@ -61,6 +61,14 @@ extern "C" {
#define CONF_FLTR 0x010000 /* filter information available */
#define CONF_FEATMSK 0xffff00
+
+/*
+ * Valid flags for conv_strproc_extract_value().
+ */
+#define CONV_SPEXV_F_NOTRIM 0x0001 /* Do not trim whitespace around '=' */
+#define CONV_SPEXV_F_UCASE 0x0002 /* Convert value to uppercase */
+#define CONV_SPEXV_F_NULLOK 0x0004 /* Empty ("") value is OK */
+
/*
* Buffer types:
*
@@ -696,7 +704,11 @@ typedef void Conv_str_to_c_literal_func_t(const void *ptr,
*/
extern uchar_t conv_check_native(char **, char **);
extern const char *conv_lddstub(int);
-extern int conv_sys_eclass();
+extern int conv_strproc_isspace(int);
+extern char *conv_strproc_trim(char *);
+extern Boolean conv_strproc_extract_value(char *, size_t, int,
+ const char **);
+extern int conv_sys_eclass(void);
/*
* Generic core formatting and iteration functionality
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h
index 570f3f76d4..d8db81bddb 100644
--- a/usr/src/cmd/sgs/include/debug.h
+++ b/usr/src/cmd/sgs/include/debug.h
@@ -158,8 +158,8 @@ extern "C" {
*/
typedef struct {
uint_t d_class; /* debugging classes */
- uint_t d_extra; /* extra information for classes */
- APlist *d_list; /* associated strings */
+ uint_t d_extra; /* extra public information */
+ APlist *d_list; /* accepted link-map list names */
} Dbg_desc;
extern Dbg_desc *dbg_desc;
@@ -174,16 +174,25 @@ extern Dbg_desc *dbg_desc;
* may be interpreted by the debugging library itself or from the callers
* dbg_print() routine.
*/
-#define DBG_E_DETAIL 0x0001 /* add detail to a class */
-#define DBG_E_LONG 0x0002 /* use long names (ie. no truncation) */
+#define DBG_E_DETAIL 0x00000001 /* add detail to a class */
+#define DBG_E_LONG 0x00000002 /* use long names (ie. no truncation) */
+#define DBG_E_DEMANGLE 0x00000004 /* demangle symbol names */
+#define DBG_E_STDNL 0x00000008 /* standard newline indicator */
+#define DBG_E_HELP 0x00000010 /* help requested */
+#define DBG_E_HELP_EXIT 0x00000020 /* hint: user should exit after help */
+
+/* ld only */
+#define DBG_E_SNAME 0x00001000 /* prepend simple name */
+#define DBG_E_FNAME 0x00002000 /* prepend full name */
+#define DBG_E_CLASS 0x00004000 /* prepend ELF class */
+
+/* ld.so.1 only */
+#define DBG_E_LMID 0x00100000 /* prepend link-map id */
+#define DBG_E_LMID_LDSO 0x00200000 /* show ldso link-map list */
+#define DBG_E_LMID_ALL 0x00400000 /* show all non-ldso link-map lists */
+#define DBG_E_LMID_ALT 0x00800000 /* show all ALT link-map lists */
+#define DBG_E_LMID_BASE 0x01000000 /* show BASE link-map list */
-#define DBG_E_STDNL 0x0010 /* standard newline indicator */
-
-#define DBG_E_SNAME 0x0100 /* prepend simple name (ld only) */
-#define DBG_E_FNAME 0x0200 /* prepend full name (ld only) */
-#define DBG_E_CLASS 0x0400 /* prepend ELF class (ld only) */
-#define DBG_E_LMID 0x0800 /* prepend link-map id (ld.so.1 only) */
-#define DBG_E_DEMANGLE 0x1000 /* demangle symbol names */
#define DBG_NOTDETAIL() !(dbg_desc->d_extra & DBG_E_DETAIL)
#define DBG_NOTLONG() !(dbg_desc->d_extra & DBG_E_LONG)
@@ -203,7 +212,16 @@ extern Dbg_desc *dbg_desc;
/* PRINTFLIKE2 */
extern void dbg_print(Lm_list *, const char *, ...);
-extern uintptr_t Dbg_setup(const char *, Dbg_desc *);
+/*
+ * Initialization routine, called before any other Dbg routines to
+ * establish the necessary state.
+ */
+typedef enum { DBG_CALLER_LD, DBG_CALLER_RTLD } dbg_setup_caller_t;
+extern int Dbg_setup(dbg_setup_caller_t, const char *,
+ Dbg_desc *, const char **);
+
+/* Call dbg_print() to produce help output */
+extern void Dbg_help(void);
/*
* Establish ELF32 and ELF64 class Dbg_*() interfaces.
@@ -766,14 +784,14 @@ extern void Dbg_reloc_error(Lm_list *, int, Half, Word, void *,
const char *);
extern void Dbg_reloc_generate(Lm_list *, Os_desc *, Word);
extern void Dbg_reloc_in(Lm_list *, int, Half, Word, void *, const char *,
- const char *);
+ Word, const char *);
extern void Dbg_reloc_ors_entry(Lm_list *, int, Word, Half, Rel_desc *);
extern void Dbg_reloc_out(Ofl_desc *, int, Word, void *, const char *,
const char *);
extern void Dbg_reloc_proc(Lm_list *, Os_desc *, Is_desc *, Is_desc *);
extern void Dbg_reloc_run(Rt_map *, uint_t, int, int);
extern void Dbg_reloc_transition(Lm_list *, Half, Word, Rel_desc *);
-extern void Dbg_reloc_sloppycomdat(Lm_list *, const char *, Sym_desc *);
+extern void Dbg_reloc_sloppycomdat(Lm_list *, Sym_desc *);
extern void Dbg_sec_added(Lm_list *, Os_desc *, Sg_desc *);
extern void Dbg_sec_backing(Lm_list *);
@@ -782,11 +800,11 @@ extern void Dbg_sec_discarded(Lm_list *, Is_desc *, Is_desc *);
extern void Dbg_sec_genstr_compress(Lm_list *, const char *,
Xword, Xword);
extern void Dbg_sec_group(Lm_list *, Is_desc *, Group_desc *);
-extern void Dbg_sec_gnu_comdat(Lm_list *, const char *, uint_t, uint_t);
+extern void Dbg_sec_gnu_comdat(Lm_list *, Is_desc *, uint_t, uint_t);
extern void Dbg_sec_in(Lm_list *, Is_desc *);
extern void Dbg_sec_order_error(Lm_list *, Ifl_desc *, Word, int);
extern void Dbg_sec_order_list(Ofl_desc *, int);
-extern void Dbg_sec_redirected(Lm_list *, const char *, const char *);
+extern void Dbg_sec_redirected(Lm_list *, Is_desc *, const char *);
extern void Dbg_sec_strtab(Lm_list *, Os_desc *, Str_tbl *);
extern void Dbg_sec_unsup_strmerge(Lm_list *, Is_desc *);
@@ -797,7 +815,7 @@ extern void Dbg_seg_os(Ofl_desc *, Os_desc *, int);
extern void Dbg_seg_title(Lm_list *);
extern void Dbg_shdr_modified(Lm_list *, const char *, uchar_t, Half,
- Shdr *, Shdr *, const char *);
+ Word, Shdr *, Shdr *, const char *);
extern void Dbg_statistics_ar(Ofl_desc *);
extern void Dbg_statistics_ld(Ofl_desc *);
diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h
index ed34982d5f..c7e66b867c 100644
--- a/usr/src/cmd/sgs/include/libld.h
+++ b/usr/src/cmd/sgs/include/libld.h
@@ -745,7 +745,8 @@ struct ent_desc { /* input section entrance criteria */
Half ec_flags;
};
-#define FLG_EC_USED 0x0001 /* entrance criteria met? */
+#define FLG_EC_BUILTIN 0x0001 /* built in descriptor */
+#define FLG_EC_USED 0x0002 /* entrance criteria met? */
/*
* One structure is allocated for a move entry, and associated to the symbol
diff --git a/usr/src/cmd/sgs/libconv/Makefile.com b/usr/src/cmd/sgs/libconv/Makefile.com
index ebd8e8ce8e..35875f0358 100644
--- a/usr/src/cmd/sgs/libconv/Makefile.com
+++ b/usr/src/cmd/sgs/libconv/Makefile.com
@@ -45,9 +45,9 @@ COMOBJS= arch.o c_literal.o \
phdr.o relocate.o \
relocate_i386.o relocate_amd64.o \
relocate_sparc.o sections.o \
- segments.o symbols.o \
- syminfo.o tokens.o \
- version.o
+ segments.o strproc.o \
+ symbols.o syminfo.o \
+ tokens.o version.o
ELFCAP_OBJS= elfcap.o
diff --git a/usr/src/cmd/sgs/libconv/common/globals.c b/usr/src/cmd/sgs/libconv/common/globals.c
index 12f6e7db5e..3486045238 100644
--- a/usr/src/cmd/sgs/libconv/common/globals.c
+++ b/usr/src/cmd/sgs/libconv/common/globals.c
@@ -26,7 +26,6 @@
#include <stdio.h>
#include <strings.h>
-#include <ctype.h>
#include <_machelf.h>
#include "_conv.h"
#include "globals_msg.h"
@@ -321,13 +320,13 @@ conv_iter_strtol_init(const char *str, conv_strtol_uvalue_t *uvalue)
{
const char *tail;
- while (isspace(*str))
+ while (conv_strproc_isspace(*str))
str++;
uvalue->csl_str = str;
uvalue->csl_found = 0;
tail = str + strlen(str);
- while ((tail > str) && isspace(*(tail - 1)))
+ while ((tail > str) && conv_strproc_isspace(*(tail - 1)))
tail--;
uvalue->csl_strlen = tail - str;
diff --git a/usr/src/cmd/sgs/libconv/common/globals_machelf.c b/usr/src/cmd/sgs/libconv/common/globals_machelf.c
index cbf0136e5e..eaeb8239bb 100644
--- a/usr/src/cmd/sgs/libconv/common/globals_machelf.c
+++ b/usr/src/cmd/sgs/libconv/common/globals_machelf.c
@@ -26,7 +26,6 @@
#include <stdio.h>
#include <strings.h>
-#include <ctype.h>
#include <_machelf.h>
#include "_conv.h"
#include "globals_msg.h"
diff --git a/usr/src/cmd/sgs/libconv/common/llib-lconv b/usr/src/cmd/sgs/libconv/common/llib-lconv
index 16e86ccb8f..2f2c28bce7 100644
--- a/usr/src/cmd/sgs/libconv/common/llib-lconv
+++ b/usr/src/cmd/sgs/libconv/common/llib-lconv
@@ -39,6 +39,10 @@
uchar_t conv_check_native(char **, char **);
const char *conv_lddstub(int);
int conv_sys_eclass(void);
+int conv_strproc_isspace(int);
+char *conv_strproc_trim(char *);
+Boolean conv_strproc_extract_value(char *, size_t, int, const char **);
+
/*
* Generic core formatting and iteration functionality
diff --git a/usr/src/cmd/sgs/libconv/common/strproc.c b/usr/src/cmd/sgs/libconv/common/strproc.c
new file mode 100644
index 0000000000..96830c75c8
--- /dev/null
+++ b/usr/src/cmd/sgs/libconv/common/strproc.c
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * General purpse string manipulation routines
+ */
+
+#include <stdio.h>
+#include <_conv.h>
+
+
+/*
+ * Implementation of isspace() that does not require <ctype.h>
+ * or <sys/ctype.h>, appropriate for simple non-localized use.
+ */
+int
+conv_strproc_isspace(int c)
+{
+ return ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'));
+}
+
+/*
+ * Remove leading and trailing whitespace from the given string.
+ *
+ * entry:
+ * str - String to be trimmed
+ *
+ * exit:
+ * The pointer to the trimmed string is returned.
+ *
+ * note:
+ * Leading whitespace is trimmed by advancing the given str pointer,
+ * and not by making a copy or allocing more memory. Hence, the caller
+ * should retain a copy of the original str pointer if they need to
+ * free the original memory or otherwise access it.
+ *
+ * Trailing whitespace is trimmed by inserting a NULL termination
+ * in the position at which the first trailing whitespce character
+ * lies. This routine can therefore modify the memory used by
+ * the input string.
+ */
+char *
+conv_strproc_trim(char *str)
+{
+ char *tail;
+
+ /* Skip leading whitespace */
+ while (conv_strproc_isspace(*str))
+ str++;
+
+ /* Back up over trailing whitespace */
+ tail = str + strlen(str);
+ while ((tail > str) && conv_strproc_isspace(*(tail - 1)))
+ tail--;
+ *tail = '\0';
+
+ return (str);
+}
+
+/*
+ * Given a debug token of the form:
+ *
+ * token=value
+ *
+ * extract and return a pointer to the value.
+ *
+ * entry:
+ * str - String to process
+ * token_len = Length of the token, not counting the '=' character,
+ * or any whitespace between the token and the '='.
+ * to_upper - True to convert the returned value to upper case.
+ * value - Address of pointer to receive the value string.
+ *
+ * exit:
+ * On success, *value is updated to point at the value string,
+ * and True (1) is returned. On failure, False (0) is returned.
+ *
+ * note:
+ * If CONV_SPEXV_F_UCASE is specified, this routine modifies
+ * the memory pointed at by str.
+ */
+Boolean
+conv_strproc_extract_value(char *str, size_t token_len, int flags,
+ const char **value)
+{
+ int trim = (flags & CONV_SPEXV_F_NOTRIM) == 0;
+
+ /* Skip the token */
+ str += token_len;
+
+ /*
+ * If TRIM, skip whitespace between token and '='
+ */
+ if (trim)
+ while (conv_strproc_isspace(*str))
+ str++;
+
+ /* If there's not a '=' here, this isn't the token we thought it was */
+ if (*str != '=')
+ return (FALSE);
+
+ str++; /* skip the '=' */
+
+ /* if TRIM, skip whitespace following the '=' */
+ if (trim)
+ while (conv_strproc_isspace(*str))
+ str++;
+
+ /* Null value and it's not OK? Make it an error. */
+ if (((flags & CONV_SPEXV_F_NULLOK) == 0) && (*str == '\0'))
+ return (FALSE);
+
+ *value = str;
+
+ /* Convert to uppercase on request */
+ if (flags & CONV_SPEXV_F_UCASE)
+ for (; *str; str++)
+ if ((*str >= 'a') && (*str <= 'z'))
+ *str = *str - ('a' - 'A');
+
+ return (TRUE);
+}
diff --git a/usr/src/cmd/sgs/libld/common/_libld.h b/usr/src/cmd/sgs/libld/common/_libld.h
index f5828dff68..674c0d35c8 100644
--- a/usr/src/cmd/sgs/libld/common/_libld.h
+++ b/usr/src/cmd/sgs/libld/common/_libld.h
@@ -705,7 +705,8 @@ extern Sdf_desc *sdf_find(const char *, APlist *);
#endif
-extern uintptr_t dbg_setup(const char *, Dbg_desc *, const char **, int);
+extern void dbg_cleanup(void);
+extern int dbg_setup(Ofl_desc *, const char *, int);
extern uintptr_t ld_add_actrel(Word, Rel_desc *, Ofl_desc *);
extern uintptr_t ld_add_libdir(Ofl_desc *, const char *);
@@ -764,9 +765,9 @@ extern Ifl_desc *ld_process_ifl(const char *, const char *, int, Elf *,
extern uintptr_t ld_process_move(Ofl_desc *);
extern Ifl_desc *ld_process_open(const char *, const char *, int *,
Ofl_desc *, Word, Rej_desc *);
-extern uintptr_t ld_process_ordered(Ifl_desc *, Ofl_desc *, Word, Word);
+extern uintptr_t ld_process_ordered(Ifl_desc *, Ofl_desc *, Word);
extern uintptr_t ld_process_sym_reloc(Ofl_desc *, Rel_desc *, Rel *,
- Is_desc *, const char *);
+ Is_desc *, const char *, Word);
extern uintptr_t ld_reloc_GOT_relative(Boolean, Rel_desc *, Ofl_desc *);
extern uintptr_t ld_reloc_plt(Rel_desc *, Ofl_desc *);
diff --git a/usr/src/cmd/sgs/libld/common/args.c b/usr/src/cmd/sgs/libld/common/args.c
index 3cfa74f789..3823c51bb1 100644
--- a/usr/src/cmd/sgs/libld/common/args.c
+++ b/usr/src/cmd/sgs/libld/common/args.c
@@ -90,6 +90,7 @@ static Boolean Blflag = FALSE;
static Boolean Beflag = FALSE;
static Boolean Bsflag = FALSE;
static Boolean Btflag = FALSE;
+static Boolean Dflag = FALSE;
static Boolean Gflag = FALSE;
static Boolean Vflag = FALSE;
@@ -706,15 +707,17 @@ check_flags(Ofl_desc * ofl, int argc)
}
/*
- * Check that we have something to work with. This check is carried out
+ * Check that we have something to work with. This check is carried out
* after mapfile processing as its possible a mapfile is being used to
* define symbols, in which case it would be sufficient to build the
* output file purely from the mapfile.
*/
if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) {
- if (Vflag && (argc == 2))
+ if ((Vflag ||
+ (Dflag && (dbg_desc->d_extra & DBG_E_HELP_EXIT))) &&
+ (argc == 2)) {
ofl->ofl_flags1 |= FLG_OF1_DONE;
- else {
+ } else {
eprintf(ofl->ofl_lml, ERR_FATAL,
MSG_INTL(MSG_ARG_NOFILES));
return (S_ERROR);
@@ -1332,9 +1335,9 @@ parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *error)
* process_files (this allows debugging to be turned
* on and off around individual groups of files).
*/
+ Dflag = 1;
if (ofl->ofl_objscnt == 0) {
- if (dbg_setup(optarg, dbg_desc,
- &ofl->ofl_name, 2) == S_ERROR)
+ if (dbg_setup(ofl, optarg, 2) == 0)
return (S_ERROR);
}
@@ -1568,8 +1571,7 @@ parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
case 'D':
DBG_CALL(Dbg_args_opts(ofl->ofl_lml, ndx, c,
optarg));
- (void) dbg_setup(optarg, dbg_desc,
- &ofl->ofl_name, 3);
+ (void) dbg_setup(ofl, optarg, 3);
break;
case 'u':
DBG_CALL(Dbg_args_opts(ofl->ofl_lml, ndx, c,
@@ -1839,7 +1841,7 @@ ld_process_files(Ofl_desc *ofl, int argc, char **argv)
{
/*
* Process command line files (taking into account any applicable
- * preseeding flags). Return if any fatal errors have occurred.
+ * preceeding flags). Return if any fatal errors have occurred.
*/
opterr = 0;
optind = 1;
diff --git a/usr/src/cmd/sgs/libld/common/debug.c b/usr/src/cmd/sgs/libld/common/debug.c
index 6508b422a9..4ffa5ef19f 100644
--- a/usr/src/cmd/sgs/libld/common/debug.c
+++ b/usr/src/cmd/sgs/libld/common/debug.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdarg.h>
+#include <errno.h>
#include <strings.h>
#include <dlfcn.h>
#include <debug.h>
@@ -51,21 +52,82 @@
static const char **Name = NULL;
static int Phase = 0;
-uintptr_t
-dbg_setup(const char *options, Dbg_desc *dbp, const char **name, int phase)
+/* Debug file output state */
+static struct {
+ FILE *fptr; /* File to send debug output */
+ int close_needed; /* True if explicitly opened stream */
+} dbg_ofile = {
+ stderr,
+ 0
+};
+
+
+/*
+ * If there is an explicitly opened debug file, close it and reset the state.
+ */
+void
+dbg_cleanup(void)
+{
+ if (dbg_ofile.close_needed) {
+ (void) fclose(dbg_ofile.fptr);
+ dbg_ofile.close_needed = 0;
+ dbg_ofile.fptr = stderr;
+ }
+}
+
+/*
+ * Process debug tokens. Returns True (1) on success, and False (0)
+ * on failure.
+ */
+int
+dbg_setup(Ofl_desc *ofl, const char *options, int phase)
{
+ const char *ofile;
+
if (Phase == 0)
Phase = phase;
else if (Phase != phase)
- return (0);
+ return (1);
- Name = name;
+ Name = &ofl->ofl_name;
/*
* Call the debugging setup routine to initialize the mask and
* debug function array.
*/
- return (Dbg_setup(options, dbp));
+ if (Dbg_setup(DBG_CALLER_LD, options, dbg_desc, &ofile) == 0)
+ return (0);
+
+ /*
+ * If output= token was used, close the old file if necessary
+ * and open a new one if the file name is not NULL.
+ */
+ if (ofile) {
+ dbg_cleanup();
+ if (*ofile != '\0') {
+ FILE *fptr = fopen(ofile, MSG_ORIG(MSG_DBG_FOPEN_MODE));
+ if (fptr == NULL) {
+ int err = errno;
+
+ eprintf(ofl->ofl_lml, ERR_FATAL,
+ MSG_INTL(MSG_SYS_OPEN), ofile,
+ strerror(err));
+ return (0);
+ } else {
+ dbg_ofile.fptr = fptr;
+ dbg_ofile.close_needed = 1;
+ }
+ }
+ }
+
+ /*
+ * Now that the output file is established, generate help
+ * output if the user specified the debug help token.
+ */
+ if (dbg_desc->d_extra & DBG_E_HELP)
+ Dbg_help();
+
+ return (1);
}
/* PRINTFLIKE2 */
@@ -138,15 +200,13 @@ dbg_print(Lm_list *lml, const char *format, ...)
(void) strcat(prestr, cls);
}
}
- if (prestr)
- (void) fputs(prestr, stderr);
- else
- (void) fputs(MSG_INTL(MSG_DBG_AOUT_FMT), stderr);
+ (void) fputs(prestr ? prestr : MSG_INTL(MSG_DBG_AOUT_FMT),
+ dbg_ofile.fptr);
} else
- (void) fputs(MSG_INTL(MSG_DBG_DFLT_FMT), stderr);
+ (void) fputs(MSG_INTL(MSG_DBG_DFLT_FMT), dbg_ofile.fptr);
va_start(args, format);
- (void) vfprintf(stderr, format, args);
- (void) fprintf(stderr, MSG_ORIG(MSG_STR_NL));
+ (void) vfprintf(dbg_ofile.fptr, format, args);
+ (void) fprintf(dbg_ofile.fptr, MSG_ORIG(MSG_STR_NL));
va_end(args);
}
diff --git a/usr/src/cmd/sgs/libld/common/entry.c b/usr/src/cmd/sgs/libld/common/entry.c
index 5b77e59f86..47eecf28eb 100644
--- a/usr/src/cmd/sgs/libld/common/entry.c
+++ b/usr/src/cmd/sgs/libld/common/entry.c
@@ -107,7 +107,7 @@ static const Sg_desc sg_desc[LD_NUM] = {
SG_DESC_INIT(LD_NOTE, PT_NOTE, 0, MSG_ORIG(MSG_ENT_NOTE), FLG_SG_TYPE),
- SG_DESC_INIT(LD_EXTRA, PT_NULL, 0, MSG_ORIG(MSG_STR_EMPTY), FLG_SG_TYPE)
+ SG_DESC_INIT(LD_EXTRA, PT_NULL, 0, MSG_ORIG(MSG_ENT_EXTRA), FLG_SG_TYPE)
};
/*
@@ -123,39 +123,39 @@ static const Sg_desc sg_desc[LD_NUM] = {
* has been allocated and the templates copied.
*/
static const Ent_desc ent_desc[] = {
- {NULL, NULL, SHT_NOTE, 0, 0,
- (Sg_desc *)LD_NOTE, 0, FALSE},
+ {NULL, MSG_ORIG(MSG_ENT_NOTE), SHT_NOTE, 0, 0,
+ (Sg_desc *)LD_NOTE, 0, FLG_EC_BUILTIN},
#if defined(_ELF64) /* (amd64-only) */
- {NULL, MSG_ORIG(MSG_SCN_LRODATA), NULL,
+ {NULL, MSG_ORIG(MSG_ENT_LRODATA), NULL,
SHF_ALLOC + SHF_AMD64_LARGE, SHF_ALLOC + SHF_AMD64_LARGE,
- (Sg_desc *)LD_LRODATA, 0, FALSE},
+ (Sg_desc *)LD_LRODATA, 0, FLG_EC_BUILTIN},
#endif
- {NULL, NULL, NULL,
+ {NULL, MSG_ORIG(MSG_ENT_TEXT), NULL,
SHF_ALLOC + SHF_WRITE, SHF_ALLOC,
- (Sg_desc *)LD_TEXT, 0, FALSE},
+ (Sg_desc *)LD_TEXT, 0, FLG_EC_BUILTIN},
- {NULL, NULL, SHT_NOBITS,
+ {NULL, MSG_ORIG(MSG_ENT_BSS), SHT_NOBITS,
SHF_ALLOC + SHF_WRITE, SHF_ALLOC + SHF_WRITE,
- (Sg_desc *)LD_BSS, 0, FALSE},
+ (Sg_desc *)LD_BSS, 0, FLG_EC_BUILTIN},
#if defined(_ELF64) /* (amd64-only) */
- {NULL, NULL, SHT_NOBITS,
+ {NULL, MSG_ORIG(MSG_ENT_LBSS), SHT_NOBITS,
SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE,
SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE,
- (Sg_desc *)LD_DATA, 0, FALSE},
+ (Sg_desc *)LD_DATA, 0, FLG_EC_BUILTIN},
- {NULL, NULL, NULL,
+ {NULL, MSG_ORIG(MSG_ENT_LDATA), NULL,
SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE,
SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE,
- (Sg_desc *)LD_LDATA, 0, FALSE},
+ (Sg_desc *)LD_LDATA, 0, FLG_EC_BUILTIN},
#endif
- {NULL, NULL, NULL,
+ {NULL, MSG_ORIG(MSG_ENT_DATA), NULL,
SHF_ALLOC + SHF_WRITE, SHF_ALLOC + SHF_WRITE,
- (Sg_desc *)LD_DATA, 0, FALSE},
+ (Sg_desc *)LD_DATA, 0, FLG_EC_BUILTIN},
- {NULL, NULL, 0, 0, 0,
- (Sg_desc *)LD_EXTRA, 0, FALSE}
+ {NULL, MSG_ORIG(MSG_ENT_EXTRA), 0, 0, 0,
+ (Sg_desc *)LD_EXTRA, 0, FLG_EC_BUILTIN}
};
/*
diff --git a/usr/src/cmd/sgs/libld/common/exit.c b/usr/src/cmd/sgs/libld/common/exit.c
index e08fdaeffc..042086d13c 100644
--- a/usr/src/cmd/sgs/libld/common/exit.c
+++ b/usr/src/cmd/sgs/libld/common/exit.c
@@ -23,10 +23,9 @@
* Copyright (c) 1988 AT&T
* All Rights Reserved
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Utility functions
@@ -54,6 +53,12 @@ ld_exit(Ofl_desc *ofl)
* Inform any support library that the link-edit has failed.
*/
ld_sup_atexit(ofl, 1);
+
+ /*
+ * Wrap up debug output file if one is open
+ */
+ dbg_cleanup();
+
return (1);
}
diff --git a/usr/src/cmd/sgs/libld/common/files.c b/usr/src/cmd/sgs/libld/common/files.c
index bf20e39b6c..c275cec30c 100644
--- a/usr/src/cmd/sgs/libld/common/files.c
+++ b/usr/src/cmd/sgs/libld/common/files.c
@@ -1912,8 +1912,7 @@ process_elf(Ifl_desc *ifl, Elf *elf, Ofl_desc *ofl)
((isp->is_flags & FLG_IS_ORDERED) == 0))
continue;
- if (ld_process_ordered(ifl, ofl, ndx,
- ifl->ifl_shnum) == S_ERROR)
+ if (ld_process_ordered(ifl, ofl, ndx) == S_ERROR)
return (S_ERROR);
}
}
diff --git a/usr/src/cmd/sgs/libld/common/ldmain.c b/usr/src/cmd/sgs/libld/common/ldmain.c
index bbdce65450..19ef992801 100644
--- a/usr/src/cmd/sgs/libld/common/ldmain.c
+++ b/usr/src/cmd/sgs/libld/common/ldmain.c
@@ -385,6 +385,11 @@ ld_main(int argc, char **argv, Half mach)
DBG_CALL(Dbg_statistics_ld(ofl));
/*
+ * Wrap up debug output file if one is open
+ */
+ dbg_cleanup();
+
+ /*
* For performance reasons we don't actually free up the memory we've
* allocated, it will be freed when we exit.
*
diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg
index 9f20faad04..bf19364ea3 100644
--- a/usr/src/cmd/sgs/libld/common/libld.msg
+++ b/usr/src/cmd/sgs/libld/common/libld.msg
@@ -732,16 +732,18 @@
# Entry criteria strings (segment names)
-@ MSG_ENT_PHDR "phdr"
-@ MSG_ENT_INTERP "interp"
-@ MSG_ENT_TEXT "text"
-@ MSG_ENT_DATA "data"
@ MSG_ENT_BSS "bss"
+@ MSG_ENT_DATA "data"
@ MSG_ENT_DTRACE "dtrace"
@ MSG_ENT_DYNAMIC "dynamic"
+@ MSG_ENT_EXTRA "extra"
+@ MSG_ENT_INTERP "interp"
+@ MSG_ENT_LBSS "lbss"
@ MSG_ENT_LDATA "ldata"
@ MSG_ENT_LRODATA "lrodata"
@ MSG_ENT_NOTE "note"
+@ MSG_ENT_PHDR "phdr"
+@ MSG_ENT_TEXT "text"
@ MSG_ENT_TLS "tls"
@ MSG_ENT_UNWIND "unwind"
@@ -1072,6 +1074,8 @@
# Reference to this strings is via the MSG_ORIG() macro, and thus no message
# translation is required.
+@ MSG_DBG_FOPEN_MODE "w"
+
@ MSG_DBG_CLS32_FMT "32: "
@ MSG_DBG_CLS64_FMT "64: "
diff --git a/usr/src/cmd/sgs/libld/common/order.c b/usr/src/cmd/sgs/libld/common/order.c
index 1cb2ed7032..2a53687846 100644
--- a/usr/src/cmd/sgs/libld/common/order.c
+++ b/usr/src/cmd/sgs/libld/common/order.c
@@ -40,29 +40,30 @@
/*
* Get the head section number
*/
-static Word
+inline static Word
is_keylink_ok(Ifl_desc *ifl, Word keylink, Word limit)
{
- if ((keylink != SHN_BEFORE) && (keylink != SHN_AFTER)) {
- /*
- * Range Check
- */
- if ((keylink == 0) || (keylink >= limit)) {
- return (DBG_ORDER_LINK_OUTRANGE);
- }
+ if ((keylink == SHN_BEFORE) || (keylink == SHN_AFTER))
+ return (0);
+
+ /*
+ * Validate the key range.
+ */
+ if ((keylink == 0) || (keylink >= limit))
+ return (DBG_ORDER_LINK_OUTRANGE);
+
+ /*
+ * The section pointed to by keylink should not be an ordered section.
+ */
+ if (ifl->ifl_isdesc[keylink]->is_shdr->sh_flags & ALL_SHF_ORDER)
+ return (DBG_ORDER_INFO_ORDER);
- /*
- * The section pointed by keylink should not be an
- * ordered section.
- */
- if (ifl->ifl_isdesc[keylink]->is_shdr->sh_flags &
- ALL_SHF_ORDER) {
- return (DBG_ORDER_INFO_ORDER);
- }
- }
return (0);
}
+/*
+ * Get the head section number.
+ */
static Word
get_shfordered_dest(Ofl_desc *ofl, Ifl_desc *ifl, Word ndx, Word limit)
{
@@ -147,19 +148,18 @@ get_shfordered_dest(Ofl_desc *ofl, Ifl_desc *ifl, Word ndx, Word limit)
* This routine does the input processing of the ordered sections.
*/
uintptr_t
-ld_process_ordered(Ifl_desc *ifl, Ofl_desc *ofl, Word ndx, Word limit)
+ld_process_ordered(Ifl_desc *ifl, Ofl_desc *ofl, Word ndx)
{
Is_desc *isp2, *isp = ifl->ifl_isdesc[ndx];
Xword shflags = isp->is_shdr->sh_flags;
- uint_t keylink;
+ Word keylink, dest_ndx, limit = ifl->ifl_shnum;
Os_desc *osp2, *osp;
- Word dest_ndx;
Sort_desc *st;
Aliste idx;
int error = 0;
/*
- * I might have been checked and marked error already.
+ * This section might have been checked and marked in error already.
*/
if ((isp->is_flags & FLG_IS_ORDERED) == 0)
return (0);
@@ -205,7 +205,9 @@ ld_process_ordered(Ifl_desc *ifl, Ofl_desc *ofl, Word ndx, Word limit)
}
/*
- * Place the section into it's output section.
+ * Place the section into its output section. It's possible that this
+ * section is discarded (possibly because it's defined COMDAT), in
+ * which case we're done.
*/
if ((osp = isp->is_osdesc) == NULL) {
if ((osp = ld_place_section(ofl, isp, isp->is_keyident,
diff --git a/usr/src/cmd/sgs/libld/common/place.c b/usr/src/cmd/sgs/libld/common/place.c
index 824552436c..86a5c83717 100644
--- a/usr/src/cmd/sgs/libld/common/place.c
+++ b/usr/src/cmd/sgs/libld/common/place.c
@@ -437,7 +437,8 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
(enp->ec_attrmask & enp->ec_attrbits) !=
(enp->ec_attrmask & shflags))
continue;
- if (enp->ec_name && (strcmp(enp->ec_name, isp->is_name) != 0))
+ if (((enp->ec_flags & FLG_EC_BUILTIN) == 0) &&
+ enp->ec_name && (strcmp(enp->ec_name, isp->is_name) != 0))
continue;
if (enp->ec_files) {
Aliste idx2;
@@ -519,8 +520,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
return ((Os_desc *)S_ERROR);
(void) strncpy(oname, isp->is_name, size);
oname[size] = '\0';
- DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp->is_name,
- oname));
+ DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp, oname));
}
isp->is_ordndx = enp->ec_ordndx;
}
@@ -544,8 +544,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
MSG_SCN_GNU_LINKONCE_SIZE) == 0)) {
if ((oname =
(char *)gnu_linkonce_sec(isp->is_name)) != isp->is_name) {
- DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp->is_name,
- oname));
+ DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp, oname));
}
/*
@@ -556,7 +555,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
isp->is_flags |= FLG_IS_COMDAT;
if ((ofl->ofl_flags1 & FLG_OF1_NRLXREL) == 0)
ofl->ofl_flags1 |= FLG_OF1_RLXREL;
- Dbg_sec_gnu_comdat(ofl->ofl_lml, isp->is_name, 1,
+ Dbg_sec_gnu_comdat(ofl->ofl_lml, isp, 1,
(ofl->ofl_flags1 & FLG_OF1_RLXREL));
}
@@ -579,8 +578,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
return ((Os_desc *)S_ERROR);
(void) strncpy(oname, isp->is_name, size);
oname[size] = '\0';
- DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp->is_name,
- oname));
+ DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp, oname));
/*
* Enable lazy relocation processing, as this is typically a
@@ -588,7 +586,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
*/
if ((ofl->ofl_flags1 & FLG_OF1_NRLXREL) == 0) {
ofl->ofl_flags1 |= FLG_OF1_RLXREL;
- Dbg_sec_gnu_comdat(ofl->ofl_lml, isp->is_name, 0,
+ Dbg_sec_gnu_comdat(ofl->ofl_lml, isp, 0,
(ofl->ofl_flags1 & FLG_OF1_RLXREL));
}
}
@@ -750,9 +748,10 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, int ident, Word link)
/*
* If this input section and file is associated to an
* artificially referenced output section, make sure
- * they are marked as referenced also. This insures this
- * input section and file isn't eliminated when -zignore
- * is in effect.
+ * they are marked as referenced also. This ensures
+ * that this input section and file isn't eliminated
+ * when -zignore is in effect.
+ *
* See -zignore comments when creating a new output
* section below.
*/
diff --git a/usr/src/cmd/sgs/libld/common/relocate.c b/usr/src/cmd/sgs/libld/common/relocate.c
index 96479d7157..2f31d506b1 100644
--- a/usr/src/cmd/sgs/libld/common/relocate.c
+++ b/usr/src/cmd/sgs/libld/common/relocate.c
@@ -1163,7 +1163,7 @@ reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
uintptr_t
ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
- const char *isname)
+ const char *isname, Word isscnndx)
{
Word rtype = reld->rel_rtype;
ofl_flag_t flags = ofl->ofl_flags;
@@ -1173,7 +1173,7 @@ ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
Conv_inv_buf_t inv_buf;
DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, ld_targ.t_m.m_mach,
- ld_targ.t_m.m_rel_sht_type, (void *)reloc, isname,
+ ld_targ.t_m.m_rel_sht_type, (void *)reloc, isname, isscnndx,
reld->rel_sname));
/*
@@ -1550,8 +1550,7 @@ sloppy_comdat_reloc(Ofl_desc *ofl, Rel_desc *reld, Sym_desc *sdp,
isp->is_name, rep_sdp->sd_file->ifl_name);
}
}
- DBG_CALL(Dbg_reloc_sloppycomdat(ofl->ofl_lml,
- isp->is_name, rep_sdp));
+ DBG_CALL(Dbg_reloc_sloppycomdat(ofl->ofl_lml, rep_sdp));
*reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_NONE;
return (ofl->ofl_sr_cache.sr_rsdp = rep_sdp);
}
@@ -1658,7 +1657,8 @@ process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
ld_targ.t_m.m_mach, isp->is_shdr->sh_type,
- (void *)reloc, isp->is_name, reld->rel_sname));
+ (void *)reloc, isp->is_name, isp->is_scnndx,
+ reld->rel_sname));
if (ld_targ.t_mr.mr_reloc_register == NULL) {
eprintf(ofl->ofl_lml, ERR_FATAL,
MSG_INTL(MSG_REL_NOREG));
@@ -1701,7 +1701,8 @@ process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
if (rtype == ld_targ.t_m.m_r_none) {
DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
ld_targ.t_m.m_mach, ld_targ.t_m.m_rel_sht_type,
- (void *)reloc, isp->is_name, reld->rel_sname));
+ (void *)reloc, isp->is_name, isp->is_scnndx,
+ reld->rel_sname));
eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_NULL),
ifl->ifl_name, isp->is_name);
return (1);
@@ -1855,7 +1856,8 @@ process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
}
reld->rel_sym = sdp;
- return (ld_process_sym_reloc(ofl, reld, reloc, isp, isp->is_name));
+ return (ld_process_sym_reloc(ofl, reld, reloc, isp, isp->is_name,
+ isp->is_scnndx));
}
static uintptr_t
diff --git a/usr/src/cmd/sgs/libld/common/sections.c b/usr/src/cmd/sgs/libld/common/sections.c
index fd4a58c880..f7bb92f3f5 100644
--- a/usr/src/cmd/sgs/libld/common/sections.c
+++ b/usr/src/cmd/sgs/libld/common/sections.c
@@ -848,7 +848,7 @@ make_array(Ofl_desc *ofl, Word shtype, const char *sectname, APlist *alp)
reld.rel_sym = sdp;
if (ld_process_sym_reloc(ofl, &reld, (Rel *)&reloc, isec,
- MSG_INTL(MSG_STR_COMMAND)) == S_ERROR) {
+ MSG_INTL(MSG_STR_COMMAND), 0) == S_ERROR) {
ret = S_ERROR;
continue;
}
diff --git a/usr/src/cmd/sgs/libld/common/support.c b/usr/src/cmd/sgs/libld/common/support.c
index 90517b4a60..c7fd00ac2f 100644
--- a/usr/src/cmd/sgs/libld/common/support.c
+++ b/usr/src/cmd/sgs/libld/common/support.c
@@ -291,7 +291,8 @@ ld_sup_input_section(Ofl_desc *ofl, Ifl_desc *ifl, const char *sname,
if (nshdr != *oshdr) {
Dbg_shdr_modified(ofl->ofl_lml, flp->fl_obj,
ifl->ifl_ehdr->e_ident[EI_OSABI],
- ifl->ifl_ehdr->e_machine, *oshdr, nshdr, sname);
+ ifl->ifl_ehdr->e_machine, ndx, *oshdr, nshdr,
+ sname);
*oshdr = nshdr;
}
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/_debug.h b/usr/src/cmd/sgs/liblddbg/common/_debug.h
index ad51ecdac0..e8606f859a 100644
--- a/usr/src/cmd/sgs/liblddbg/common/_debug.h
+++ b/usr/src/cmd/sgs/liblddbg/common/_debug.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _DEBUG_DOT_H
#define _DEBUG_DOT_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <debug.h>
#include <conv.h>
@@ -46,29 +44,29 @@ extern "C" {
#define DBG_NOTCLASS(c) !(dbg_desc->d_class & (c))
#define DBG_C_ARGS 0x00000001
-#define DBG_C_BASIC 0x00000002
-#define DBG_C_BINDINGS 0x00000004
-#define DBG_C_ENTRY 0x00000008
-#define DBG_C_FILES 0x00000010
-#define DBG_C_HELP 0x00000020
-#define DBG_C_LIBS 0x00000040
-#define DBG_C_MAP 0x00000080
-#define DBG_C_RELOC 0x00000100
-#define DBG_C_SECTIONS 0x00000200
-#define DBG_C_SEGMENTS 0x00000400
-#define DBG_C_SYMBOLS 0x00000800
-#define DBG_C_SUPPORT 0x00001000
-#define DBG_C_VERSIONS 0x00002000
-#define DBG_C_AUDITING 0x00004000
-#define DBG_C_GOT 0x00008000
-#define DBG_C_MOVE 0x00010000
-#define DBG_C_DEMANGLE 0x00020000
-#define DBG_C_TLS 0x00040000
-#define DBG_C_STRTAB 0x00080000
-#define DBG_C_STATS 0x00100000
+#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_CAP 0x00400000
-#define DBG_C_INIT 0x00800000
+#define DBG_C_VERSIONS 0x00400000
+
#define DBG_C_ALL 0xffffffff
@@ -214,6 +212,28 @@ typedef struct {
#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
diff --git a/usr/src/cmd/sgs/liblddbg/common/debug.c b/usr/src/cmd/sgs/liblddbg/common/debug.c
index 9a291ea543..110d64938a 100644
--- a/usr/src/cmd/sgs/liblddbg/common/debug.c
+++ b/usr/src/cmd/sgs/liblddbg/common/debug.c
@@ -50,140 +50,218 @@ int _Dbg_cnt = 0;
* 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.
*/
-DBG_options _Dbg_options[] = {
+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_NAME), 0, DBG_E_SNAME},
- {MSG_ORIG(MSG_TOK_FULLNAME), 0, DBG_E_SNAME | DBG_E_FNAME},
- {MSG_ORIG(MSG_TOK_CLASS), 0, DBG_E_SNAME | DBG_E_CLASS},
- {MSG_ORIG(MSG_TOK_LMID), 0, DBG_E_LMID},
+ {MSG_ORIG(MSG_TOK_HELP), 0, DBG_E_HELP},
{MSG_ORIG(MSG_TOK_ALL), DBG_C_ALL, 0},
- {MSG_ORIG(MSG_TOK_ARGS), DBG_C_ARGS, 0},
{MSG_ORIG(MSG_TOK_BASIC), DBG_C_BASIC, 0},
- {MSG_ORIG(MSG_TOK_BINDINGS), DBG_C_BINDINGS, 0},
- {MSG_ORIG(MSG_TOK_ENTRY), DBG_C_ENTRY, 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_HELP), DBG_C_HELP, 0},
{MSG_ORIG(MSG_TOK_LIBS), DBG_C_LIBS, 0},
- {MSG_ORIG(MSG_TOK_MAP), DBG_C_MAP, 0},
+ {MSG_ORIG(MSG_TOK_MOVE), DBG_C_MOVE, 0},
{MSG_ORIG(MSG_TOK_RELOC), DBG_C_RELOC, 0},
- {MSG_ORIG(MSG_TOK_SECTIONS), DBG_C_SECTIONS, 0},
- {MSG_ORIG(MSG_TOK_SEGMENTS), DBG_C_SEGMENTS, 0},
- {MSG_ORIG(MSG_TOK_SUPPORT), DBG_C_SUPPORT, 0},
{MSG_ORIG(MSG_TOK_SYMBOLS), DBG_C_SYMBOLS, 0},
{MSG_ORIG(MSG_TOK_TLS), DBG_C_TLS, 0},
- {MSG_ORIG(MSG_TOK_AUDIT), DBG_C_AUDITING, 0},
+ {MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0},
{MSG_ORIG(MSG_TOK_VERSIONS), DBG_C_VERSIONS, 0},
+ {NULL, NULL},
+};
+
+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_MOVE), DBG_C_MOVE, 0},
- {MSG_ORIG(MSG_TOK_STRTAB), DBG_C_STRTAB, 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_UNUSED), DBG_C_UNUSED, 0},
- {MSG_ORIG(MSG_TOK_DEMANGLE), DBG_C_DEMANGLE, 0},
- {MSG_ORIG(MSG_TOK_CAP), DBG_C_CAP, 0},
+ {MSG_ORIG(MSG_TOK_STRTAB), DBG_C_STRTAB, 0},
+ {MSG_ORIG(MSG_TOK_SUPPORT), DBG_C_SUPPORT, 0},
+ {NULL, NULL},
+};
+
+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_INIT), DBG_C_INIT, 0},
{NULL, NULL},
};
/*
- * Tokens may also define identifiers for diagnostics. Presently, only ld.so.1
- * uses these strings to identify, or isolate its output to selected link-map
- * lists. See ld.so.1:dbg_print().
+ * Compare name to the options found in optarr. If one matches,
+ * update *dbp and return TRUE. Otherwise, FALSE.
*/
-const char *_Dbg_strs[] = {
- MSG_ORIG(MSG_TOK_BASE), MSG_ORIG(MSG_TOK_LDSO),
- MSG_ORIG(MSG_TOK_NEWLM), NULL
-};
+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_usage()
+Dbg_help(void)
{
Dbg_util_nl(0, DBG_NL_FRC);
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_A));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_B));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_C));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_D));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_E));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_F));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_G));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_H));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_I));
+ 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_RTLD_J));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_K));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_L));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_M));
+ 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_util_nl(0, DBG_NL_FRC);
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_N));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_O));
+ 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_print(0, MSG_INTL(MSG_USE_R2_R));
+ dbg_print(0, MSG_INTL(MSG_USE_R2_S));
+
+ 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_RTLD_P));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_Q));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_R));
- dbg_print(0, MSG_INTL(MSG_USE_RTLD_S));
+ 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_LD_A));
- dbg_print(0, MSG_INTL(MSG_USE_LD_B));
- dbg_print(0, MSG_INTL(MSG_USE_LD_C));
- dbg_print(0, MSG_INTL(MSG_USE_LD_D));
- dbg_print(0, MSG_INTL(MSG_USE_LD_E));
- dbg_print(0, MSG_INTL(MSG_USE_LD_F));
- dbg_print(0, MSG_INTL(MSG_USE_LD_G));
- dbg_print(0, MSG_INTL(MSG_USE_LD_H));
+ dbg_print(0, MSG_INTL(MSG_USE_R3_N));
+
Dbg_util_nl(0, DBG_NL_FRC);
- dbg_print(0, MSG_INTL(MSG_USE_LD_I));
+ 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_D));
+ dbg_print(0, MSG_INTL(MSG_USE_R4_D2));
+ dbg_print(0, MSG_INTL(MSG_USE_R4_D3));
+
Dbg_util_nl(0, DBG_NL_FRC);
- dbg_print(0, MSG_INTL(MSG_USE_LD_J));
- dbg_print(0, MSG_INTL(MSG_USE_LD_K));
+ 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_LD_L));
+ 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_LD_M));
- dbg_print(0, MSG_INTL(MSG_USE_LD_N));
- dbg_print(0, MSG_INTL(MSG_USE_LD_O));
+ 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_util_nl(0, DBG_NL_FRC);
- dbg_print(0, MSG_INTL(MSG_USE_ARGS));
- dbg_print(0, MSG_INTL(MSG_USE_AUDIT));
- dbg_print(0, MSG_INTL(MSG_USE_BASIC));
- dbg_print(0, MSG_INTL(MSG_USE_BINDINGS));
- dbg_print(0, MSG_INTL(MSG_USE_BINDINGS_2));
- dbg_print(0, MSG_INTL(MSG_USE_CAP));
- dbg_print(0, MSG_INTL(MSG_USE_DETAIL));
-#ifdef DEMANGLE
- dbg_print(0, MSG_INTL(MSG_USE_DEMANGLE));
-#endif
- dbg_print(0, MSG_INTL(MSG_USE_ENTRY));
- dbg_print(0, MSG_INTL(MSG_USE_FILES));
- dbg_print(0, MSG_INTL(MSG_USE_GOT));
- dbg_print(0, MSG_INTL(MSG_USE_HELP));
- dbg_print(0, MSG_INTL(MSG_USE_INIT));
- dbg_print(0, MSG_INTL(MSG_USE_LIBS));
- dbg_print(0, MSG_INTL(MSG_USE_LIBS_2));
- dbg_print(0, MSG_INTL(MSG_USE_LMID));
- dbg_print(0, MSG_INTL(MSG_USE_LONG));
- dbg_print(0, MSG_INTL(MSG_USE_MAP));
- dbg_print(0, MSG_INTL(MSG_USE_MOVE));
- dbg_print(0, MSG_INTL(MSG_USE_RELOC));
- dbg_print(0, MSG_INTL(MSG_USE_SECTIONS));
- dbg_print(0, MSG_INTL(MSG_USE_SEGMENTS));
- dbg_print(0, MSG_INTL(MSG_USE_SEGMENTS_2));
- dbg_print(0, MSG_INTL(MSG_USE_STATS));
- dbg_print(0, MSG_INTL(MSG_USE_STRTAB));
- dbg_print(0, MSG_INTL(MSG_USE_STRTAB_2));
- dbg_print(0, MSG_INTL(MSG_USE_SUPPORT));
- dbg_print(0, MSG_INTL(MSG_USE_SYMBOLS));
- dbg_print(0, MSG_INTL(MSG_USE_SYMBOLS_2));
- dbg_print(0, MSG_INTL(MSG_USE_TLS));
- dbg_print(0, MSG_INTL(MSG_USE_UNUSED));
- dbg_print(0, MSG_INTL(MSG_USE_UNUSED_2));
- dbg_print(0, MSG_INTL(MSG_USE_VERSIONS));
+ 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);
}
@@ -198,20 +276,140 @@ _liblddbg_msg(Msg 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, NULL},
+ };
+
+ 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.
*/
-uintptr_t
-Dbg_setup(const char *string, Dbg_desc *dbp)
+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);
- if ((_name = (char *)malloc(strlen(string) + 1)) == 0)
- return (S_ERROR);
+ /*
+ * 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
@@ -219,10 +417,10 @@ Dbg_setup(const char *string, Dbg_desc *dbp)
*/
if ((name = strtok_r(_name, delimit, &lasts)) != NULL) {
do {
- DBG_options *opt;
- const char *str;
- Boolean set, found = FALSE;
- int ndx = 0;
+ Boolean set;
+
+ /* Remove leading and trailing whitespace */
+ name = conv_strproc_trim(name);
if (name[0] == '!') {
set = FALSE;
@@ -230,81 +428,70 @@ Dbg_setup(const char *string, Dbg_desc *dbp)
} else
set = TRUE;
+ if (*name == '\0')
+ continue; /* Skip null token */
+
/*
* First, determine if the token represents a class or
* extra.
*/
- for (opt = _Dbg_options; opt->o_name != NULL; opt++) {
- if (strcmp(name, opt->o_name) != 0)
+ 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;
-
- 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);
- }
- found = TRUE;
break;
}
- if (found == TRUE)
+
+ /* The remaining options do not accept negation */
+ if (!set) {
+ dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name);
continue;
+ }
/*
- * Second, determine if the token represents a known
- * diagnostic identifier. Note, newlm identifiers are
- * typically followed by a numeric id, for example
- * newlm1, newlm2 ... Thus we only compare the
- * initial text of the string.
+ * 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.
*/
- while ((str = _Dbg_strs[ndx++]) != NULL) {
- char *tup;
-
- if (strncmp(name, str, strlen(str)) != 0)
+ 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;
-
- /*
- * Translate lmid identifier to uppercase.
- */
- for (tup = name; *tup; tup++) {
- if ((*tup >= 'a') && (*tup <= 'z'))
- *tup = *tup - ('a' - 'A');
- }
-
- /*
- * Save this lmid. The whole token buffer has
- * been reallocated, so these names will remain
- * once this routine returns.
- */
- if (aplist_append(&dbp->d_list, name,
- AL_CNT_DEBUG) == NULL)
- return (S_ERROR);
-
- found = TRUE;
- break;
}
- if (found == FALSE)
- dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name);
+ /*
+ * 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 dump a usage message. If
- * this is the only debug class, return an indication that the user
- * should exit.
+ * 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_class & DBG_C_HELP)) {
- Dbg_usage();
- if (dbp->d_class == DBG_C_HELP)
- return (0);
- }
+ if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) &&
+ (dbp->d_class == 0))
+ dbp->d_extra |= DBG_E_HELP_EXIT;
+
return (1);
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
index b486aa6f74..acf7fad9ba 100644
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
@@ -33,253 +33,462 @@
# Usage messages
-@ MSG_USE_UNRECOG "warning: unrecognized debug option `%s' (try help)"
+@ MSG_USE_UNRECOG "warning: unrecognized debug option (try help): %s"
+@ MSG_USE_CNTNEGOPT "warning: ignoring non-negatable debug option: %s"
-# TRANSLATION_NOTE - Use the following output in C as a reference, 1.
+@ 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.
#
-# Runtime Linking
-# Diagnostics that trace the runtime linking of an application can be
-# enabled to stderr by using the environment variable setting:
-# LD_DEBUG=token1,token2
-# Alternatively, the diagnostics can be redirected to an output file
-# using the additional environment variable:
-# LD_DEBUG_OUTPUT=file
-# The output file is given the specified name and the process id as a
-# suffix.
+# 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.
#
-# By default, all diagnostics are prepended with the process id,
-# together with the thread id. Note, all applications are effectively
-# thread aware, and once thread capabilities are enabled, even a single
-# threaded application is labeled as thread 1.
+# 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.
#
-# The token `lmid' prepends a link-map list identifier to each
-# diagnostic.
+# 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"
+@ MSG_USE_R2_M " specified, without a process id suffix."
+
+
+@ MSG_USE_R2_N " All runtime linker diagnostics are prepended with \
+ the process"
+@ MSG_USE_R2_O " id. If thread capabilities are enabled for the \
+ process, the"
+@ MSG_USE_R2_P " thread id is also shown. All Solaris applications are \
+ thread"
+@ MSG_USE_R2_Q " capable, and a single threaded application may \
+ use threads via"
+@ MSG_USE_R2_R " the libraries it links to. Diagnostics from such \
+ applications"
+@ MSG_USE_R2_S " reference thread id 1."
+
+# TRANSLATION_NOTE - End of reference 2
+
+
+# TRANSLATION_NOTE - Use the following output in the C locale as reference 3.
#
-# The tokens `base', `ldso' and `newlm[0-9]*' can be used to isolate
-# diagnostics to the associated link-map lists. Note, by default, any
-# diagnostics associated with loading components for the runtime linker
-# itself are suppressed, unless `ldso' is explicitly specified.
+# 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 ...
#
-# Link-Editing
-# Diagnostics that trace the link-editing of an application can be
-# enabled to stderr using the -D option:
-# ld -Dtoken1,token2 -o prog ...
-# As the -D option can also be meaningful to compiler drivers, an
-# alternative mechanism to enable diagnostics is to use the environment
-# variable:
-# LD_OPTIONS=-Dtoken1,token2 cc -o prog ...
-#
-# The use 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 `!'.
+# 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.
#
-# By default, all diagnostics are prepended with the string `debug'.
+# demangle show C++ symbol names in their demangled form
+# detail provide more information in conjunction with
+# other options
+# 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.
#
-# The tokens `name', `fullname' and `class' can be used to prepend the
-# output file basename, fullname, and class respectively, to each
-# diagnostic.
-
# TRANSLATION_NOTE - The next series of messages makes the above output in C
-# locale. Use tabs and space alignment characters as needed.
-#
-@ MSG_USE_RTLD_A "Runtime Linking"
-@ MSG_USE_RTLD_B " Diagnostics that trace the runtime linking of an \
- application can be"
-@ MSG_USE_RTLD_C " enabled to stderr by using the environment \
- variable setting:"
-@ MSG_USE_RTLD_D " LD_DEBUG=token1,token2 app ..."
-@ MSG_USE_RTLD_E " Alternatively, the diagnostics can be redirected \
- to an output file"
-@ MSG_USE_RTLD_F " using the additional environment variable:"
-@ MSG_USE_RTLD_G " LD_DEBUG_OUTPUT=file"
-@ MSG_USE_RTLD_H " The output file is given the specified name and \
- the process id as a"
-@ MSG_USE_RTLD_I " suffix."
-@ MSG_USE_RTLD_J " By default, all diagnostics are prepended with \
- the process id,"
-@ MSG_USE_RTLD_K " together with the thread id. Note, all \
- applications are effectively"
-@ MSG_USE_RTLD_L " thread aware, and once thread capabilities are \
- enabled, even a single"
-@ MSG_USE_RTLD_M " threaded application is labeled as thread 1."
-@ MSG_USE_RTLD_N " The token `lmid' prepends a link-map list \
- identifier to each"
-@ MSG_USE_RTLD_O " diagnostic."
-@ MSG_USE_RTLD_P " The tokens `base', `ldso' and `newlm[0-9]*' can \
- be used to isolate"
-@ MSG_USE_RTLD_Q " diagnostics to the associated link-map lists. \
- Note, by default, any"
-@ MSG_USE_RTLD_R " diagnostics associated with loading components \
- for the runtime linker"
-@ MSG_USE_RTLD_S " itself are suppressed, unless `ldso' is \
- explicitly specified."
-
-@ MSG_USE_LD_A "Link-Editing"
-@ MSG_USE_LD_B " Diagnostics that trace the link-editing of an \
- application can be"
-@ MSG_USE_LD_C " enabled to stderr using the -D option:"
-@ MSG_USE_LD_D " ld -Dtoken1,token2 -o prog ..."
-@ MSG_USE_LD_E " As the -D option can also be meaningful to \
- compiler drivers, an"
-@ MSG_USE_LD_F " alternative mechanism to enable diagnostics is to \
- use the environment"
-@ MSG_USE_LD_G " variable:"
-@ MSG_USE_LD_H " LD_OPTIONS=-Dtoken1,token2 cc -o prog ..."
-@ MSG_USE_LD_I " The use of -D on the link-edit command line is \
- significant."
-@ MSG_USE_LD_J " Diagnostics are enabled when a debug token is \
- first encountered, and"
-@ MSG_USE_LD_K " can be switched off by prepending the token \
- with `!'."
-@ MSG_USE_LD_L " By default, all diagnostics are prepended with \
- the string `debug'."
-@ MSG_USE_LD_M " The tokens `name', `fullname' and `class' can be \
- used to prepend"
-@ MSG_USE_LD_N " the output file basename, fullname, and class \
- respectively, to each"
-@ MSG_USE_LD_O " diagnostic."
+# locale.
-# TRANSLATION_NOTE - End of reference 1
+# 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 "long".
+@ MSG_USE_R4_C " long display long object names without \
+ truncation"
+# TRANSLATION_NOTE -- do not translate the first token "output".
+@ MSG_USE_R4_D " output=file debug output is sent to the \
+ named file"
+@ MSG_USE_R4_D2 " instead of stderr. If file is \
+ empty (\"\"),"
+@ MSG_USE_R4_D3 " following output will be \
+ sent to stderr."
-# TRANSLATION_NOTE - The next series of messages makes the following usage
-# table. Use tabs and space alignment characters as needed.
+# TRANSLATION_NOTE - End of reference 4
+
+
+# TRANSLATION_NOTE - Use the following output in the C locale as reference 5.
#
-# args display input argument processing (ld only)
-# audit display runtime link-audit processing (ld.so.1 only)
-# basic provide basic trace information/warnings
-# bindings display symbol binding; detail flag shows absolute:relative
-# addresses (ld.so.1 only)
-# cap display hardware/software capability processing
-# demangle display C++ symbol names in their demangled form
-# detail provide more information in conjunction with other options
-# entry display entrance criteria descriptors (ld only)
-# files display input file processing (files and libraries)
-# got display GOT symbol information (ld only)
-# help display this help message
-# init display init and fini processing (ld.so.1 only)
-# libs display library search paths; detail flag shows actual
-# library lookup (-l) processing
-# long display long object names without truncation
-# map display map file processing (ld only)
-# move display Move section information
-# reloc display relocation processing
-# sections display input section processing (ld only)
-# segments display available output segments and address/offset
-# processing; detail flag shows associated sections (ld only)
-# support display support library processing (ld only)
-# symbols display symbol table processing; detail flag shows internal
-# symbol table addition and resolution (ld only)
-# statistics display processing statistics (ld only)
-# strtab display information about string table compression; detail
-# flag shows layout of string tables (ld only)
-# tls display TLS processing
-# unused display unused/unreferenced files; detail flag shows unused
-# sections (ld only), and unused search paths (ld.so.1 only)
-# versions display version processing
+# 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.
#
-# TRANSLATION_NOTE -- do not translate the first token `args'.
-@ MSG_USE_ARGS "args\t display input argument processing (ld only)"
+# all display information for all categories
+# basic basic trace information/warnings
+# cap 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 -- do not translate the first token `audit'.
-@ MSG_USE_AUDIT "audit\t display runtime link-audit processing \
- (ld.so.1 only)"
+# TRANSLATION_NOTE - The next series of messages makes the above output in C
+# locale.
-# TRANSLATION_NOTE -- do not translate the first token `basic'.
-@ MSG_USE_BASIC "basic\t provide basic trace information/warnings"
-# TRANSLATION_NOTE -- do not translate the first token `bindings'.
-@ MSG_USE_BINDINGS "bindings\t display symbol binding; detail flag shows \
- absolute:relative"
-@ MSG_USE_BINDINGS_2 "\t\t addresses (ld.so.1 only)"
+# 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 `cap'
-@ MSG_USE_CAP "cap\t display hardware/software capability \
- processing"
+# 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 `detail'.
-@ MSG_USE_DETAIL "detail\t provide more information in conjunction \
- with other options"
+# TRANSLATION_NOTE -- do not translate the first token "cap".
+@ MSG_USE_R7_C " cap hardware/software capabilities"
-# TRANSLATION_NOTE -- do not translate the first token `demangle'.
-@ MSG_USE_DEMANGLE "demangle\t display C++ symbol names in their \
- demangled form"
+# 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 `entry'.
-@ MSG_USE_ENTRY "entry\t display entrance criteria descriptors \
- (ld only)"
+# 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 `files'.
-@ MSG_USE_FILES "files\t display input file processing \
- (files and libraries)"
+# 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 `got'.
-@ MSG_USE_GOT "got\t display GOT symbol information (ld only)"
+# TRANSLATION_NOTE -- do not translate the first token "move".
+@ MSG_USE_R7_G " move move sections"
-# TRANSLATION_NOTE -- do not translate the first token `help'.
-@ MSG_USE_HELP "help\t display this help message"
+# TRANSLATION_NOTE -- do not translate the first token "reloc".
+@ MSG_USE_R7_H " reloc relocations"
-# TRANSLATION_NOTE -- do not translate the first token `init'.
-@ MSG_USE_INIT "init\t display init and fini processing \
- (ld.so.1 only)"
+# 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 `libs'.
-@ MSG_USE_LIBS "libs\t display library search paths; detail flag \
- shows actual"
-@ MSG_USE_LIBS_2 "\t\t library lookup (-l) processing"
+# 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 `lmid'.
-@ MSG_USE_LMID "lmid\t display link-map list identifier \
- (ld.so.1 only)"
+# 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 `long'.
-@ MSG_USE_LONG "long\t display long object names without truncation"
+# TRANSLATION_NOTE -- do not translate the first token "versions".
+@ MSG_USE_R7_L " versions ELF versioning"
-# TRANSLATION_NOTE -- do not translate the first token `map'.
-@ MSG_USE_MAP "map\t display map file processing (ld only)"
+# TRANSLATION_NOTE - End of reference 7
-# TRANSLATION_NOTE -- do not translate the first token `move'.
-@ MSG_USE_MOVE "move\t display move section processing"
-# TRANSLATION_NOTE -- do not translate the first token `reloc'.
-@ MSG_USE_RELOC "reloc\t display relocation processing"
+# 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
+# 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 `sections'.
-@ MSG_USE_SECTIONS "sections display input section processing (ld only)"
+# 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 `segments'.
-@ MSG_USE_SEGMENTS "segments display available output segments and \
- address/offset"
-@ MSG_USE_SEGMENTS_2 "\t\t processing; detail flag shows associated \
- sections (ld only)"
-# TRANSLATION_NOTE -- do not translate the first token `support'.
-@ MSG_USE_SUPPORT "support\t display support library processing (ld only)"
+# 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 `symbols'.
-@ MSG_USE_SYMBOLS "symbols\t display symbol table processing; detail \
- flag shows internal"
-@ MSG_USE_SYMBOLS_2 "\t\t symbol table addition and resolution (ld only)"
+# TRANSLATION_NOTE -- do not translate the first token "init".
+@ MSG_USE_R8_C " init init and fini processing"
-# TRANSLATION_NOTE -- do not translate the first token `statistics'.
-@ MSG_USE_STATS "statistics display processing statistics (ld only)"
+# 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 map file 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 `strtab'.
-@ MSG_USE_STRTAB "strtab\t display information about string table \
- compression; detail"
-@ MSG_USE_STRTAB_2 "\t\t flag shows layout of string tables (ld only)"
+# TRANSLATION_NOTE -- do not translate the first token "args".
+@ MSG_USE_R9_A " args input arguments"
-# TRANSLATION_NOTE -- do not translate the first token `tls/TLS'.
-@ MSG_USE_TLS "tls\t display TLS processing info"
+# 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 `unused'.
-@ MSG_USE_UNUSED "unused\t display unused/unreferenced files; detail \
- flag shows unused"
-@ MSG_USE_UNUSED_2 "\t\t sections (ld only)"
+# 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 map file 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
-# TRANSLATION_NOTE -- do not translate the first token `versions'.
-@ MSG_USE_VERSIONS "versions\t display version processing"
# Argument messages
@@ -363,14 +572,14 @@
# 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"
+@ 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"
+@ MSG_EDATA_ENTRY_64 " %3s %#18llx %-5s %#18llx %#16llx %2lld %s %s%s"
@ MSG_EDATA_IGNSCN " (section ignored)"
@@ -572,6 +781,7 @@
@ MSG_SEC_BACKING "map file 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)"
@@ -588,14 +798,14 @@
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_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"
+ 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"
@@ -720,10 +930,9 @@
@ MSG_ORD_SORT_AFTER "section=%s; output section reordered:"
@ MSG_ORD_HDR_1 " number of SHN_BEGIN=%u, SHN_AFTER=%u, \
sh_info/sh_link=%u"
-@ MSG_ORD_TITLE_0 " section=%s from %s is not an ordered section"
-@ MSG_ORD_TITLE_1 " section=%s from %s, %s=SHN_BEGIN"
-@ MSG_ORD_TITLE_2 " section=%s from %s, %s=SHN_AFTER"
-@ MSG_ORD_TITLE_3 " section=%s from %s, %s=%s, sort key=%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"
@@ -1143,9 +1352,13 @@
@ MSG_TOK_FULLNAME "fullname"
@ MSG_TOK_CLASS "class"
@ MSG_TOK_LMID "lmid"
-@ MSG_TOK_BASE "base"
-@ MSG_TOK_LDSO "ldso"
-@ MSG_TOK_NEWLM "newlm"
+@ 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
@@ -1267,6 +1480,7 @@
@ MSG_STR_NL "\n"
@ MSG_FMT_INDEX " [%d]"
+@ MSG_FMT_ISEC_NAME "[%u]%s"
@ MSG_SUNW_OST_SGS "SUNW_OST_SGS"
diff --git a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
index 08ce393167..98d4ccaef6 100644
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
@@ -30,8 +30,7 @@
#include <sys/auxv.h>
#include <debug.h>
-uintptr_t
- Dbg_setup(const char *, Dbg_desc *);
+int Dbg_setup(dbg_setup_caller_t, const char *, Dbg_desc *, const char **);
const char *
Dbg_demangle_name(const char *);
@@ -268,9 +267,9 @@ void Dbg64_reloc_error(Lm_list *, int, Elf64_Half, Elf64_Word, void *,
void Dbg32_reloc_generate(Lm_list *, Os_desc *, Elf32_Word);
void Dbg64_reloc_generate(Lm_list *, Os_desc *, Elf64_Word);
void Dbg32_reloc_in(Lm_list *, int, Elf32_Half, Elf32_Word, void *,
- const char *, const char *);
+ const char *, Elf32_Word, const char *);
void Dbg64_reloc_in(Lm_list *, int, Elf64_Half, Elf64_Word, void *,
- const char *, const char *);
+ const char *, Elf64_Word, const char *);
void Dbg32_reloc_ors_entry(Lm_list *, int, Elf32_Word, Elf32_Half, Rel_desc *);
void Dbg64_reloc_ors_entry(Lm_list *, int, Elf64_Word, Elf64_Half, Rel_desc *);
void Dbg32_reloc_out(Ofl_desc *, int, Elf32_Word, void *, const char *,
@@ -294,16 +293,16 @@ void Dbg32_sec_discarded(Lm_list *, Is_desc *, Is_desc *);
void Dbg64_sec_discarded(Lm_list *, Is_desc *, Is_desc *);
void Dbg32_sec_group(Lm_list *, Is_desc *, Group_desc *);
void Dbg64_sec_group(Lm_list *, Is_desc *, Group_desc *);
-void Dbg32_sec_gnu_comdat(Lm_list *, const char *, uint_t, uint_t);
-void Dbg64_sec_gnu_comdat(Lm_list *, const char *, uint_t, uint_t);
+void Dbg32_sec_gnu_comdat(Lm_list *, Is_desc *, uint_t, uint_t);
+void Dbg64_sec_gnu_comdat(Lm_list *, Is_desc *, uint_t, uint_t);
void Dbg32_sec_in(Lm_list *, Is_desc *);
void Dbg64_sec_in(Lm_list *, Is_desc *);
void Dbg32_sec_order_error(Lm_list *, Ifl_desc *, Elf32_Word, int);
void Dbg64_sec_order_error(Lm_list *, Ifl_desc *, Elf64_Word, int);
void Dbg32_sec_order_list(Ofl_desc *, int);
void Dbg64_sec_order_list(Ofl_desc *, int);
-void Dbg32_sec_redirected(Lm_list *, const char *, const char *);
-void Dbg64_sec_redirected(Lm_list *, const char *, const char *);
+void Dbg32_sec_redirected(Lm_list *, Is_desc *, const char *);
+void Dbg64_sec_redirected(Lm_list *, Is_desc *, const char *);
void Dbg32_sec_strtab(Lm_list *, Os_desc *, Str_tbl *);
void Dbg64_sec_strtab(Lm_list *, Os_desc *, Str_tbl *);
@@ -319,9 +318,9 @@ void Dbg32_seg_title(Lm_list *);
void Dbg64_seg_title(Lm_list *);
void Dbg32_shdr_modified(Lm_list *, const char *, uchar_t, Half,
- Shdr *, Shdr *, const char *);
+ Elf32_Word, Shdr *, Shdr *, const char *);
void Dbg64_shdr_modified(Lm_list *, const char *, uchar_t, Half,
- Shdr *, Shdr *, const char *);
+ Elf64_Word, Shdr *, Shdr *, const char *);
void Dbg32_statistics_ar(Ofl_desc *);
void Dbg64_statistics_ar(Ofl_desc *);
diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
index f69949a4bb..dc6b90c4f2 100644
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
@@ -41,7 +41,7 @@
# MAPFILE HEADER END
#
-SUNWprivate_4.70 {
+SUNWprivate_4.71 {
global:
dbg_desc = NODIRECT; # interposed - ld.so.1(1)
dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1)
@@ -59,6 +59,7 @@ SUNWprivate_4.70 {
Dbg_audit_terminate;
Dbg_audit_version;
+ Dbg_help;
Dbg_setup;
Dbg32_bind_global;
diff --git a/usr/src/cmd/sgs/liblddbg/common/relocate.c b/usr/src/cmd/sgs/liblddbg/common/relocate.c
index 23c2a41873..d9d6d33610 100644
--- a/usr/src/cmd/sgs/liblddbg/common/relocate.c
+++ b/usr/src/cmd/sgs/liblddbg/common/relocate.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -152,6 +152,20 @@ Dbg_reloc_generate(Lm_list *lml, Os_desc *osp, Word type)
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)
{
@@ -233,8 +247,10 @@ Dbg_reloc_dooutrel(Lm_list *lml, Word type)
void
Dbg_reloc_discard(Lm_list *lml, Half mach, Rel_desc *rsp)
{
- Conv_inv_buf_t inv_buf;
- Is_desc *isp;
+ 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;
@@ -242,17 +258,21 @@ Dbg_reloc_discard(Lm_list *lml, Half mach, Rel_desc *rsp)
return;
isp = rsp->rel_isdesc;
- dbg_print(lml, MSG_INTL(MSG_REL_DISCARDED), isp->is_name,
- isp->is_file->ifl_name,
+ 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)
{
- Conv_inv_buf_t inv_buf1, inv_buf2;
- Is_desc *isp;
+ 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;
@@ -260,9 +280,11 @@ Dbg_reloc_transition(Lm_list *lml, Half mach, Word rtype, Rel_desc *rsp)
isp = rsp->rel_isdesc;
dbg_print(lml, MSG_INTL(MSG_REL_TRANSITION),
conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf1),
- isp->is_name, isp->is_file->ifl_name,
+ dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name,
EC_OFF(rsp->rel_roffset), rsp->rel_sname,
conv_reloc_type(mach, rtype, 0, &inv_buf2));
+ if (alloc_mem != NULL)
+ free(alloc_mem);
}
void
@@ -281,15 +303,22 @@ Dbg_reloc_out(Ofl_desc *ofl, int caller, Word type, void *reloc,
void
Dbg_reloc_in(Lm_list *lml, int caller, Half mach, Word type, void *reloc,
- const char *secname, const char *symname)
+ 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,
- secname, symname, MSG_ORIG(MSG_STR_EMPTY));
+ dbg_fmt_isec_name2(secname, secndx, buf, &alloc_mem), symname,
+ MSG_ORIG(MSG_STR_EMPTY));
+
+ if (alloc_mem != NULL)
+ free(alloc_mem);
}
/*
@@ -302,9 +331,11 @@ Dbg_reloc_in(Lm_list *lml, int caller, Half mach, Word type, void *reloc,
* which references the kept section.
*/
void
-Dbg_reloc_sloppycomdat(Lm_list *lml, const char *secname, Sym_desc *sdp)
+Dbg_reloc_sloppycomdat(Lm_list *lml, Sym_desc *sdp)
{
- const char *nfname;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *nfname;
if (DBG_NOTCLASS(DBG_C_RELOC) || DBG_NOTDETAIL())
return;
@@ -312,7 +343,10 @@ Dbg_reloc_sloppycomdat(Lm_list *lml, const char *secname, Sym_desc *sdp)
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), secname, nfname);
+ 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);
}
/*
diff --git a/usr/src/cmd/sgs/liblddbg/common/sections.c b/usr/src/cmd/sgs/liblddbg/common/sections.c
index 5f46e4c786..8eb3e06fac 100644
--- a/usr/src/cmd/sgs/liblddbg/common/sections.c
+++ b/usr/src/cmd/sgs/liblddbg/common/sections.c
@@ -23,11 +23,74 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+#include <stdio.h>
#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)
{
@@ -58,7 +121,7 @@ Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp)
for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) {
Str_hash *strhash = stp->st_hashbcks[cnt];
- if (strhash == 0)
+ if (strhash == NULL)
continue;
dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_BCKT), cnt);
@@ -97,7 +160,9 @@ Dbg_sec_genstr_compress(Lm_list *lml, const char *os_name,
void
Dbg_sec_unsup_strmerge(Lm_list *lml, Is_desc *isp)
{
- const char *str;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *str;
if (DBG_NOTCLASS(DBG_C_SECTIONS))
return;
@@ -113,8 +178,11 @@ Dbg_sec_unsup_strmerge(Lm_list *lml, Is_desc *isp)
str = (isp->is_file != NULL) ? isp->is_file->ifl_name :
MSG_INTL(MSG_STR_NULL);
dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_UNSUP),
- isp->is_name, str, EC_XWORD(isp->is_shdr->sh_addralign),
+ 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);
}
}
@@ -131,8 +199,6 @@ Dbg_sec_backing(Lm_list *lml)
void
Dbg_sec_in(Lm_list *lml, Is_desc *isp)
{
- const char *str;
-
if (DBG_NOTCLASS(DBG_C_SECTIONS))
return;
@@ -146,11 +212,19 @@ Dbg_sec_in(Lm_list *lml, Is_desc *isp)
* 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 */
- str = (isp->is_file != NULL) ? isp->is_file->ifl_name :
- MSG_INTL(MSG_STR_NULL);
- dbg_print(lml, MSG_INTL(MSG_SEC_INPUT), isp->is_name, str);
+ 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);
}
}
@@ -198,20 +272,37 @@ Dbg_sec_discarded(Lm_list *lml, Is_desc *isp, Is_desc *disp)
* 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),
- isp->is_name, isp->is_file->ifl_name);
+ 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_print(lml, MSG_INTL(MSG_SEC_DISCARDED), isp->is_name,
- isp->is_file->ifl_name, disp->is_name,
+ 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)
{
- const char *comdat;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *comdat, *isp_str;
if (DBG_NOTCLASS(DBG_C_SECTIONS))
return;
@@ -221,19 +312,24 @@ Dbg_sec_group(Lm_list *lml, Is_desc *isp, Group_desc *gdp)
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->is_name,
+ 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->is_name,
+ 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->is_name,
+ 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
@@ -264,50 +360,54 @@ Dbg_sec_order_list(Ofl_desc *ofl, int flag)
Aliste idx2;
Sort_desc *sort = osp->os_sort;
+ 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(sort->st_beforecnt), EC_WORD(sort->st_aftercnt),
EC_WORD(sort->st_ordercnt));
for (APLIST_TRAVERSE(osp->os_isdescs, idx2, isp1)) {
- Word link;
- Ifl_desc *ifl = isp1->is_file;
- Is_desc *isp2;
- const char *msg;
-
+ 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 section with sorted input sections
+ * can also have a large number of unsorted sections.
+ * Skip these without comment.
+ */
if ((isp1->is_flags & FLG_IS_ORDERED) == 0) {
- dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_0),
- isp1->is_name, isp1->is_file->ifl_name);
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 */
+ } else { /* SHF_LINK_ORDER */
link = isp1->is_shdr->sh_link;
msg = MSG_ORIG(MSG_SH_LINK);
}
- if (link == SHN_BEFORE) {
- dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_1),
- isp1->is_name, isp1->is_file->ifl_name,
- msg);
- continue;
- }
+ isp1_str = dbg_fmt_isec_name(isp1, buf, &alloc_mem);
- if (link == SHN_AFTER) {
- dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_2),
- isp1->is_name, isp1->is_file->ifl_name,
- msg);
- continue;
+ 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);
}
-
- isp2 = ifl->ifl_isdesc[link];
- dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_3),
- isp1->is_name, ifl->ifl_name, msg, isp2->is_name,
- EC_WORD(isp2->is_keyident));
+ if (alloc_mem != NULL)
+ free(alloc_mem);
}
}
Dbg_util_nl(lml, DBG_NL_STD);
@@ -328,6 +428,9 @@ static const Msg order_errors[] = {
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())
@@ -337,25 +440,36 @@ Dbg_sec_order_error(Lm_list *lml, Ifl_desc *ifl, Word ndx, int error)
return;
dbg_print(lml, MSG_INTL(MSG_ORD_ERR_TITLE),
- ifl->ifl_isdesc[ndx]->is_name, ifl->ifl_name);
+ 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, const char *oname, const char *nname)
+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), oname, nname);
+ 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, const char *name, uint_t comdat, uint_t relax)
+Dbg_sec_gnu_comdat(Lm_list *lml, Is_desc *isp, uint_t comdat, uint_t relax)
{
- const char *fmt;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *fmt;
if (DBG_NOTCLASS(DBG_C_SECTIONS))
return;
@@ -367,5 +481,7 @@ Dbg_sec_gnu_comdat(Lm_list *lml, const char *name, uint_t comdat, uint_t relax)
else
fmt = MSG_INTL(MSG_SEC_GNU_COMDAT_3);
- dbg_print(lml, fmt, name);
+ dbg_print(lml, fmt, dbg_fmt_isec_name(isp, buf, &alloc_mem));
+ if (alloc_mem != NULL)
+ free(alloc_mem);
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/segments.c b/usr/src/cmd/sgs/liblddbg/common/segments.c
index 00a6eae94c..62fdfb58c7 100644
--- a/usr/src/cmd/sgs/liblddbg/common/segments.c
+++ b/usr/src/cmd/sgs/liblddbg/common/segments.c
@@ -122,6 +122,7 @@ Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx)
Is_desc *isp;
Elf_Data *data;
Shdr *shdr;
+ const char *empty = MSG_ORIG(MSG_STR_EMPTY);
if (DBG_NOTCLASS(DBG_C_SEGMENTS))
return;
@@ -136,15 +137,16 @@ Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx)
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), MSG_ORIG(MSG_STR_EMPTY),
- MSG_ORIG(MSG_STR_EMPTY));
+ EC_XWORD(data->d_align), empty, empty, empty);
if (DBG_NOTDETAIL())
return;
for (APLIST_TRAVERSE(osp->os_isdescs, idx, isp)) {
- const char *file, *str;
- Addr addr;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *file, *str;
+ Addr addr;
data = isp->is_indata;
@@ -152,18 +154,21 @@ Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx)
str = MSG_INTL(MSG_EDATA_IGNSCN);
addr = 0;
} else {
- str = MSG_ORIG(MSG_STR_EMPTY);
+ 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 = MSG_ORIG(MSG_STR_EMPTY);
+ 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, str);
+ EC_XWORD(data->d_align), file,
+ dbg_fmt_isec_name(isp, buf, &alloc_mem), str);
+ if (alloc_mem != NULL)
+ free(alloc_mem);
}
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/shdr.c b/usr/src/cmd/sgs/liblddbg/common/shdr.c
index 13d40b237d..421875c7e4 100644
--- a/usr/src/cmd/sgs/liblddbg/common/shdr.c
+++ b/usr/src/cmd/sgs/liblddbg/common/shdr.c
@@ -59,15 +59,21 @@ Elf_shdr(Lm_list *lml, uchar_t osabi, Half mach, Shdr *shdr)
void
Dbg_shdr_modified(Lm_list *lml, const char *obj, uchar_t osabi, Half mach,
- Shdr *oshdr, Shdr *nshdr, const char *name)
+ 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), name, obj);
+ 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);
diff --git a/usr/src/cmd/sgs/liblddbg/common/syms.c b/usr/src/cmd/sgs/liblddbg/common/syms.c
index 8b9321fa7e..2f5e44dc48 100644
--- a/usr/src/cmd/sgs/liblddbg/common/syms.c
+++ b/usr/src/cmd/sgs/liblddbg/common/syms.c
@@ -192,7 +192,9 @@ Dbg_syms_spec_title(Lm_list *lml)
void
Dbg_syms_discarded(Lm_list *lml, Sym_desc *sdp)
{
- const char *file;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *file;
if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_UNUSED))
return;
@@ -204,8 +206,10 @@ Dbg_syms_discarded(Lm_list *lml, Sym_desc *sdp)
if (sdp->sd_isc) {
dbg_print(lml, MSG_INTL(MSG_SYM_DISCARD_SEC),
- Dbg_demangle_name(sdp->sd_name), sdp->sd_isc->is_name,
- file);
+ 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);
diff --git a/usr/src/cmd/sgs/liblddbg/common/unused.c b/usr/src/cmd/sgs/liblddbg/common/unused.c
index 4d28b6312c..fd9321683e 100644
--- a/usr/src/cmd/sgs/liblddbg/common/unused.c
+++ b/usr/src/cmd/sgs/liblddbg/common/unused.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,7 +42,9 @@ Dbg_unused_unref(Rt_map *lmp, const char *depend)
void
Dbg_unused_sec(Lm_list *lml, Is_desc *isp)
{
- const char *str;
+ dbg_isec_name_buf_t buf;
+ char *alloc_mem;
+ const char *str;
if (DBG_NOTCLASS(DBG_C_UNUSED))
return;
@@ -63,8 +65,11 @@ Dbg_unused_sec(Lm_list *lml, Is_desc *isp)
else
str = MSG_ORIG(MSG_STR_EMPTY);
- dbg_print(lml, MSG_INTL(MSG_USD_SEC), isp->is_name,
+ 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
diff --git a/usr/src/cmd/sgs/packages/Makefile.com b/usr/src/cmd/sgs/packages/Makefile.com
index 748d1618c5..4512a20777 100644
--- a/usr/src/cmd/sgs/packages/Makefile.com
+++ b/usr/src/cmd/sgs/packages/Makefile.com
@@ -19,18 +19,16 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
include $(SRC)/Makefile.master
LINTLOG= ../lint.$(MACH).log
PKGARCHIVE= .
-DATAFILES= copyright prototype_com prototype_$(MACH) postinstall \
+DATAFILES= admin copyright prototype_com prototype_$(MACH) postinstall \
preremove depend checkinstall
README= SUNWonld-README
FILES= $(DATAFILES) pkginfo
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index c647cc83da..d7c897c6c4 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1474,3 +1474,4 @@ Bugid Risk Synopsis
6752883 ld.so.1 error message should be buffered (not sent to stderr).
6577982 ld.so.1 calls getpid() before it should when any LD_* are set
6826513 ldd gets confused by a crle(1) LD_PRELOAD setting
+6831285 linker LD_DEBUG support needs improvements
diff --git a/usr/src/cmd/sgs/packages/common/admin b/usr/src/cmd/sgs/packages/common/admin
new file mode 100644
index 0000000000..2d57427f83
--- /dev/null
+++ b/usr/src/cmd/sgs/packages/common/admin
@@ -0,0 +1,45 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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
+#
+
+# This admin file can be used to force the installation of the
+# SUNWonld package on a system that already has it installed, without
+# having to first uninstall the existing instance. This is a generally
+# undesirable thing to do, but can be handy if you forget to uninstall
+# SUNWonld before BFUing the system. In that state, removing the
+# package can break your system, and the only safe route forward is
+# to install on top of the existing package.
+#
+# # pkgadd -a admin -d SUNWonld
+#
+
+mail=
+instance=overwrite
+partial=ask
+runlevel=nocheck
+idepend=nocheck
+rdepend=ask
+space=nocheck
+setuid=nocheck
+conflict=nocheck
+action=nocheck
diff --git a/usr/src/cmd/sgs/packages/common/checkinstall b/usr/src/cmd/sgs/packages/common/checkinstall
index 75edddde5b..b728b6489c 100644
--- a/usr/src/cmd/sgs/packages/common/checkinstall
+++ b/usr/src/cmd/sgs/packages/common/checkinstall
@@ -22,11 +22,25 @@
# CDDL HEADER END
#
+# Installing the wrong architecture of runtime linker will immediately
+# brick the system. Catch this case and refuse to do it.
+if [ "$PKG_INSTALL_ROOT" = '' -o "$PKG_INSTALL_ROOT" = '/' ]; then
+ SYSARCH=`uname -p`
+ if [ "$SYSARCH" != "$ARCH" ]; then
+ echo "***"
+ echo "*** Cannot install $ARCH linker into root of $SYSARCH system."
+ echo "***"
+ exit 1
+ fi
+fi
+
if [ -d $BASEDIR/$SGSBACKUPDIR ];
then
echo "***"
- echo "*** Previous version of SUNWonld already installed"
- echo "*** please '# pkgrm SUNWonld' before installing a newer version"
+ echo "*** Previous version of SUNWonld already installed. Use"
+ echo "*** # pkgrm SUNWonld"
+ echo "*** to remove it before installing a newer version, or"
+ echo "*** use an admin file to force an overwrite."
echo "***"
exit 1
fi
@@ -43,6 +57,4 @@ then
exit 1
fi
-
-
exit 0
diff --git a/usr/src/cmd/sgs/packages/sparcv9/Makefile b/usr/src/cmd/sgs/packages/sparcv9/Makefile
deleted file mode 100644
index 05d5e0be3f..0000000000
--- a/usr/src/cmd/sgs/packages/sparcv9/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1993 by Sun Microsystems, Inc.
-#
-
-
-include ../Makefile.com
-
-
-.KEEP_STATE:
-
-
-DATAFILES64= copyright depend
-PACKAGE= SUNWldv9
-FILES64= $(DATAFILES64) pkginfo
-CLEANFILES64= $(FILES64) awk_pkginfo ../bld_awk_pkginfo
-CLOBBERFILES= $(PACKAGE)
-
-
-all: $(FILES64)
-install: all .WAIT pkg
-
-
-$(DATAFILES64): ../common/$$@
- $(RM) $@; cp ../common/$@ $@
-
-pkginfo: pkginfo.tmpl awk_pkginfo
- $(RM) $@; nawk -f awk_pkginfo $@.tmpl > $@
-
-pkg: FRC
- @rm -rf $(PACKAGE)
- pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) \
- -o $(PACKAGE) \
- 2>&1 | grep -v "$(SRC)"
- pkgtrans -o -s . $(PACKAGE).tmp $(PACKAGE)
- rm -rf $(PACKAGE)
- mv $(PACKAGE).tmp $(PACKAGE)
-
-awk_pkginfo: ../bld_awk_pkginfo
- ../bld_awk_pkginfo -m $(MACH) -p "$(RELEASE)/$(VERSION)" -o $@
-
-clean: FRC
- -$(RM) $(CLEANFILES64)
-
-clobber: clean FRC
- -$(RM) -r $(CLOBBERFILES)
-
-FRC:
diff --git a/usr/src/cmd/sgs/packages/sparcv9/pkginfo.tmpl b/usr/src/cmd/sgs/packages/sparcv9/pkginfo.tmpl
deleted file mode 100644
index 4dbd62edd2..0000000000
--- a/usr/src/cmd/sgs/packages/sparcv9/pkginfo.tmpl
+++ /dev/null
@@ -1,45 +0,0 @@
-# ident "%Z%%M% %I% %E% SMI"
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (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
-#
-#
-#
-# This required package information file describes characteristics of the
-# package, such as package abbreviation, full package name, package version,
-# and package architecture.
-#
-PKG="SUNWldv9"
-NAME="OS-Net Static/Dynamic linker package for SPARC V9"
-ARCH="ISA"
-VERSION="2.4.2,REV=0.0.0"
-PRODNAME="SunOS"
-PRODVERS="RELEASE/VERSION"
-SUNW_PKGTYPE="usr"
-MAXINST="1000"
-CATEGORY="internal"
-DESC="OS-Net Static/Dynamic linker package for SPARC V9"
-VENDOR="Sun Microsystems, Inc."
-HOTLINE="see email"
-EMAIL="Richard.Goldstein@Eng"
-CLASSES="none"
-BASEDIR=/
diff --git a/usr/src/cmd/sgs/packages/sparcv9/postremove b/usr/src/cmd/sgs/packages/sparcv9/postremove
deleted file mode 100644
index b7e6aca5e8..0000000000
--- a/usr/src/cmd/sgs/packages/sparcv9/postremove
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1995 by Sun Microsystems, Inc.
-# All rights reserved.
-
-SUNWldv9_files="\
- usr/ccs/lib/libld.so.3 \
- usr/ccs/lib/sparcv9/libld.so.3 \
- usr/ccs/lib/sparcv9/liblddbg.so.4 \
- usr/lib/sparcv9/libelf.so.1 \
- usr/lib/sparcv9/librtld.so.1 \
- usr/lib/sparcv9/librtld_db.so.1 \
- usr/lib/sparcv9/ld.so.1 \
- usr/lib/sparcv9/lddstub
- "
-
-MV="/usr/sbin/static/mv"
-RM="/usr/bin/rm -f"
-
-for F in $SUNWldv9_files
-do
- if [ -f ${BASEDIR}/$F.orig ]
- then
- ${MV} ${BASEDIR}/$F.orig ${BASEDIR}/$F
- installf SUNWldv9 ${BASEDIR}/$F
- fi
-done
-
-
-installf -f SUNWldv9
-
diff --git a/usr/src/cmd/sgs/packages/sparcv9/preinstall b/usr/src/cmd/sgs/packages/sparcv9/preinstall
deleted file mode 100644
index 61483e8d74..0000000000
--- a/usr/src/cmd/sgs/packages/sparcv9/preinstall
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (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
-#
-#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1995 by Sun Microsystems, Inc.
-# All rights reserved.
-
-files="\
- usr/ccs/lib/libld.so.3 \
- usr/ccs/lib/sparcv9/libld.so.3 \
- usr/ccs/lib/sparcv9/liblddbg.so.4 \
- usr/lib/sparcv9/ld.so.1 \
- usr/lib/sparcv9/libdl.so.1 \
- usr/lib/sparcv9/libelf.so.1 \
- usr/lib/sparcv9/librtld.so.1 \
- usr/lib/sparcv9/librtld_db.so.1 \
- usr/lib/sparcv9/lddstub
- "
-
-
-for F in $files
-do
- if [ ! -f ${BASEDIR}/$F.orig ]
- then
- if [ -f ${BASEDIR}/$F ]
- then
- cp ${BASEDIR}/$F ${BASEDIR}/$F.orig
- fi
- fi
-done
diff --git a/usr/src/cmd/sgs/packages/sparcv9/prototype b/usr/src/cmd/sgs/packages/sparcv9/prototype
deleted file mode 100644
index 67ba955e3c..0000000000
--- a/usr/src/cmd/sgs/packages/sparcv9/prototype
+++ /dev/null
@@ -1,64 +0,0 @@
-#ident "%Z%%M% %I% %E% SMI"
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (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
-#
-#
-# This required package information file contains a list of package contents.
-# The 'pkgmk' command uses this file to identify the contents of a package
-# and their location on the development machine when building the package.
-# Can be created via a text editor or through use of the 'pkgproto' command.
-
-#!search <pathname pathname ...> # where to find pkg objects
-#!include <filename> # include another 'prototype' file
-#!default <mode> <owner> <group> # default used if not specified on entry
-#!<param>=<value> # puts parameter in pkg environment
-
-# packaging files
-i pkginfo
-i copyright
-i preinstall
-i postremove
-i depend
-#
-# source locations relative to the prototype file
-#
-# SUNWldv9
-#
-d none usr 755 root sys
-d none usr/ccs 755 root bin
-d none usr/ccs/lib 755 root bin
-f none usr/ccs/lib/libld.so.3 755 root bin
-d none usr/ccs/lib/sparcv9 755 root bin
-f none usr/ccs/lib/sparcv9/libld.so.3 755 root bin
-f none usr/ccs/lib/sparcv9/liblddbg.so.4 755 root bin
-d none usr/lib 755 root bin
-d none usr/lib/sparcv9 755 root bin
-f none usr/lib/sparcv9/ld.so.1 755 root bin
-f none usr/lib/sparcv9/libelf.so.1 755 root bin
-s none usr/lib/sparcv9/libelf.so=./libelf.so.1
-f none usr/lib/sparcv9/libdl.so.1 755 root bin
-s none usr/lib/sparcv9/libdl.so=./libdl.so.1
-f none usr/lib/sparcv9/librtld.so.1 755 root bin
-f none usr/lib/sparcv9/librtld_db.so.1 755 root bin
-s none usr/lib/sparcv9/librtld_db.so=./librtld_db.so.1
-f none usr/lib/sparcv9/lddstub 755 root bin
diff --git a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
index e7741829f6..55bb7a5eb4 100644
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
+++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
@@ -826,7 +826,7 @@ elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
}
DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
+ M_REL_SHT_TYPE, rel, NULL, 0, name));
/*
* Make sure the segment is writable.
diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h
index ee7907f43d..ff9589dd16 100644
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h
@@ -612,7 +612,7 @@ extern void cap_assign(Cap *, Rt_map *);
extern const char *_conv_reloc_type(uint_t rel);
extern Aliste create_cntl(Lm_list *, int);
extern void defrag(void);
-extern uintptr_t dbg_setup(const char *, Dbg_desc *);
+extern int dbg_setup(const char *, Dbg_desc *);
extern const char *demangle(const char *);
extern int dlclose_intn(Grp_hdl *, Rt_map *);
extern int dlclose_core(Grp_hdl *, Rt_map *, Lm_list *);
diff --git a/usr/src/cmd/sgs/rtld/common/debug.c b/usr/src/cmd/sgs/rtld/common/debug.c
index 558e16021e..1fde0068c0 100644
--- a/usr/src/cmd/sgs/rtld/common/debug.c
+++ b/usr/src/cmd/sgs/rtld/common/debug.c
@@ -43,31 +43,32 @@
static int dbg_fd; /* debugging output file descriptor */
static dev_t dbg_dev;
static rtld_ino_t dbg_ino;
+static int dbg_add_pid; /* True to add pid to debug file name */
static pid_t pid;
/*
* Enable diagnostic output. All debugging functions reside in the linker
* debugging library liblddbg.so which is lazy loaded when required.
*/
-uintptr_t
+int
dbg_setup(const char *options, Dbg_desc *dbp)
{
- uintptr_t ret;
rtld_stat_t status;
+ const char *ofile;
/*
* If we're running secure, only allow debugging if ld.so.1 itself is
* owned by root and has its mode setuid. Fail silently.
*/
if ((rtld_flags & RT_FL_SECURE) && (is_rtld_setuid() == 0))
- return (0);
+ return (1);
/*
* As Dbg_setup() will effectively lazy load the necessary support
* libraries, make sure ld.so.1 is initialized for plt relocations.
*/
if (elf_rtld_load() == 0)
- return (0);
+ return (1);
/*
* Call the debugging setup routine. This function verifies the
@@ -75,8 +76,8 @@ dbg_setup(const char *options, Dbg_desc *dbp)
* categories selected. The mask effectively enables calls to the
* debugging library.
*/
- if ((ret = Dbg_setup(options, dbp)) != (uintptr_t)1)
- return (ret);
+ if (Dbg_setup(DBG_CALLER_RTLD, options, dbp, &ofile) == 0)
+ return (0);
/*
* Obtain the process id.
@@ -88,13 +89,37 @@ dbg_setup(const char *options, Dbg_desc *dbp)
* diagnostics to the specified file. Add the process id as a file
* suffix so that multiple processes that inherit the same debugging
* environment variable don't fight over the same file.
+ *
+ * If LD_DEBUG_OUTPUT is not specified, and the output=file token
+ * was, then we direct all diagnostics to that file. Unlike
+ * LD_DEBUG_OUTPUT, we do not add the process id suffix. This
+ * is more convenient for interactive use.
+ *
+ * If neither redirection option is present, we send debugging
+ * output to stderr. Note that the caller will not be able
+ * to pipe or redirect this output at the shell level. libc
+ * has not yet initialized things to make that possible.
*/
+ if (dbg_file == NULL) {
+ if (ofile && (*ofile != '\0'))
+ dbg_file = ofile;
+ } else {
+ dbg_add_pid = 1;
+ }
+
if (dbg_file) {
- char file[MAXPATHLEN];
+ char _file[MAXPATHLEN];
+ const char *file;
- (void) snprintf(file, MAXPATHLEN, MSG_ORIG(MSG_DBG_FILE),
- dbg_file, pid);
- if ((dbg_fd = open(file, (O_RDWR | O_CREAT), 0666)) == -1) {
+ if (dbg_add_pid) {
+ file = _file;
+ (void) snprintf(_file, MAXPATHLEN,
+ MSG_ORIG(MSG_DBG_FILE), dbg_file, pid);
+ } else {
+ file = dbg_file;
+ }
+ dbg_fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ if (dbg_fd == -1) {
int err = errno;
eprintf(&lml_rtld, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN),
@@ -118,19 +143,61 @@ dbg_setup(const char *options, Dbg_desc *dbp)
dbg_dev = status.st_dev;
dbg_ino = status.st_ino;
- return (ret);
+ /*
+ * Now that the output file is established, generate help
+ * output if the user specified the debug help token.
+ */
+ if (dbp->d_extra & DBG_E_HELP)
+ Dbg_help();
+
+ return (1);
}
+/*
+ * Return True (1) if dbg_print() should produce output for the
+ * specified link-map list, and False (0) otherwise.
+ */
static int
-dbg_lmid(Lm_list *lml)
+dbg_lmid_validate(Lm_list *lml)
{
const char *str;
Aliste idx;
- for (APLIST_TRAVERSE(dbg_desc->d_list, idx, str)) {
+ /*
+ * The LDSO link-map list is a special case, requiring
+ * an explicit user request.
+ */
+ if (lml->lm_flags & LML_FLG_RTLDLM)
+ return ((dbg_desc->d_extra & DBG_E_LMID_LDSO) != 0);
+
+ /*
+ * Approve special cases:
+ * - The link-map list has no name
+ * - lmid=all was set
+ * - lmid=alt was set, and this is not the BASE linkmap
+ */
+ if ((lml->lm_lmidstr == NULL) ||
+ ((dbg_desc->d_extra & DBG_E_LMID_ALL) != 0) ||
+ (((dbg_desc->d_extra & DBG_E_LMID_ALT) != 0) &&
+ ((lml->lm_flags & LML_FLG_BASELM) == 0)))
+ return (1);
+
+ /*
+ * If there is no list of specific link-map list names to check,
+ * then approval depends on lmid={ldso|alt} not being specified.
+ */
+ if (aplist_nitems(dbg_desc->d_list) == 0)
+ return ((dbg_desc->d_extra &
+ (DBG_E_LMID_LDSO | DBG_E_LMID_ALT)) == 0);
+
+ /*
+ * Compare the link-map list name against the list of approved names
+ */
+ for (APLIST_TRAVERSE(dbg_desc->d_list, idx, str))
if (strcmp(lml->lm_lmidstr, str) == 0)
return (1);
- }
+
+ /* Output for this linkmap is denied */
return (0);
}
@@ -156,14 +223,9 @@ dbg_print(Lm_list *lml, const char *format, ...)
/*
* If debugging has been isolated to individual link-map lists,
* determine whether this request originates from a link-map list that
- * is being monitored. Otherwise, process all link-map list diagnostics
- * except those that originate from ld.so.1 processing its own
- * dependencies.
- */
- if (dbg_desc->d_list && lml && lml->lm_lmidstr) {
- if (dbg_lmid(lml) == 0)
- return;
- } else if (lml && (lml->lm_flags & LML_FLG_RTLDLM))
+ * is being monitored.
+ */
+ if (lml && (dbg_lmid_validate(lml) == 0))
return;
/*
@@ -180,10 +242,17 @@ dbg_print(Lm_list *lml, const char *format, ...)
* If the user specified output file has been
* disconnected try and reconnect to it.
*/
- char file[MAXPATHLEN];
+ char _file[MAXPATHLEN];
+ const char *file;
- (void) snprintf(file, MAXPATHLEN,
- MSG_ORIG(MSG_DBG_FILE), dbg_file, pid);
+ if (dbg_add_pid) {
+ file = _file;
+ (void) snprintf(_file, MAXPATHLEN,
+ MSG_ORIG(MSG_DBG_FILE), dbg_file,
+ pid);
+ } else {
+ file = dbg_file;
+ }
if ((dbg_fd = open(file, (O_RDWR | O_APPEND),
0)) == -1) {
dbg_desc->d_class = 0;
diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c
index e8d12ba4da..8ccd79ece4 100644
--- a/usr/src/cmd/sgs/rtld/common/elf.c
+++ b/usr/src/cmd/sgs/rtld/common/elf.c
@@ -2681,7 +2681,7 @@ elf_static_tls(Rt_map *lmp, Sym *sym, void *rel, uchar_t rtype, char *name,
*/
if (PTTLS(lmp) == NULL) {
DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
+ M_REL_SHT_TYPE, rel, NULL, 0, name));
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
_conv_reloc_type((uint_t)rtype), NAME(lmp),
name ? demangle(name) : MSG_INTL(MSG_STR_UNKNOWN));
@@ -2699,7 +2699,7 @@ elf_static_tls(Rt_map *lmp, Sym *sym, void *rel, uchar_t rtype, char *name,
if (tls_assign(lml, lmp, PTTLS(lmp)) == 0) {
DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
+ M_REL_SHT_TYPE, rel, NULL, 0, name));
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
_conv_reloc_type((uint_t)rtype), NAME(lmp),
name ? demangle(name) : MSG_INTL(MSG_STR_UNKNOWN));
@@ -2758,7 +2758,7 @@ elf_reloc_error(Rt_map *lmp, const char *name, void *rel, uint_t binfo)
* Otherwise, the unresolved references is fatal.
*/
DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH, M_REL_SHT_TYPE, rel,
- NULL, name));
+ NULL, 0, name));
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c
index 2e604f5041..2ac3070ca5 100644
--- a/usr/src/cmd/sgs/rtld/common/setup.c
+++ b/usr/src/cmd/sgs/rtld/common/setup.c
@@ -858,11 +858,9 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
Dbg_desc _dbg_desc = {0, 0, NULL};
if (rpl_debug) {
- uintptr_t ret;
-
- if ((ret = dbg_setup(rpl_debug, &_dbg_desc)) == S_ERROR)
+ if (dbg_setup(rpl_debug, &_dbg_desc) == 0)
return (0);
- if (ret == 0)
+ if (_dbg_desc.d_extra & DBG_E_HELP_EXIT)
rtldexit(&lml_main, 0);
}
if (prm_debug)
diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c
index 931efc33b5..f460541cc9 100644
--- a/usr/src/cmd/sgs/rtld/common/util.c
+++ b/usr/src/cmd/sgs/rtld/common/util.c
@@ -41,7 +41,6 @@
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
-#include <ctype.h>
#include <dlfcn.h>
#include <unistd.h>
#include <stdlib.h>
@@ -2253,7 +2252,7 @@ ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags,
s2 = NULL;
} else {
len = s2 - s1 - 1;
- while (isspace(*s2))
+ while (conv_strproc_isspace(*s2))
s2++;
}
diff --git a/usr/src/cmd/sgs/rtld/i386/i386_elf.c b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
index 93083df98e..c106cc2a16 100644
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c
+++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
@@ -783,7 +783,7 @@ elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
}
DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
+ M_REL_SHT_TYPE, rel, NULL, 0, name));
/*
* Make sure the segment is writable.
@@ -932,7 +932,7 @@ _elf_copy_reloc(const char *name, Rt_map *rlmp, Rt_map *dlmp)
rel.r_offset = (Addr)ref;
rel.r_info = (Word)R_386_COPY;
DBG_CALL(Dbg_reloc_in(LIST(rlmp), ELF_DBG_RTLD, M_MACH, M_REL_SHT_TYPE,
- &rel, NULL, name));
+ &rel, NULL, 0, name));
return (elf_copy_reloc((char *)name, symref, rlmp, (void *)ref, symdef,
_lmp, (void *)def));
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
index c8b01c19d2..b0485642ad 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
@@ -951,7 +951,7 @@ elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
}
DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
+ M_REL_SHT_TYPE, rel, NULL, 0, name));
/*
* Make sure the segment is writable.
diff --git a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
index 5c4290e00c..b15212d49f 100644
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
@@ -1183,7 +1183,7 @@ elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
}
DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
+ M_REL_SHT_TYPE, rel, NULL, 0, name));
/*
* Make sure the segment is writable.