summaryrefslogtreecommitdiff
path: root/usr/src/tools/ctf
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/tools/ctf')
-rw-r--r--usr/src/tools/ctf/cvt/Makefile.com9
-rw-r--r--usr/src/tools/ctf/cvt/ctftools.h12
-rw-r--r--usr/src/tools/ctf/cvt/dwarf.c45
-rw-r--r--usr/src/tools/ctf/cvt/fixup_tdescs.c (renamed from usr/src/tools/ctf/cvt/st_bugs.c)103
-rw-r--r--usr/src/tools/ctf/cvt/iidesc.c17
-rw-r--r--usr/src/tools/ctf/cvt/output.c12
-rw-r--r--usr/src/tools/ctf/cvt/st_parse.c9
-rw-r--r--usr/src/tools/ctf/cvt/stabs.c3
-rw-r--r--usr/src/tools/ctf/cvt/util.c23
-rw-r--r--usr/src/tools/ctf/scripts/ctffindmod.sh9
-rw-r--r--usr/src/tools/ctf/stabs/common/genassym.c20
11 files changed, 159 insertions, 103 deletions
diff --git a/usr/src/tools/ctf/cvt/Makefile.com b/usr/src/tools/ctf/cvt/Makefile.com
index 323df50520..677253e7ab 100644
--- a/usr/src/tools/ctf/cvt/Makefile.com
+++ b/usr/src/tools/ctf/cvt/Makefile.com
@@ -2,9 +2,8 @@
# 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.
+# 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.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -55,7 +54,7 @@ CVTSRCS=$(GENSRCS) \
ctfconvert.c \
dwarf.c \
stabs.c \
- st_bugs.c \
+ fixup_tdescs.c \
st_parse.c
CVTOBJS=$(CVTSRCS:%.c=%.o)
CVTLINTFILES = $(CVTSRCS:%.c=%.ln)
diff --git a/usr/src/tools/ctf/cvt/ctftools.h b/usr/src/tools/ctf/cvt/ctftools.h
index 76bd58292e..991f3bc921 100644
--- a/usr/src/tools/ctf/cvt/ctftools.h
+++ b/usr/src/tools/ctf/cvt/ctftools.h
@@ -342,8 +342,9 @@ typedef struct ctf_buf ctf_buf_t;
typedef struct symit_data symit_data_t;
-/* bugs.c */
-void cvt_fixbugs(tdata_t *td);
+/* fixup_tdescs.c */
+void cvt_fixstabs(tdata_t *);
+void cvt_fixups(tdata_t *, size_t);
/* ctf.c */
caddr_t ctf_gen(iiburst_t *, size_t *, int);
@@ -352,6 +353,8 @@ tdata_t *ctf_load(char *, caddr_t, size_t, symit_data_t *, char *);
/* iidesc.c */
iidesc_t *iidesc_new(char *);
int iidesc_hash(int, void *);
+void iter_iidescs_by_name(tdata_t *, const char *,
+ int (*)(iidesc_t *, void *), void *);
iidesc_t *iidesc_dup(iidesc_t *);
iidesc_t *iidesc_dup_rename(iidesc_t *, char const *, char const *);
void iidesc_add(hash_t *, iidesc_t *);
@@ -396,7 +399,7 @@ void parse_init(tdata_t *);
void parse_finish(tdata_t *);
int parse_stab(stab_t *, char *, iidesc_t **);
tdesc_t *lookup(int);
-tdesc_t *lookupname(char *);
+tdesc_t *lookupname(const char *);
void check_hash(void);
void resolve_typed_bitfields(void);
@@ -427,8 +430,9 @@ void tdata_merge(tdata_t *, tdata_t *);
void tdata_label_newmax(tdata_t *, int);
/* util.c */
-int streq(char *, char *);
+int streq(const char *, const char *);
int findelfsecidx(Elf *, const char *, const char *);
+size_t elf_ptrsz(Elf *);
char *mktmpname(const char *, const char *);
void terminate(char *, ...);
void aborterr(char *, ...);
diff --git a/usr/src/tools/ctf/cvt/dwarf.c b/usr/src/tools/ctf/cvt/dwarf.c
index c8ad300354..32bcc77286 100644
--- a/usr/src/tools/ctf/cvt/dwarf.c
+++ b/usr/src/tools/ctf/cvt/dwarf.c
@@ -955,10 +955,15 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
ml = xcalloc(sizeof (mlist_t));
- if ((ml->ml_name = die_name(dw, mem)) == NULL) {
- terminate("die %llu: mem %llu: member has no name\n",
- off, memoff);
- }
+ /*
+ * This could be a GCC anon struct/union member, so we'll allow
+ * an empty name, even though nothing can really handle them
+ * properly. Note that some versions of GCC miss out debug
+ * info for anon structs, though recent versions are fixed (gcc
+ * bug 11816).
+ */
+ if ((ml->ml_name = die_name(dw, mem)) == NULL)
+ ml->ml_name = "";
ml->ml_type = die_lookup_pass1(dw, mem, DW_AT_type);
@@ -983,7 +988,7 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
#endif
}
- debug(3, "die %llu: mem %llu: created %s (off %u sz %u)\n",
+ debug(3, "die %llu: mem %llu: created \"%s\" (off %u sz %u)\n",
off, memoff, ml->ml_name, ml->ml_offset, ml->ml_size);
*mlastp = ml;
@@ -1105,9 +1110,10 @@ die_sou_failed(tdesc_t *tdp, tdesc_t **tdpp, void *private)
for (ml = tdp->t_members; ml != NULL; ml = ml->ml_next) {
if (ml->ml_size == 0) {
- fprintf(stderr, "%s %d: failed to size member %s of "
- "type %s (%d)\n", typename, tdp->t_id, ml->ml_name,
- tdesc_name(ml->ml_type), ml->ml_type->t_id);
+ fprintf(stderr, "%s %d: failed to size member \"%s\" "
+ "of type %s (%d)\n", typename, tdp->t_id,
+ ml->ml_name, tdesc_name(ml->ml_type),
+ ml->ml_type->t_id);
}
}
@@ -1771,27 +1777,6 @@ die_resolve(dwarf_t *dw)
} while (dw->dw_nunres != 0);
}
-static size_t
-elf_ptrsz(Elf *elf)
-{
- GElf_Ehdr ehdr;
-
- if (gelf_getehdr(elf, &ehdr) == NULL) {
- terminate("failed to read ELF header: %s\n",
- elf_errmsg(-1));
- }
-
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
- return (4);
- else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
- return (8);
- else
- terminate("unknown ELF class %d\n", ehdr.e_ident[EI_CLASS]);
-
- /*NOTREACHED*/
- return (0);
-}
-
/*ARGSUSED*/
int
dw_read(tdata_t *td, Elf *elf, const char *filename)
@@ -1871,6 +1856,8 @@ dw_read(tdata_t *td, Elf *elf, const char *filename)
die_resolve(&dw);
+ cvt_fixups(td, dw.dw_ptrsz);
+
/* leak the dwarf_t */
return (0);
diff --git a/usr/src/tools/ctf/cvt/st_bugs.c b/usr/src/tools/ctf/cvt/fixup_tdescs.c
index 85cb2a1a22..8524693d02 100644
--- a/usr/src/tools/ctf/cvt/st_bugs.c
+++ b/usr/src/tools/ctf/cvt/fixup_tdescs.c
@@ -2,9 +2,8 @@
* 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.
+ * 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.
@@ -20,14 +19,15 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * Workarounds for stabs generation bugs in the compiler
+ * Workarounds for stabs generation bugs in the compiler and general needed
+ * fixups.
*/
#include <stdio.h>
@@ -147,6 +147,43 @@ fix_ptr_to_struct(tdata_t *td)
}
/*
+ * Fix stabs generation bugs. These routines must be run before the
+ * post-conversion merge
+ */
+void
+cvt_fixstabs(tdata_t *td)
+{
+ fix_ptrptr_to_struct(td);
+ fix_ptr_to_struct(td);
+}
+
+struct match {
+ tdesc_t *m_ret;
+ const char *m_name;
+};
+
+static int
+matching_iidesc(iidesc_t *iidesc, struct match *match)
+{
+ if (!streq(iidesc->ii_name, match->m_name))
+ return (0);
+
+ if (iidesc->ii_type != II_TYPE && iidesc->ii_type != II_SOU)
+ return (0);
+
+ match->m_ret = iidesc->ii_dtype;
+ return (-1);
+}
+
+static tdesc_t *
+lookup_tdesc(tdata_t *td, const char *name)
+{
+ struct match match = { NULL, name };
+ iter_iidescs_by_name(td, name, (int (*)())matching_iidesc, &match);
+ return (match.m_ret);
+}
+
+/*
* The cpu structure grows, with the addition of a machcpu member, if
* _MACHDEP is defined. This means that, for example, the cpu structure
* in unix is different from the cpu structure in genunix. As one might
@@ -158,24 +195,31 @@ fix_ptr_to_struct(tdata_t *td)
* we make a forward node for it.
*/
static void
-fix_small_cpu_struct(tdata_t *td)
+fix_small_cpu_struct(tdata_t *td, size_t ptrsize)
{
tdesc_t *cput, *cpu;
tdesc_t *machcpu;
mlist_t *ml, *lml;
mlist_t *cpum;
int foundcpucyc = 0;
- size_t lmlsz;
/*
* We're going to take the circuitous route finding the cpu structure,
* because we want to make sure that we find the right one. It would
- * be nice if we could verify the header name too.
+ * be nice if we could verify the header name too. DWARF might not
+ * have the cpu_t, so we let this pass.
*/
- if ((cput = lookupname("cpu_t")) == NULL || cput->t_type != TYPEDEF)
+ if ((cput = lookup_tdesc(td, "cpu_t")) != NULL) {
+ if (cput->t_type != TYPEDEF)
+ return;
+ cpu = cput->t_tdesc;
+ } else {
+ cpu = lookup_tdesc(td, "cpu");
+ }
+
+ if (cpu == NULL)
return;
- cpu = cput->t_tdesc;
if (!streq(cpu->t_name, "cpu") || cpu->t_type != STRUCT)
return;
@@ -190,33 +234,34 @@ fix_small_cpu_struct(tdata_t *td)
return;
/*
- * We need to find out how big the last element is so we can compute the
- * offset of the new one. If the last element has a size, we use it.
- * If it doesn't, it should be a pointer, which won't have a size. In
- * that case, we look up the size of a long and use that as the size of
- * the pointer.
+ * We need to derive the right offset for the fake cpu_m member. To do
+ * that, we require a special unused member to be the last member
+ * before the 'cpu_m', that we encode knowledge of here. ABI alignment
+ * on all platforms is such that we only need to add a pointer-size
+ * number of bits to get the right offset for cpu_m. This would most
+ * likely break if gcc's -malign-double were ever used, but that option
+ * breaks the ABI anyway.
*/
- if (lml->ml_type->t_size)
- lmlsz = lml->ml_type->t_size * NBBY;
- else {
- tdesc_t *tdp = lookupname("long");
- lmlsz = tdp->t_intr->intr_nbits;
+ if (!streq(lml->ml_name, "cpu_m_pad") &&
+ getenv("CTFCONVERT_PERMISSIVE") == NULL) {
+ terminate("last cpu_t member before cpu_m is %s; "
+ "it must be cpu_m_pad.\n", lml->ml_name);
}
- if ((machcpu = lookupname("machcpu")) == NULL) {
+ if ((machcpu = lookup_tdesc(td, "machcpu")) == NULL) {
machcpu = xcalloc(sizeof (*machcpu));
machcpu->t_name = xstrdup("machcpu");
machcpu->t_id = td->td_nextid++;
machcpu->t_type = FORWARD;
-
- } else if (machcpu->t_type != STRUCT)
+ } else if (machcpu->t_type != STRUCT) {
return;
+ }
debug(3, "Adding cpu_m machcpu %s to cpu struct\n",
(machcpu->t_type == FORWARD ? "forward" : "struct"));
cpum = xmalloc(sizeof (*cpum));
- cpum->ml_offset = lml->ml_offset + lmlsz;
+ cpum->ml_offset = lml->ml_offset + (ptrsize * NBBY);
cpum->ml_size = 0;
cpum->ml_name = xstrdup("cpu_m");
cpum->ml_type = machcpu;
@@ -225,14 +270,8 @@ fix_small_cpu_struct(tdata_t *td)
lml->ml_next = cpum;
}
-/*
- * Fix stabs generation bugs. These routines must be run before the
- * post-conversion merge
- */
void
-cvt_fixbugs(tdata_t *td)
+cvt_fixups(tdata_t *td, size_t ptrsize)
{
- fix_ptrptr_to_struct(td);
- fix_ptr_to_struct(td);
- fix_small_cpu_struct(td);
+ fix_small_cpu_struct(td, ptrsize);
}
diff --git a/usr/src/tools/ctf/cvt/iidesc.c b/usr/src/tools/ctf/cvt/iidesc.c
index 50dc57fcd1..b6b9a0c7f2 100644
--- a/usr/src/tools/ctf/cvt/iidesc.c
+++ b/usr/src/tools/ctf/cvt/iidesc.c
@@ -2,9 +2,8 @@
* 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.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -107,6 +106,16 @@ iidesc_add(hash_t *hash, iidesc_t *new)
hash_add(hash, new);
}
+void
+iter_iidescs_by_name(tdata_t *td, const char *name,
+ int (*func)(iidesc_t *, void *), void *data)
+{
+ iidesc_t tmpdesc;
+ bzero(&tmpdesc, sizeof (iidesc_t));
+ tmpdesc.ii_name = (char *)name;
+ (void) hash_match(td->td_iihash, &tmpdesc, (int (*)())func, data);
+}
+
iidesc_t *
iidesc_dup(iidesc_t *src)
{
diff --git a/usr/src/tools/ctf/cvt/output.c b/usr/src/tools/ctf/cvt/output.c
index ea7469b282..f699fbf6d3 100644
--- a/usr/src/tools/ctf/cvt/output.c
+++ b/usr/src/tools/ctf/cvt/output.c
@@ -190,13 +190,11 @@ matching_iidesc(iidesc_t *iidesc, iidesc_match_t *match)
}
static iidesc_t *
-find_iidesc(hash_t *hash, iidesc_match_t *match)
+find_iidesc(tdata_t *td, iidesc_match_t *match)
{
- iidesc_t tmpdesc;
match->iim_ret = NULL;
- bzero(&tmpdesc, sizeof (iidesc_t));
- tmpdesc.ii_name = match->iim_name;
- (void) hash_match(hash, &tmpdesc, (int (*)())matching_iidesc, match);
+ iter_iidescs_by_name(td, match->iim_name,
+ (int (*)())matching_iidesc, match);
return (match->iim_ret);
}
@@ -390,7 +388,7 @@ sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
if (ignore_symbol(&sym, match.iim_name))
continue;
- iidesc = find_iidesc(td->td_iihash, &match);
+ iidesc = find_iidesc(td, &match);
if (iidesc != NULL) {
tolist[*curr] = iidesc;
@@ -412,7 +410,7 @@ sort_iidescs(Elf *elf, const char *file, tdata_t *td, int fuzzymatch,
debug(3, "Weak symbol %s resolved to %s\n", match.iim_name,
smatch.iim_name);
- iidesc = find_iidesc(td->td_iihash, &smatch);
+ iidesc = find_iidesc(td, &smatch);
if (iidesc != NULL) {
tolist[*curr] = copy_from_strong(td, &sym,
diff --git a/usr/src/tools/ctf/cvt/st_parse.c b/usr/src/tools/ctf/cvt/st_parse.c
index 04bb40579e..d4d4921321 100644
--- a/usr/src/tools/ctf/cvt/st_parse.c
+++ b/usr/src/tools/ctf/cvt/st_parse.c
@@ -64,8 +64,7 @@ static jmp_buf resetbuf;
static char *soudef(char *cp, stabtype_t type, tdesc_t **rtdp);
static void enumdef(char *cp, tdesc_t **rtdp);
-static int compute_sum(char *w);
-tdesc_t *lookupname(char *name);
+static int compute_sum(const char *w);
static char *number(char *cp, int *n);
static char *name(char *cp, char **w);
@@ -1040,7 +1039,7 @@ enumdef(char *cp, tdesc_t **rtdp)
}
tdesc_t *
-lookup_name(tdesc_t **hash, char *name)
+lookup_name(tdesc_t **hash, const char *name)
{
int bucket = compute_sum(name);
tdesc_t *tdp, *ttdp = NULL;
@@ -1058,7 +1057,7 @@ lookup_name(tdesc_t **hash, char *name)
}
tdesc_t *
-lookupname(char *name)
+lookupname(const char *name)
{
return (lookup_name(name_table, name));
}
@@ -1101,7 +1100,7 @@ addhash(tdesc_t *tdp, int num)
}
static int
-compute_sum(char *w)
+compute_sum(const char *w)
{
char c;
int sum;
diff --git a/usr/src/tools/ctf/cvt/stabs.c b/usr/src/tools/ctf/cvt/stabs.c
index 666afe871c..f7b3034c64 100644
--- a/usr/src/tools/ctf/cvt/stabs.c
+++ b/usr/src/tools/ctf/cvt/stabs.c
@@ -374,7 +374,8 @@ parse_loop_end:
resolve_typed_bitfields();
parse_finish(td);
- cvt_fixbugs(td);
+ cvt_fixstabs(td);
+ cvt_fixups(td, elf_ptrsz(elf));
return (0);
}
diff --git a/usr/src/tools/ctf/cvt/util.c b/usr/src/tools/ctf/cvt/util.c
index c7857fb1ab..799ca1279c 100644
--- a/usr/src/tools/ctf/cvt/util.c
+++ b/usr/src/tools/ctf/cvt/util.c
@@ -47,7 +47,7 @@ static void (*terminate_cleanup)() = NULL;
/* returns 1 if s1 == s2, 0 otherwise */
int
-streq(char *s1, char *s2)
+streq(const char *s1, const char *s2)
{
if (s1 == NULL) {
if (s2 != NULL)
@@ -93,6 +93,27 @@ findelfsecidx(Elf *elf, const char *file, const char *tofind)
return (-1);
}
+size_t
+elf_ptrsz(Elf *elf)
+{
+ GElf_Ehdr ehdr;
+
+ if (gelf_getehdr(elf, &ehdr) == NULL) {
+ terminate("failed to read ELF header: %s\n",
+ elf_errmsg(-1));
+ }
+
+ if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
+ return (4);
+ else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+ return (8);
+ else
+ terminate("unknown ELF class %d\n", ehdr.e_ident[EI_CLASS]);
+
+ /*NOTREACHED*/
+ return (0);
+}
+
/*PRINTFLIKE2*/
static void
whine(char *type, char *format, va_list ap)
diff --git a/usr/src/tools/ctf/scripts/ctffindmod.sh b/usr/src/tools/ctf/scripts/ctffindmod.sh
index 693d7e5279..8f583371d9 100644
--- a/usr/src/tools/ctf/scripts/ctffindmod.sh
+++ b/usr/src/tools/ctf/scripts/ctffindmod.sh
@@ -3,9 +3,8 @@
# 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.
+# 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.
@@ -23,7 +22,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Given a machine-optimal patch makeup table (see ctfcvtptbl), this program
@@ -161,7 +160,7 @@ if [[ $print_lastgu -eq 1 ]] ; then
if [ `uname -p` = "sparc" ] ; then
suffix=/sparcv9
else
- suffix=/ia64
+ suffix=/amd64
fi
fi
echo "$space$garpath/$ku$suffix/genunix\c"
diff --git a/usr/src/tools/ctf/stabs/common/genassym.c b/usr/src/tools/ctf/stabs/common/genassym.c
index ed10446b00..9183e52ffd 100644
--- a/usr/src/tools/ctf/stabs/common/genassym.c
+++ b/usr/src/tools/ctf/stabs/common/genassym.c
@@ -2,9 +2,8 @@
* 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.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -301,15 +300,16 @@ static int
ga_process_line(char *line)
{
static int curtype = -1;
- int nblank = 0;
+ static int blanks = 0;
if (strlen(line) == 0) {
- curtype = -1;
- if (nblank++ == 1)
- (void) fprintf(out, "\n");
+ blanks++;
return (1);
- } else
- nblank = 0;
+ } else if (blanks) {
+ if (!isspace(line[0]))
+ curtype = -1;
+ blanks = 0;
+ }
if (line[0] == '\\') {
if (line[1] == '#') {