123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385moduleBind=Xedbindings_bind.Bindlet()=Bind.xed_tables_init ()includeBind.ConstantsmodulePtr=Bind.Ptrletstring_of_cx=leteos=(tryBytes.indexx'\x00'withNot_found->Bytes.lengthx)inBytes.sub_stringx0eosmoduleEnum=structincludeBind.Enumopenstructexternal_get_cpuid_rec:int->int*int*int*int*int*int="xb_get_cpuid_rec"endletoperand_action_read x=operand_action_read x<>0letoperand_action_read_only x=operand_action_read_only x<>0letoperand_action_writtenx=operand_action_writtenx<>0letoperand_action_written_onlyx=operand_action_written_only x<>0letoperand_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_writex<>0letoperand_is_register x=operand_is_registerx<>0letoperand_is_memory_addressing_register x=operand_is_memory_addressing_register x<>0letregister_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_iclassx|>Unsigned.UInt32.to_intletattributes =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_rec x=let leaf,subleaf,reg,bit_start,bit_end,value=_get_cpuid_rec@@cpuid_rec_to_intxin{leaf;subleaf;reg=reg_of_int reg;bit_start;bit_end;value}letcpuid_groups_of_isa_setisa_set:cpuid_group list=letrecfisa_setli=ifi<0then lelsematchcpuid_group_enum_for_isa_set isa_set iwith|INVALID ->fisa_setl(i-1)|x->fisa_set(x::l)(i-1)infisa_set[](max_cpuid_groups_per_isa_set-1)letcpuid_recs_of_cpuid_groupcpuid_group:cpuid_reclist=letrecfcpuid_groupli=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 no duplicates.*)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_size inletarr =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_groupgroupjwith|INVALID ->()|cpuid_rec ->let idx=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 througheach word of the bitset to build output list;
this means the outputlist happens to be in sorted order. *)letrecfarrijl=ifi<0thenlelseletrecgwordijl=ifj<0thenlelsegwordi(j-1)(if(wordlsrj)land1<>0thencpuid_rec_of_int(i*Sys.int_size+j)::lelse l)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=structincludeBind.ChipFeaturesletof_chipchip=let x=uninit ()inget_chip_features xchip;xletaddxisa=modify_chip_featuresxisatrueletremovexisa=modify_chip_features xisafalseendmoduleDecodedInst=structincludeBind.DecodedInstopen structexternal_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"endletget_attributes(x:[>`Read]t):Enum.attribute list=_decoded_inst_get_attributes@@Ptr.raw_addressxletinitmode=letx=uninit()inzero_set_modexmode;xletdumpx=letbytes=Bytes.create4000indumpxbytes;string_of_cbytesletdump_xed_formatxaddr=letbytes=Bytes.create1000inmatchdump_xed_formatxbytesaddrwith|true->string_of_c bytes|false->failwith"xed_decoded_inst_dump_xed_format"(** As with the XED C library, running this more than once withoutusing one
of the `zero_` functions firstwill result in an error.
Note that for basic usage, you can (and should) useXed.decode to both
`init` & `decode` at thesame time.
*)letdecodex?featuress=beginmatchfeatureswith|None->Bind.xed_decodexs|Somef->Bind.xed_decode_with_features xsfend|>function|Enum.NONE->Ok x|err->Errorerrletild_decode xs=matchBind.xed_ild_decodexswith|Enum.NONE->Okx|err->Errorerr(* Disable get_byte because it's ause-after-freeand 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_attribute xy<>Unsigned.UInt32.zeroletget_immediate_is_signed x=get_immediate_is_signed x<>0lethas_mpx_prefix x=has_mpx_prefix x<>Unsigned.UInt32.zerolet is_xacquirex=is_xacquire x<>Unsigned.UInt32.zerolet is_xreleasex=is_xrelease x<>Unsigned.UInt32.zeroletget_operand_widthx=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=let options=0lor(ifaddress_with_names then1lsl0else0)lor(ifxml_athen1lsl1else0)lor (ifxml_fthen1lsl2else0)lor(ifomit_unit_scale then1lsl 3else0)lor(ifno_ext_signed_imm then1lsl4else0)lor(ifcurly_mask_omit_k0 then1lsl5else0)lor(iflowercase_hexthen1lsl6else0)lor(ifpositive_mem_disp then1lsl7else0)in_format(Enum.syntax_to_int syntax)(Ptr.raw_address x)addroptionssymbolizer(**
It's undefined exactly what format you get from to_string.
Currently, it assumes address 0 and formats in intel syntax.
*)letto_stringx=formatx0LendmoduleEncoderRequest=structincludeBind.EncoderRequestopenstructexternal_encode :nativeint->(int*string)="xb_encode"external _init_from_decode:nativeint->nativeint->unit ="xb_encoder_request_init_from_decode"endletencode(x:[>`Read]t)=leterr,dat=_encode@@Ptr.raw_addressxinmatchEnum.error_of_interrwith|Enum.NONE->Okdat|err->Errorerrletinitmode=let x=uninit()inzero_set_mode xmode;xlet of_decoded_inst (y:[>`Read]Bind.DecodedInst.t)=letx=uninit()in_init_from_decode(Ptr.raw_addressx)(Ptr.raw_address y);xletto_string x=letbytes =Bytes.create5000inBind.xed_encode_request_printxbytes;matchBytes.index_optbytes'\000' with|Somei->Bytes.sub_string bytes0i|None->Bytes.unsafe_to_stringbytesendmoduleFlagAction=structinclude Bind.FlagActionletto_string x=letbytes=Bytes.create100inprint xbytes|>Bytes.sub_stringbytes0endmodule FlagSet=structincludeBind.FlagSetletto_string x=letbytes=Bytes.create100inprintxbytes |>Bytes.sub_stringbytes0endmoduleFlagDFV=structtypet={dfv_of:bool;dfv_sf:bool;dfv_zf:bool;dfv_cf:bool}letflatx=(ifx.dfv_ofthen1else0)+(ifx.dfv_sfthen2else0)+(ifx.dfv_zfthen4else 0)+(ifx.dfv_cf then8else0)letget_default_flags_valuesx=letmoduleTypes=Bind.Typesinlety=Types.Ptr.rw@@Ctypes.allocate_n~count:1Types.flag_dfvinifnot@@Bind.xed_flag_dfv_get_default_flags_valuesxythenNoneelseletz=Ctypes.(!@)(Ctypes.coerceTypes.flag_dfv_ptrCtypes.(ptruint8_t)y)|>Unsigned.UInt8.to_intinSome{dfv_of =zland1<>0;dfv_sf=zland2<>0;dfv_zf=zland4<>0;dfv_cf=zland8<>0;}endmoduleInst=structinclude Bind.Instopenstructexternal _inst_get_attributes :nativeint ->Enum.attribute list="xb_inst_get_attributes"endletget_attributes(x:[>`Read]t):Enum.attribute list=_inst_get_attributes (Ptr.raw_address x)letget_attribute xy=get_attribute xy<>Unsigned.UInt32.zerolet flag_info_index x=flag_info_index x|>Unsigned.UInt32.to_intletfold_left_operandsinst~init ~f=letacc=refinitinfori=0tonoperandsinst -1doacc:=fi!acc@@operand instidone;!accletfold_right_operandsinst~f~init=letacc=refinit infori=noperandsinst-1downto0doacc:=fi(operandinsti)!accdone;!accendmoduleOperand=structincludeBind.Operandletto_stringx=letbytes=Bytes.create 100inprintxbytes;string_of_cbytesletreadx=readx<>0letread_onlyx=read_onlyx<>0letwrittenx=written x<>0letwritten_onlyx=written_onlyx<>0letread_and_writtenx=read_and_writtenx<>0letconditional_read x=conditional_read x<>0letconditional_writex=conditional_write x<>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=structinclude Bind.Operand3letget_has_modrm x=get_has_modrm x<>0letset_has_modrmxb=set_has_modrmx(ifbthen1else0)letget_has_sib x=get_has_sib x<>0letset_has_sibxb=set_has_sibx(ifbthen1else0)endmoduleOperandValues=structinclude Bind.OperandValuesletdumpx=letbytes=Bytes.create100indumpxbytes;string_of_c bytesletto_stringx=letbytes=Bytes.create100inprint_shortxbytes;string_of_cbytesletget_immediate_is_signedx=get_immediate_is_signedx<>0letget_branch_displacement_lengthx=get_branch_displacement_length x|>Unsigned.UInt32.to_intletget_branch_displacement_length_bitsx=get_branch_displacement_length_bitsx|>Unsigned.UInt32.to_intletget_effective_address_widthx=get_effective_address_width x|>Unsigned.UInt32.to_intletget_effective_operand_widthx=get_effective_operand_width x|>Unsigned.UInt32.to_intletget_memory_displacement_lengthx=get_memory_displacement_lengthx|>Unsigned.UInt32.to_intletget_memory_displacement_length_bits x=get_memory_displacement_length_bitsx|>Unsigned.UInt32.to_intletget_memory_displacement_length_bits_raw x=get_memory_displacement_length_bits_raw x|>Unsigned.UInt32.to_intletget_stack_address_widthx=get_stack_address_width x|>Unsigned.UInt32.to_intendmoduleSimpleFlag=structinclude Bind.SimpleFlagletto_string x=letbytes =Bytes.create100inprintxbytes|>Bytes.sub_string bytes0endmoduleState=structincludeBind.Stateletto_string x=let bytes =Bytes.create100inprintxbytes|>Bytes.sub_stringbytes0endmoduleEnc=structincludeBind.Encendletstate32=State.init2Enum.LEGACY_32Enum.A32b|>Ptr.constletstate64=State.init2Enum.LONG_64Enum.A64b|>Ptr.constletdecodestate?featuress=DecodedInst.decode(DecodedInst.initstate)?features sletild_decode states=DecodedInst.ild_decode (DecodedInst.initstate)sletdecode_lengthstates=Result.mapDecodedInst.get_length@@ild_decodestatesletencode_noplen=letbytes=Bytes.createleninmatchBind.xed_encode_nopbyteswith|Enum.NONE->Okbytes|err->Error errletget_copyright=Bind.xed_get_copyrightletget_version=Bind.xed_get_versionletset_verbosity=Bind.xed_set_verbosityletok_exn=functionOkx->x|Errore->failwith(Enum.error_to_stringe)