Home | History | Annotate | Download | only in common
      1  6635  ab196087 /*
      2  6635  ab196087  * CDDL HEADER START
      3  6635  ab196087  *
      4  6635  ab196087  * The contents of this file are subject to the terms of the
      5  6635  ab196087  * Common Development and Distribution License (the "License").
      6  6635  ab196087  * You may not use this file except in compliance with the License.
      7  6635  ab196087  *
      8  6635  ab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  6635  ab196087  * or http://www.opensolaris.org/os/licensing.
     10  6635  ab196087  * See the License for the specific language governing permissions
     11  6635  ab196087  * and limitations under the License.
     12  6635  ab196087  *
     13  6635  ab196087  * When distributing Covered Code, include this CDDL HEADER in each
     14  6635  ab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  6635  ab196087  * If applicable, add the following below this CDDL HEADER, with the
     16  6635  ab196087  * fields enclosed by brackets "[]" replaced with your own identifying
     17  6635  ab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  6635  ab196087  *
     19  6635  ab196087  * CDDL HEADER END
     20  6635  ab196087  */
     21  6635  ab196087 
     22  6635  ab196087 /*
     23  6635  ab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  6635  ab196087  * Use is subject to license terms.
     25  6635  ab196087  */
     26  6635  ab196087 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27  6635  ab196087 
     28  6635  ab196087 #include <stdlib.h>
     29  6635  ab196087 #include <stdio.h>
     30  6635  ab196087 #include <string.h>
     31  6635  ab196087 #include <msg.h>
     32  6635  ab196087 #include <_elfdump.h>
     33  6635  ab196087 #include <struct_layout.h>
     34  6635  ab196087 #include <conv.h>
     35  6635  ab196087 
     36  6635  ab196087 
     37  6635  ab196087 /*
     38  6635  ab196087  * Functions for extracting and formatting numeric values from
     39  6635  ab196087  * structure data.
     40  6635  ab196087  */
     41  6635  ab196087 
     42  6635  ab196087 
     43  6635  ab196087 
     44  6635  ab196087 
     45  6635  ab196087 /*
     46  6635  ab196087  * Extract the integral field into the value union given and
     47  6635  ab196087  * perform any necessary byte swapping to make the result readable
     48  6635  ab196087  * on the elfdump host.
     49  6635  ab196087  */
     50  6635  ab196087 void
     51  6635  ab196087 sl_extract_num_field(const char *data, int do_swap, const sl_field_t *fdesc,
     52  6635  ab196087     sl_data_t *field_data)
     53  6635  ab196087 {
     54  6635  ab196087 	/* Copy the value bytes into our union */
     55  6635  ab196087 	(void) memcpy(field_data, data + fdesc->slf_offset,
     56  6635  ab196087 	    fdesc->slf_eltlen);
     57  6635  ab196087 
     58  6635  ab196087 	/* Do byte swapping as necessary */
     59  6635  ab196087 	if (do_swap) {
     60  6635  ab196087 		switch (fdesc->slf_eltlen) {
     61  6635  ab196087 		case 2:
     62  6635  ab196087 			field_data->sld_ui16 = BSWAP_HALF(field_data->sld_ui16);
     63  6635  ab196087 			break;
     64  6635  ab196087 
     65  6635  ab196087 		case 4:
     66  6635  ab196087 			field_data->sld_ui32 = BSWAP_WORD(field_data->sld_ui32);
     67  6635  ab196087 			break;
     68  6635  ab196087 
     69  6635  ab196087 		case 8:
     70  6635  ab196087 			field_data->sld_ui64 =
     71  6635  ab196087 			    BSWAP_LWORD(field_data->sld_ui64);
     72  6635  ab196087 			break;
     73  6635  ab196087 		}
     74  6635  ab196087 	}
     75  6635  ab196087 }
     76  6635  ab196087 
     77  6635  ab196087 /*
     78  6635  ab196087  * Extract the given integer field, and return its value, cast
     79  6635  ab196087  * to Word. Note that this operation must not be used on values
     80  6635  ab196087  * that can be negative, or larger than 32-bits, as information
     81  6635  ab196087  * can be lost.
     82  6635  ab196087  */
     83  6635  ab196087 Word
     84  6635  ab196087 sl_extract_as_word(const char *data, int do_swap, const sl_field_t *fdesc)
     85  6635  ab196087 {
     86  6635  ab196087 	sl_data_t	v;
     87  6635  ab196087 
     88  6635  ab196087 	/* Extract the value from the raw data */
     89  6635  ab196087 	sl_extract_num_field(data, do_swap, fdesc, &v);
     90  6635  ab196087 
     91  6635  ab196087 	if (fdesc->slf_sign) {
     92  6635  ab196087 		switch (fdesc->slf_eltlen) {
     93  6635  ab196087 			case 1:
     94  6635  ab196087 				return ((Word) v.sld_i8);
     95  6635  ab196087 			case 2:
     96  6635  ab196087 				return ((Word) v.sld_i16);
     97  6635  ab196087 			case 4:
     98  6635  ab196087 				return ((Word) v.sld_i32);
     99  6635  ab196087 			case 8:
    100  6635  ab196087 				return ((Word) v.sld_i64);
    101  6635  ab196087 		}
    102  6635  ab196087 	} else {
    103  6635  ab196087 		switch (fdesc->slf_eltlen) {
    104  6635  ab196087 			case 1:
    105  6635  ab196087 				return ((Word) v.sld_ui8);
    106  6635  ab196087 			case 2:
    107  6635  ab196087 				return ((Word) v.sld_ui16);
    108  6635  ab196087 			case 4:
    109  6635  ab196087 				return ((Word) v.sld_ui32);
    110  6635  ab196087 			case 8:
    111  6635  ab196087 				return ((Word) v.sld_ui64);
    112  6635  ab196087 		}
    113  6635  ab196087 	}
    114  6635  ab196087 
    115  6635  ab196087 	/* This should not be reached */
    116  6635  ab196087 	assert(0);
    117  6635  ab196087 	return (0);
    118  6635  ab196087 }
    119  6635  ab196087 
    120  6635  ab196087 
    121  6635  ab196087 /*
    122  6635  ab196087  * Extract the given integer field, and return its value, cast
    123  6635  ab196087  * to Word. Note that this operation must not be used on values
    124  6635  ab196087  * that can be negative, as information can be lost.
    125  6635  ab196087  */
    126  6635  ab196087 Lword
    127  6635  ab196087 sl_extract_as_lword(const char *data, int do_swap, const sl_field_t *fdesc)
    128  6635  ab196087 {
    129  6635  ab196087 	sl_data_t	v;
    130  6635  ab196087 
    131  6635  ab196087 	/* Extract the value from the raw data */
    132  6635  ab196087 	sl_extract_num_field(data, do_swap, fdesc, &v);
    133  6635  ab196087 
    134  6635  ab196087 	if (fdesc->slf_sign) {
    135  6635  ab196087 		switch (fdesc->slf_eltlen) {
    136  6635  ab196087 			case 1:
    137  6635  ab196087 				return ((Lword) v.sld_i8);
    138  6635  ab196087 			case 2:
    139  6635  ab196087 				return ((Lword) v.sld_i16);
    140  6635  ab196087 			case 4:
    141  6635  ab196087 				return ((Lword) v.sld_i32);
    142  6635  ab196087 			case 8:
    143  6635  ab196087 				return ((Lword) v.sld_i64);
    144  6635  ab196087 		}
    145  6635  ab196087 	} else {
    146  6635  ab196087 		switch (fdesc->slf_eltlen) {
    147  6635  ab196087 			case 1:
    148  6635  ab196087 				return ((Lword) v.sld_ui8);
    149  6635  ab196087 			case 2:
    150  6635  ab196087 				return ((Lword) v.sld_ui16);
    151  6635  ab196087 			case 4:
    152  6635  ab196087 				return ((Lword) v.sld_ui32);
    153  6635  ab196087 			case 8:
    154  6635  ab196087 				return ((Lword) v.sld_ui64);
    155  6635  ab196087 		}
    156  6635  ab196087 	}
    157  6635  ab196087 
    158  6635  ab196087 	/* This should not be reached */
    159  6635  ab196087 	assert(0);
    160  6635  ab196087 	return (0);
    161  6635  ab196087 }
    162  6635  ab196087 
    163  6635  ab196087 
    164  6635  ab196087 /*
    165  6635  ab196087  * Extract the given integer field, and return its value, cast
    166  6635  ab196087  * to int32_t. Note that this operation must not be used on unsigned
    167  6635  ab196087  * values larger than 31-bits, or on signed values larger than 32-bits,
    168  6635  ab196087  * as information can be lost.
    169  6635  ab196087  */
    170  6635  ab196087 Sword
    171  6635  ab196087 sl_extract_as_sword(const char *data, int do_swap, const sl_field_t *fdesc)
    172  6635  ab196087 {
    173  6635  ab196087 	sl_data_t	v;
    174  6635  ab196087 
    175  6635  ab196087 	/* Extract the value from the raw data */
    176  6635  ab196087 	sl_extract_num_field(data, do_swap, fdesc, &v);
    177  6635  ab196087 
    178  6635  ab196087 	if (fdesc->slf_sign) {
    179  6635  ab196087 		switch (fdesc->slf_eltlen) {
    180  6635  ab196087 			case 1:
    181  6635  ab196087 				return ((Sword)v.sld_i8);
    182  6635  ab196087 			case 2:
    183  6635  ab196087 				return ((Sword)v.sld_i16);
    184  6635  ab196087 			case 4:
    185  6635  ab196087 				return ((Sword)v.sld_i32);
    186  6635  ab196087 			case 8:
    187  6635  ab196087 				return ((Sword)v.sld_i64);
    188  6635  ab196087 		}
    189  6635  ab196087 	} else {
    190  6635  ab196087 		switch (fdesc->slf_eltlen) {
    191  6635  ab196087 			case 1:
    192  6635  ab196087 				return ((Sword)v.sld_ui8);
    193  6635  ab196087 			case 2:
    194  6635  ab196087 				return ((Sword)v.sld_ui16);
    195  6635  ab196087 			case 4:
    196  6635  ab196087 				return ((Sword)v.sld_ui32);
    197  6635  ab196087 			case 8:
    198  6635  ab196087 				return ((Sword)v.sld_ui64);
    199  6635  ab196087 		}
    200  6635  ab196087 	}
    201  6635  ab196087 
    202  6635  ab196087 	/* This should not be reached */
    203  6635  ab196087 	assert(0);
    204  6635  ab196087 	return (0);
    205  6635  ab196087 }
    206  6635  ab196087 
    207  6635  ab196087 
    208  6635  ab196087 /*
    209  6635  ab196087  * Extract the integral field and format it into the supplied buffer.
    210  6635  ab196087  */
    211  6635  ab196087 const char *
    212  6635  ab196087 sl_fmt_num(const char *data, int do_swap, const sl_field_t *fdesc,
    213  6635  ab196087     sl_fmt_num_t fmt_type, sl_fmtbuf_t buf)
    214  6635  ab196087 {
    215  6635  ab196087 	/*
    216  6635  ab196087 	 * These static arrays are indexed by [fdesc->slf_sign][fmt_type]
    217  6635  ab196087 	 * to get a format string to use for the specified combination.
    218  6635  ab196087 	 */
    219  6635  ab196087 	static const char *fmt_i8[2][3] = {
    220  6635  ab196087 		{
    221  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_U),
    222  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_X),
    223  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z2X)
    224  6635  ab196087 		},
    225  6635  ab196087 		{
    226  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_D),
    227  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_X),
    228  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z2X)
    229  6635  ab196087 		}
    230  6635  ab196087 	};
    231  6635  ab196087 	static const char *fmt_i16[2][3] = {
    232  6635  ab196087 		{
    233  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_U),
    234  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_X),
    235  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z4X)
    236  6635  ab196087 		},
    237  6635  ab196087 		{
    238  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_D),
    239  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_X),
    240  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z4X)
    241  6635  ab196087 		}
    242  6635  ab196087 	};
    243  6635  ab196087 	static const char *fmt_i32[2][3] = {
    244  6635  ab196087 		{
    245  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_U),
    246  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_X),
    247  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z8X)
    248  6635  ab196087 		},
    249  6635  ab196087 		{
    250  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_D),
    251  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_X),
    252  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z8X)
    253  6635  ab196087 		}
    254  6635  ab196087 	};
    255  6635  ab196087 	static const char *fmt_i64[2][3] = {
    256  6635  ab196087 		{
    257  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_LLU),
    258  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_LLX),
    259  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z16LLX)
    260  6635  ab196087 		},
    261  6635  ab196087 		{
    262  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_LLD),
    263  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_LLX),
    264  6635  ab196087 			MSG_ORIG(MSG_CNOTE_FMT_Z16LLX)
    265  6635  ab196087 		}
    266  6635  ab196087 	};
    267  6635  ab196087 
    268  6635  ab196087 	sl_data_t	v;
    269  6635  ab196087 
    270  6635  ab196087 	/* Extract the value from the raw data */
    271  6635  ab196087 	sl_extract_num_field(data, do_swap, fdesc, &v);
    272  6635  ab196087 
    273  6635  ab196087 	/*
    274  6635  ab196087 	 * Format into the buffer. Note that we depend on the signed
    275  6635  ab196087 	 * and unsigned versions of each width being equivalent as long
    276  6635  ab196087 	 * as the format specifies the proper formatting.
    277  6635  ab196087 	 */
    278  6635  ab196087 	switch (fdesc->slf_eltlen) {
    279  6635  ab196087 	case 1:
    280  6635  ab196087 		(void) snprintf(buf, sizeof (sl_fmtbuf_t),
    281  6635  ab196087 		    fmt_i8[fdesc->slf_sign][fmt_type], (uint32_t)v.sld_ui8);
    282  6635  ab196087 		break;
    283  6635  ab196087 
    284  6635  ab196087 	case 2:
    285  6635  ab196087 		(void) snprintf(buf, sizeof (sl_fmtbuf_t),
    286  6635  ab196087 		    fmt_i16[fdesc->slf_sign][fmt_type], (uint32_t)v.sld_ui16);
    287  6635  ab196087 		break;
    288  6635  ab196087 
    289  6635  ab196087 	case 4:
    290  6635  ab196087 		(void) snprintf(buf, sizeof (sl_fmtbuf_t),
    291  6635  ab196087 		    fmt_i32[fdesc->slf_sign][fmt_type], v.sld_ui32);
    292  6635  ab196087 		break;
    293  6635  ab196087 
    294  6635  ab196087 	case 8:
    295  6635  ab196087 		(void) snprintf(buf, sizeof (sl_fmtbuf_t),
    296  6635  ab196087 		    fmt_i64[fdesc->slf_sign][fmt_type], v.sld_ui64);
    297  6635  ab196087 		break;
    298  6635  ab196087 	}
    299  6635  ab196087 
    300  6635  ab196087 	return (buf);
    301  6635  ab196087 }
    302  6635  ab196087 
    303  6635  ab196087 /*
    304  6635  ab196087  * Return structure layout definition for the given machine type,
    305  6635  ab196087  * or NULL if the specified machine is not supported.
    306  6635  ab196087  */
    307  6635  ab196087 const sl_arch_layout_t	*
    308  6635  ab196087 sl_mach(Half mach)
    309  6635  ab196087 {
    310  6635  ab196087 	switch (mach) {
    311  6635  ab196087 	case EM_386:
    312  6635  ab196087 		return (struct_layout_i386());
    313  6635  ab196087 
    314  6635  ab196087 	case EM_AMD64:
    315  6635  ab196087 		return (struct_layout_amd64());
    316  6635  ab196087 
    317  6635  ab196087 	case EM_SPARC:
    318  6635  ab196087 	case EM_SPARC32PLUS:
    319  6635  ab196087 		return (struct_layout_sparc());
    320  6635  ab196087 
    321  6635  ab196087 	case EM_SPARCV9:
    322  6635  ab196087 		return (struct_layout_sparcv9());
    323  6635  ab196087 	}
    324  6635  ab196087 
    325  6635  ab196087 	/* Unsupported architecture */
    326  6635  ab196087 	return (NULL);
    327  6635  ab196087 }
    328