123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394moduleBind=Xedbindings_bind.Bind(** (expr, file, lineno) for xed_assert failures *)exceptionXedAbortofstring*string*intlet()=Callback.register_exception"XedAbort exception"(XedAbort("XedAbort exception","none",0))let()=letopenstructexternal_init:unit->unit="xb_init"endin_init()includeBind.ConstantsmodulePtr=Bind.Ptrletstring_of_cx=leteos=(tryBytes.index x'\x00'withNot_found-> Bytes.lengthx)inBytes.sub_stringx0eosmoduleEnum=structinclude Bind.Enumopenstructexternal _get_cpuid_rec:int-> int*int*int*int*int*int="xb_get_cpuid_rec"endletoperand_action_readx=operand_action_readx<>0letoperand_action_read_onlyx=operand_action_read_onlyx<>0letoperand_action_writtenx=operand_action_writtenx<>0letoperand_action_written_only x=operand_action_written_only x<>0let operand_action_read_and_written x=operand_action_read_and_written x<>0letoperand_action_conditional_read x=operand_action_conditional_read x<>0letoperand_action_conditional_writex=operand_action_conditional_write x<>0letoperand_is_register x=operand_is_register x<>0letoperand_is_memory_addressing_register x=operand_is_memory_addressing_register x<>0let register_width_bitsx=register_width_bitsx|>Unsigned.UInt32.to_intletregister_width_bits64x=register_width_bits64x|>Unsigned.UInt32.to_intletiform_max_per_iclass x=iform_max_per_iclass x|>Unsigned.UInt32.to_intletiform_first_per_iclass x=iform_first_per_iclass x|>Unsigned.UInt32.to_inttypeiform_map ={category:category;extension:extension;iclass:iclass;isa_set:isa_set;string_table_idx:int;}externaliform_map:iform->iform_map="xb_iform_map"letattributes=Array.init(Bind.xed_attribute_max ())Bind.xed_attributetypecpuid_bit_rec ={leaf:int;subleaf:int;reg:reg;bit_start:int;bit_end:int;value:int;}letcpuid_bit_recx=letleaf,subleaf,reg,bit_start,bit_end,value=_get_cpuid_rec@@cpuid_rec_to_intxin{leaf;subleaf;reg=reg_of_intreg;bit_start;bit_end;value}letcpuid_groups_of_isa_setisa_set:cpuid_grouplist=letrecfisa_setli=ifi<0thenlelsematchcpuid_group_enum_for_isa_setisa_setiwith|INVALID ->fisa_set l(i-1)|x->fisa_set (x::l)(i-1)infisa_set [](max_cpuid_groups_per_isa_set -1)letcpuid_recs_of_cpuid_group cpuid_group :cpuid_reclist=letrecfcpuid_group li=ifi<0thenlelsematchcpuid_group_cpuid_rec_enum_for_groupcpuid_groupiwith|INVALID->fcpuid_groupl(i-1)|x->fcpuid_group (x::l)(i-1)infcpuid_group[](max_cpuid_recs_per_group -1)(** Like `cpuid_groups_of_isa_set x |> List.map cpuid_recs_of_cpuid_group`
except there will be noduplicates.*)letcpuid_recs_of_isa_setisa_set:cpuid_reclist=(* Fill a bitset with the cpuid_recs *)letwords=(cpuid_rec_len +Sys.int_size -1)/Sys.int_sizeinletarr=Array.makewords 0infori=0tomax_cpuid_groups_per_isa_set-1domatch cpuid_group_enum_for_isa_set isa_setiwith|INVALID ->()|group ->forj=0tomax_cpuid_recs_per_group -1domatchcpuid_group_cpuid_rec_enum_for_group groupjwith|INVALID->()|cpuid_rec->letidx=cpuid_rec_to_intcpuid_recinletword=Array.getarr(idx/Sys.int_size)inletword=wordlor(1lsl(idxmodSys.int_size))inArray.setarr(idx /Sys.int_size)worddonedone;(* Reverse iterate through each word of the bitset to buildoutput list;
this means the output list happens to be in sorted order. *)letrecfarrijl=ifi<0thenlelseletrecgwordijl=ifj<0thenlelsegwordi(j-1)(if(word lsr j)land1<>0thencpuid_rec_of_int(i*Sys.int_size+j)::lelsel)infarr (i-1)(Sys.int_size-1)@@g(Array.getarri)ijlinfarr(words-1)(Sys.int_size-(words*Sys.int_size-cpuid_rec_len)-1)[]endmoduleChipFeatures =structinclude Bind.ChipFeaturesletof_chip chip=letx=uninit()inget_chip_featuresxchip;xletaddxisa=modify_chip_featuresxisatrueletremove xisa=modify_chip_features xisafalseendmodule FlagDFV=structtypet={dfv_of:bool;dfv_sf:bool;dfv_zf:bool;dfv_cf:bool}letto_intx=(ifx.dfv_ofthen1else0)+(ifx.dfv_sfthen2else0)+(ifx.dfv_zfthen4else0)+(ifx.dfv_cfthen8else0)letof_intz={dfv_of=zland1<>0;dfv_sf=zland2<>0;dfv_zf =zland4<>0;dfv_cf =zland8<>0}endmoduleDecodedInst =structincludeBind.DecodedInstopenstructexternal_decoded_inst_get_attributes:nativeint->Enum.attributelist="xb_decoded_inst_get_attributes"typesymbolizer=(int64->(string*int64)option)optionexternal_format:int->nativeint->int64->int ->symbolizer->string="xb_format"endlet get_attributes (x:[>`Read]t):Enum.attribute list=_decoded_inst_get_attributes @@Ptr.raw_address xletinitmode=letx=uninit()inzero_set_mode xmode;xletdumpx=letbytes =Bytes.create 4000indumpxbytes;string_of_c bytesletdump_xed_format xaddr=letbytes =Bytes.create1000inmatchdump_xed_formatxbytesaddrwith|true->string_of_cbytes|false->failwith"xed_decoded_inst_dump_xed_format"(** As with the XED C library, running this more than once without using one of the `zero_`functions first will result in an error.
Note that for basic usage, you can (and should) use Xed.decode to both
`init`& `decode` at the same time.
*)letdecodex?features s=beginmatchfeatureswith|None->Bind.xed_decodexs|Somef->Bind.xed_decode_with_featuresxsfend|>function|Enum.NONE->Okx|err->Errorerrletild_decodexs=matchBind.xed_ild_decodexswith|Enum.NONE->Okx|err->Errorerr(* Disable get_byte because it's a use-after-free and you get random heap bytes.
* (A xed_decoded_inst_t only keeps the pointer passed to xed_decode, not the * actual input bytes. Luckily, no other decoded-inst-api methods use it.) *)letget_byte=()(* let get_bytes x =
String.init (get_length x) (get_byte x) *)letget_attributexy=get_attributexy<>Unsigned.UInt32.zeroletget_immediate_is_signedx=get_immediate_is_signedx<>0lethas_mpx_prefixx=has_mpx_prefixx<>Unsigned.UInt32.zeroletis_xacquirex=is_xacquirex<>Unsigned.UInt32.zeroletis_xreleasex=is_xreleasex<>Unsigned.UInt32.zeroletget_operand_width x=get_operand_widthx|>Unsigned.UInt32.to_int(**
@param symbolizer callback function to turn an address into a name & offset.
*)letformat?(address_with_names=true)?(xml_a=false)?(xml_f=false)?(omit_unit_scale=false)?(no_ext_signed_imm=false)?(curly_mask_omit_k0=true)?(lowercase_hex=true)?(positive_mem_disp=false)?(syntax=Enum.INTEL)?(symbolizer:symbolizer)(x:[>`Read]t)addr=letoptions=0lor(ifaddress_with_names then1lsl0else0)lor(ifxml_athen1lsl1else 0)lor(ifxml_fthen1lsl2else0)lor (ifomit_unit_scalethen1lsl3else0)lor(ifno_ext_signed_immthen1lsl4else0)lor(ifcurly_mask_omit_k0then 1lsl5else0)lor(iflowercase_hexthen1lsl6else0)lor(ifpositive_mem_dispthen1lsl7else0)in_format(Enum.syntax_to_intsyntax)(Ptr.raw_addressx)addroptionssymbolizer(**
It's undefined exactly what format you get from to_string.
Currently, it assumes address 0 and formats in intel syntax.
*)letto_stringx=formatx0Llet get_default_flags_valuesx=letmoduleTypes=Bind.Typesinlety=Types.Ptr.rw@@Ctypes.allocate_n~count:1Types.flag_dfvinifnot@@Bind.DecodedInst.get_default_flags_values xythen NoneelseCtypes.(!@)(Ctypes.coerceTypes.flag_dfv_ptrCtypes.(ptruint8_t)y)|>Unsigned.UInt8.to_int|>FlagDFV.of_int|>Option.someendmoduleEncoderRequest=structinclude Bind.EncoderRequestopenstructexternal_encode:nativeint->(int*string)="xb_encode"external_init_from_decode:nativeint->nativeint->unit="xb_encoder_request_init_from_decode"endletencode(x:[>`Read]t)=let err,dat=_encode@@Ptr.raw_addressxinmatchEnum.error_of_interrwith|Enum.NONE->Okdat|err->Errorerrletinit mode=letx=uninit ()inzero_set_modexmode;xletof_decoded_inst (y:[>`Read]Bind.DecodedInst.t)=letx=uninit()in_init_from_decode(Ptr.raw_addressx)(Ptr.raw_addressy);xletto_stringx=letbytes=Bytes.create5000inBind.xed_encode_request_printxbytes;matchBytes.index_optbytes'\000'with|Somei->Bytes.sub_stringbytes0i|None->Bytes.unsafe_to_stringbytesendmoduleFlagAction=structincludeBind.FlagActionletto_string x=letbytes=Bytes.create100inprintxbytes |>Bytes.sub_stringbytes0endmoduleFlagSet=structincludeBind.FlagSetletto_stringx=letbytes =Bytes.create100inprint xbytes |>Bytes.sub_stringbytes0endmoduleInst=structincludeBind.Instopenstructexternal _inst_get_attributes :nativeint ->Enum.attributelist="xb_inst_get_attributes"endletget_attributes (x:[>`Read]t):Enum.attribute list =_inst_get_attributes(Ptr.raw_addressx)letget_attributexy=get_attribute xy<>Unsigned.UInt32.zeroletflag_info_indexx=flag_info_indexx|>Unsigned.UInt32.to_intletfold_left_operands inst~init~f=letacc =ref initinfori=0tonoperandsinst-1doacc:=fi!acc@@operand instidone;!accletfold_right_operands inst~f~init =letacc=refinitinfori=noperandsinst-1downto0doacc:=fi(operandinsti)!accdone;!accendmoduleOperand=structincludeBind.Operandletreadx=readx<>0letread_onlyx=read_onlyx<>0letwrittenx=writtenx<>0letwritten_onlyx=written_onlyx<>0letread_and_writtenx=read_and_writtenx<>0letconditional_readx=conditional_read x<>0letconditional_write x=conditional_writex<>0lettemplate_is_register x=template_is_registerx<>0letwidth_bitsxeosz=leteosz=matcheoszwith|`B16->1|`B32->2|`B64->3inwidth_bitsx(Unsigned.UInt32.of_inteosz)|>Unsigned.UInt32.to_intendmoduleOperand3=structincludeBind.Operand3letget_has_modrm x=get_has_modrm x<>0letset_has_modrm xb=set_has_modrm x(ifbthen 1else0)letget_has_sib x=get_has_sib x<>0letset_has_sib xb=set_has_sib x(ifbthen1else0)endmoduleOperandValues =structincludeBind.OperandValueslet dump x=letbytes=Bytes.create100indumpxbytes;string_of_c bytesletto_stringx=letbytes=Bytes.create 100inprint_shortxbytes;string_of_c bytesletget_immediate_is_signed x=get_immediate_is_signed x<>0letget_branch_displacement_lengthx=get_branch_displacement_lengthx|>Unsigned.UInt32.to_intletget_branch_displacement_length_bits x=get_branch_displacement_length_bitsx|>Unsigned.UInt32.to_intletget_effective_address_width x=get_effective_address_width x|>Unsigned.UInt32.to_intletget_effective_operand_width x=get_effective_operand_width x|>Unsigned.UInt32.to_intletget_memory_displacement_lengthx=get_memory_displacement_length x|>Unsigned.UInt32.to_intlet get_memory_displacement_length_bits x=get_memory_displacement_length_bits x|>Unsigned.UInt32.to_intletget_memory_displacement_length_bits_rawx=get_memory_displacement_length_bits_raw x|>Unsigned.UInt32.to_intletget_stack_address_widthx=get_stack_address_widthx|>Unsigned.UInt32.to_intendmoduleSimpleFlag=structincludeBind.SimpleFlagletto_stringx=letbytes=Bytes.create100inprintxbytes|>Bytes.sub_string bytes0endmoduleState=structinclude Bind.Stateletto_stringx=letbytes=Bytes.create100inprintxbytes|>Bytes.sub_stringbytes 0endletstate32=State.init2Enum.LEGACY_32Enum.A32b|>Ptr.constletstate64=State.init2Enum.LONG_64Enum.A64b|>Ptr.constletdecodestate?featuress=DecodedInst.decode(DecodedInst.initstate)?featuressletild_decodestates=DecodedInst.ild_decode(DecodedInst.initstate)sletdecode_lengthstates=Result.mapDecodedInst.get_length@@ild_decodestatesletencode_nop len=letbytes=Bytes.createleninmatchBind.xed_encode_nopbyteswith|Enum.NONE->Okbytes|err->Errorerrletget_copyright =Bind.xed_get_copyrightletget_version =Bind.xed_get_versionletset_verbosity =Bind.xed_set_verbosityletok_exn=functionOkx->x|Errore->failwith (Enum.error_to_stringe)letoperand_to_string(di:[>`Read]DecodedInst.t)(op:int)=letbytes=Bytes.create 100inBind.xed_operand_printdiopbytes;string_of_cbytes