Path: blob/main/cddl/contrib/opensolaris/tools/ctf/cvt/fixup_tdescs.c
39586 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License (the "License").5* You may not use this file except in compliance with the License.6*7* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE8* or http://www.opensolaris.org/os/licensing.9* See the License for the specific language governing permissions10* and limitations under the License.11*12* When distributing Covered Code, include this CDDL HEADER in each13* file and include the License file at usr/src/OPENSOLARIS.LICENSE.14* If applicable, add the following below this CDDL HEADER, with the15* fields enclosed by brackets "[]" replaced with your own identifying16* information: Portions Copyright [yyyy] [name of copyright owner]17*18* CDDL HEADER END19*/20/*21* Copyright 2006 Sun Microsystems, Inc. All rights reserved.22* Use is subject to license terms.23*/2425#pragma ident "%Z%%M% %I% %E% SMI"2627/*28* Workarounds for stabs generation bugs in the compiler and general needed29* fixups.30*/3132#include <stdio.h>33#include <strings.h>3435#include "ctf_headers.h"36#include "ctftools.h"37#include "hash.h"38#include "memory.h"3940struct match {41tdesc_t *m_ret;42const char *m_name;43};4445static int46matching_iidesc(void *arg1, void *arg2)47{48iidesc_t *iidesc = arg1;49struct match *match = arg2;50if (!streq(iidesc->ii_name, match->m_name))51return (0);5253if (iidesc->ii_type != II_TYPE && iidesc->ii_type != II_SOU)54return (0);5556match->m_ret = iidesc->ii_dtype;57return (-1);58}5960static tdesc_t *61lookup_tdesc(tdata_t *td, char const *name)62{63struct match match = { NULL, name };64iter_iidescs_by_name(td, name, matching_iidesc, &match);65return (match.m_ret);66}6768/*69* The cpu structure grows, with the addition of a machcpu member, if70* _MACHDEP is defined. This means that, for example, the cpu structure71* in unix is different from the cpu structure in genunix. As one might72* expect, this causes merges to fail. Since everyone indirectly contains73* a pointer to a CPU structure, the failed merges can cause massive amounts74* of duplication. In the case of unix uniquifying against genunix, upwards75* of 50% of the structures were unmerged due to this problem. We fix this76* by adding a cpu_m member. If machcpu hasn't been defined in our module,77* we make a forward node for it.78*/79static void80fix_small_cpu_struct(tdata_t *td, size_t ptrsize)81{82tdesc_t *cput, *cpu;83tdesc_t *machcpu;84mlist_t *ml, *lml;85mlist_t *cpum;86int foundcpucyc = 0;8788/*89* We're going to take the circuitous route finding the cpu structure,90* because we want to make sure that we find the right one. It would91* be nice if we could verify the header name too. DWARF might not92* have the cpu_t, so we let this pass.93*/94if ((cput = lookup_tdesc(td, "cpu_t")) != NULL) {95if (cput->t_type != TYPEDEF)96return;97cpu = cput->t_tdesc;98} else {99cpu = lookup_tdesc(td, "cpu");100}101102if (cpu == NULL)103return;104105if (!streq(cpu->t_name, "cpu") || cpu->t_type != STRUCT)106return;107108for (ml = cpu->t_members, lml = NULL; ml;109lml = ml, ml = ml->ml_next) {110if (strcmp(ml->ml_name, "cpu_cyclic") == 0)111foundcpucyc = 1;112}113114if (foundcpucyc == 0 || lml == NULL ||115strcmp(lml->ml_name, "cpu_m") == 0)116return;117118/*119* We need to derive the right offset for the fake cpu_m member. To do120* that, we require a special unused member to be the last member121* before the 'cpu_m', that we encode knowledge of here. ABI alignment122* on all platforms is such that we only need to add a pointer-size123* number of bits to get the right offset for cpu_m. This would most124* likely break if gcc's -malign-double were ever used, but that option125* breaks the ABI anyway.126*/127if (!streq(lml->ml_name, "cpu_m_pad") &&128getenv("CTFCONVERT_PERMISSIVE") == NULL) {129terminate("last cpu_t member before cpu_m is %s; "130"it must be cpu_m_pad.\n", lml->ml_name);131}132133if ((machcpu = lookup_tdesc(td, "machcpu")) == NULL) {134machcpu = xcalloc(sizeof (*machcpu));135machcpu->t_name = xstrdup("machcpu");136machcpu->t_id = td->td_nextid++;137machcpu->t_type = FORWARD;138} else if (machcpu->t_type != STRUCT) {139return;140}141142debug(3, "Adding cpu_m machcpu %s to cpu struct\n",143(machcpu->t_type == FORWARD ? "forward" : "struct"));144145cpum = xmalloc(sizeof (*cpum));146cpum->ml_offset = lml->ml_offset + (ptrsize * NBBY);147cpum->ml_size = 0;148cpum->ml_name = xstrdup("cpu_m");149cpum->ml_type = machcpu;150cpum->ml_next = NULL;151152lml->ml_next = cpum;153}154155void156cvt_fixups(tdata_t *td, size_t ptrsize)157{158fix_small_cpu_struct(td, ptrsize);159}160161162