#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <msg.h>
#include <_elfdump.h>
#include <struct_layout.h>
#include <conv.h>
void
sl_extract_num_field(const char *data, int do_swap, const sl_field_t *fdesc,
sl_data_t *field_data)
{
(void) memcpy(field_data, data + fdesc->slf_offset,
fdesc->slf_eltlen);
if (do_swap) {
switch (fdesc->slf_eltlen) {
case 2:
field_data->sld_ui16 = BSWAP_HALF(field_data->sld_ui16);
break;
case 4:
field_data->sld_ui32 = BSWAP_WORD(field_data->sld_ui32);
break;
case 8:
field_data->sld_ui64 =
BSWAP_LWORD(field_data->sld_ui64);
break;
}
}
}
Word
sl_extract_as_word(const char *data, int do_swap, const sl_field_t *fdesc)
{
sl_data_t v;
sl_extract_num_field(data, do_swap, fdesc, &v);
if (fdesc->slf_sign) {
switch (fdesc->slf_eltlen) {
case 1:
return ((Word) v.sld_i8);
case 2:
return ((Word) v.sld_i16);
case 4:
return ((Word) v.sld_i32);
case 8:
return ((Word) v.sld_i64);
}
} else {
switch (fdesc->slf_eltlen) {
case 1:
return ((Word) v.sld_ui8);
case 2:
return ((Word) v.sld_ui16);
case 4:
return ((Word) v.sld_ui32);
case 8:
return ((Word) v.sld_ui64);
}
}
assert(0);
return (0);
}
Lword
sl_extract_as_lword(const char *data, int do_swap, const sl_field_t *fdesc)
{
sl_data_t v;
sl_extract_num_field(data, do_swap, fdesc, &v);
if (fdesc->slf_sign) {
switch (fdesc->slf_eltlen) {
case 1:
return ((Lword) v.sld_i8);
case 2:
return ((Lword) v.sld_i16);
case 4:
return ((Lword) v.sld_i32);
case 8:
return ((Lword) v.sld_i64);
}
} else {
switch (fdesc->slf_eltlen) {
case 1:
return ((Lword) v.sld_ui8);
case 2:
return ((Lword) v.sld_ui16);
case 4:
return ((Lword) v.sld_ui32);
case 8:
return ((Lword) v.sld_ui64);
}
}
assert(0);
return (0);
}
Sword
sl_extract_as_sword(const char *data, int do_swap, const sl_field_t *fdesc)
{
sl_data_t v;
sl_extract_num_field(data, do_swap, fdesc, &v);
if (fdesc->slf_sign) {
switch (fdesc->slf_eltlen) {
case 1:
return ((Sword)v.sld_i8);
case 2:
return ((Sword)v.sld_i16);
case 4:
return ((Sword)v.sld_i32);
case 8:
return ((Sword)v.sld_i64);
}
} else {
switch (fdesc->slf_eltlen) {
case 1:
return ((Sword)v.sld_ui8);
case 2:
return ((Sword)v.sld_ui16);
case 4:
return ((Sword)v.sld_ui32);
case 8:
return ((Sword)v.sld_ui64);
}
}
assert(0);
return (0);
}
const char *
sl_fmt_num(const char *data, int do_swap, const sl_field_t *fdesc,
sl_fmt_num_t fmt_type, sl_fmtbuf_t buf)
{
static const char *fmt_i8[2][3] = {
{
MSG_ORIG(MSG_CNOTE_FMT_U),
MSG_ORIG(MSG_CNOTE_FMT_X),
MSG_ORIG(MSG_CNOTE_FMT_Z2X)
},
{
MSG_ORIG(MSG_CNOTE_FMT_D),
MSG_ORIG(MSG_CNOTE_FMT_X),
MSG_ORIG(MSG_CNOTE_FMT_Z2X)
}
};
static const char *fmt_i16[2][3] = {
{
MSG_ORIG(MSG_CNOTE_FMT_U),
MSG_ORIG(MSG_CNOTE_FMT_X),
MSG_ORIG(MSG_CNOTE_FMT_Z4X)
},
{
MSG_ORIG(MSG_CNOTE_FMT_D),
MSG_ORIG(MSG_CNOTE_FMT_X),
MSG_ORIG(MSG_CNOTE_FMT_Z4X)
}
};
static const char *fmt_i32[2][3] = {
{
MSG_ORIG(MSG_CNOTE_FMT_U),
MSG_ORIG(MSG_CNOTE_FMT_X),
MSG_ORIG(MSG_CNOTE_FMT_Z8X)
},
{
MSG_ORIG(MSG_CNOTE_FMT_D),
MSG_ORIG(MSG_CNOTE_FMT_X),
MSG_ORIG(MSG_CNOTE_FMT_Z8X)
}
};
static const char *fmt_i64[2][3] = {
{
MSG_ORIG(MSG_CNOTE_FMT_LLU),
MSG_ORIG(MSG_CNOTE_FMT_LLX),
MSG_ORIG(MSG_CNOTE_FMT_Z16LLX)
},
{
MSG_ORIG(MSG_CNOTE_FMT_LLD),
MSG_ORIG(MSG_CNOTE_FMT_LLX),
MSG_ORIG(MSG_CNOTE_FMT_Z16LLX)
}
};
sl_data_t v;
sl_extract_num_field(data, do_swap, fdesc, &v);
switch (fdesc->slf_eltlen) {
case 1:
(void) snprintf(buf, sizeof (sl_fmtbuf_t),
fmt_i8[fdesc->slf_sign][fmt_type], (uint32_t)v.sld_ui8);
break;
case 2:
(void) snprintf(buf, sizeof (sl_fmtbuf_t),
fmt_i16[fdesc->slf_sign][fmt_type], (uint32_t)v.sld_ui16);
break;
case 4:
(void) snprintf(buf, sizeof (sl_fmtbuf_t),
fmt_i32[fdesc->slf_sign][fmt_type], v.sld_ui32);
break;
case 8:
(void) snprintf(buf, sizeof (sl_fmtbuf_t),
fmt_i64[fdesc->slf_sign][fmt_type], v.sld_ui64);
break;
}
return (buf);
}
const sl_arch_layout_t *
sl_mach(Half mach)
{
switch (mach) {
case EM_386:
return (struct_layout_i386());
case EM_AMD64:
return (struct_layout_amd64());
case EM_SPARC:
case EM_SPARC32PLUS:
return (struct_layout_sparc());
case EM_SPARCV9:
return (struct_layout_sparcv9());
}
return (NULL);
}