dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * CDDL HEADER START
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * The contents of this file are subject to the terms of the
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Common Development and Distribution License (the "License").
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * You may not use this file except in compliance with the License.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * or http://www.opensolaris.org/os/licensing.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * See the License for the specific language governing permissions
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * and limitations under the License.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * When distributing Covered Code, include this CDDL HEADER in each
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * If applicable, add the following below this CDDL HEADER, with the
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * fields enclosed by brackets "[]" replaced with your own identifying
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * information: Portions Copyright [yyyy] [name of copyright owner]
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * CDDL HEADER END
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Use is subject to license terms.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#pragma ident "%Z%%M% %I% %E% SMI"
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#include <stddef.h>
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#include <stdlib.h>
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#include <string.h>
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#include "dis_target.h"
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#include "dis_list.h"
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock#include "dis_util.h"
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * List support functions.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Support routines for managing lists of sections and functions. We first
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * process the command line arguments into lists of strings. For each target,
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * we resolve these strings against the set of available sections and/or
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * functions to arrive at the set of objects to disassemble.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * We export two types of lists, namelists and resolvelists. The first is used
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * to record names given as command line options. The latter is used to
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * maintain the data objects specific to a given target.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrocktypedef struct unresolved_name {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock const char *un_name; /* name of function or object */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock int un_value; /* user-supplied data */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock int un_mark; /* internal counter */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_node_t un_node; /* uulist node */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock} unresolved_name_t;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrocktypedef struct resolved_name {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock void *rn_data; /* section or function data */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock int rn_value; /* user-supplied data */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_node_t rn_node; /* uulist node */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock} resolved_name_t;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic uu_list_pool_t *unresolved_pool;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic uu_list_pool_t *resolved_pool;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic int current_mark = 0;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic void
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockinitialize_pools(void)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unresolved_pool = uu_list_pool_create(
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock "unresolved_pool", sizeof (unresolved_name_t),
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock offsetof(unresolved_name_t, un_node), NULL, 0);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_pool = uu_list_pool_create(
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock "resolved_pool", sizeof (resolved_name_t),
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock offsetof(resolved_name_t, rn_node), NULL, 0);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if (unresolved_pool == NULL ||
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_pool == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Returns an empty list of unresolved names.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_t *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_create(void)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_t *listp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock /*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * If this is the first request to create a list, initialize the list
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * pools.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if (unresolved_pool == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock initialize_pools();
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((listp = uu_list_create(unresolved_pool, NULL, 0)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock return (listp);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Adds the given name to the unresolved list. 'value' is an arbitrary value
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * which is preserved for this entry, even when resolved against a target. This
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * allows the caller to associate similar behavior (such as the difference
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * between -d, -D, and -s) without having to create multiple lists.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockvoid
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_add(dis_namelist_t *list, const char *name, int value)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unresolved_name_t *node;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock node = safe_malloc(sizeof (unresolved_name_t));
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock node->un_name = name;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock node->un_value = value;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock node->un_mark = 0;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock (void) uu_list_insert_before(list, NULL, node);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Internal callback structure used
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrocktypedef struct cb_data {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock int cb_mark;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_t *cb_source;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_t *cb_resolved;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock} cb_data_t;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * For each section, walk the list of unresolved names and resolve those that
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * correspond to real functions. We mark functions as we see them, and re-walk
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * the list a second time to warn about functions we didn't find.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * This is an O(n * m) algorithm, but we typically search for only a single
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * function.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/* ARGSUSED */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic void
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockwalk_sections(dis_tgt_t *tgt, dis_scn_t *scn, void *data)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb_data_t *cb = data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unresolved_name_t *unp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(cb->cb_source, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((unp = uu_list_walk_next(walk)) != NULL) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if (strcmp(unp->un_name, dis_section_name(scn)) == 0) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_name_t *resolved;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock /*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Mark the current node as seen
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unp->un_mark = cb->cb_mark;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock /*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Add the data to the resolved list
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved = safe_malloc(sizeof (resolved_name_t));
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved->rn_data = dis_section_copy(scn);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved->rn_value = unp->un_value;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock (void) uu_list_insert_before(cb->cb_resolved, NULL,
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Take a list of unresolved names and create a resolved list of sections. We
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * rely on walk_sections() to do the dirty work. After resolving the sections,
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * we check for any unmarked names and warn the user about missing sections.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_scnlist_t *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_resolve_sections(dis_namelist_t *namelist, dis_tgt_t *tgt)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_t *listp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb_data_t cb;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unresolved_name_t *unp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock /*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Walk all sections in the target, calling walk_sections() for each
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * one.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((listp = uu_list_create(resolved_pool, NULL, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb.cb_mark = ++current_mark;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb.cb_source = namelist;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb.cb_resolved = listp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock dis_tgt_section_iter(tgt, walk_sections, &cb);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock /*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Walk all elements of the unresolved list, and report any that we
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * didn't mark in the process.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(namelist, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((unp = uu_list_walk_next(walk)) != NULL) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if (unp->un_mark != current_mark)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock warn("failed to find section '%s' in '%s'",
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unp->un_name, dis_tgt_name(tgt));
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock return (listp);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Similar to walk_sections(), but for functions.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/* ARGSUSED */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic void
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockwalk_functions(dis_tgt_t *tgt, dis_func_t *func, void *data)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb_data_t *cb = data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unresolved_name_t *unp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(cb->cb_source, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((unp = uu_list_walk_next(walk)) != NULL) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if (strcmp(unp->un_name, dis_function_name(func)) == 0) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_name_t *resolved;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unp->un_mark = cb->cb_mark;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved = safe_malloc(sizeof (resolved_name_t));
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved->rn_data = dis_function_copy(func);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved->rn_value = unp->un_value;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock (void) uu_list_insert_before(cb->cb_resolved, NULL,
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Take a list of unresolved names and create a resolved list of functions. We
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * rely on walk_functions() to do the dirty work. After resolving the
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * functions, * we check for any unmarked names and warn the user about missing
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * functions.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_funclist_t *
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_resolve_functions(dis_namelist_t *namelist, dis_tgt_t *tgt)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_t *listp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unresolved_name_t *unp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb_data_t cb;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((listp = uu_list_create(resolved_pool, NULL, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb.cb_mark = ++current_mark;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb.cb_source = namelist;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock cb.cb_resolved = listp;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock dis_tgt_function_iter(tgt, walk_functions, &cb);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock /*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Walk unresolved list and report any missing functions.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(namelist, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((unp = uu_list_walk_next(walk)) != NULL) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if (unp->un_mark != current_mark)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock warn("failed to find function '%s' in '%s'",
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock unp->un_name, dis_tgt_name(tgt));
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock return (listp);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Returns true if the given list is empty.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockint
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_empty(dis_namelist_t *list)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock return (uu_list_numnodes(list) == 0);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockstatic void
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockfree_list(uu_list_t *list)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock void *data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(list, UU_WALK_ROBUST)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((data = uu_list_walk_next(walk)) != NULL) {
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_remove(list, data);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock free(data);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock }
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_destroy(list);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Destroy a list of sections. First, walk the list and free the associated
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * section data. Pass the list onto to free_list() to clean up the rest of the
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * list.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockvoid
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_scnlist_destroy(dis_scnlist_t *list)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_name_t *data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((data = uu_list_walk_next(walk)) != NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock dis_section_free(data->rn_data);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock free_list(list);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Destroy a list of functions. First, walk the list and free the associated
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * function data. Pass the list onto to free_list() to clean up the rest of the
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * list.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockvoid
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_funclist_destroy(dis_funclist_t *list)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_name_t *data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((data = uu_list_walk_next(walk)) != NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock dis_function_free(data->rn_data);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock free_list(list);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Destroy a lis tof unresolved names.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockvoid
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_namelist_destroy(dis_namelist_t *list)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock free_list(list);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Iterate over a resolved list of sections.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockvoid
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_scnlist_iter(uu_list_t *list, void (*func)(dis_scn_t *, int, void *),
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock void *arg)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_name_t *data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((data = uu_list_walk_next(walk)) != NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock func(data->rn_data, data->rn_value, arg);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock/*
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock * Iterate over a resolved list of functions.
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock */
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockvoid
dc0093f44ee4fac928e006850f8ed53f68277af5eschrockdis_funclist_iter(uu_list_t *list, void (*func)(dis_func_t *, int, void *),
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock void *arg)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock{
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_t *walk;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock resolved_name_t *data;
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock if ((walk = uu_list_walk_start(list, UU_DEFAULT)) == NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock die("out of memory");
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock while ((data = uu_list_walk_next(walk)) != NULL)
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock func(data->rn_data, data->rn_value, arg);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock uu_list_walk_end(walk);
dc0093f44ee4fac928e006850f8ed53f68277af5eschrock}