globals.c revision 9273:9a0603d78ad3
194575Sdes/* 294575Sdes * CDDL HEADER START 394575Sdes * 494575Sdes * The contents of this file are subject to the terms of the 594575Sdes * Common Development and Distribution License (the "License"). 694575Sdes * You may not use this file except in compliance with the License. 794575Sdes * 894575Sdes * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 994575Sdes * or http://www.opensolaris.org/os/licensing. 1094575Sdes * See the License for the specific language governing permissions 1194575Sdes * and limitations under the License. 1294575Sdes * 1394575Sdes * When distributing Covered Code, include this CDDL HEADER in each 1494575Sdes * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1594575Sdes * If applicable, add the following below this CDDL HEADER, with the 1694575Sdes * fields enclosed by brackets "[]" replaced with your own identifying 1794575Sdes * information: Portions Copyright [yyyy] [name of copyright owner] 1894575Sdes * 1994575Sdes * CDDL HEADER END 2094575Sdes */ 2194575Sdes 2294575Sdes/* 2394575Sdes * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2494575Sdes * Use is subject to license terms. 2594575Sdes */ 2694575Sdes 2794575Sdes#include <stdio.h> 2894575Sdes#include <strings.h> 2994575Sdes#include <ctype.h> 3094575Sdes#include <_machelf.h> 3194575Sdes#include "_conv.h" 3294575Sdes#include "globals_msg.h" 3394575Sdes 3494575Sdes 3594575Sdes/* 3694575Sdes * Map an integer into a descriptive string. 3794577Sdes * 3894577Sdes * entry: 3994577Sdes * inv_buf - A buffer into which this routine can format 4094577Sdes * a result string, if necessary. 4194575Sdes * val - The value for which a string is desired. 4294575Sdes * flags - CONV_FMT_* values to be passed to conv_invalid_val() if 4394577Sdes * necessary. The caller is reponsible for having examined 4494577Sdes * the CONV_FMT_ALT_* part of flags and passing the proper 4594575Sdes * msg array. 4694575Sdes * num_msg - # of Msg entries in msg. 4794575Sdes * msg - Array of num_msg Msg items corresponding to the possible 4894577Sdes * strings corresponding to val. 4994575Sdes * local_sgs_msg - Message string table from module from which 5094575Sdes * this function is called. 5194575Sdes * 5294575Sdes * exit: 5394575Sdes * If val lies in the range [0-(num_msg-1)], then the string 5494577Sdes * corresponding to it is returned. If val is outside the range, 5594575Sdes * conv_invalid_val() is called to format an ASCII representation 5694577Sdes * of it into inv_buf, and that is returned. 5794577Sdes */ 5894577Sdes/*ARGSUSED5*/ 5994575Sdesstatic const char * 6094575Sdesmap_msg2str(Conv_inv_buf_t *inv_buf, Conv_elfvalue_t val, 6194575Sdes Conv_fmt_flags_t flags, size_t num_msg, const Msg *msg, 6294577Sdes const char *local_sgs_msg) 6394577Sdes{ 6494575Sdes if ((val < num_msg) && (msg[val] != 0)) 6594575Sdes return (MSG_ORIG_STRTAB(msg[val], local_sgs_msg)); 6694575Sdes 6794575Sdes /* If we get here, it's an unknown value */ 6894575Sdes return (conv_invalid_val(inv_buf, val, flags)); 6994575Sdes} 7094575Sdes 7194575Sdes/* 7294577Sdes * Map an integer into a descriptive string from a NULL terminated 7394577Sdes * array of Val_desc or Val_desc2 descriptors. 7494577Sdes * 7594577Sdes * entry: 7694577Sdes * inv_buf - A buffer into which this routine can format 7794577Sdes * a result string, if necessary. 7894577Sdes * osabi,mach (_conv_vd22str only) - The osab/mach under which 7994577Sdes * val is to be interpreted. Items with a non-0 osabi or machine 8094577Sdes * that do not match are quietly ignored. 8194577Sdes * val - The value for which a string is desired. 8294577Sdes * flags - CONV_FMT_* values to be passed to conv_invalid_val() if 8394577Sdes * necessary. The caller is reponsible for having examined 8494577Sdes * the CONV_FMT_ALT_* part of flags and passing the proper 8594577Sdes * descriptor array. 8694577Sdes * vdp - Pointer to NULL terminated array of Val_desc descriptors. 8794577Sdes * local_sgs_msg - Message string table from module from which 8894577Sdes * this function is called. 8994577Sdes * 9094577Sdes * exit: 9194577Sdes * If val is found in the vdp array, and in the osabi version of 9294577Sdes * this function if the osabi matches, then the string corresponding 9394577Sdes * val is returned. If a string for val is not found, conv_invalid_val() 9494577Sdes * is called to format an ASCII representation of it into inv_buf, and 9594577Sdes * that is returned. 9694577Sdes */ 9794577Sdes/*ARGSUSED4*/ 9894577Sdesstatic const char * 9994577Sdesmap_vd2str(Conv_inv_buf_t *inv_buf, Conv_elfvalue_t val, 10094577Sdes Conv_fmt_flags_t flags, const Val_desc *vdp, const char *local_sgs_msg) 10194577Sdes{ 10294577Sdes for (; vdp->v_msg; vdp++) { 10394577Sdes if (val == vdp->v_val) 10494577Sdes return (MSG_ORIG_STRTAB(vdp->v_msg, local_sgs_msg)); 10594577Sdes } 10694577Sdes 10794577Sdes /* If we get here, it's an unknown value */ 10894577Sdes return (conv_invalid_val(inv_buf, val, flags)); 10994577Sdes} 11094577Sdes 11194577Sdes/*ARGSUSED6*/ 11294577Sdesstatic const char * 11394577Sdesmap_vd22str(Conv_inv_buf_t *inv_buf, uchar_t osabi, Half mach, 11494577Sdes Conv_elfvalue_t val, Conv_fmt_flags_t flags, const Val_desc2 *vdp, 11594577Sdes const char *local_sgs_msg) 11694577Sdes{ 11794577Sdes for (; vdp->v_msg; vdp++) { 11894577Sdes if (CONV_VD2_SKIP(osabi, mach, vdp)) 11994577Sdes continue; 12094577Sdes 12194577Sdes if (val == vdp->v_val) 12294577Sdes return (MSG_ORIG_STRTAB(vdp->v_msg, local_sgs_msg)); 12394577Sdes } 12494577Sdes 12594577Sdes /* If we get here, it's an unknown value */ 12694577Sdes return (conv_invalid_val(inv_buf, val, flags)); 12794577Sdes} 12894577Sdes 12994577Sdes/* 13094577Sdes * Process an array of conv_ds_XXX_t structures and call the appropriate 13194577Sdes * map functions for the format of the strings given. 13294577Sdes */ 13394577Sdesconst char * 13494577Sdes_conv_map_ds(uchar_t osabi, Half mach, Conv_elfvalue_t value, 13594577Sdes const conv_ds_t **dsp, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf, 13694577Sdes const char *local_sgs_msg) 13794577Sdes{ 13894577Sdes const conv_ds_t *ds; 13994577Sdes 14094577Sdes for (ds = *dsp; ds != NULL; ds = *(++dsp)) { 14194577Sdes if ((value < ds->ds_baseval) || (value > ds->ds_topval)) 14294577Sdes continue; 14394577Sdes 14494577Sdes switch (ds->ds_type) { 14594577Sdes case CONV_DS_MSGARR: 14694577Sdes return (map_msg2str(inv_buf, value - ds->ds_baseval, 14794577Sdes fmt_flags, ds->ds_topval - ds->ds_baseval + 1, 14894577Sdes /*LINTED*/ 14994577Sdes ((conv_ds_msg_t *)ds)->ds_msg, 15094577Sdes local_sgs_msg)); 15194577Sdes 15294577Sdes case CONV_DS_VD: 15394577Sdes return (map_vd2str(inv_buf, value, fmt_flags, 15494577Sdes /*LINTED*/ 15594577Sdes ((conv_ds_vd_t *)ds)->ds_vd, 15694577Sdes local_sgs_msg)); 15794577Sdes 15894577Sdes case CONV_DS_VD2: 15994577Sdes return (map_vd22str(inv_buf, osabi, mach, value, 16094577Sdes fmt_flags, 16194577Sdes /*LINTED*/ 16294577Sdes ((conv_ds_vd2_t *)ds)->ds_vd2, 16394577Sdes local_sgs_msg)); 16494577Sdes } 16594577Sdes } 16694577Sdes 16794577Sdes return (conv_invalid_val(inv_buf, value, fmt_flags)); 16894577Sdes} 16994577Sdes 17094577Sdes/* 17194577Sdes * Iterate over every message string in a given array of Msg codes, 17294577Sdes * calling a user supplied callback for each one. 17394577Sdes * 17494577Sdes * entry: 17594577Sdes * basevalue - Value corresponding to the first Msg in the array. 17694577Sdes * local_sgs_msg - Pointer to the __sgs_msg array for the 17794577Sdes * libconv module making the call. 17894577Sdes * num_msg - # of items in array referenced by msg 17994577Sdes * msg - Array of Msg indexes for the strings to iterate over. 18094577Sdes * The value corresponding to each element of msg must be: 18194577Sdes * value[i] = basevalue + i 18294577Sdes * func, uvalue - User supplied function to be called for each 18394577Sdes * string in msg. uvalue is an arbitrary user supplied pointer 18494577Sdes * to be passed to func. 18594577Sdes * local_sgs_msg - Pointer to the __sgs_msg array for the 18694577Sdes * libconv module making the call. 18794577Sdes * 18894577Sdes * exit: 18994577Sdes * The callback function is called for every non-zero item in 19094577Sdes * msg[]. If any callback returns CONV_ITER_DONE, execution stops 19194577Sdes * with that item and the function returns immediately. Otherwise, 19294577Sdes * it continues to the end of the array. 19394577Sdes * 19494577Sdes * The value from the last callback is returned. 19594577Sdes */ 19694577Sdes/*ARGSUSED5*/ 19794577Sdesstatic conv_iter_ret_t 19894577Sdes_conv_iter_msgarr(uint32_t basevalue, const Msg *msg, size_t num_msg, 19994577Sdes conv_iter_cb_t func, void *uvalue, const char *local_sgs_msg) 20094577Sdes{ 20194575Sdes for (; num_msg-- > 0; basevalue++, msg++) { 20294575Sdes if (*msg != 0) 20394575Sdes if ((* func)(MSG_ORIG_STRTAB(*msg, local_sgs_msg), 20494575Sdes basevalue, uvalue) == CONV_ITER_DONE) 20594575Sdes return (CONV_ITER_DONE); 20694575Sdes } 20794575Sdes 20894575Sdes return (CONV_ITER_CONT); 20994575Sdes} 21094575Sdes 21194575Sdes/* 21294575Sdes * Iterate over every message string in a given array of Val_desc or 21394575Sdes * Val_desc2 descriptors, calling a user supplied callback for each one. 21494575Sdes * 21594575Sdes * entry: 21694575Sdes * osabi,mach (_conv_iter_vd2 only) - The osabi/mach for which 21794575Sdes * strings are desired. Strings with a non-0 osabi or machine 21894575Sdes * that do not match are quietly ignored. 21994575Sdes * vdp - Pointer to NULL terminated array of Val_desc descriptors. 22094575Sdes * func, uvalue - User supplied function to be called for each 22194575Sdes * string in msg. uvalue is an arbitrary user supplied pointer 22294575Sdes * to be passed to func. 22394575Sdes * local_sgs_msg - Pointer to the __sgs_msg array for the 22494575Sdes * libconv module making the call. 22594575Sdes * 22694575Sdes * exit: 22794575Sdes * The callback function is called for every descriptor referenced by 22894575Sdes * vdp. In the case of the OSABI-version of this function, strings from 22994575Sdes * the wrong osabi are not used. If any callback returns CONV_ITER_DONE, 23094575Sdes * execution stops with that item and the function returns immediately. 23194575Sdes * Otherwise, it continues to the end of the array. 23294575Sdes * 23394575Sdes * The value from the last callback is returned. 23494575Sdes */ 23594575Sdes/*ARGSUSED3*/ 23694575Sdesconv_iter_ret_t 23794575Sdes_conv_iter_vd(const Val_desc *vdp, conv_iter_cb_t func, void *uvalue, 23894575Sdes const char *local_sgs_msg) 23994575Sdes{ 24094575Sdes for (; vdp->v_msg; vdp++) { 24194575Sdes if ((* func)(MSG_ORIG_STRTAB(vdp->v_msg, local_sgs_msg), 24294575Sdes vdp->v_val, uvalue) == CONV_ITER_DONE) 24394575Sdes return (CONV_ITER_DONE); 24494575Sdes } 24594575Sdes 24694575Sdes return (CONV_ITER_CONT); 24794575Sdes} 24894575Sdes 24994575Sdes/*ARGSUSED5*/ 25094575Sdesconv_iter_ret_t 25194575Sdes_conv_iter_vd2(conv_iter_osabi_t osabi, Half mach, const Val_desc2 *vdp, 25294575Sdes conv_iter_cb_t func, void *uvalue, const char *local_sgs_msg) 25394575Sdes{ 25494575Sdes for (; vdp->v_msg; vdp++) { 25594575Sdes if (CONV_ITER_VD2_SKIP(osabi, mach, vdp)) 25694575Sdes continue; 25794575Sdes 25894575Sdes if ((* func)(MSG_ORIG_STRTAB(vdp->v_msg, local_sgs_msg), 25994575Sdes vdp->v_val, uvalue) == CONV_ITER_DONE) 26094575Sdes return (CONV_ITER_DONE); 26194575Sdes } 26294575Sdes 26394575Sdes return (CONV_ITER_CONT); 26494575Sdes} 26594575Sdes 26694575Sdes/* 26794575Sdes * Process an array of conv_ds_XXX_t structures and call the appropriate 268 * iteration functions for the format of the strings given. 269 */ 270conv_iter_ret_t 271_conv_iter_ds(conv_iter_osabi_t osabi, Half mach, const conv_ds_t **dsp, 272 conv_iter_cb_t func, void *uvalue, const char *local_sgs_msg) 273{ 274 const conv_ds_t *ds; 275 276 for (ds = *dsp; ds != NULL; ds = *(++dsp)) { 277 switch (ds->ds_type) { 278 case CONV_DS_MSGARR: 279 if (_conv_iter_msgarr(ds->ds_baseval, 280 /*LINTED*/ 281 ((conv_ds_msg_t *)ds)->ds_msg, 282 ds->ds_topval - ds->ds_baseval + 1, func, uvalue, 283 local_sgs_msg) == CONV_ITER_DONE) 284 return (CONV_ITER_DONE); 285 break; 286 287 case CONV_DS_VD: 288 /*LINTED*/ 289 if (_conv_iter_vd(((conv_ds_vd_t *)ds)->ds_vd, 290 func, uvalue, local_sgs_msg) == CONV_ITER_DONE) 291 return (CONV_ITER_DONE); 292 break; 293 294 case CONV_DS_VD2: 295 if (_conv_iter_vd2(osabi, mach, 296 /*LINTED*/ 297 ((conv_ds_vd2_t *)ds)->ds_vd2, 298 func, uvalue, local_sgs_msg) == CONV_ITER_DONE) 299 return (CONV_ITER_DONE); 300 break; 301 } 302 } 303 304 return (CONV_ITER_CONT); 305} 306 307/* 308 * Initialize the uvalue block prior to use of an interation function 309 * employing conv_iter_strtol(). 310 * 311 * entry: 312 * str - String to be matched to a value 313 * uvalue - Pointer to uninitialized uvalue block 314 * 315 * exit: 316 * Initializes the uvalue block for use. Returns True (1) if a non-empty 317 * string was supplied, and False (0). 318 */ 319int 320conv_iter_strtol_init(const char *str, conv_strtol_uvalue_t *uvalue) 321{ 322 const char *tail; 323 324 while (isspace(*str)) 325 str++; 326 uvalue->csl_str = str; 327 uvalue->csl_found = 0; 328 329 tail = str + strlen(str); 330 while ((tail > str) && isspace(*(tail - 1))) 331 tail--; 332 uvalue->csl_strlen = tail - str; 333 334 return (uvalue->csl_strlen > 0); 335} 336 337/* 338 * conv_iter_strtol() is used with iteration functions to map a string 339 * to the value of its corresponding ELF constant. 340 * 341 * entry: 342 * str - String supplied by this iteration 343 * value - Value of ELF constant corresponding to str 344 * uvalue - Pointer to conv_strtol_uvalue_t block previously 345 * initialized by a call to conv_iter_strtol_init(). 346 */ 347conv_iter_ret_t 348conv_iter_strtol(const char *str, uint32_t value, void *uvalue) 349{ 350 conv_strtol_uvalue_t *state = (conv_strtol_uvalue_t *)uvalue; 351 352 if ((strlen(str) == state->csl_strlen) && 353 (strncasecmp(str, state->csl_str, state->csl_strlen) == 0)) { 354 state->csl_found = 1; 355 state->csl_value = value; 356 return (CONV_ITER_DONE); /* Found it. Stop now. */ 357 } 358 359 return (CONV_ITER_CONT); /* Keep looking */ 360} 361