#include "dt_dof_byteswap.h"
#ifdef __APPLE__
#include <CoreFoundation/CFByteOrder.h>
#include <dt_impl.h>
#include <dt_strtab.h>
#include <dt_program.h>
#include <dt_provider.h>
#include <dt_xlator.h>
#include <dt_dof.h>
#define swapu16(x) do { x = CFSwapInt16(x); } while(0)
#define swapu32(x) do { x = CFSwapInt32(x); } while(0)
#define swapu64(x) do { x = CFSwapInt64(x); } while(0)
static void
byteswap_dof_ecbdesc(uint8_t* base, dof_sec_t* sec)
{
dof_ecbdesc_t* ecbdesc = (dof_ecbdesc_t*)(base + sec->dofs_offset);
swapu32(ecbdesc->dofe_probes);
swapu32(ecbdesc->dofe_pred);
swapu32(ecbdesc->dofe_actions);
swapu32(ecbdesc->dofe_pad);
swapu64(ecbdesc->dofe_uarg);
return;
}
static void
byteswap_dof_probedesc(uint8_t* base, dof_sec_t* sec)
{
dof_probedesc_t* probedesc = (dof_probedesc_t*)(base + sec->dofs_offset);
swapu32(probedesc->dofp_strtab);
swapu32(probedesc->dofp_provider);
swapu32(probedesc->dofp_mod);
swapu32(probedesc->dofp_func);
swapu32(probedesc->dofp_name);
swapu32(probedesc->dofp_id);
return;
}
static void
byteswap_dof_actdescs(uint8_t* base, dof_sec_t* sec)
{
dof_actdesc_t* actdescs = (dof_actdesc_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < (sec->dofs_size / sec->dofs_entsize); i++) {
swapu32(actdescs[i].dofa_difo);
swapu32(actdescs[i].dofa_strtab);
swapu32(actdescs[i].dofa_kind);
swapu32(actdescs[i].dofa_ntuple);
swapu64(actdescs[i].dofa_arg);
swapu64(actdescs[i].dofa_uarg);
}
return;
}
static void
byteswap_dof_difohdr(uint8_t* base, dof_sec_t* sec)
{
dof_difohdr_t* difohdr = (dof_difohdr_t*)(base + sec->dofs_offset);
swapu32(difohdr->dofd_rtype.dtdt_size);
int i;
for(i = 0;
i < ((sec->dofs_size - sizeof(*difohdr)) / sizeof(dof_secidx_t)) + 1;
i++) {
swapu32(difohdr->dofd_links[i]);
}
return;
}
static void
byteswap_dof_dif(uint8_t* base, dof_sec_t* sec)
{
uint32_t* dif = (uint32_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < (sec->dofs_size / sizeof(uint32_t)); i++)
swapu32(dif[i]);
return;
}
static void
byteswap_dof_difvs(uint8_t* base, dof_sec_t* sec)
{
dtrace_difv_t* difvs = (dtrace_difv_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < (sec->dofs_size / sec->dofs_entsize); i++) {
swapu32(difvs[i].dtdv_name);
swapu32(difvs[i].dtdv_id);
swapu16(difvs[i].dtdv_flags);
swapu32(difvs[i].dtdv_type.dtdt_size);
}
return;
}
static void
byteswap_dof_relodescs(uint8_t* base, dof_sec_t* sec)
{
dof_relodesc_t* relodescs = (dof_relodesc_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < (sec->dofs_size / sec->dofs_entsize); i++) {
swapu32(relodescs[i].dofr_name);
swapu32(relodescs[i].dofr_type);
swapu64(relodescs[i].dofr_offset);
swapu64(relodescs[i].dofr_data);
}
return;
}
static void
byteswap_dof_diftypes(uint8_t* base, dof_sec_t* sec)
{
dtrace_diftype_t* types = (dtrace_diftype_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < (sec->dofs_size / sec->dofs_entsize); i++)
swapu32(types[i].dtdt_size);
return;
}
static void
byteswap_dof_relohdr(uint8_t* base, dof_sec_t* sec)
{
dof_relohdr_t* relohdr = (dof_relohdr_t*)(base + sec->dofs_offset);
swapu32(relohdr->dofr_strtab);
swapu32(relohdr->dofr_relsec);
swapu32(relohdr->dofr_tgtsec);
return;
}
static void
byteswap_dof_optdescs(uint8_t* base, dof_sec_t* sec)
{
dof_optdesc_t* optdescs = (dof_optdesc_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < (sec->dofs_size / sec->dofs_entsize); i++) {
swapu32(optdescs[i].dofo_option);
swapu32(optdescs[i].dofo_strtab);
swapu64(optdescs[i].dofo_value);
}
return;
}
static void
byteswap_dof_provider(uint8_t* base, dof_sec_t* sec)
{
dof_provider_t* provider = (dof_provider_t*)(base + sec->dofs_offset);
swapu32(provider->dofpv_strtab);
swapu32(provider->dofpv_probes);
swapu32(provider->dofpv_prargs);
swapu32(provider->dofpv_proffs);
swapu32(provider->dofpv_name);
swapu32(provider->dofpv_provattr);
swapu32(provider->dofpv_modattr);
swapu32(provider->dofpv_funcattr);
swapu32(provider->dofpv_nameattr);
swapu32(provider->dofpv_argsattr);
swapu32(provider->dofpv_prenoffs);
return;
}
static void
byteswap_dof_probes(uint8_t* base, dof_sec_t* sec)
{
dof_probe_t* probes = (dof_probe_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < sec->dofs_size / sec->dofs_entsize; i++) {
swapu64(probes[i].dofpr_addr);
swapu32(probes[i].dofpr_func);
swapu32(probes[i].dofpr_name);
swapu32(probes[i].dofpr_nargv);
swapu32(probes[i].dofpr_xargv);
swapu32(probes[i].dofpr_argidx);
swapu32(probes[i].dofpr_offidx);
swapu16(probes[i].dofpr_noffs);
swapu32(probes[i].dofpr_enoffidx);
swapu16(probes[i].dofpr_nenoffs);
}
return;
}
static void
byteswap_dof_uint32s(uint8_t* base, dof_sec_t* sec)
{
uint32_t* uint32s = (uint32_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < sec->dofs_size / sizeof(uint32_t); i++)
swapu32(uint32s[i]);
return;
}
static void
byteswap_dof_uint64s(uint8_t* base, dof_sec_t* sec)
{
uint64_t* uint64s = (uint64_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < sec->dofs_size / sizeof(uint64_t); i++)
swapu64(uint64s[i]);
return;
}
static void
byteswap_dof_xlrefs(uint8_t* base, dof_sec_t* sec)
{
dof_xlref_t* xlrefs = (dof_xlref_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < sec->dofs_size / sec->dofs_entsize; i++) {
swapu32(xlrefs[i].dofxr_xlator);
swapu32(xlrefs[i].dofxr_member);
swapu32(xlrefs[i].dofxr_argn);
}
return;
}
static void
byteswap_dof_xlmembers(uint8_t* base, dof_sec_t* sec)
{
dof_xlmember_t* xlmembers = (dof_xlmember_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < sec->dofs_size / sec->dofs_entsize; i++) {
swapu32(xlmembers[i].dofxm_difo);
swapu32(xlmembers[i].dofxm_name);
swapu32(xlmembers[i].dofxm_type.dtdt_size);
}
return;
}
static void
byteswap_dof_xlator(uint8_t* base, dof_sec_t* sec)
{
dof_xlator_t* xlator = (dof_xlator_t*)(base + sec->dofs_offset);
swapu32(xlator->dofxl_members);
swapu32(xlator->dofxl_strtab);
swapu32(xlator->dofxl_argv);
swapu32(xlator->dofxl_argc);
swapu32(xlator->dofxl_type);
swapu32(xlator->dofxl_attr);
return;
}
static void
byteswap_dof_secidxs(uint8_t* base, dof_sec_t* sec)
{
dof_secidx_t* secidxs = (dof_secidx_t*)(base + sec->dofs_offset);
int i;
for(i = 0; i < sec->dofs_size / sizeof(dof_secidx_t); i++)
swapu32(secidxs[i]);
return;
}
static void
byteswap_dof_sec(uint8_t* base, dof_sec_t* sec)
{
#define HANDLE_SEC(sectype, handler) \
case sectype: \
handler(base, sec); \
break;
switch(sec->dofs_type) {
HANDLE_SEC(DOF_SECT_ECBDESC, byteswap_dof_ecbdesc);
HANDLE_SEC(DOF_SECT_PROBEDESC, byteswap_dof_probedesc);
HANDLE_SEC(DOF_SECT_ACTDESC, byteswap_dof_actdescs);
HANDLE_SEC(DOF_SECT_DIFOHDR, byteswap_dof_difohdr);
HANDLE_SEC(DOF_SECT_DIF, byteswap_dof_dif);
HANDLE_SEC(DOF_SECT_VARTAB, byteswap_dof_difvs);
HANDLE_SEC(DOF_SECT_RELTAB, byteswap_dof_relodescs);
HANDLE_SEC(DOF_SECT_TYPTAB, byteswap_dof_diftypes);
HANDLE_SEC(DOF_SECT_URELHDR, byteswap_dof_relohdr);
HANDLE_SEC(DOF_SECT_KRELHDR, byteswap_dof_relohdr);
HANDLE_SEC(DOF_SECT_OPTDESC, byteswap_dof_optdescs);
HANDLE_SEC(DOF_SECT_PROVIDER, byteswap_dof_provider);
HANDLE_SEC(DOF_SECT_PROBES, byteswap_dof_probes);
HANDLE_SEC(DOF_SECT_PROFFS, byteswap_dof_uint32s);
HANDLE_SEC(DOF_SECT_INTTAB, byteswap_dof_uint64s);
HANDLE_SEC(DOF_SECT_XLTAB, byteswap_dof_xlrefs);
HANDLE_SEC(DOF_SECT_XLMEMBERS, byteswap_dof_xlmembers);
HANDLE_SEC(DOF_SECT_XLIMPORT, byteswap_dof_xlator);
HANDLE_SEC(DOF_SECT_XLEXPORT, byteswap_dof_xlator);
HANDLE_SEC(DOF_SECT_PREXPORT, byteswap_dof_secidxs);
case DOF_SECT_NONE:
case DOF_SECT_COMMENTS:
case DOF_SECT_SOURCE:
case DOF_SECT_STRTAB:
case DOF_SECT_UTSNAME:
break;
}
swapu32(sec->dofs_type);
swapu32(sec->dofs_align);
swapu32(sec->dofs_flags);
swapu32(sec->dofs_entsize);
swapu64(sec->dofs_offset);
swapu64(sec->dofs_size);
}
static void
byteswap_dof_hdr(uint8_t* base, dof_hdr_t* hdr)
{
uint32_t i;
dof_sec_t* secs;
secs = (dof_sec_t*)(base + hdr->dofh_secoff);
for(i = 0; i < hdr->dofh_secnum; i++)
byteswap_dof_sec(base, &secs[i]);
hdr->dofh_ident[DOF_ID_ENCODING] = (hdr->dofh_ident[DOF_ID_ENCODING] == DOF_ENCODE_LSB) ? DOF_ENCODE_MSB : DOF_ENCODE_LSB;
swapu32(hdr->dofh_flags);
swapu32(hdr->dofh_hdrsize);
swapu32(hdr->dofh_secsize);
swapu32(hdr->dofh_secnum);
swapu64(hdr->dofh_secoff);
swapu64(hdr->dofh_loadsz);
swapu64(hdr->dofh_filesz);
swapu64(hdr->dofh_pad);
return;
}
void
dtrace_dof_byteswap(dof_hdr_t* hdr)
{
uint8_t* base = (uint8_t*)hdr;
byteswap_dof_hdr(base, hdr);
}
#endif