diff options
Diffstat (limited to 'usr/src/tools/ctf')
-rw-r--r-- | usr/src/tools/ctf/cvt/Makefile.com | 9 | ||||
-rw-r--r-- | usr/src/tools/ctf/cvt/ctftools.h | 12 | ||||
-rw-r--r-- | usr/src/tools/ctf/cvt/dwarf.c | 45 | ||||
-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.c | 17 | ||||
-rw-r--r-- | usr/src/tools/ctf/cvt/output.c | 12 | ||||
-rw-r--r-- | usr/src/tools/ctf/cvt/st_parse.c | 9 | ||||
-rw-r--r-- | usr/src/tools/ctf/cvt/stabs.c | 3 | ||||
-rw-r--r-- | usr/src/tools/ctf/cvt/util.c | 23 | ||||
-rw-r--r-- | usr/src/tools/ctf/scripts/ctffindmod.sh | 9 | ||||
-rw-r--r-- | usr/src/tools/ctf/stabs/common/genassym.c | 20 |
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] == '#') { |