xref: /onnv-gate/usr/src/cmd/latencytop/common/table.c (revision 10673:b22eb20aa9ca)
1*10673SKrishnendu.Sadhukhan@Sun.COM /*
2*10673SKrishnendu.Sadhukhan@Sun.COM  * CDDL HEADER START
3*10673SKrishnendu.Sadhukhan@Sun.COM  *
4*10673SKrishnendu.Sadhukhan@Sun.COM  * The contents of this file are subject to the terms of the
5*10673SKrishnendu.Sadhukhan@Sun.COM  * Common Development and Distribution License (the "License").
6*10673SKrishnendu.Sadhukhan@Sun.COM  * You may not use this file except in compliance with the License.
7*10673SKrishnendu.Sadhukhan@Sun.COM  *
8*10673SKrishnendu.Sadhukhan@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10673SKrishnendu.Sadhukhan@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*10673SKrishnendu.Sadhukhan@Sun.COM  * See the License for the specific language governing permissions
11*10673SKrishnendu.Sadhukhan@Sun.COM  * and limitations under the License.
12*10673SKrishnendu.Sadhukhan@Sun.COM  *
13*10673SKrishnendu.Sadhukhan@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*10673SKrishnendu.Sadhukhan@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10673SKrishnendu.Sadhukhan@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*10673SKrishnendu.Sadhukhan@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*10673SKrishnendu.Sadhukhan@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10673SKrishnendu.Sadhukhan@Sun.COM  *
19*10673SKrishnendu.Sadhukhan@Sun.COM  * CDDL HEADER END
20*10673SKrishnendu.Sadhukhan@Sun.COM  */
21*10673SKrishnendu.Sadhukhan@Sun.COM /*
22*10673SKrishnendu.Sadhukhan@Sun.COM  * Copyright (c) 2008-2009, Intel Corporation.
23*10673SKrishnendu.Sadhukhan@Sun.COM  * All Rights Reserved.
24*10673SKrishnendu.Sadhukhan@Sun.COM  */
25*10673SKrishnendu.Sadhukhan@Sun.COM 
26*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdlib.h>
27*10673SKrishnendu.Sadhukhan@Sun.COM #include <string.h>
28*10673SKrishnendu.Sadhukhan@Sun.COM #include <memory.h>
29*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdio.h>
30*10673SKrishnendu.Sadhukhan@Sun.COM #include <ctype.h>
31*10673SKrishnendu.Sadhukhan@Sun.COM 
32*10673SKrishnendu.Sadhukhan@Sun.COM #include "latencytop.h"
33*10673SKrishnendu.Sadhukhan@Sun.COM 
34*10673SKrishnendu.Sadhukhan@Sun.COM /*
35*10673SKrishnendu.Sadhukhan@Sun.COM  * Structure that holds detail of a cause.
36*10673SKrishnendu.Sadhukhan@Sun.COM  */
37*10673SKrishnendu.Sadhukhan@Sun.COM typedef struct {
38*10673SKrishnendu.Sadhukhan@Sun.COM 	int lt_c_cause_id;
39*10673SKrishnendu.Sadhukhan@Sun.COM 	int lt_c_flags;
40*10673SKrishnendu.Sadhukhan@Sun.COM 	char *lt_c_name;
41*10673SKrishnendu.Sadhukhan@Sun.COM } lt_cause_t;
42*10673SKrishnendu.Sadhukhan@Sun.COM 
43*10673SKrishnendu.Sadhukhan@Sun.COM /*
44*10673SKrishnendu.Sadhukhan@Sun.COM  * Structure that represents a matched cause.
45*10673SKrishnendu.Sadhukhan@Sun.COM  */
46*10673SKrishnendu.Sadhukhan@Sun.COM typedef struct  {
47*10673SKrishnendu.Sadhukhan@Sun.COM 	int lt_mt_priority;
48*10673SKrishnendu.Sadhukhan@Sun.COM 	int lt_mt_cause_id;
49*10673SKrishnendu.Sadhukhan@Sun.COM } lt_match_t;
50*10673SKrishnendu.Sadhukhan@Sun.COM 
51*10673SKrishnendu.Sadhukhan@Sun.COM /* All lt_cause_t that are created. */
52*10673SKrishnendu.Sadhukhan@Sun.COM static GHashTable *cause_lookup = NULL;
53*10673SKrishnendu.Sadhukhan@Sun.COM static GPtrArray *causes_array = NULL;
54*10673SKrishnendu.Sadhukhan@Sun.COM static int causes_array_len = 0;
55*10673SKrishnendu.Sadhukhan@Sun.COM 
56*10673SKrishnendu.Sadhukhan@Sun.COM /*
57*10673SKrishnendu.Sadhukhan@Sun.COM  * This hash table maps a symbol to a cause.
58*10673SKrishnendu.Sadhukhan@Sun.COM  * key is of type "char *" and value is of type "lt_match_t *".
59*10673SKrishnendu.Sadhukhan@Sun.COM  */
60*10673SKrishnendu.Sadhukhan@Sun.COM static GHashTable *symbol_lookup_table = NULL;
61*10673SKrishnendu.Sadhukhan@Sun.COM 
62*10673SKrishnendu.Sadhukhan@Sun.COM /*
63*10673SKrishnendu.Sadhukhan@Sun.COM  * The dtrace translation rules we get from the script
64*10673SKrishnendu.Sadhukhan@Sun.COM  */
65*10673SKrishnendu.Sadhukhan@Sun.COM char *dtrans = NULL;
66*10673SKrishnendu.Sadhukhan@Sun.COM 
67*10673SKrishnendu.Sadhukhan@Sun.COM /*
68*10673SKrishnendu.Sadhukhan@Sun.COM  * These structures are only used inside .trans parser.
69*10673SKrishnendu.Sadhukhan@Sun.COM  */
70*10673SKrishnendu.Sadhukhan@Sun.COM typedef struct {
71*10673SKrishnendu.Sadhukhan@Sun.COM 	int lt_dm_priority;
72*10673SKrishnendu.Sadhukhan@Sun.COM 	char *lt_dm_macro;
73*10673SKrishnendu.Sadhukhan@Sun.COM } lt_dmacro_t;
74*10673SKrishnendu.Sadhukhan@Sun.COM 
75*10673SKrishnendu.Sadhukhan@Sun.COM typedef struct {
76*10673SKrishnendu.Sadhukhan@Sun.COM 	GSequence *lt_pr_cmd_disable;
77*10673SKrishnendu.Sadhukhan@Sun.COM 	GHashTable *lt_pr_dmacro;
78*10673SKrishnendu.Sadhukhan@Sun.COM } lt_parser_t;
79*10673SKrishnendu.Sadhukhan@Sun.COM 
80*10673SKrishnendu.Sadhukhan@Sun.COM /* ARGSUSED */
81*10673SKrishnendu.Sadhukhan@Sun.COM static void
free_cause(lt_cause_t * cause,void * user)82*10673SKrishnendu.Sadhukhan@Sun.COM free_cause(lt_cause_t *cause, void *user)
83*10673SKrishnendu.Sadhukhan@Sun.COM {
84*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(cause != NULL && cause->lt_c_name != NULL);
85*10673SKrishnendu.Sadhukhan@Sun.COM 
86*10673SKrishnendu.Sadhukhan@Sun.COM 	free(cause->lt_c_name);
87*10673SKrishnendu.Sadhukhan@Sun.COM 	free(cause);
88*10673SKrishnendu.Sadhukhan@Sun.COM }
89*10673SKrishnendu.Sadhukhan@Sun.COM 
90*10673SKrishnendu.Sadhukhan@Sun.COM static void
free_dmacro(lt_dmacro_t * d)91*10673SKrishnendu.Sadhukhan@Sun.COM free_dmacro(lt_dmacro_t *d)
92*10673SKrishnendu.Sadhukhan@Sun.COM {
93*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(d->lt_dm_macro != NULL);
94*10673SKrishnendu.Sadhukhan@Sun.COM 	free(d->lt_dm_macro);
95*10673SKrishnendu.Sadhukhan@Sun.COM 	free(d);
96*10673SKrishnendu.Sadhukhan@Sun.COM }
97*10673SKrishnendu.Sadhukhan@Sun.COM 
98*10673SKrishnendu.Sadhukhan@Sun.COM /*
99*10673SKrishnendu.Sadhukhan@Sun.COM  * Add a cause.
100*10673SKrishnendu.Sadhukhan@Sun.COM  */
101*10673SKrishnendu.Sadhukhan@Sun.COM static lt_cause_t *
new_cause(char * name,int flags)102*10673SKrishnendu.Sadhukhan@Sun.COM new_cause(char *name, int flags)
103*10673SKrishnendu.Sadhukhan@Sun.COM {
104*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *entry;
105*10673SKrishnendu.Sadhukhan@Sun.COM 
106*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(name != NULL);
107*10673SKrishnendu.Sadhukhan@Sun.COM 
108*10673SKrishnendu.Sadhukhan@Sun.COM 	entry = (lt_cause_t *)lt_malloc(sizeof (lt_cause_t));
109*10673SKrishnendu.Sadhukhan@Sun.COM 	entry->lt_c_flags = flags;
110*10673SKrishnendu.Sadhukhan@Sun.COM 	entry->lt_c_name = name;
111*10673SKrishnendu.Sadhukhan@Sun.COM 	entry->lt_c_cause_id = causes_array_len;
112*10673SKrishnendu.Sadhukhan@Sun.COM 
113*10673SKrishnendu.Sadhukhan@Sun.COM 	g_ptr_array_add(causes_array, entry);
114*10673SKrishnendu.Sadhukhan@Sun.COM 	++causes_array_len;
115*10673SKrishnendu.Sadhukhan@Sun.COM 
116*10673SKrishnendu.Sadhukhan@Sun.COM 	return (entry);
117*10673SKrishnendu.Sadhukhan@Sun.COM }
118*10673SKrishnendu.Sadhukhan@Sun.COM 
119*10673SKrishnendu.Sadhukhan@Sun.COM /*
120*10673SKrishnendu.Sadhukhan@Sun.COM  * Set a cause to "disabled" state.
121*10673SKrishnendu.Sadhukhan@Sun.COM  */
122*10673SKrishnendu.Sadhukhan@Sun.COM static void
disable_cause(char * cause_str,GHashTable * cause_table)123*10673SKrishnendu.Sadhukhan@Sun.COM disable_cause(char *cause_str, GHashTable *cause_table)
124*10673SKrishnendu.Sadhukhan@Sun.COM {
125*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause;
126*10673SKrishnendu.Sadhukhan@Sun.COM 
127*10673SKrishnendu.Sadhukhan@Sun.COM 	cause = (lt_cause_t *)g_hash_table_lookup(cause_table, cause_str);
128*10673SKrishnendu.Sadhukhan@Sun.COM 
129*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause != NULL) {
130*10673SKrishnendu.Sadhukhan@Sun.COM 		cause->lt_c_flags |= CAUSE_FLAG_DISABLED;
131*10673SKrishnendu.Sadhukhan@Sun.COM 	}
132*10673SKrishnendu.Sadhukhan@Sun.COM }
133*10673SKrishnendu.Sadhukhan@Sun.COM 
134*10673SKrishnendu.Sadhukhan@Sun.COM /*
135*10673SKrishnendu.Sadhukhan@Sun.COM  * Helper functions that reads a line from a character array.
136*10673SKrishnendu.Sadhukhan@Sun.COM  */
137*10673SKrishnendu.Sadhukhan@Sun.COM static int
read_line_from_mem(const char * mem,int mem_len,char * line,int line_len,int * index)138*10673SKrishnendu.Sadhukhan@Sun.COM read_line_from_mem(const char *mem, int mem_len, char *line, int line_len,
139*10673SKrishnendu.Sadhukhan@Sun.COM     int *index)
140*10673SKrishnendu.Sadhukhan@Sun.COM {
141*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(mem != NULL && line != NULL && index != NULL);
142*10673SKrishnendu.Sadhukhan@Sun.COM 
143*10673SKrishnendu.Sadhukhan@Sun.COM 	if (line_len <= 0 || mem_len <= 0) {
144*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
145*10673SKrishnendu.Sadhukhan@Sun.COM 	}
146*10673SKrishnendu.Sadhukhan@Sun.COM 
147*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*index >= mem_len) {
148*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
149*10673SKrishnendu.Sadhukhan@Sun.COM 	}
150*10673SKrishnendu.Sadhukhan@Sun.COM 
151*10673SKrishnendu.Sadhukhan@Sun.COM 	while (line_len > 1 && *index < mem_len) {
152*10673SKrishnendu.Sadhukhan@Sun.COM 		*line = mem[(*index)++];
153*10673SKrishnendu.Sadhukhan@Sun.COM 		--line_len;
154*10673SKrishnendu.Sadhukhan@Sun.COM 		++line;
155*10673SKrishnendu.Sadhukhan@Sun.COM 
156*10673SKrishnendu.Sadhukhan@Sun.COM 		if (*(line-1) == '\r' || *(line-1) == '\n') {
157*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
158*10673SKrishnendu.Sadhukhan@Sun.COM 		}
159*10673SKrishnendu.Sadhukhan@Sun.COM 	}
160*10673SKrishnendu.Sadhukhan@Sun.COM 	*line = '\0';
161*10673SKrishnendu.Sadhukhan@Sun.COM 
162*10673SKrishnendu.Sadhukhan@Sun.COM 	return (1);
163*10673SKrishnendu.Sadhukhan@Sun.COM }
164*10673SKrishnendu.Sadhukhan@Sun.COM 
165*10673SKrishnendu.Sadhukhan@Sun.COM /*
166*10673SKrishnendu.Sadhukhan@Sun.COM  * Parse special command from configuration file. Special command
167*10673SKrishnendu.Sadhukhan@Sun.COM  * has the following format :
168*10673SKrishnendu.Sadhukhan@Sun.COM 
169*10673SKrishnendu.Sadhukhan@Sun.COM  *	disable_cause <cause name>
170*10673SKrishnendu.Sadhukhan@Sun.COM  */
171*10673SKrishnendu.Sadhukhan@Sun.COM static int
parse_config_cmd(char * begin,lt_parser_t * parser)172*10673SKrishnendu.Sadhukhan@Sun.COM parse_config_cmd(char *begin, lt_parser_t *parser)
173*10673SKrishnendu.Sadhukhan@Sun.COM {
174*10673SKrishnendu.Sadhukhan@Sun.COM 	char *tmp;
175*10673SKrishnendu.Sadhukhan@Sun.COM 	char old_chr = 0;
176*10673SKrishnendu.Sadhukhan@Sun.COM 
177*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
178*10673SKrishnendu.Sadhukhan@Sun.COM 	 * disable_cause  FSFlush Daemon
179*10673SKrishnendu.Sadhukhan@Sun.COM 	 * ^
180*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
181*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*begin == '\0') {
182*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
183*10673SKrishnendu.Sadhukhan@Sun.COM 	}
184*10673SKrishnendu.Sadhukhan@Sun.COM 
185*10673SKrishnendu.Sadhukhan@Sun.COM 	for (tmp = begin;
186*10673SKrishnendu.Sadhukhan@Sun.COM 	    *tmp != '\0' && !isspace(*tmp);
187*10673SKrishnendu.Sadhukhan@Sun.COM 	    ++tmp) {
188*10673SKrishnendu.Sadhukhan@Sun.COM 	}
189*10673SKrishnendu.Sadhukhan@Sun.COM 	old_chr = *tmp;
190*10673SKrishnendu.Sadhukhan@Sun.COM 	*tmp = '\0';
191*10673SKrishnendu.Sadhukhan@Sun.COM 
192*10673SKrishnendu.Sadhukhan@Sun.COM 	if (strcmp("disable_cause", begin) == 0) {
193*10673SKrishnendu.Sadhukhan@Sun.COM 		if (old_chr == '\0') {
194*10673SKrishnendu.Sadhukhan@Sun.COM 			/* Must have an argument */
195*10673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error(
196*10673SKrishnendu.Sadhukhan@Sun.COM 			    "Invalid command format: %s\n",
197*10673SKrishnendu.Sadhukhan@Sun.COM 			    begin);
198*10673SKrishnendu.Sadhukhan@Sun.COM 			return (-1);
199*10673SKrishnendu.Sadhukhan@Sun.COM 		}
200*10673SKrishnendu.Sadhukhan@Sun.COM 
201*10673SKrishnendu.Sadhukhan@Sun.COM 		begin = tmp+1;
202*10673SKrishnendu.Sadhukhan@Sun.COM 		while (isspace(*begin)) {
203*10673SKrishnendu.Sadhukhan@Sun.COM 			++begin;
204*10673SKrishnendu.Sadhukhan@Sun.COM 		}
205*10673SKrishnendu.Sadhukhan@Sun.COM 
206*10673SKrishnendu.Sadhukhan@Sun.COM 		g_sequence_append(parser->lt_pr_cmd_disable,
207*10673SKrishnendu.Sadhukhan@Sun.COM 		    lt_strdup(begin));
208*10673SKrishnendu.Sadhukhan@Sun.COM 	} else   {
209*10673SKrishnendu.Sadhukhan@Sun.COM 		*tmp = old_chr;
210*10673SKrishnendu.Sadhukhan@Sun.COM 		lt_display_error(
211*10673SKrishnendu.Sadhukhan@Sun.COM 		    "Unknown command: %s\n", begin);
212*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
213*10673SKrishnendu.Sadhukhan@Sun.COM 	}
214*10673SKrishnendu.Sadhukhan@Sun.COM 
215*10673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
216*10673SKrishnendu.Sadhukhan@Sun.COM }
217*10673SKrishnendu.Sadhukhan@Sun.COM 
218*10673SKrishnendu.Sadhukhan@Sun.COM /*
219*10673SKrishnendu.Sadhukhan@Sun.COM  * Parse symbol translation from configuration file. Symbol translation
220*10673SKrishnendu.Sadhukhan@Sun.COM  * has the following format :
221*10673SKrishnendu.Sadhukhan@Sun.COM  *
222*10673SKrishnendu.Sadhukhan@Sun.COM  *	<priority> <symbol name> <cause>
223*10673SKrishnendu.Sadhukhan@Sun.COM  *
224*10673SKrishnendu.Sadhukhan@Sun.COM  * Finally check if that cause has already been mapped.
225*10673SKrishnendu.Sadhukhan@Sun.COM  */
226*10673SKrishnendu.Sadhukhan@Sun.COM static int
parse_sym_trans(char * begin)227*10673SKrishnendu.Sadhukhan@Sun.COM parse_sym_trans(char *begin)
228*10673SKrishnendu.Sadhukhan@Sun.COM {
229*10673SKrishnendu.Sadhukhan@Sun.COM 	int priority = 0;
230*10673SKrishnendu.Sadhukhan@Sun.COM 	char *match;
231*10673SKrishnendu.Sadhukhan@Sun.COM 	char *match_dup;
232*10673SKrishnendu.Sadhukhan@Sun.COM 	char *cause_str;
233*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause;
234*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_match_t *match_entry;
235*10673SKrishnendu.Sadhukhan@Sun.COM 	char *tmp;
236*10673SKrishnendu.Sadhukhan@Sun.COM 
237*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
238*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	genunix`pread			Syscall pread
239*10673SKrishnendu.Sadhukhan@Sun.COM 	 * ^
240*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
241*10673SKrishnendu.Sadhukhan@Sun.COM 	priority = strtol(begin, &tmp, 10);
242*10673SKrishnendu.Sadhukhan@Sun.COM 
243*10673SKrishnendu.Sadhukhan@Sun.COM 	if (tmp == begin || priority == 0) {
244*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
245*10673SKrishnendu.Sadhukhan@Sun.COM 	}
246*10673SKrishnendu.Sadhukhan@Sun.COM 
247*10673SKrishnendu.Sadhukhan@Sun.COM 	begin = tmp;
248*10673SKrishnendu.Sadhukhan@Sun.COM 
249*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
250*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	genunix`pread			Syscall pread
251*10673SKrishnendu.Sadhukhan@Sun.COM 	 * --^
252*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
253*10673SKrishnendu.Sadhukhan@Sun.COM 
254*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!isspace(*begin)) {
255*10673SKrishnendu.Sadhukhan@Sun.COM 		/* At least one space char after <priority> */
256*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
257*10673SKrishnendu.Sadhukhan@Sun.COM 	}
258*10673SKrishnendu.Sadhukhan@Sun.COM 
259*10673SKrishnendu.Sadhukhan@Sun.COM 	while (isspace(*begin)) {
260*10673SKrishnendu.Sadhukhan@Sun.COM 		++begin;
261*10673SKrishnendu.Sadhukhan@Sun.COM 	}
262*10673SKrishnendu.Sadhukhan@Sun.COM 
263*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*begin == 0) {
264*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
265*10673SKrishnendu.Sadhukhan@Sun.COM 	}
266*10673SKrishnendu.Sadhukhan@Sun.COM 
267*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
268*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	genunix`pread			Syscall pread
269*10673SKrishnendu.Sadhukhan@Sun.COM 	 * -----^
270*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
271*10673SKrishnendu.Sadhukhan@Sun.COM 	for (tmp = begin;
272*10673SKrishnendu.Sadhukhan@Sun.COM 	    *tmp != '\0' && !isspace(*tmp);
273*10673SKrishnendu.Sadhukhan@Sun.COM 	    ++tmp) {
274*10673SKrishnendu.Sadhukhan@Sun.COM 	}
275*10673SKrishnendu.Sadhukhan@Sun.COM 
276*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*tmp == '\0') {
277*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
278*10673SKrishnendu.Sadhukhan@Sun.COM 	}
279*10673SKrishnendu.Sadhukhan@Sun.COM 
280*10673SKrishnendu.Sadhukhan@Sun.COM 	*tmp = '\0';
281*10673SKrishnendu.Sadhukhan@Sun.COM 	match = begin;
282*10673SKrishnendu.Sadhukhan@Sun.COM 
283*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Check if we have mapped this function before. */
284*10673SKrishnendu.Sadhukhan@Sun.COM 	match_entry = (lt_match_t *)
285*10673SKrishnendu.Sadhukhan@Sun.COM 	    g_hash_table_lookup(symbol_lookup_table, match);
286*10673SKrishnendu.Sadhukhan@Sun.COM 
287*10673SKrishnendu.Sadhukhan@Sun.COM 	if (match_entry != NULL &&
288*10673SKrishnendu.Sadhukhan@Sun.COM 	    HIGHER_PRIORITY(match_entry->lt_mt_priority, priority)) {
289*10673SKrishnendu.Sadhukhan@Sun.COM 		/* We already have a higher entry. Ignore this. */
290*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
291*10673SKrishnendu.Sadhukhan@Sun.COM 	}
292*10673SKrishnendu.Sadhukhan@Sun.COM 
293*10673SKrishnendu.Sadhukhan@Sun.COM 	begin = tmp + 1;
294*10673SKrishnendu.Sadhukhan@Sun.COM 
295*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
296*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	genunix`pread			Syscall pread
297*10673SKrishnendu.Sadhukhan@Sun.COM 	 * -------------------------------------^
298*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
299*10673SKrishnendu.Sadhukhan@Sun.COM 	while (isspace(*begin)) {
300*10673SKrishnendu.Sadhukhan@Sun.COM 		++begin;
301*10673SKrishnendu.Sadhukhan@Sun.COM 	}
302*10673SKrishnendu.Sadhukhan@Sun.COM 
303*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*begin == 0) {
304*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
305*10673SKrishnendu.Sadhukhan@Sun.COM 	}
306*10673SKrishnendu.Sadhukhan@Sun.COM 
307*10673SKrishnendu.Sadhukhan@Sun.COM 	cause_str = begin;
308*10673SKrishnendu.Sadhukhan@Sun.COM 
309*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Check if we have mapped this cause before. */
310*10673SKrishnendu.Sadhukhan@Sun.COM 	cause = (lt_cause_t *)
311*10673SKrishnendu.Sadhukhan@Sun.COM 	    g_hash_table_lookup(cause_lookup, cause_str);
312*10673SKrishnendu.Sadhukhan@Sun.COM 
313*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause == NULL) {
314*10673SKrishnendu.Sadhukhan@Sun.COM 		char *cause_dup = lt_strdup(cause_str);
315*10673SKrishnendu.Sadhukhan@Sun.COM 		cause = new_cause(cause_dup, 0);
316*10673SKrishnendu.Sadhukhan@Sun.COM 		g_hash_table_insert(cause_lookup, cause_dup, cause);
317*10673SKrishnendu.Sadhukhan@Sun.COM 	}
318*10673SKrishnendu.Sadhukhan@Sun.COM 
319*10673SKrishnendu.Sadhukhan@Sun.COM 	match_entry = (lt_match_t *)lt_malloc(sizeof (lt_match_t));
320*10673SKrishnendu.Sadhukhan@Sun.COM 	match_entry->lt_mt_priority = priority;
321*10673SKrishnendu.Sadhukhan@Sun.COM 	match_entry->lt_mt_cause_id = cause->lt_c_cause_id;
322*10673SKrishnendu.Sadhukhan@Sun.COM 	match_dup = lt_strdup(match);
323*10673SKrishnendu.Sadhukhan@Sun.COM 
324*10673SKrishnendu.Sadhukhan@Sun.COM 	g_hash_table_insert(symbol_lookup_table, match_dup,
325*10673SKrishnendu.Sadhukhan@Sun.COM 	    match_entry);
326*10673SKrishnendu.Sadhukhan@Sun.COM 
327*10673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
328*10673SKrishnendu.Sadhukhan@Sun.COM }
329*10673SKrishnendu.Sadhukhan@Sun.COM 
330*10673SKrishnendu.Sadhukhan@Sun.COM /*
331*10673SKrishnendu.Sadhukhan@Sun.COM  * Parse D macro. D macros have the following format :
332*10673SKrishnendu.Sadhukhan@Sun.COM  *
333*10673SKrishnendu.Sadhukhan@Sun.COM  *	<priority> <entry probe> <return probe> <cause>
334*10673SKrishnendu.Sadhukhan@Sun.COM  *
335*10673SKrishnendu.Sadhukhan@Sun.COM  * Finally check if that cause has already been mapped.
336*10673SKrishnendu.Sadhukhan@Sun.COM  */
337*10673SKrishnendu.Sadhukhan@Sun.COM static int
parse_dmacro(char * begin,lt_parser_t * parser)338*10673SKrishnendu.Sadhukhan@Sun.COM parse_dmacro(char *begin, lt_parser_t *parser)
339*10673SKrishnendu.Sadhukhan@Sun.COM {
340*10673SKrishnendu.Sadhukhan@Sun.COM 	int priority = 0;
341*10673SKrishnendu.Sadhukhan@Sun.COM 	char *entryprobe;
342*10673SKrishnendu.Sadhukhan@Sun.COM 	char *returnprobe;
343*10673SKrishnendu.Sadhukhan@Sun.COM 	char *cause_str;
344*10673SKrishnendu.Sadhukhan@Sun.COM 	char buf[512];
345*10673SKrishnendu.Sadhukhan@Sun.COM 	char probepair[512];
346*10673SKrishnendu.Sadhukhan@Sun.COM 	char *tmp = NULL;
347*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause;
348*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_dmacro_t *dmacro;
349*10673SKrishnendu.Sadhukhan@Sun.COM 
350*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
351*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	syscall::pread:entry	syscall::pread:return	Syscall pread
352*10673SKrishnendu.Sadhukhan@Sun.COM 	 * ^
353*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
354*10673SKrishnendu.Sadhukhan@Sun.COM 	priority = strtol(begin, &tmp, 10);
355*10673SKrishnendu.Sadhukhan@Sun.COM 
356*10673SKrishnendu.Sadhukhan@Sun.COM 	if (tmp == begin || priority == 0) {
357*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
358*10673SKrishnendu.Sadhukhan@Sun.COM 	}
359*10673SKrishnendu.Sadhukhan@Sun.COM 
360*10673SKrishnendu.Sadhukhan@Sun.COM 	begin = tmp;
361*10673SKrishnendu.Sadhukhan@Sun.COM 
362*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
363*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	syscall::pread:entry	syscall::pread:return	Syscall pread
364*10673SKrishnendu.Sadhukhan@Sun.COM 	 * --^
365*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
366*10673SKrishnendu.Sadhukhan@Sun.COM 	while (isspace(*begin)) {
367*10673SKrishnendu.Sadhukhan@Sun.COM 		++begin;
368*10673SKrishnendu.Sadhukhan@Sun.COM 	}
369*10673SKrishnendu.Sadhukhan@Sun.COM 
370*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*begin == 0) {
371*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
372*10673SKrishnendu.Sadhukhan@Sun.COM 	}
373*10673SKrishnendu.Sadhukhan@Sun.COM 
374*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
375*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	syscall::pread:entry	syscall::pread:return	Syscall pread
376*10673SKrishnendu.Sadhukhan@Sun.COM 	 * -----^
377*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
378*10673SKrishnendu.Sadhukhan@Sun.COM 	for (tmp = begin;
379*10673SKrishnendu.Sadhukhan@Sun.COM 	    *tmp != '\0' && !isspace(*tmp);
380*10673SKrishnendu.Sadhukhan@Sun.COM 	    ++tmp) {
381*10673SKrishnendu.Sadhukhan@Sun.COM 	}
382*10673SKrishnendu.Sadhukhan@Sun.COM 
383*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*tmp == '\0') {
384*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
385*10673SKrishnendu.Sadhukhan@Sun.COM 	}
386*10673SKrishnendu.Sadhukhan@Sun.COM 
387*10673SKrishnendu.Sadhukhan@Sun.COM 	*tmp = '\0';
388*10673SKrishnendu.Sadhukhan@Sun.COM 	entryprobe = begin;
389*10673SKrishnendu.Sadhukhan@Sun.COM 	begin = tmp + 1;
390*10673SKrishnendu.Sadhukhan@Sun.COM 
391*10673SKrishnendu.Sadhukhan@Sun.COM 	while (isspace(*begin)) {
392*10673SKrishnendu.Sadhukhan@Sun.COM 		++begin;
393*10673SKrishnendu.Sadhukhan@Sun.COM 	}
394*10673SKrishnendu.Sadhukhan@Sun.COM 
395*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
396*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	syscall::pread:entry	syscall::pread:return	Syscall pread
397*10673SKrishnendu.Sadhukhan@Sun.COM 	 * -----------------------------^
398*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
399*10673SKrishnendu.Sadhukhan@Sun.COM 	for (tmp = begin;
400*10673SKrishnendu.Sadhukhan@Sun.COM 	    *tmp != '\0' && !isspace(*tmp);
401*10673SKrishnendu.Sadhukhan@Sun.COM 	    ++tmp) {
402*10673SKrishnendu.Sadhukhan@Sun.COM 	}
403*10673SKrishnendu.Sadhukhan@Sun.COM 
404*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*tmp == '\0') {
405*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
406*10673SKrishnendu.Sadhukhan@Sun.COM 	}
407*10673SKrishnendu.Sadhukhan@Sun.COM 
408*10673SKrishnendu.Sadhukhan@Sun.COM 	*tmp = '\0';
409*10673SKrishnendu.Sadhukhan@Sun.COM 	returnprobe = begin;
410*10673SKrishnendu.Sadhukhan@Sun.COM 	begin = tmp + 1;
411*10673SKrishnendu.Sadhukhan@Sun.COM 
412*10673SKrishnendu.Sadhukhan@Sun.COM 	while (isspace(*begin)) {
413*10673SKrishnendu.Sadhukhan@Sun.COM 		++begin;
414*10673SKrishnendu.Sadhukhan@Sun.COM 	}
415*10673SKrishnendu.Sadhukhan@Sun.COM 
416*10673SKrishnendu.Sadhukhan@Sun.COM 	/*
417*10673SKrishnendu.Sadhukhan@Sun.COM 	 * 10	syscall::pread:entry	syscall::pread:return	Syscall pread
418*10673SKrishnendu.Sadhukhan@Sun.COM 	 * -----------------------------------------------------^
419*10673SKrishnendu.Sadhukhan@Sun.COM 	 */
420*10673SKrishnendu.Sadhukhan@Sun.COM 	if (*begin == 0) {
421*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
422*10673SKrishnendu.Sadhukhan@Sun.COM 	}
423*10673SKrishnendu.Sadhukhan@Sun.COM 
424*10673SKrishnendu.Sadhukhan@Sun.COM 	cause_str = begin;
425*10673SKrishnendu.Sadhukhan@Sun.COM 
426*10673SKrishnendu.Sadhukhan@Sun.COM 	dmacro = NULL;
427*10673SKrishnendu.Sadhukhan@Sun.COM 
428*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Check if we have mapped this cause before. */
429*10673SKrishnendu.Sadhukhan@Sun.COM 	cause = (lt_cause_t *)
430*10673SKrishnendu.Sadhukhan@Sun.COM 	    g_hash_table_lookup(cause_lookup, cause_str);
431*10673SKrishnendu.Sadhukhan@Sun.COM 
432*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause == NULL) {
433*10673SKrishnendu.Sadhukhan@Sun.COM 		char *cause_dup = lt_strdup(cause_str);
434*10673SKrishnendu.Sadhukhan@Sun.COM 		cause = new_cause(cause_dup, 0);
435*10673SKrishnendu.Sadhukhan@Sun.COM 		g_hash_table_insert(cause_lookup, cause_dup, cause);
436*10673SKrishnendu.Sadhukhan@Sun.COM 	}
437*10673SKrishnendu.Sadhukhan@Sun.COM 
438*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) snprintf(buf, sizeof (buf), "\nTRANSLATE(%s, %s, \"%s\", %d)\n",
439*10673SKrishnendu.Sadhukhan@Sun.COM 	    entryprobe, returnprobe, cause_str, priority);
440*10673SKrishnendu.Sadhukhan@Sun.COM 
441*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) snprintf(probepair, sizeof (probepair), "%s %s", entryprobe,
442*10673SKrishnendu.Sadhukhan@Sun.COM 	    returnprobe);
443*10673SKrishnendu.Sadhukhan@Sun.COM 
444*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(cause != NULL);
445*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(parser->lt_pr_dmacro != NULL);
446*10673SKrishnendu.Sadhukhan@Sun.COM 
447*10673SKrishnendu.Sadhukhan@Sun.COM 	dmacro = g_hash_table_lookup(parser->lt_pr_dmacro, probepair);
448*10673SKrishnendu.Sadhukhan@Sun.COM 
449*10673SKrishnendu.Sadhukhan@Sun.COM 	if (dmacro == NULL) {
450*10673SKrishnendu.Sadhukhan@Sun.COM 		dmacro = (lt_dmacro_t *)lt_malloc(sizeof (lt_dmacro_t));
451*10673SKrishnendu.Sadhukhan@Sun.COM 		dmacro->lt_dm_priority = priority;
452*10673SKrishnendu.Sadhukhan@Sun.COM 		dmacro->lt_dm_macro = lt_strdup(buf);
453*10673SKrishnendu.Sadhukhan@Sun.COM 		g_hash_table_insert(parser->lt_pr_dmacro, lt_strdup(probepair),
454*10673SKrishnendu.Sadhukhan@Sun.COM 		    dmacro);
455*10673SKrishnendu.Sadhukhan@Sun.COM 	} else if (dmacro->lt_dm_priority < priority) {
456*10673SKrishnendu.Sadhukhan@Sun.COM 		free(dmacro->lt_dm_macro);
457*10673SKrishnendu.Sadhukhan@Sun.COM 		dmacro->lt_dm_priority = priority;
458*10673SKrishnendu.Sadhukhan@Sun.COM 		dmacro->lt_dm_macro = lt_strdup(buf);
459*10673SKrishnendu.Sadhukhan@Sun.COM 	}
460*10673SKrishnendu.Sadhukhan@Sun.COM 
461*10673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
462*10673SKrishnendu.Sadhukhan@Sun.COM }
463*10673SKrishnendu.Sadhukhan@Sun.COM 
464*10673SKrishnendu.Sadhukhan@Sun.COM /*
465*10673SKrishnendu.Sadhukhan@Sun.COM  * Helper function to collect TRANSLATE() macros.
466*10673SKrishnendu.Sadhukhan@Sun.COM  */
467*10673SKrishnendu.Sadhukhan@Sun.COM /* ARGSUSED */
468*10673SKrishnendu.Sadhukhan@Sun.COM static void
genscript(void * key,lt_dmacro_t * dmacro,GString * str)469*10673SKrishnendu.Sadhukhan@Sun.COM genscript(void *key, lt_dmacro_t *dmacro, GString *str)
470*10673SKrishnendu.Sadhukhan@Sun.COM {
471*10673SKrishnendu.Sadhukhan@Sun.COM 	g_string_append(str, dmacro->lt_dm_macro);
472*10673SKrishnendu.Sadhukhan@Sun.COM }
473*10673SKrishnendu.Sadhukhan@Sun.COM 
474*10673SKrishnendu.Sadhukhan@Sun.COM /*
475*10673SKrishnendu.Sadhukhan@Sun.COM  * Main logic that parses translation rules one line at a time,
476*10673SKrishnendu.Sadhukhan@Sun.COM  * and creates a lookup table from it. The syntax for the translation
477*10673SKrishnendu.Sadhukhan@Sun.COM  * is as follows :
478*10673SKrishnendu.Sadhukhan@Sun.COM  *
479*10673SKrishnendu.Sadhukhan@Sun.COM  *	#				<--- comment
480*10673SKrishnendu.Sadhukhan@Sun.COM  *	D <D macro rule>		<--- D macro
481*10673SKrishnendu.Sadhukhan@Sun.COM  *	S <Symbol translation>		<--- Symbols
482*10673SKrishnendu.Sadhukhan@Sun.COM  *	disable_cause <cause>		<--- special command
483*10673SKrishnendu.Sadhukhan@Sun.COM  */
484*10673SKrishnendu.Sadhukhan@Sun.COM static int
parse_config(const char * work,int work_len)485*10673SKrishnendu.Sadhukhan@Sun.COM parse_config(const char *work, int work_len)
486*10673SKrishnendu.Sadhukhan@Sun.COM {
487*10673SKrishnendu.Sadhukhan@Sun.COM 	char line[256];
488*10673SKrishnendu.Sadhukhan@Sun.COM 	int len;
489*10673SKrishnendu.Sadhukhan@Sun.COM 	char *begin, *end;
490*10673SKrishnendu.Sadhukhan@Sun.COM 	int current = 0;
491*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_parser_t parser;
492*10673SKrishnendu.Sadhukhan@Sun.COM 	int ret = 0;
493*10673SKrishnendu.Sadhukhan@Sun.COM 	char flag;
494*10673SKrishnendu.Sadhukhan@Sun.COM 	GString *script;
495*10673SKrishnendu.Sadhukhan@Sun.COM 
496*10673SKrishnendu.Sadhukhan@Sun.COM 	cause_lookup = g_hash_table_new(g_str_hash, g_str_equal);
497*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_check_null(cause_lookup);
498*10673SKrishnendu.Sadhukhan@Sun.COM 
499*10673SKrishnendu.Sadhukhan@Sun.COM 	parser.lt_pr_cmd_disable = g_sequence_new((GDestroyNotify)free);
500*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_check_null(parser.lt_pr_cmd_disable);
501*10673SKrishnendu.Sadhukhan@Sun.COM 
502*10673SKrishnendu.Sadhukhan@Sun.COM 	parser.lt_pr_dmacro = g_hash_table_new_full(g_str_hash,
503*10673SKrishnendu.Sadhukhan@Sun.COM 	    g_str_equal, (GDestroyNotify)free, (GDestroyNotify)free_dmacro);
504*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_check_null(parser.lt_pr_dmacro);
505*10673SKrishnendu.Sadhukhan@Sun.COM 
506*10673SKrishnendu.Sadhukhan@Sun.COM 	while (read_line_from_mem(work, work_len, line, sizeof (line),
507*10673SKrishnendu.Sadhukhan@Sun.COM 	    &current)) {
508*10673SKrishnendu.Sadhukhan@Sun.COM 		len = strlen(line);
509*10673SKrishnendu.Sadhukhan@Sun.COM 
510*10673SKrishnendu.Sadhukhan@Sun.COM 		if (line[len-1] != '\n' && line[len-1] != '\r' &&
511*10673SKrishnendu.Sadhukhan@Sun.COM 		    current < work_len) {
512*10673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error("Configuration line too long.\n");
513*10673SKrishnendu.Sadhukhan@Sun.COM 			goto err;
514*10673SKrishnendu.Sadhukhan@Sun.COM 		}
515*10673SKrishnendu.Sadhukhan@Sun.COM 
516*10673SKrishnendu.Sadhukhan@Sun.COM 		begin = line;
517*10673SKrishnendu.Sadhukhan@Sun.COM 
518*10673SKrishnendu.Sadhukhan@Sun.COM 		while (isspace(*begin)) {
519*10673SKrishnendu.Sadhukhan@Sun.COM 			++begin;
520*10673SKrishnendu.Sadhukhan@Sun.COM 		}
521*10673SKrishnendu.Sadhukhan@Sun.COM 
522*10673SKrishnendu.Sadhukhan@Sun.COM 		if (*begin == '\0') {
523*10673SKrishnendu.Sadhukhan@Sun.COM 			/* Ignore empty line */
524*10673SKrishnendu.Sadhukhan@Sun.COM 			continue;
525*10673SKrishnendu.Sadhukhan@Sun.COM 		}
526*10673SKrishnendu.Sadhukhan@Sun.COM 
527*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Delete trailing spaces. */
528*10673SKrishnendu.Sadhukhan@Sun.COM 		end = begin + strlen(begin) - 1;
529*10673SKrishnendu.Sadhukhan@Sun.COM 
530*10673SKrishnendu.Sadhukhan@Sun.COM 		while (isspace(*end)) {
531*10673SKrishnendu.Sadhukhan@Sun.COM 			--end;
532*10673SKrishnendu.Sadhukhan@Sun.COM 		}
533*10673SKrishnendu.Sadhukhan@Sun.COM 
534*10673SKrishnendu.Sadhukhan@Sun.COM 		end[1] = '\0';
535*10673SKrishnendu.Sadhukhan@Sun.COM 
536*10673SKrishnendu.Sadhukhan@Sun.COM 		flag = *begin;
537*10673SKrishnendu.Sadhukhan@Sun.COM 		++begin;
538*10673SKrishnendu.Sadhukhan@Sun.COM 
539*10673SKrishnendu.Sadhukhan@Sun.COM 		switch (flag) {
540*10673SKrishnendu.Sadhukhan@Sun.COM 		case '#':
541*10673SKrishnendu.Sadhukhan@Sun.COM 			ret = 0;
542*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
543*10673SKrishnendu.Sadhukhan@Sun.COM 		case ';':
544*10673SKrishnendu.Sadhukhan@Sun.COM 			ret = parse_config_cmd(begin, &parser);
545*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
546*10673SKrishnendu.Sadhukhan@Sun.COM 		case 'D':
547*10673SKrishnendu.Sadhukhan@Sun.COM 		case 'd':
548*10673SKrishnendu.Sadhukhan@Sun.COM 			if (!isspace(*begin)) {
549*10673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
550*10673SKrishnendu.Sadhukhan@Sun.COM 				    "No space after flag char: %s\n", line);
551*10673SKrishnendu.Sadhukhan@Sun.COM 			}
552*10673SKrishnendu.Sadhukhan@Sun.COM 			while (isspace(*begin)) {
553*10673SKrishnendu.Sadhukhan@Sun.COM 				++begin;
554*10673SKrishnendu.Sadhukhan@Sun.COM 			}
555*10673SKrishnendu.Sadhukhan@Sun.COM 			ret = parse_dmacro(begin, &parser);
556*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
557*10673SKrishnendu.Sadhukhan@Sun.COM 		case 'S':
558*10673SKrishnendu.Sadhukhan@Sun.COM 		case 's':
559*10673SKrishnendu.Sadhukhan@Sun.COM 			if (!isspace(*begin)) {
560*10673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_error(
561*10673SKrishnendu.Sadhukhan@Sun.COM 				    "No space after flag char: %s\n", line);
562*10673SKrishnendu.Sadhukhan@Sun.COM 			}
563*10673SKrishnendu.Sadhukhan@Sun.COM 			while (isspace(*begin)) {
564*10673SKrishnendu.Sadhukhan@Sun.COM 				++begin;
565*10673SKrishnendu.Sadhukhan@Sun.COM 			}
566*10673SKrishnendu.Sadhukhan@Sun.COM 			ret = parse_sym_trans(begin);
567*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
568*10673SKrishnendu.Sadhukhan@Sun.COM 		default:
569*10673SKrishnendu.Sadhukhan@Sun.COM 			ret = -1;
570*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
571*10673SKrishnendu.Sadhukhan@Sun.COM 		}
572*10673SKrishnendu.Sadhukhan@Sun.COM 
573*10673SKrishnendu.Sadhukhan@Sun.COM 		if (ret != 0) {
574*10673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error(
575*10673SKrishnendu.Sadhukhan@Sun.COM 			    "Invalid configuration line: %s\n", line);
576*10673SKrishnendu.Sadhukhan@Sun.COM 			goto err;
577*10673SKrishnendu.Sadhukhan@Sun.COM 		}
578*10673SKrishnendu.Sadhukhan@Sun.COM 	}
579*10673SKrishnendu.Sadhukhan@Sun.COM 
580*10673SKrishnendu.Sadhukhan@Sun.COM 	script = g_string_new(NULL);
581*10673SKrishnendu.Sadhukhan@Sun.COM 	g_hash_table_foreach(parser.lt_pr_dmacro, (GHFunc)genscript, script);
582*10673SKrishnendu.Sadhukhan@Sun.COM 	dtrans = g_string_free(script, FALSE);
583*10673SKrishnendu.Sadhukhan@Sun.COM 
584*10673SKrishnendu.Sadhukhan@Sun.COM 	if (dtrans != NULL && strlen(dtrans) == 0) {
585*10673SKrishnendu.Sadhukhan@Sun.COM 		free(dtrans);
586*10673SKrishnendu.Sadhukhan@Sun.COM 		dtrans = NULL;
587*10673SKrishnendu.Sadhukhan@Sun.COM 	}
588*10673SKrishnendu.Sadhukhan@Sun.COM 
589*10673SKrishnendu.Sadhukhan@Sun.COM 	g_sequence_foreach(parser.lt_pr_cmd_disable, (GFunc)disable_cause,
590*10673SKrishnendu.Sadhukhan@Sun.COM 	    cause_lookup);
591*10673SKrishnendu.Sadhukhan@Sun.COM 	g_sequence_free(parser.lt_pr_cmd_disable);
592*10673SKrishnendu.Sadhukhan@Sun.COM 
593*10673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
594*10673SKrishnendu.Sadhukhan@Sun.COM 
595*10673SKrishnendu.Sadhukhan@Sun.COM err:
596*10673SKrishnendu.Sadhukhan@Sun.COM 	g_sequence_free(parser.lt_pr_cmd_disable);
597*10673SKrishnendu.Sadhukhan@Sun.COM 	g_hash_table_destroy(parser.lt_pr_dmacro);
598*10673SKrishnendu.Sadhukhan@Sun.COM 	return (-1);
599*10673SKrishnendu.Sadhukhan@Sun.COM 
600*10673SKrishnendu.Sadhukhan@Sun.COM }
601*10673SKrishnendu.Sadhukhan@Sun.COM 
602*10673SKrishnendu.Sadhukhan@Sun.COM /*
603*10673SKrishnendu.Sadhukhan@Sun.COM  * Init function, called when latencytop starts.
604*10673SKrishnendu.Sadhukhan@Sun.COM  * It loads translation rules from the configuration file. The configuration
605*10673SKrishnendu.Sadhukhan@Sun.COM  * file defines some causes and symbols that match those causes.
606*10673SKrishnendu.Sadhukhan@Sun.COM  */
607*10673SKrishnendu.Sadhukhan@Sun.COM int
lt_table_init(void)608*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_init(void)
609*10673SKrishnendu.Sadhukhan@Sun.COM {
610*10673SKrishnendu.Sadhukhan@Sun.COM 	char *config_loaded = NULL;
611*10673SKrishnendu.Sadhukhan@Sun.COM 	int config_loaded_len = 0;
612*10673SKrishnendu.Sadhukhan@Sun.COM 	const char *work = NULL;
613*10673SKrishnendu.Sadhukhan@Sun.COM 	int work_len = 0;
614*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause;
615*10673SKrishnendu.Sadhukhan@Sun.COM 
616*10673SKrishnendu.Sadhukhan@Sun.COM #ifdef EMBED_CONFIGS
617*10673SKrishnendu.Sadhukhan@Sun.COM 	work = &latencytop_trans_start;
618*10673SKrishnendu.Sadhukhan@Sun.COM 	work_len = (int)(&latencytop_trans_end - &latencytop_trans_start);
619*10673SKrishnendu.Sadhukhan@Sun.COM #endif
620*10673SKrishnendu.Sadhukhan@Sun.COM 
621*10673SKrishnendu.Sadhukhan@Sun.COM 	if (g_config.lt_cfg_config_name != NULL) {
622*10673SKrishnendu.Sadhukhan@Sun.COM 		FILE *fp;
623*10673SKrishnendu.Sadhukhan@Sun.COM 		fp = fopen(g_config.lt_cfg_config_name, "r");
624*10673SKrishnendu.Sadhukhan@Sun.COM 
625*10673SKrishnendu.Sadhukhan@Sun.COM 		if (NULL == fp) {
626*10673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error(
627*10673SKrishnendu.Sadhukhan@Sun.COM 			    "Unable to open configuration file.\n");
628*10673SKrishnendu.Sadhukhan@Sun.COM 			return (-1);
629*10673SKrishnendu.Sadhukhan@Sun.COM 		}
630*10673SKrishnendu.Sadhukhan@Sun.COM 
631*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) fseek(fp, 0, SEEK_END);
632*10673SKrishnendu.Sadhukhan@Sun.COM 		config_loaded_len = (int)ftell(fp);
633*10673SKrishnendu.Sadhukhan@Sun.COM 		config_loaded = (char *)lt_malloc(config_loaded_len);
634*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) fseek(fp, 0, SEEK_SET);
635*10673SKrishnendu.Sadhukhan@Sun.COM 
636*10673SKrishnendu.Sadhukhan@Sun.COM 		/* A zero-byte translation is valid */
637*10673SKrishnendu.Sadhukhan@Sun.COM 		if (config_loaded_len != 0 &&
638*10673SKrishnendu.Sadhukhan@Sun.COM 		    fread(config_loaded, config_loaded_len, 1, fp) == 0) {
639*10673SKrishnendu.Sadhukhan@Sun.COM 			lt_display_error(
640*10673SKrishnendu.Sadhukhan@Sun.COM 			    "Unable to read configuration file.\n");
641*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) fclose(fp);
642*10673SKrishnendu.Sadhukhan@Sun.COM 			free(config_loaded);
643*10673SKrishnendu.Sadhukhan@Sun.COM 			return (-1);
644*10673SKrishnendu.Sadhukhan@Sun.COM 		}
645*10673SKrishnendu.Sadhukhan@Sun.COM 
646*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) fclose(fp);
647*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) printf("Loaded configuration from %s\n",
648*10673SKrishnendu.Sadhukhan@Sun.COM 		    g_config.lt_cfg_config_name);
649*10673SKrishnendu.Sadhukhan@Sun.COM 
650*10673SKrishnendu.Sadhukhan@Sun.COM 		work = config_loaded;
651*10673SKrishnendu.Sadhukhan@Sun.COM 		work_len = config_loaded_len;
652*10673SKrishnendu.Sadhukhan@Sun.COM 	}
653*10673SKrishnendu.Sadhukhan@Sun.COM 
654*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_table_deinit();
655*10673SKrishnendu.Sadhukhan@Sun.COM 	causes_array = g_ptr_array_new();
656*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_check_null(causes_array);
657*10673SKrishnendu.Sadhukhan@Sun.COM 
658*10673SKrishnendu.Sadhukhan@Sun.COM 	/* 0 is not used, but it is kept as a place for bugs etc. */
659*10673SKrishnendu.Sadhukhan@Sun.COM 	cause = new_cause(lt_strdup("Nothing"), CAUSE_FLAG_DISABLED);
660*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(cause->lt_c_cause_id == INVALID_CAUSE);
661*10673SKrishnendu.Sadhukhan@Sun.COM 
662*10673SKrishnendu.Sadhukhan@Sun.COM 	symbol_lookup_table = g_hash_table_new_full(
663*10673SKrishnendu.Sadhukhan@Sun.COM 	    g_str_hash, g_str_equal,
664*10673SKrishnendu.Sadhukhan@Sun.COM 	    (GDestroyNotify)free, (GDestroyNotify)free);
665*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_check_null(symbol_lookup_table);
666*10673SKrishnendu.Sadhukhan@Sun.COM 
667*10673SKrishnendu.Sadhukhan@Sun.COM 	if (work_len != 0 && parse_config(work, work_len) != 0) {
668*10673SKrishnendu.Sadhukhan@Sun.COM 		return (-1);
669*10673SKrishnendu.Sadhukhan@Sun.COM 	}
670*10673SKrishnendu.Sadhukhan@Sun.COM 
671*10673SKrishnendu.Sadhukhan@Sun.COM 	if (config_loaded != NULL) {
672*10673SKrishnendu.Sadhukhan@Sun.COM 		free(config_loaded);
673*10673SKrishnendu.Sadhukhan@Sun.COM 	}
674*10673SKrishnendu.Sadhukhan@Sun.COM 
675*10673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
676*10673SKrishnendu.Sadhukhan@Sun.COM }
677*10673SKrishnendu.Sadhukhan@Sun.COM 
678*10673SKrishnendu.Sadhukhan@Sun.COM /*
679*10673SKrishnendu.Sadhukhan@Sun.COM  * Some causes, such as "lock spinning", do not have stack trace. Names
680*10673SKrishnendu.Sadhukhan@Sun.COM  * of such causes are explicitly specified in the D script.
681*10673SKrishnendu.Sadhukhan@Sun.COM  * This function resolves such causes and dynamically adds them
682*10673SKrishnendu.Sadhukhan@Sun.COM  * to the global tables when they are found first. If auto_create is set
683*10673SKrishnendu.Sadhukhan@Sun.COM  * to TRUE, the entry will be created if it is not found.
684*10673SKrishnendu.Sadhukhan@Sun.COM  * Return cause_id of the cause.
685*10673SKrishnendu.Sadhukhan@Sun.COM  */
686*10673SKrishnendu.Sadhukhan@Sun.COM int
lt_table_cause_from_name(char * name,int auto_create,int flags)687*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_cause_from_name(char *name, int auto_create, int flags)
688*10673SKrishnendu.Sadhukhan@Sun.COM {
689*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause = NULL;
690*10673SKrishnendu.Sadhukhan@Sun.COM 
691*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause_lookup == NULL) {
692*10673SKrishnendu.Sadhukhan@Sun.COM 		cause_lookup = g_hash_table_new(g_str_hash, g_str_equal);
693*10673SKrishnendu.Sadhukhan@Sun.COM 		lt_check_null(cause_lookup);
694*10673SKrishnendu.Sadhukhan@Sun.COM 	} else   {
695*10673SKrishnendu.Sadhukhan@Sun.COM 		cause = (lt_cause_t *)
696*10673SKrishnendu.Sadhukhan@Sun.COM 		    g_hash_table_lookup(cause_lookup, name);
697*10673SKrishnendu.Sadhukhan@Sun.COM 	}
698*10673SKrishnendu.Sadhukhan@Sun.COM 
699*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause == NULL && auto_create) {
700*10673SKrishnendu.Sadhukhan@Sun.COM 		char *cause_dup;
701*10673SKrishnendu.Sadhukhan@Sun.COM 
702*10673SKrishnendu.Sadhukhan@Sun.COM 		if (name[0] == '#') {
703*10673SKrishnendu.Sadhukhan@Sun.COM 			flags |= CAUSE_FLAG_HIDE_IN_SUMMARY;
704*10673SKrishnendu.Sadhukhan@Sun.COM 		}
705*10673SKrishnendu.Sadhukhan@Sun.COM 
706*10673SKrishnendu.Sadhukhan@Sun.COM 		cause_dup = lt_strdup(name);
707*10673SKrishnendu.Sadhukhan@Sun.COM 		cause = new_cause(cause_dup, flags);
708*10673SKrishnendu.Sadhukhan@Sun.COM 		g_hash_table_insert(cause_lookup, cause_dup, cause);
709*10673SKrishnendu.Sadhukhan@Sun.COM 	}
710*10673SKrishnendu.Sadhukhan@Sun.COM 
711*10673SKrishnendu.Sadhukhan@Sun.COM 	return (cause == NULL ? INVALID_CAUSE : cause->lt_c_cause_id);
712*10673SKrishnendu.Sadhukhan@Sun.COM }
713*10673SKrishnendu.Sadhukhan@Sun.COM 
714*10673SKrishnendu.Sadhukhan@Sun.COM /*
715*10673SKrishnendu.Sadhukhan@Sun.COM  * Try to map a symbol on stack to a known cause.
716*10673SKrishnendu.Sadhukhan@Sun.COM  * module_func has the format "module_name`function_name".
717*10673SKrishnendu.Sadhukhan@Sun.COM  * cause_id and priority will be set if a cause is found.
718*10673SKrishnendu.Sadhukhan@Sun.COM  * If cause is found return 1, otherwise return 0.
719*10673SKrishnendu.Sadhukhan@Sun.COM  */
720*10673SKrishnendu.Sadhukhan@Sun.COM int
lt_table_cause_from_stack(const char * module_func,int * cause_id,int * priority)721*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_cause_from_stack(const char *module_func, int *cause_id, int *priority)
722*10673SKrishnendu.Sadhukhan@Sun.COM {
723*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_match_t *match;
724*10673SKrishnendu.Sadhukhan@Sun.COM 
725*10673SKrishnendu.Sadhukhan@Sun.COM 	g_assert(module_func != NULL && cause_id != NULL && priority != NULL);
726*10673SKrishnendu.Sadhukhan@Sun.COM 
727*10673SKrishnendu.Sadhukhan@Sun.COM 	if (symbol_lookup_table == NULL) {
728*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
729*10673SKrishnendu.Sadhukhan@Sun.COM 	}
730*10673SKrishnendu.Sadhukhan@Sun.COM 
731*10673SKrishnendu.Sadhukhan@Sun.COM 	match = (lt_match_t *)
732*10673SKrishnendu.Sadhukhan@Sun.COM 	    g_hash_table_lookup(symbol_lookup_table, module_func);
733*10673SKrishnendu.Sadhukhan@Sun.COM 
734*10673SKrishnendu.Sadhukhan@Sun.COM 	if (match == NULL) {
735*10673SKrishnendu.Sadhukhan@Sun.COM 		char *func = strchr(module_func, '`');
736*10673SKrishnendu.Sadhukhan@Sun.COM 
737*10673SKrishnendu.Sadhukhan@Sun.COM 		if (func != NULL) {
738*10673SKrishnendu.Sadhukhan@Sun.COM 			match = (lt_match_t *)
739*10673SKrishnendu.Sadhukhan@Sun.COM 			    g_hash_table_lookup(symbol_lookup_table, func);
740*10673SKrishnendu.Sadhukhan@Sun.COM 		}
741*10673SKrishnendu.Sadhukhan@Sun.COM 	}
742*10673SKrishnendu.Sadhukhan@Sun.COM 
743*10673SKrishnendu.Sadhukhan@Sun.COM 	if (match == NULL) {
744*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
745*10673SKrishnendu.Sadhukhan@Sun.COM 	} else   {
746*10673SKrishnendu.Sadhukhan@Sun.COM 		*cause_id = match->lt_mt_cause_id;
747*10673SKrishnendu.Sadhukhan@Sun.COM 		*priority = match->lt_mt_priority;
748*10673SKrishnendu.Sadhukhan@Sun.COM 		return (1);
749*10673SKrishnendu.Sadhukhan@Sun.COM 	}
750*10673SKrishnendu.Sadhukhan@Sun.COM }
751*10673SKrishnendu.Sadhukhan@Sun.COM 
752*10673SKrishnendu.Sadhukhan@Sun.COM /*
753*10673SKrishnendu.Sadhukhan@Sun.COM  * Get the display name of a cause. cause_id must be valid,
754*10673SKrishnendu.Sadhukhan@Sun.COM  * it is usually returned from lt_table_cause_from_stack() or
755*10673SKrishnendu.Sadhukhan@Sun.COM  * lt_table_cause_from_name().
756*10673SKrishnendu.Sadhukhan@Sun.COM  */
757*10673SKrishnendu.Sadhukhan@Sun.COM const char *
lt_table_get_cause_name(int cause_id)758*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_get_cause_name(int cause_id)
759*10673SKrishnendu.Sadhukhan@Sun.COM {
760*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause;
761*10673SKrishnendu.Sadhukhan@Sun.COM 
762*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause_id < 0 || cause_id >= causes_array_len) {
763*10673SKrishnendu.Sadhukhan@Sun.COM 		return (NULL);
764*10673SKrishnendu.Sadhukhan@Sun.COM 	}
765*10673SKrishnendu.Sadhukhan@Sun.COM 
766*10673SKrishnendu.Sadhukhan@Sun.COM 	cause = (lt_cause_t *)g_ptr_array_index(causes_array, cause_id);
767*10673SKrishnendu.Sadhukhan@Sun.COM 
768*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause == NULL) {
769*10673SKrishnendu.Sadhukhan@Sun.COM 		return (NULL);
770*10673SKrishnendu.Sadhukhan@Sun.COM 	} else {
771*10673SKrishnendu.Sadhukhan@Sun.COM 		return (cause->lt_c_name);
772*10673SKrishnendu.Sadhukhan@Sun.COM 	}
773*10673SKrishnendu.Sadhukhan@Sun.COM }
774*10673SKrishnendu.Sadhukhan@Sun.COM 
775*10673SKrishnendu.Sadhukhan@Sun.COM /*
776*10673SKrishnendu.Sadhukhan@Sun.COM  * Check cause flag.
777*10673SKrishnendu.Sadhukhan@Sun.COM  * If CAUSE_ALL_FLAGS is passed in, all flags are returned.
778*10673SKrishnendu.Sadhukhan@Sun.COM  */
779*10673SKrishnendu.Sadhukhan@Sun.COM int
lt_table_get_cause_flag(int cause_id,int flag)780*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_get_cause_flag(int cause_id, int flag)
781*10673SKrishnendu.Sadhukhan@Sun.COM {
782*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_cause_t *cause;
783*10673SKrishnendu.Sadhukhan@Sun.COM 
784*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause_id < 0 || cause_id >= causes_array_len) {
785*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
786*10673SKrishnendu.Sadhukhan@Sun.COM 	}
787*10673SKrishnendu.Sadhukhan@Sun.COM 
788*10673SKrishnendu.Sadhukhan@Sun.COM 	cause = (lt_cause_t *)g_ptr_array_index(causes_array, cause_id);
789*10673SKrishnendu.Sadhukhan@Sun.COM 
790*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause == NULL) {
791*10673SKrishnendu.Sadhukhan@Sun.COM 		return (0);
792*10673SKrishnendu.Sadhukhan@Sun.COM 	} else {
793*10673SKrishnendu.Sadhukhan@Sun.COM 		return (cause->lt_c_flags & flag);
794*10673SKrishnendu.Sadhukhan@Sun.COM 	}
795*10673SKrishnendu.Sadhukhan@Sun.COM }
796*10673SKrishnendu.Sadhukhan@Sun.COM 
797*10673SKrishnendu.Sadhukhan@Sun.COM /*
798*10673SKrishnendu.Sadhukhan@Sun.COM  * Append macros to D script, if any.
799*10673SKrishnendu.Sadhukhan@Sun.COM  */
800*10673SKrishnendu.Sadhukhan@Sun.COM int
lt_table_append_trans(FILE * fp)801*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_append_trans(FILE *fp)
802*10673SKrishnendu.Sadhukhan@Sun.COM {
803*10673SKrishnendu.Sadhukhan@Sun.COM 	if (dtrans != NULL) {
804*10673SKrishnendu.Sadhukhan@Sun.COM 		if (fwrite(dtrans, strlen(dtrans), 1, fp) != 1) {
805*10673SKrishnendu.Sadhukhan@Sun.COM 			return (-1);
806*10673SKrishnendu.Sadhukhan@Sun.COM 		}
807*10673SKrishnendu.Sadhukhan@Sun.COM 	}
808*10673SKrishnendu.Sadhukhan@Sun.COM 
809*10673SKrishnendu.Sadhukhan@Sun.COM 	return (0);
810*10673SKrishnendu.Sadhukhan@Sun.COM }
811*10673SKrishnendu.Sadhukhan@Sun.COM 
812*10673SKrishnendu.Sadhukhan@Sun.COM /*
813*10673SKrishnendu.Sadhukhan@Sun.COM  * Clean up function.
814*10673SKrishnendu.Sadhukhan@Sun.COM  * Free the resources used for symbol table (symbols, causes etc.).
815*10673SKrishnendu.Sadhukhan@Sun.COM  */
816*10673SKrishnendu.Sadhukhan@Sun.COM void
lt_table_deinit(void)817*10673SKrishnendu.Sadhukhan@Sun.COM lt_table_deinit(void)
818*10673SKrishnendu.Sadhukhan@Sun.COM {
819*10673SKrishnendu.Sadhukhan@Sun.COM 	if (symbol_lookup_table != NULL) {
820*10673SKrishnendu.Sadhukhan@Sun.COM 		g_hash_table_destroy(symbol_lookup_table);
821*10673SKrishnendu.Sadhukhan@Sun.COM 		symbol_lookup_table = NULL;
822*10673SKrishnendu.Sadhukhan@Sun.COM 	}
823*10673SKrishnendu.Sadhukhan@Sun.COM 
824*10673SKrishnendu.Sadhukhan@Sun.COM 	if (cause_lookup != NULL) {
825*10673SKrishnendu.Sadhukhan@Sun.COM 		g_hash_table_destroy(cause_lookup);
826*10673SKrishnendu.Sadhukhan@Sun.COM 		cause_lookup = NULL;
827*10673SKrishnendu.Sadhukhan@Sun.COM 	}
828*10673SKrishnendu.Sadhukhan@Sun.COM 
829*10673SKrishnendu.Sadhukhan@Sun.COM 	if (causes_array != NULL) {
830*10673SKrishnendu.Sadhukhan@Sun.COM 		g_ptr_array_foreach(causes_array, (GFunc)free_cause, NULL);
831*10673SKrishnendu.Sadhukhan@Sun.COM 		g_ptr_array_free(causes_array, TRUE);
832*10673SKrishnendu.Sadhukhan@Sun.COM 		causes_array = NULL;
833*10673SKrishnendu.Sadhukhan@Sun.COM 		causes_array_len = 0;
834*10673SKrishnendu.Sadhukhan@Sun.COM 	}
835*10673SKrishnendu.Sadhukhan@Sun.COM 
836*10673SKrishnendu.Sadhukhan@Sun.COM 	if (dtrans != NULL) {
837*10673SKrishnendu.Sadhukhan@Sun.COM 		g_free(dtrans);
838*10673SKrishnendu.Sadhukhan@Sun.COM 		dtrans = NULL;
839*10673SKrishnendu.Sadhukhan@Sun.COM 	}
840*10673SKrishnendu.Sadhukhan@Sun.COM }
841