1178481Sjb/* 2178481Sjb * CDDL HEADER START 3178481Sjb * 4178481Sjb * The contents of this file are subject to the terms of the 5178481Sjb * Common Development and Distribution License (the "License"). 6178481Sjb * You may not use this file except in compliance with the License. 7178481Sjb * 8178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178481Sjb * or http://www.opensolaris.org/os/licensing. 10178481Sjb * See the License for the specific language governing permissions 11178481Sjb * and limitations under the License. 12178481Sjb * 13178481Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178481Sjb * If applicable, add the following below this CDDL HEADER, with the 16178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178481Sjb * 19178481Sjb * CDDL HEADER END 20178481Sjb */ 21178481Sjb/* 22178481Sjb * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23178481Sjb * Use is subject to license terms. 24178481Sjb */ 25178481Sjb 26178481Sjb#pragma ident "%Z%%M% %I% %E% SMI" 27178481Sjb 28178481Sjb/* 29178481Sjb * Workarounds for stabs generation bugs in the compiler and general needed 30178481Sjb * fixups. 31178481Sjb */ 32178481Sjb 33178481Sjb#include <stdio.h> 34178481Sjb#include <strings.h> 35178481Sjb 36178481Sjb#include "ctf_headers.h" 37178481Sjb#include "ctftools.h" 38178481Sjb#include "hash.h" 39178481Sjb#include "memory.h" 40178481Sjb 41178481Sjb/* 42178481Sjb * Due to 4432619, the 6.1 compiler will sometimes incorrectly generate pointer 43178481Sjb * stabs. Given a struct foo, and a corresponding typedef struct foo foo_t. 44178481Sjb * In some cases, when faced with a pointer to a foo_t, the compiler will 45178481Sjb * sometimes generate a stab that describes a pointer to a struct foo. 46178481Sjb * Regardless of correctness, this breaks merges, as it occurs inconsistently 47178481Sjb * by file. The following two routines know how to recognize and repair foo_t * 48178481Sjb * and foo_t ** bugs in a specific set of cases. There is no general way to 49178481Sjb * solve this problem without a fix to the compiler. In general, cases should 50178481Sjb * only be added to these routines to fix merging problems in genunix. 51178481Sjb */ 52178481Sjbstatic void 53178481Sjbfix_ptrptr_to_struct(tdata_t *td) 54178481Sjb{ 55178546Sjb const char *strs[2] = { "as", "fdbuffer" }; 56178546Sjb const char *mems[2] = { "a_objectdir", "fd_shadow" }; 57178546Sjb const char *acts[2] = { "vnode", "page" }; 58178546Sjb const char *tgts[2] = { "vnode_t", "page_t" }; 59178481Sjb tdesc_t *str; 60178481Sjb tdesc_t *act, *tgt; 61178481Sjb tdesc_t *p1, *p2; 62178481Sjb mlist_t *ml; 63178481Sjb int i; 64178481Sjb 65178546Sjb for (i = 0; i < (int) (sizeof (strs) / sizeof (strs[0])); i++) { 66178481Sjb if (!(str = lookupname(strs[i])) || str->t_type != STRUCT) 67178481Sjb continue; 68178481Sjb 69178481Sjb for (ml = str->t_members; ml; ml = ml->ml_next) { 70178481Sjb if (streq(ml->ml_name, mems[i])) 71178481Sjb break; 72178481Sjb } 73178481Sjb if (!ml) 74178481Sjb continue; 75178481Sjb 76178481Sjb if (ml->ml_type->t_type != POINTER || ml->ml_type->t_name || 77178481Sjb ml->ml_type->t_tdesc->t_type != POINTER || 78178481Sjb ml->ml_type->t_tdesc->t_name) 79178481Sjb continue; 80178481Sjb 81178481Sjb act = ml->ml_type->t_tdesc->t_tdesc; 82178481Sjb if (act->t_type != STRUCT || !streq(act->t_name, acts[i])) 83178481Sjb continue; 84178481Sjb 85178481Sjb if (!(tgt = lookupname(tgts[i])) || tgt->t_type != TYPEDEF) 86178481Sjb continue; 87178481Sjb 88178481Sjb /* We have an instance of the bug */ 89178481Sjb p2 = xcalloc(sizeof (*p2)); 90178481Sjb p2->t_type = POINTER; 91178481Sjb p2->t_id = td->td_nextid++; 92178481Sjb p2->t_tdesc = tgt; 93178481Sjb 94178481Sjb p1 = xcalloc(sizeof (*p1)); 95178481Sjb p1->t_type = POINTER; 96178481Sjb p1->t_id = td->td_nextid++; 97178481Sjb p1->t_tdesc = p2; 98178481Sjb 99178481Sjb ml->ml_type = p1; 100178481Sjb 101178481Sjb debug(3, "Fixed %s->%s => ptrptr struct %s bug\n", 102178481Sjb strs[i], mems[i], acts[i]); 103178481Sjb } 104178481Sjb} 105178481Sjb 106178481Sjbstatic void 107178481Sjbfix_ptr_to_struct(tdata_t *td) 108178481Sjb{ 109178546Sjb const char *strs[2] = { "vmem", "id_space" }; 110178546Sjb const char *mems[2] = { NULL, "is_vmem" }; 111178481Sjb tdesc_t *ptr = NULL; 112178481Sjb tdesc_t *str, *vmt; 113178481Sjb mlist_t *ml; 114178481Sjb int i; 115178481Sjb 116178481Sjb if ((vmt = lookupname("vmem_t")) == NULL || vmt->t_type != TYPEDEF) 117178481Sjb return; 118178481Sjb 119178546Sjb for (i = 0; i < (int) (sizeof (strs) / sizeof (strs[0])); i++) { 120178481Sjb if (!(str = lookupname(strs[i])) || str->t_type != STRUCT) 121178481Sjb continue; 122178481Sjb 123178481Sjb for (ml = str->t_members; ml; ml = ml->ml_next) { 124178481Sjb if (mems[i] && !streq(ml->ml_name, mems[i])) 125178481Sjb continue; 126178481Sjb 127178481Sjb if (ml->ml_type->t_type != POINTER || 128178481Sjb ml->ml_type->t_name || 129178481Sjb (ml->ml_type->t_tdesc->t_type != STRUCT && 130178481Sjb ml->ml_type->t_tdesc->t_type != FORWARD) || 131178481Sjb !streq(ml->ml_type->t_tdesc->t_name, "vmem")) 132178481Sjb continue; 133178481Sjb 134178481Sjb debug(3, "Fixed %s->%s => ptr struct vmem bug\n", 135178481Sjb strs[i], ml->ml_name); 136178481Sjb 137178481Sjb if (!ptr) { 138178481Sjb ptr = xcalloc(sizeof (*ptr)); 139178481Sjb ptr->t_type = POINTER; 140178481Sjb ptr->t_id = td->td_nextid++; 141178481Sjb ptr->t_tdesc = vmt; 142178481Sjb } 143178481Sjb 144178481Sjb ml->ml_type = ptr; 145178481Sjb } 146178481Sjb } 147178481Sjb} 148178481Sjb 149178481Sjb/* 150178481Sjb * Fix stabs generation bugs. These routines must be run before the 151178481Sjb * post-conversion merge 152178481Sjb */ 153178481Sjbvoid 154178481Sjbcvt_fixstabs(tdata_t *td) 155178481Sjb{ 156178481Sjb fix_ptrptr_to_struct(td); 157178481Sjb fix_ptr_to_struct(td); 158178481Sjb} 159178481Sjb 160178481Sjbstruct match { 161178481Sjb tdesc_t *m_ret; 162178481Sjb const char *m_name; 163178481Sjb}; 164178481Sjb 165178481Sjbstatic int 166178546Sjbmatching_iidesc(void *arg1, void *arg2) 167178481Sjb{ 168178546Sjb iidesc_t *iidesc = arg1; 169178546Sjb struct match *match = arg2; 170178481Sjb if (!streq(iidesc->ii_name, match->m_name)) 171178481Sjb return (0); 172178481Sjb 173178481Sjb if (iidesc->ii_type != II_TYPE && iidesc->ii_type != II_SOU) 174178481Sjb return (0); 175178481Sjb 176178481Sjb match->m_ret = iidesc->ii_dtype; 177178481Sjb return (-1); 178178481Sjb} 179178481Sjb 180178481Sjbstatic tdesc_t * 181178546Sjblookup_tdesc(tdata_t *td, char const *name) 182178481Sjb{ 183178481Sjb struct match match = { NULL, name }; 184178546Sjb iter_iidescs_by_name(td, name, matching_iidesc, &match); 185178481Sjb return (match.m_ret); 186178481Sjb} 187178481Sjb 188178481Sjb/* 189178481Sjb * The cpu structure grows, with the addition of a machcpu member, if 190178481Sjb * _MACHDEP is defined. This means that, for example, the cpu structure 191178481Sjb * in unix is different from the cpu structure in genunix. As one might 192178481Sjb * expect, this causes merges to fail. Since everyone indirectly contains 193178481Sjb * a pointer to a CPU structure, the failed merges can cause massive amounts 194178481Sjb * of duplication. In the case of unix uniquifying against genunix, upwards 195178481Sjb * of 50% of the structures were unmerged due to this problem. We fix this 196178481Sjb * by adding a cpu_m member. If machcpu hasn't been defined in our module, 197178481Sjb * we make a forward node for it. 198178481Sjb */ 199178481Sjbstatic void 200178481Sjbfix_small_cpu_struct(tdata_t *td, size_t ptrsize) 201178481Sjb{ 202178481Sjb tdesc_t *cput, *cpu; 203178481Sjb tdesc_t *machcpu; 204178481Sjb mlist_t *ml, *lml; 205178481Sjb mlist_t *cpum; 206178481Sjb int foundcpucyc = 0; 207178481Sjb 208178481Sjb /* 209178481Sjb * We're going to take the circuitous route finding the cpu structure, 210178481Sjb * because we want to make sure that we find the right one. It would 211178481Sjb * be nice if we could verify the header name too. DWARF might not 212178481Sjb * have the cpu_t, so we let this pass. 213178481Sjb */ 214178481Sjb if ((cput = lookup_tdesc(td, "cpu_t")) != NULL) { 215178481Sjb if (cput->t_type != TYPEDEF) 216178481Sjb return; 217178481Sjb cpu = cput->t_tdesc; 218178481Sjb } else { 219178481Sjb cpu = lookup_tdesc(td, "cpu"); 220178481Sjb } 221178481Sjb 222178481Sjb if (cpu == NULL) 223178481Sjb return; 224178481Sjb 225178481Sjb if (!streq(cpu->t_name, "cpu") || cpu->t_type != STRUCT) 226178481Sjb return; 227178481Sjb 228178481Sjb for (ml = cpu->t_members, lml = NULL; ml; 229178481Sjb lml = ml, ml = ml->ml_next) { 230178481Sjb if (strcmp(ml->ml_name, "cpu_cyclic") == 0) 231178481Sjb foundcpucyc = 1; 232178481Sjb } 233178481Sjb 234178481Sjb if (foundcpucyc == 0 || lml == NULL || 235178481Sjb strcmp(lml->ml_name, "cpu_m") == 0) 236178481Sjb return; 237178481Sjb 238178481Sjb /* 239178481Sjb * We need to derive the right offset for the fake cpu_m member. To do 240178481Sjb * that, we require a special unused member to be the last member 241178481Sjb * before the 'cpu_m', that we encode knowledge of here. ABI alignment 242178481Sjb * on all platforms is such that we only need to add a pointer-size 243178481Sjb * number of bits to get the right offset for cpu_m. This would most 244178481Sjb * likely break if gcc's -malign-double were ever used, but that option 245178481Sjb * breaks the ABI anyway. 246178481Sjb */ 247178481Sjb if (!streq(lml->ml_name, "cpu_m_pad") && 248178481Sjb getenv("CTFCONVERT_PERMISSIVE") == NULL) { 249178481Sjb terminate("last cpu_t member before cpu_m is %s; " 250178481Sjb "it must be cpu_m_pad.\n", lml->ml_name); 251178481Sjb } 252178481Sjb 253178481Sjb if ((machcpu = lookup_tdesc(td, "machcpu")) == NULL) { 254178481Sjb machcpu = xcalloc(sizeof (*machcpu)); 255178481Sjb machcpu->t_name = xstrdup("machcpu"); 256178481Sjb machcpu->t_id = td->td_nextid++; 257178481Sjb machcpu->t_type = FORWARD; 258178481Sjb } else if (machcpu->t_type != STRUCT) { 259178481Sjb return; 260178481Sjb } 261178481Sjb 262178481Sjb debug(3, "Adding cpu_m machcpu %s to cpu struct\n", 263178481Sjb (machcpu->t_type == FORWARD ? "forward" : "struct")); 264178481Sjb 265178481Sjb cpum = xmalloc(sizeof (*cpum)); 266178481Sjb cpum->ml_offset = lml->ml_offset + (ptrsize * NBBY); 267178481Sjb cpum->ml_size = 0; 268178481Sjb cpum->ml_name = xstrdup("cpu_m"); 269178481Sjb cpum->ml_type = machcpu; 270178481Sjb cpum->ml_next = NULL; 271178481Sjb 272178481Sjb lml->ml_next = cpum; 273178481Sjb} 274178481Sjb 275178481Sjbvoid 276178481Sjbcvt_fixups(tdata_t *td, size_t ptrsize) 277178481Sjb{ 278178481Sjb fix_small_cpu_struct(td, ptrsize); 279178481Sjb} 280