Home | History | Annotate | Line # | Download | only in cvt
      1  1.1    darran /*
      2  1.1    darran  * CDDL HEADER START
      3  1.1    darran  *
      4  1.1    darran  * The contents of this file are subject to the terms of the
      5  1.1    darran  * Common Development and Distribution License (the "License").
      6  1.1    darran  * You may not use this file except in compliance with the License.
      7  1.1    darran  *
      8  1.1    darran  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  1.1    darran  * or http://www.opensolaris.org/os/licensing.
     10  1.1    darran  * See the License for the specific language governing permissions
     11  1.1    darran  * and limitations under the License.
     12  1.1    darran  *
     13  1.1    darran  * When distributing Covered Code, include this CDDL HEADER in each
     14  1.1    darran  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  1.1    darran  * If applicable, add the following below this CDDL HEADER, with the
     16  1.1    darran  * fields enclosed by brackets "[]" replaced with your own identifying
     17  1.1    darran  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  1.1    darran  *
     19  1.1    darran  * CDDL HEADER END
     20  1.1    darran  */
     21  1.1    darran /*
     22  1.1    darran  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     23  1.1    darran  * Use is subject to license terms.
     24  1.1    darran  */
     25  1.1    darran 
     26  1.1    darran #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27  1.1    darran 
     28  1.1    darran /*
     29  1.1    darran  * Workarounds for stabs generation bugs in the compiler and general needed
     30  1.1    darran  * fixups.
     31  1.1    darran  */
     32  1.1    darran 
     33  1.3    darran #if HAVE_NBTOOL_CONFIG_H
     34  1.3    darran # include "nbtool_config.h"
     35  1.3    darran #endif
     36  1.3    darran 
     37  1.1    darran #include <stdio.h>
     38  1.1    darran #include <strings.h>
     39  1.1    darran 
     40  1.1    darran #include "ctf_headers.h"
     41  1.1    darran #include "ctftools.h"
     42  1.1    darran #include "hash.h"
     43  1.1    darran #include "memory.h"
     44  1.5   hannken #include "traverse.h"
     45  1.1    darran 
     46  1.1    darran /*
     47  1.1    darran  * Due to 4432619, the 6.1 compiler will sometimes incorrectly generate pointer
     48  1.1    darran  * stabs.  Given a struct foo, and a corresponding typedef struct foo foo_t.
     49  1.1    darran  * In some cases, when faced with a pointer to a foo_t, the compiler will
     50  1.1    darran  * sometimes generate a stab that describes a pointer to a struct foo.
     51  1.1    darran  * Regardless of correctness, this breaks merges, as it occurs inconsistently
     52  1.1    darran  * by file.  The following two routines know how to recognize and repair foo_t *
     53  1.1    darran  * and foo_t ** bugs in a specific set of cases.  There is no general way to
     54  1.1    darran  * solve this problem without a fix to the compiler.  In general, cases should
     55  1.1    darran  * only be added to these routines to fix merging problems in genunix.
     56  1.1    darran  */
     57  1.1    darran static void
     58  1.1    darran fix_ptrptr_to_struct(tdata_t *td)
     59  1.1    darran {
     60  1.2    darran 	const char *strs[2] = { "as", "fdbuffer" };
     61  1.2    darran 	const char *mems[2] = { "a_objectdir", "fd_shadow" };
     62  1.2    darran 	const char *acts[2] = { "vnode", "page" };
     63  1.2    darran 	const char *tgts[2] = { "vnode_t", "page_t" };
     64  1.1    darran 	tdesc_t *str;
     65  1.1    darran 	tdesc_t *act, *tgt;
     66  1.1    darran 	tdesc_t *p1, *p2;
     67  1.1    darran 	mlist_t *ml;
     68  1.1    darran 	int i;
     69  1.1    darran 
     70  1.2    darran 	for (i = 0; i < (int) (sizeof (strs) / sizeof (strs[0])); i++) {
     71  1.1    darran 		if (!(str = lookupname(strs[i])) || str->t_type != STRUCT)
     72  1.1    darran 			continue;
     73  1.1    darran 
     74  1.1    darran 		for (ml = str->t_members; ml; ml = ml->ml_next) {
     75  1.1    darran 			if (streq(ml->ml_name, mems[i]))
     76  1.1    darran 				break;
     77  1.1    darran 		}
     78  1.1    darran 		if (!ml)
     79  1.1    darran 			continue;
     80  1.1    darran 
     81  1.1    darran 		if (ml->ml_type->t_type != POINTER || ml->ml_type->t_name ||
     82  1.1    darran 		    ml->ml_type->t_tdesc->t_type != POINTER ||
     83  1.1    darran 		    ml->ml_type->t_tdesc->t_name)
     84  1.1    darran 			continue;
     85  1.1    darran 
     86  1.1    darran 		act = ml->ml_type->t_tdesc->t_tdesc;
     87  1.1    darran 		if (act->t_type != STRUCT || !streq(act->t_name, acts[i]))
     88  1.1    darran 			continue;
     89  1.1    darran 
     90  1.1    darran 		if (!(tgt = lookupname(tgts[i])) || tgt->t_type != TYPEDEF)
     91  1.1    darran 			continue;
     92  1.1    darran 
     93  1.1    darran 		/* We have an instance of the bug */
     94  1.1    darran 		p2 = xcalloc(sizeof (*p2));
     95  1.1    darran 		p2->t_type = POINTER;
     96  1.1    darran 		p2->t_id = td->td_nextid++;
     97  1.1    darran 		p2->t_tdesc = tgt;
     98  1.1    darran 
     99  1.1    darran 		p1 = xcalloc(sizeof (*p1));
    100  1.1    darran 		p1->t_type = POINTER;
    101  1.1    darran 		p1->t_id = td->td_nextid++;
    102  1.1    darran 		p1->t_tdesc = p2;
    103  1.1    darran 
    104  1.1    darran 		ml->ml_type = p1;
    105  1.1    darran 
    106  1.1    darran 		debug(3, "Fixed %s->%s => ptrptr struct %s bug\n",
    107  1.1    darran 		    strs[i], mems[i], acts[i]);
    108  1.1    darran 	}
    109  1.1    darran }
    110  1.1    darran 
    111  1.1    darran static void
    112  1.1    darran fix_ptr_to_struct(tdata_t *td)
    113  1.1    darran {
    114  1.2    darran 	const char *strs[2] = { "vmem", "id_space" };
    115  1.2    darran 	const char *mems[2] = { NULL, "is_vmem" };
    116  1.1    darran 	tdesc_t *ptr = NULL;
    117  1.1    darran 	tdesc_t *str, *vmt;
    118  1.1    darran 	mlist_t *ml;
    119  1.1    darran 	int i;
    120  1.1    darran 
    121  1.1    darran 	if ((vmt = lookupname("vmem_t")) == NULL || vmt->t_type != TYPEDEF)
    122  1.1    darran 		return;
    123  1.1    darran 
    124  1.2    darran 	for (i = 0; i < (int) (sizeof (strs) / sizeof (strs[0])); i++) {
    125  1.1    darran 		if (!(str = lookupname(strs[i])) || str->t_type != STRUCT)
    126  1.1    darran 			continue;
    127  1.1    darran 
    128  1.1    darran 		for (ml = str->t_members; ml; ml = ml->ml_next) {
    129  1.1    darran 			if (mems[i] && !streq(ml->ml_name, mems[i]))
    130  1.1    darran 				continue;
    131  1.1    darran 
    132  1.1    darran 			if (ml->ml_type->t_type != POINTER ||
    133  1.1    darran 			    ml->ml_type->t_name ||
    134  1.1    darran 			    (ml->ml_type->t_tdesc->t_type != STRUCT &&
    135  1.1    darran 			    ml->ml_type->t_tdesc->t_type != FORWARD) ||
    136  1.1    darran 			    !streq(ml->ml_type->t_tdesc->t_name, "vmem"))
    137  1.1    darran 				continue;
    138  1.1    darran 
    139  1.1    darran 			debug(3, "Fixed %s->%s => ptr struct vmem bug\n",
    140  1.1    darran 			    strs[i], ml->ml_name);
    141  1.1    darran 
    142  1.1    darran 			if (!ptr) {
    143  1.1    darran 				ptr = xcalloc(sizeof (*ptr));
    144  1.1    darran 				ptr->t_type = POINTER;
    145  1.1    darran 				ptr->t_id = td->td_nextid++;
    146  1.1    darran 				ptr->t_tdesc = vmt;
    147  1.1    darran 			}
    148  1.1    darran 
    149  1.1    darran 			ml->ml_type = ptr;
    150  1.1    darran 		}
    151  1.1    darran 	}
    152  1.1    darran }
    153  1.1    darran 
    154  1.1    darran /*
    155  1.1    darran  * Fix stabs generation bugs.  These routines must be run before the
    156  1.1    darran  * post-conversion merge
    157  1.1    darran  */
    158  1.1    darran void
    159  1.1    darran cvt_fixstabs(tdata_t *td)
    160  1.1    darran {
    161  1.1    darran 	fix_ptrptr_to_struct(td);
    162  1.1    darran 	fix_ptr_to_struct(td);
    163  1.1    darran }
    164  1.1    darran 
    165  1.1    darran struct match {
    166  1.1    darran 	tdesc_t *m_ret;
    167  1.1    darran 	const char *m_name;
    168  1.1    darran };
    169  1.1    darran 
    170  1.1    darran static int
    171  1.2    darran matching_iidesc(void *arg1, void *arg2)
    172  1.1    darran {
    173  1.2    darran 	iidesc_t *iidesc = arg1;
    174  1.2    darran 	struct match *match = arg2;
    175  1.1    darran 	if (!streq(iidesc->ii_name, match->m_name))
    176  1.1    darran 		return (0);
    177  1.1    darran 
    178  1.1    darran 	if (iidesc->ii_type != II_TYPE && iidesc->ii_type != II_SOU)
    179  1.1    darran 		return (0);
    180  1.1    darran 
    181  1.1    darran 	match->m_ret = iidesc->ii_dtype;
    182  1.1    darran 	return (-1);
    183  1.1    darran }
    184  1.1    darran 
    185  1.1    darran static tdesc_t *
    186  1.2    darran lookup_tdesc(tdata_t *td, char const *name)
    187  1.1    darran {
    188  1.1    darran 	struct match match = { NULL, name };
    189  1.2    darran 	iter_iidescs_by_name(td, name, matching_iidesc, &match);
    190  1.1    darran 	return (match.m_ret);
    191  1.1    darran }
    192  1.1    darran 
    193  1.1    darran /*
    194  1.1    darran  * The cpu structure grows, with the addition of a machcpu member, if
    195  1.1    darran  * _MACHDEP is defined.  This means that, for example, the cpu structure
    196  1.1    darran  * in unix is different from the cpu structure in genunix.  As one might
    197  1.1    darran  * expect, this causes merges to fail.  Since everyone indirectly contains
    198  1.1    darran  * a pointer to a CPU structure, the failed merges can cause massive amounts
    199  1.1    darran  * of duplication.  In the case of unix uniquifying against genunix, upwards
    200  1.1    darran  * of 50% of the structures were unmerged due to this problem.  We fix this
    201  1.1    darran  * by adding a cpu_m member.  If machcpu hasn't been defined in our module,
    202  1.1    darran  * we make a forward node for it.
    203  1.1    darran  */
    204  1.1    darran static void
    205  1.1    darran fix_small_cpu_struct(tdata_t *td, size_t ptrsize)
    206  1.1    darran {
    207  1.1    darran 	tdesc_t *cput, *cpu;
    208  1.1    darran 	tdesc_t *machcpu;
    209  1.1    darran 	mlist_t *ml, *lml;
    210  1.1    darran 	mlist_t *cpum;
    211  1.1    darran 	int foundcpucyc = 0;
    212  1.1    darran 
    213  1.1    darran 	/*
    214  1.1    darran 	 * We're going to take the circuitous route finding the cpu structure,
    215  1.1    darran 	 * because we want to make sure that we find the right one.  It would
    216  1.1    darran 	 * be nice if we could verify the header name too.  DWARF might not
    217  1.1    darran 	 * have the cpu_t, so we let this pass.
    218  1.1    darran 	 */
    219  1.1    darran 	if ((cput = lookup_tdesc(td, "cpu_t")) != NULL) {
    220  1.1    darran 		if (cput->t_type != TYPEDEF)
    221  1.1    darran 			return;
    222  1.1    darran 		cpu = cput->t_tdesc;
    223  1.1    darran 	} else {
    224  1.1    darran 		cpu = lookup_tdesc(td, "cpu");
    225  1.1    darran 	}
    226  1.1    darran 
    227  1.1    darran 	if (cpu == NULL)
    228  1.1    darran 		return;
    229  1.1    darran 
    230  1.1    darran 	if (!streq(cpu->t_name, "cpu") || cpu->t_type != STRUCT)
    231  1.1    darran 		return;
    232  1.1    darran 
    233  1.1    darran 	for (ml = cpu->t_members, lml = NULL; ml;
    234  1.1    darran 	    lml = ml, ml = ml->ml_next) {
    235  1.1    darran 		if (strcmp(ml->ml_name, "cpu_cyclic") == 0)
    236  1.1    darran 			foundcpucyc = 1;
    237  1.1    darran 	}
    238  1.1    darran 
    239  1.1    darran 	if (foundcpucyc == 0 || lml == NULL ||
    240  1.1    darran 	    strcmp(lml->ml_name, "cpu_m") == 0)
    241  1.1    darran 		return;
    242  1.1    darran 
    243  1.1    darran 	/*
    244  1.1    darran 	 * We need to derive the right offset for the fake cpu_m member.  To do
    245  1.1    darran 	 * that, we require a special unused member to be the last member
    246  1.1    darran 	 * before the 'cpu_m', that we encode knowledge of here.  ABI alignment
    247  1.1    darran 	 * on all platforms is such that we only need to add a pointer-size
    248  1.1    darran 	 * number of bits to get the right offset for cpu_m.  This would most
    249  1.1    darran 	 * likely break if gcc's -malign-double were ever used, but that option
    250  1.1    darran 	 * breaks the ABI anyway.
    251  1.1    darran 	 */
    252  1.1    darran 	if (!streq(lml->ml_name, "cpu_m_pad") &&
    253  1.1    darran 	    getenv("CTFCONVERT_PERMISSIVE") == NULL) {
    254  1.1    darran 		terminate("last cpu_t member before cpu_m is %s; "
    255  1.1    darran 		    "it must be cpu_m_pad.\n", lml->ml_name);
    256  1.1    darran 	}
    257  1.1    darran 
    258  1.1    darran 	if ((machcpu = lookup_tdesc(td, "machcpu")) == NULL) {
    259  1.1    darran 		machcpu = xcalloc(sizeof (*machcpu));
    260  1.1    darran 		machcpu->t_name = xstrdup("machcpu");
    261  1.1    darran 		machcpu->t_id = td->td_nextid++;
    262  1.1    darran 		machcpu->t_type = FORWARD;
    263  1.1    darran 	} else if (machcpu->t_type != STRUCT) {
    264  1.1    darran 		return;
    265  1.1    darran 	}
    266  1.1    darran 
    267  1.1    darran 	debug(3, "Adding cpu_m machcpu %s to cpu struct\n",
    268  1.1    darran 	    (machcpu->t_type == FORWARD ? "forward" : "struct"));
    269  1.1    darran 
    270  1.1    darran 	cpum = xmalloc(sizeof (*cpum));
    271  1.1    darran 	cpum->ml_offset = lml->ml_offset + (ptrsize * NBBY);
    272  1.1    darran 	cpum->ml_size = 0;
    273  1.1    darran 	cpum->ml_name = xstrdup("cpu_m");
    274  1.1    darran 	cpum->ml_type = machcpu;
    275  1.1    darran 	cpum->ml_next = NULL;
    276  1.1    darran 
    277  1.1    darran 	lml->ml_next = cpum;
    278  1.1    darran }
    279  1.1    darran 
    280  1.8  christos #if defined(__NetBSD__) || HAVE_NBTOOL_CONFIG_H
    281  1.4   hannken 
    282  1.4   hannken /*
    283  1.5   hannken  * XXX: A crude hack to bring down the number of types for a
    284  1.7       wiz  * GENERIC kernel below 2**15-1 (from ~34000 to ~29800).
    285  1.5   hannken  *
    286  1.5   hannken  * Remove the type attributes "volatile", "const" and "restrict",
    287  1.5   hannken  * for DTRACE these attributes are of little value.
    288  1.5   hannken  */
    289  1.5   hannken 
    290  1.5   hannken static int
    291  1.5   hannken fix_kill_attr_cb(tdesc_t *tdp, tdesc_t **tdpp, void *private __unused)
    292  1.5   hannken {
    293  1.5   hannken 
    294  1.5   hannken 	while (tdp->t_type == VOLATILE ||
    295  1.5   hannken 	    tdp->t_type == RESTRICT ||
    296  1.5   hannken 	    tdp->t_type == CONST)
    297  1.5   hannken 		tdp = tdp->t_tdesc;
    298  1.5   hannken 
    299  1.5   hannken 	*tdpp = tdp;
    300  1.5   hannken 
    301  1.5   hannken 	return 1;
    302  1.5   hannken }
    303  1.5   hannken 
    304  1.5   hannken static tdtrav_cb_f fix_kill_attr_tab[] = {
    305  1.5   hannken 	NULL,
    306  1.5   hannken 	NULL,			/* intrinsic */
    307  1.5   hannken 	NULL,			/* pointer */
    308  1.5   hannken 	NULL,			/* reference */
    309  1.5   hannken 	NULL,			/* array */
    310  1.5   hannken 	NULL,			/* function */
    311  1.5   hannken 	NULL,			/* struct */
    312  1.5   hannken 	NULL,			/* union */
    313  1.5   hannken 	NULL,			/* class */
    314  1.5   hannken 	NULL,			/* enum */
    315  1.5   hannken 	NULL		,	/* forward */
    316  1.5   hannken 	NULL,			/* typedef */
    317  1.5   hannken 	NULL,			/* typedef unres */
    318  1.5   hannken 	fix_kill_attr_cb,	/* volatile */
    319  1.5   hannken 	fix_kill_attr_cb,	/* const */
    320  1.5   hannken 	fix_kill_attr_cb,	/* restrict */
    321  1.5   hannken };
    322  1.5   hannken 
    323  1.5   hannken static void
    324  1.5   hannken fix_kill_attr(tdata_t *td, size_t ptrsize)
    325  1.5   hannken {
    326  1.5   hannken 
    327  1.5   hannken 	(void) iitraverse_hash(td->td_iihash, &td->td_curvgen,
    328  1.5   hannken 	    fix_kill_attr_tab, NULL, NULL, NULL);
    329  1.5   hannken }
    330  1.5   hannken 
    331  1.9     ozaki #endif /* __NetBSD__ || HAVE_NBTOOL_CONFIG_H */
    332  1.4   hannken 
    333  1.1    darran void
    334  1.1    darran cvt_fixups(tdata_t *td, size_t ptrsize)
    335  1.1    darran {
    336  1.1    darran 	fix_small_cpu_struct(td, ptrsize);
    337  1.9     ozaki #if defined(__NetBSD__) || HAVE_NBTOOL_CONFIG_H
    338  1.5   hannken 	fix_kill_attr(td, ptrsize);
    339  1.4   hannken #endif
    340  1.1    darran }
    341