#line 1 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 61 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .type input_reg <: symbol #line 68 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .type reg_nullable <: symbol #line 76 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .type register <: reg_nullable .type address <: unsigned .type operand_code <: unsigned .type operand_index <: unsigned #line 83 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "binary/elf/elf_binaries.dl" #line 24 "binary/elf/elf_binaries.dl" #line 1 "exceptions.dl" #line 32 "exceptions.dl" .decl cie_entry(CieAddr: address,Length:unsigned,CodeAlignmentFactor:unsigned,DataAlignmentFactor:number) .input cie_entry #line 39 "exceptions.dl" .decl cie_encoding(CieAddr: address,FdeEncoding:unsigned,LsdaEncoding:unsigned) .input cie_encoding #line 46 "exceptions.dl" .decl cie_personality(CieAddr:address,Personality:address,PersonalityPos:address,PersonalitySize:unsigned,Encoding:unsigned) .input cie_personality #line 55 "exceptions.dl" .decl fde_entry(FdeAddr: address,Length:unsigned,Cie:address,Start:address,End:address,Lsda:address) .input fde_entry #line 62 "exceptions.dl" .decl fde_pointer_locations(addr:address,startLocation:address,endLocation:address, endSize:unsigned,lsdaLocation:address,lsdaSize:unsigned) .input fde_pointer_locations #line 80 "exceptions.dl" .decl fde_instruction(FdeAddr:address,Index:unsigned,Size:unsigned,InsnAddr:address,Insn:symbol,Op1:number,Op2:number) .input fde_instruction #line 88 "exceptions.dl" .decl lsda(lsdaAddress:address,callsiteTable:address,callsiteTableEncoding:unsigned,callSiteTableLength:unsigned, typeTable:address,typeTableEncoding:unsigned,landingPadBaseAddress: address) .input lsda #line 95 "exceptions.dl" .decl lsda_pointer_locations(lsdaAddress:address,typeTablePointerLocation:address,callsiteTablePointerLoc:address) .input lsda_pointer_locations #line 104 "exceptions.dl" .decl lsda_callsite(CallSiteTable_address:address,EA_start:address,Start:address, EA_end:address,End:address, EA_landingPad:address,LandingPad:address,EA_endLandindPad:address) .input lsda_callsite #line 116 "exceptions.dl" .decl lsda_type_entry(lsdaTypeTableAddress:address,index:unsigned,address:address) .input lsda_type_entry #line 129 "exceptions.dl" .decl cfi_directive(BlockAddress:address,Offset:unsigned,LocalIndex:unsigned, directive:symbol,ReferenceSym:symbol,Nargs:unsigned,arg1:number,arg2:number) .output cfi_directive #line 136 "exceptions.dl" .decl symbol_special_encoding(EA:address,encoding:symbol) .output symbol_special_encoding .decl fde_addresses(start:address, end:address) .output fde_addresses fde_addresses(Start,End):- fde_entry(_,_,_,Start,End,_). .decl fde_block_addresses(FdeAddr:address,StartAddr:address,EndAddr:address) fde_block_addresses(FdeAddr,Start,EndAddr):- fde_entry(FdeAddr,_,_,Start,EndAddr,_), refined_block(Start), block_information(_,_,EndAddr). fde_block_addresses(FdeAddr,Start,EndBlock):- fde_entry(FdeAddr,_,_,Start,EndAddr,_), refined_block(Start), !block_information(_,_,EndAddr), after_end(EndAddr,End), refined_block_last_instruction(Block,End), block_information(Block,_,EndBlock). .decl lsda_callsite_addresses(Start:address,End:address,LandingPad:address) lsda_callsite_addresses(Start,End,LandingPad):- lsda_callsite(_,_,Start,_,End,_,LandingPad,_). labeled_ea(Lsda):- fde_entry(_,_,_,_,_,Lsda), Lsda != 0. labeled_ea(Personality):- cie_personality(_,Personality,_,_,_), Personality != 0. symbol_special_encoding(TypeTablePointerLocation,"uleb128"), symbol_minus_symbol(TypeTablePointerLocation,Size,CallsiteTablePointerLoc-1,LsdaTypeTableAddress,1,0):- lsda_pointer_locations(Lsda,TypeTablePointerLocation,CallsiteTablePointerLoc), lsda(Lsda,_,_,_,LsdaTypeTableAddress, _, _), LsdaTypeTableAddress != 0, Size = (CallsiteTablePointerLoc-1) - TypeTablePointerLocation, Size > 0. symbol_special_encoding(CallsiteTablePointerLoc,"uleb128"), symbol_minus_symbol(CallsiteTablePointerLoc,Size,CallSiteTable_address,CallSiteTable_address+CallSiteTableLength,1,0):- lsda_pointer_locations(Lsda,_,CallsiteTablePointerLoc), lsda(Lsda,CallSiteTable_address,_,CallSiteTableLength,_, _, _), Size = CallSiteTable_address - CallsiteTablePointerLoc, Size > 0. symbol_special_encoding(EA_start,EncodingName), symbol_special_encoding(EA_end,EncodingName), symbol_special_encoding(EA_landingPad,EncodingName):- lsda_callsite(CallSiteTable_address,EA_start,_,EA_end,_,EA_landingPad,_,_), lsda(_,CallSiteTable_address,CallSiteEncoding,_,_,_,_), special_encoding(Encoding,EncodingName), CallSiteEncoding band 0xF = Encoding. symbol_minus_symbol(EA_start,Size,LandingPadBaseAddress,StartRegion,1,0):- lsda_callsite(CallSiteTable_address, EA_start, StartRegion,EA_end,_,_,_,_), lsda(_,CallSiteTable_address,_,_,_,_,LandingPadBaseAddress), Size = EA_end-EA_start, Size > 0. boundary_sym_expr(EA_end,EndRegion), symbol_minus_symbol(EA_end,Size,StartRegion,EndRegion,1,0):- lsda_callsite(_, _, StartRegion,EA_end,EndRegion,EA_landingPad,_,_), Size = EA_landingPad-EA_end, Size > 0, block_boundaries(_,_,EndRegion). symbol_minus_symbol(EA_landingPad,Size,LandingPadBaseAddress,LandingPad,1,0):- lsda_callsite(CallSiteTable_address, _, _,_,_,EA_landingPad,LandingPad,EA_endLandingPad), lsda(_,CallSiteTable_address,_,_,_,_,LandingPadBaseAddress), LandingPad != 0, Size = EA_endLandingPad-EA_landingPad, Size > 0. symbolic_data(EAType,EncodingSize,Type):- lsda_type_entry(LsdaTypeTableAddress, Index,Type), lsda(_,_,_,_,LsdaTypeTableAddress, TypeTableEncoding, _), TypeTableEncoding band 0xF = Encoding, TypeTableEncoding band 0x10 = 0, dwarf_encoding_size(Encoding,EncodingSize), EAType=LsdaTypeTableAddress-(EncodingSize*(Index+1)), Type != 0. symbol_minus_symbol(EAType,EncodingSize,EAType,Type,1,0):- lsda_type_entry(LsdaTypeTableAddress, Index,Type), lsda(_,_,_,_,LsdaTypeTableAddress, TypeTableEncoding, _), TypeTableEncoding band 0xF = Encoding, TypeTableEncoding band 0x10 > 0, dwarf_encoding_size(Encoding,EncodingSize), EAType=LsdaTypeTableAddress-(EncodingSize*(Index+1)), Type != 0. symbol_minus_symbol(Addr,4,Addr+4,Addr+Length+4,1,0):- option("no-cfi-directives"), cie_entry(Addr,Length,_,_). symbol_special_encoding(PersonalityPos,EncodingName):- option("no-cfi-directives"), cie_personality(_,Personality,PersonalityPos,_,PersonalityEncoding), Personality != 0, special_encoding(Encoding,EncodingName), PersonalityEncoding band 0xF = Encoding. symbolic_data(PersonalityPos,Size,Personality):- option("no-cfi-directives"), cie_personality(_,Personality,PersonalityPos,Size,_), Personality != 0. symbol_minus_symbol(Addr,4,Addr+4,Addr+Length+4,1,0):- option("no-cfi-directives"), fde_entry(Addr,Length,_,_,_,_), !last_fde(Addr). symbol_minus_symbol(Addr,4,Addr+4,EndSection,1,0):- option("no-cfi-directives"), fde_entry(Addr,_,_, _, _,_), last_fde(Addr), loaded_section(_,EndSection,".eh_frame"). symbol_minus_symbol(Addr+4,4,Cie,Addr+4,1,0):- option("no-cfi-directives"), fde_entry(Addr,_,Cie, _, _,_). symbol_special_encoding(StartLocation,EncodingName), symbol_special_encoding(EndLocation,EncodingName):- option("no-cfi-directives"), fde_pointer_locations(Addr,StartLocation,EndLocation,_,_,_), fde_entry(Addr,_,Cie,_,_,_), cie_encoding(Cie,FdeEncoding,_), special_encoding(Encoding,EncodingName), FdeEncoding band 0xF = Encoding. symbolic_data(StartLocation,EndLocation-StartLocation,StartFunction):- option("no-cfi-directives"), fde_entry(Addr,_,Cie, StartFunction, _,_), cie_encoding(Cie,FdeEncoding,_), FdeEncoding band 0x10 = 0, fde_pointer_locations(Addr,StartLocation,EndLocation, _,_,_). symbol_minus_symbol(StartLocation,EndLocation-StartLocation,StartLocation,StartFunction,1,0):- option("no-cfi-directives"), fde_entry(Addr,_,Cie, StartFunction, _,_), cie_encoding(Cie,FdeEncoding,_), FdeEncoding band 0x10 > 0, fde_pointer_locations(Addr,StartLocation,EndLocation, _,_,_), EndLocation-StartLocation > 0. symbol_minus_symbol(EndLocation,EndSize,StartFunction,EndFunction,1,0):- option("no-cfi-directives"), fde_entry(Addr,_,_, StartFunction, EndFunction,_), fde_pointer_locations(Addr,_,EndLocation, EndSize,_,_), EndSize > 0. symbol_special_encoding(LsdaLocation,EncodingName):- option("no-cfi-directives"), fde_pointer_locations(Addr,_,_, _,LsdaLocation,_), fde_entry(Addr,_,Cie, _, _,_), cie_encoding(Cie,_,LsdaEncoding), special_encoding(Encoding,EncodingName), LsdaEncoding band 0xF = Encoding. symbolic_data(LsdaLocation,LsdaSize,LsdaAddress):- option("no-cfi-directives"), fde_entry(Addr,_,Cie, _, _,LsdaAddress), fde_pointer_locations(Addr,_,_, _,LsdaLocation,LsdaSize), LsdaSize > 0, cie_encoding(Cie,_,LsdaEncoding), LsdaEncoding band 0x10 = 0. symbol_minus_symbol(LsdaLocation,LsdaSize,LsdaLocation,LsdaAddress,1,0):- option("no-cfi-directives"), fde_entry(Addr,_,Cie, _, _,LsdaAddress), fde_pointer_locations(Addr,_,_, _,LsdaLocation,LsdaSize), LsdaSize > 0, cie_encoding(Cie,_,LsdaEncoding), LsdaEncoding band 0x10 > 0. symbol_minus_symbol(InstructionAddr+1,Size-1,Addr+(AdvanceUnsigned*CodeAlignmentFactor),Addr,CodeAlignmentFactor,0):- option("no-cfi-directives"), fde_instruction(FdeAddr,Index,Size,InstructionAddr,"advance_loc",Advance,_), AdvanceUnsigned = as(Advance,unsigned), Size > 1, fde_instruction_ref(FdeAddr,Index,_,Addr), fde_entry(FdeAddr,_,Cie,_,_,_), cie_entry(Cie,_,CodeAlignmentFactor,_). .decl special_encoding(Code:unsigned,Name:symbol) special_encoding(1,"uleb128"). special_encoding(9,"sleb128"). .decl dwarf_encoding_size(Encoding:unsigned,Size:unsigned) dwarf_encoding_size(0,4). dwarf_encoding_size(2,2). dwarf_encoding_size(3,4). dwarf_encoding_size(4,8). dwarf_encoding_size(10,2). dwarf_encoding_size(11,4). dwarf_encoding_size(12,8). .decl last_fde(Addr:address) last_fde(Addr):- fde_entry(Addr,Length,_, _, _,_), !fde_entry(Addr+Length+4,_,_, _, _,_), !cie_entry(Addr+Length+4,_,_,_). .decl last_fde_instruction(FdeAddr:address,Index:unsigned) last_fde_instruction(FdeAddr,Index+1):- fde_instruction(FdeAddr,Index,_,_,_,_,_), !fde_instruction(FdeAddr,Index+1,_,_,_,_,_). .decl fde_instruction_ref(FdeAddr:address,Index:unsigned,LocalIndex:unsigned,ReferenceAddr:address) fde_instruction_ref(FdeAddr,0,3,StartFunction):- fde_entry(FdeAddr,_, _,StartFunction,_,_). fde_instruction_ref(FdeAddr,Index+1,NextLocalIndex,Addr):- fde_instruction_ref(FdeAddr,Index,LocalIndex,Addr), fde_instruction(FdeAddr,Index,_,_,Insn,_,_), Insn != "advance_loc", Insn != "cf_advance_loc", ( Insn = "nop", NextLocalIndex = LocalIndex ; Insn != "nop", NextLocalIndex = LocalIndex+1 ). fde_instruction_ref(FdeAddr,Index+1,0,Addr+(CodeAlignmentFactor*as(Advance,unsigned))):- fde_instruction_ref(FdeAddr,Index,_,Addr), fde_entry(FdeAddr,_,Cie,_,_,_), cie_entry(Cie,_,CodeAlignmentFactor,_), ( fde_instruction(FdeAddr,Index,_,_,"advance_loc",Advance,_); fde_instruction(FdeAddr,Index,_,_,"cf_advance_loc",Advance,_) ). .decl endproc_local_index(FdeAddr:address,LocalIndex:unsigned) endproc_local_index(FdeAddr,LocalIndex):- fde_entry(FdeAddr,_, _,_,EndAddr,_), last_fde_instruction(FdeAddr,Index), ( fde_instruction_ref(FdeAddr,Index,LastLocalIndex,Addr), Addr = EndAddr, LocalIndex = LastLocalIndex ; fde_instruction_ref(FdeAddr,Index,_,Addr), Addr != EndAddr, LocalIndex = 0 ). cfi_directive(StartFunction,0,0,".cfi_startproc","",0,0,0), cfi_directive(Block,BlockSize,LastLocalIndex,".cfi_endproc","",0,0,0):- !option("no-cfi-directives"), fde_block_addresses(FdeAddr,StartFunction, EndAddr), block_information(Block,BlockSize,EndAddr), endproc_local_index(FdeAddr,LastLocalIndex). cfi_directive(StartFunction,0,1,".cfi_lsda",LsdaSymbol,1,Encoding,0):- !option("no-cfi-directives"), fde_entry(FdeAddr,_,Cie,StartFunction,_,Lsda), fde_block_addresses(FdeAddr,_,_), cie_encoding(Cie,_,LsdaEncoding), ( Lsda != 0, Encoding = as(LsdaEncoding,number), best_symexpr_symbol(Lsda,LsdaSymbol,"Beg") ; Lsda = 0, Encoding = 255, LsdaSymbol = "", LsdaEncoding = LsdaEncoding ). cfi_directive(StartFunction,0,2,".cfi_personality",PersonalitySymbol,1,Encoding,0):- !option("no-cfi-directives"), fde_entry(FdeAddr,_,Cie,StartFunction,_,_), fde_block_addresses(FdeAddr,_,_), ( cie_personality(Cie,Personality,_,_,PersonalityEncoding), Personality != 0, Encoding = as(PersonalityEncoding,number), best_symexpr_symbol(Personality,PersonalitySymbol,"Beg") ; cie_personality(Cie,Personality,_,_,_), Personality = 0, Encoding = 255, PersonalitySymbol = "" ). cfi_directive(Block,Offset,LocalIndex,CfiInsn,"",NOperands,ScaledOp1,ScaledOp2):- !option("no-cfi-directives"), fde_instruction(FdeAddr,Index,_,_,Insn,Op1,Op2), fde_entry(FdeAddr,_,Cie,_,_,_), fde_block_addresses(FdeAddr,_,EndBlockAddr), dwarf_to_cfi(Insn,NOperands,CfiInsn), cie_entry(Cie,_,_,DataAlignmentFactor), ( !cfi_operand_is_register(Insn,1), ScaledOp1 = Op1*DataAlignmentFactor ; cfi_operand_is_register(Insn,1), ScaledOp1 = Op1 ), ( !cfi_operand_is_register(Insn,2), ScaledOp2 = Op2*DataAlignmentFactor ; cfi_operand_is_register(Insn,2), ScaledOp2 = Op2 ), fde_instruction_ref(FdeAddr,Index,LocalIndex,Addr), ( Addr >= EndBlockAddr, block_information(Block,Offset,EndBlockAddr) ; Addr < EndBlockAddr, code_in_refined_block(Addr,Block), Offset = Addr-Block ). cfi_directive(Block,Offset,LocalIndex,".cfi_escape","",Size,as(InstructionBytesAddr,number),0):- !option("no-cfi-directives"), fde_instruction(FdeAddr,Index,Size,InstructionBytesAddr,"unhandled_instruction",_,_), fde_block_addresses(FdeAddr,_,EndBlockAddr), fde_instruction_ref(FdeAddr,Index,LocalIndex,Addr), ( Addr >= EndBlockAddr, block_information(Block,Offset,EndBlockAddr) ; Addr < EndBlockAddr, code_in_refined_block(Addr,Block), Offset = Addr-Block ). .decl cfi_operand_is_register(Insn:symbol,OpNumber:unsigned) cfi_operand_is_register("def_cfa",1). cfi_operand_is_register("def_cfa",2). cfi_operand_is_register("def_cfa_sf",1). cfi_operand_is_register("def_cfa_offset",1). cfi_operand_is_register("def_cfa_register",1). cfi_operand_is_register("offset",1). cfi_operand_is_register("offset_extended",1). cfi_operand_is_register("offset_extended_sf",1). cfi_operand_is_register("register",1). cfi_operand_is_register("register",2). cfi_operand_is_register("rel_offset",1). cfi_operand_is_register("restore",1). cfi_operand_is_register("restore_extended",1). cfi_operand_is_register("return_column",1). cfi_operand_is_register("same_value",1). cfi_operand_is_register("undefined",1). cfi_operand_is_register("val_offset",1). .decl dwarf_to_cfi(DwarfInsn:symbol,OpNumber:unsigned,CfiInsn:symbol) dwarf_to_cfi("def_cfa",2,".cfi_def_cfa"). dwarf_to_cfi("def_cfa_offset",1,".cfi_def_cfa_offset"). dwarf_to_cfi("def_cfa_offset_sf",1,".cfi_def_cfa_offset"). dwarf_to_cfi("def_cfa_register",1,".cfi_def_cfa_register"). dwarf_to_cfi("def_cfa_sf",2,".cfi_def_cfa"). dwarf_to_cfi("offset",2,".cfi_offset"). dwarf_to_cfi("offset_extended",2,".cfi_offset"). dwarf_to_cfi("offset_extended_sf",2,".cfi_offset"). dwarf_to_cfi("register",2,".cfi_register"). dwarf_to_cfi("remember_state",0,".cfi_remember_state"). dwarf_to_cfi("restore",1,".cfi_restore"). dwarf_to_cfi("restore_extended",1,".cfi_restore"). dwarf_to_cfi("restore_state",0,".cfi_restore_state"). dwarf_to_cfi("same_value",1,".cfi_same_value"). dwarf_to_cfi("undefined",1,".cfi_undefined"). dwarf_to_cfi("val_offset",2,".cfi_val_offset"). dwarf_to_cfi("val_offset_sf",2,".cfi_val_offset"). #line 25 "binary/elf/elf_binaries.dl" #line 1 "relocations.dl" #line 27 "relocations.dl" .decl elf_relocation_size(ISA:symbol,Type:symbol,Size:unsigned) elf_relocation_size("X64", "NONE", 0). elf_relocation_size("X64", "R64", 64). elf_relocation_size("X64", "PC32", 32). elf_relocation_size("X64", "GOT32", 32). elf_relocation_size("X64", "PLT32", 32). elf_relocation_size("X64", "COPY", 32). elf_relocation_size("X64", "GLOB_DAT", 64). elf_relocation_size("X64", "JUMP_SLOT", 64). elf_relocation_size("X64", "RELATIVE", 64). elf_relocation_size("X64", "GOTPCREL", 32). elf_relocation_size("X64", "R32", 32). elf_relocation_size("X64", "R32S", 32). elf_relocation_size("X64", "R16", 16). elf_relocation_size("X64", "PC16", 16). elf_relocation_size("X64", "R8", 8). elf_relocation_size("X64", "PC8", 8). elf_relocation_size("X64", "DTPMOD64", 64). elf_relocation_size("X64", "DTPOFF64", 64). elf_relocation_size("X64", "TPOFF64", 64). elf_relocation_size("X64", "TLSGD", 32). elf_relocation_size("X64", "TLSLD", 32). elf_relocation_size("X64", "DTPOFF32", 32). elf_relocation_size("X64", "GOTTPOFF", 32). elf_relocation_size("X64", "TPOFF32", 32). elf_relocation_size("X64", "PC64", 64). elf_relocation_size("X64", "GOTOFF64", 64). elf_relocation_size("X64", "GOTPC32", 32). elf_relocation_size("X64", "GOT64", 64). elf_relocation_size("X64", "GOTPCREL64", 64). elf_relocation_size("X64", "GOTPC64", 64). elf_relocation_size("X64", "GOTPLT64", 64). elf_relocation_size("X64", "PLTOFF64", 64). elf_relocation_size("X64", "SIZE32", 32). elf_relocation_size("X64", "SIZE64", 64). elf_relocation_size("X64", "GOTPC32_TLSDESC", 32). elf_relocation_size("X64", "TLSDESC_CALL", 0). elf_relocation_size("X64", "TLSDESC", 64). elf_relocation_size("X64", "IRELATIVE", 64). elf_relocation_size("X64", "RELATIVE64", 64). elf_relocation_size("X64", "PC32_BND", 32). elf_relocation_size("X64", "PLT32_BND", 32). elf_relocation_size("X64", "GOTPCRELX", 32). elf_relocation_size("X64", "REX_GOTPCRELX", 32). elf_relocation_size("X86", "NONE", 0). elf_relocation_size("X86", "R32", 32). elf_relocation_size("X86", "PC32", 32). elf_relocation_size("X86", "GOT32", 32). elf_relocation_size("X86", "PLT32", 32). elf_relocation_size("X86", "COPY", 32). elf_relocation_size("X86", "GLOB_DAT", 32). elf_relocation_size("X86", "JUMP_SLOT", 32). elf_relocation_size("X86", "RELATIVE", 32). elf_relocation_size("X86", "GOTOFF", 32). elf_relocation_size("X86", "GOTPC", 32). elf_relocation_size("X86", "R32PLT", 32). elf_relocation_size("X86", "TLS_TPOFF", 32). elf_relocation_size("X86", "TLS_IE", 32). elf_relocation_size("X86", "TLS_GOTIE", 32). elf_relocation_size("X86", "TLS_LE", 32). elf_relocation_size("X86", "TLS_GD", 32). elf_relocation_size("X86", "TLS_LDM", 32). elf_relocation_size("X86", "R16", 16). elf_relocation_size("X86", "PC16", 16). elf_relocation_size("X86", "R8", 8). elf_relocation_size("X86", "PC8", 8). elf_relocation_size("X86", "TLS_GD_32", 32). elf_relocation_size("X86", "TLS_GD_PUSH", 32). elf_relocation_size("X86", "TLS_GD_CALL", 32). elf_relocation_size("X86", "TLS_GD_POP", 32). elf_relocation_size("X86", "TLS_LDM_32", 32). elf_relocation_size("X86", "TLS_LDM_PUSH", 32). elf_relocation_size("X86", "TLS_LDM_CALL", 0). elf_relocation_size("X86", "TLS_LDM_POP", 32). elf_relocation_size("X86", "TLS_LDO_32", 32). elf_relocation_size("X86", "TLS_IE_32", 32). elf_relocation_size("X86", "TLS_LE_32", 32). elf_relocation_size("X86", "TLS_DTPMOD32", 32). elf_relocation_size("X86", "TLS_DTPOFF32", 32). elf_relocation_size("X86", "TLS_TPOFF32", 32). elf_relocation_size("X86", "TLS_GOTDESC", 32). elf_relocation_size("X86", "TLS_DESC_CALL", 32). elf_relocation_size("X86", "TLS_DESC", 32). elf_relocation_size("X86", "IRELATIVE", 32). elf_relocation_size("ARM64", "NONE", 0). elf_relocation_size("ARM64", "ABS64", 64). elf_relocation_size("ARM64", "ABS32", 32). elf_relocation_size("ARM64", "ABS16", 16). elf_relocation_size("ARM64", "PREL64", 64). elf_relocation_size("ARM64", "PREL32", 32). elf_relocation_size("ARM64", "PREL16", 16). elf_relocation_size("ARM64", "MOVW_UABS_G0", 16). elf_relocation_size("ARM64", "MOVW_UABS_G0_NC", 16). elf_relocation_size("ARM64", "MOVW_UABS_G1", 16). elf_relocation_size("ARM64", "MOVW_UABS_G1_NC", 16). elf_relocation_size("ARM64", "MOVW_UABS_G2", 16). elf_relocation_size("ARM64", "MOVW_UABS_G2_NC", 16). elf_relocation_size("ARM64", "MOVW_UABS_G3", 16). elf_relocation_size("ARM64", "MOVW_SABS_G0", 16). elf_relocation_size("ARM64", "MOVW_SABS_G1", 16). elf_relocation_size("ARM64", "MOVW_SABS_G2", 16). elf_relocation_size("ARM64", "LD_PREL_LO19", 19). elf_relocation_size("ARM64", "ADR_PREL_LO21", 21). elf_relocation_size("ARM64", "ADR_PREL_PG_HI21", 21). elf_relocation_size("ARM64", "ADR_PREL_PG_HI21_NC", 21). elf_relocation_size("ARM64", "ADD_ABS_LO12_NC", 12). elf_relocation_size("ARM64", "LDST8_ABS_LO12_NC", 12). elf_relocation_size("ARM64", "TSTBR14", 14). elf_relocation_size("ARM64", "CONDBR19", 19). elf_relocation_size("ARM64", "JUMP26", 26). elf_relocation_size("ARM64", "CALL26", 26). elf_relocation_size("ARM64", "LDST16_ABS_LO12_NC", 12). elf_relocation_size("ARM64", "LDST32_ABS_LO12_NC", 12). elf_relocation_size("ARM64", "LDST64_ABS_LO12_NC", 12). elf_relocation_size("ARM64", "MOVW_PREL_G0", 16). elf_relocation_size("ARM64", "MOVW_PREL_G0_NC", 16). elf_relocation_size("ARM64", "MOVW_PREL_G1", 16). elf_relocation_size("ARM64", "MOVW_PREL_G1_NC", 16). elf_relocation_size("ARM64", "MOVW_PREL_G2", 16). elf_relocation_size("ARM64", "MOVW_PREL_G2_NC", 16). elf_relocation_size("ARM64", "MOVW_PREL_G3", 16). elf_relocation_size("ARM64", "LDST128_ABS_LO12_NC", 12). elf_relocation_size("ARM64", "MOVW_GOTOFF_G0", 16). elf_relocation_size("ARM64", "MOVW_GOTOFF_G0_NC", 16). elf_relocation_size("ARM64", "MOVW_GOTOFF_G1", 16). elf_relocation_size("ARM64", "MOVW_GOTOFF_G1_NC", 16). elf_relocation_size("ARM64", "MOVW_GOTOFF_G2", 16). elf_relocation_size("ARM64", "MOVW_GOTOFF_G2_NC", 16). elf_relocation_size("ARM64", "MOVW_GOTOFF_G3", 16). elf_relocation_size("ARM64", "GOTREL64", 64). elf_relocation_size("ARM64", "GOTREL32", 64). elf_relocation_size("ARM64", "GOT_LD_PREL19", 19). elf_relocation_size("ARM64", "LD64_GOTOFF_LO15", 15). elf_relocation_size("ARM64", "ADR_GOT_PAGE", 21). elf_relocation_size("ARM64", "LD64_GOT_LO12_NC", 12). elf_relocation_size("ARM64", "LD64_GOTPAGE_LO15", 15). elf_relocation_size("ARM64", "TLSGD_ADR_PREL21", 21). elf_relocation_size("ARM64", "TLSGD_ADR_PAGE21", 21). elf_relocation_size("ARM64", "TLSGD_ADD_LO12_NC", 12). elf_relocation_size("ARM64", "TLSGD_MOVW_G1", 16). elf_relocation_size("ARM64", "TLSGD_MOVW_G0_NC", 16). elf_relocation_size("ARM64", "TLSLD_ADR_PREL21", 21). elf_relocation_size("ARM64", "TLSLD_ADR_PAGE21", 21). elf_relocation_size("ARM64", "TLSLD_ADD_LO12_NC", 0). elf_relocation_size("ARM64", "TLSLD_MOVW_G1", 0). elf_relocation_size("ARM64", "TLSLD_MOVW_G0_NC", 0). elf_relocation_size("ARM64", "TLSLD_LD_PREL19", 19). elf_relocation_size("ARM64", "TLSLD_MOVW_DTPREL_G2", 16). elf_relocation_size("ARM64", "TLSLD_MOVW_DTPREL_G1", 16). elf_relocation_size("ARM64", "TLSLD_MOVW_DTPREL_G1_NC", 16). elf_relocation_size("ARM64", "TLSLD_MOVW_DTPREL_G0", 16). elf_relocation_size("ARM64", "TLSLD_MOVW_DTPREL_G0_NC", 16). elf_relocation_size("ARM64", "TLSLD_ADD_DTPREL_HI12", 12). elf_relocation_size("ARM64", "TLSLD_ADD_DTPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLD_ADD_DTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLD_LDST8_DTPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLD_LDST8_DTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLD_LDST16_DTPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLD_LDST16_DTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLD_LDST32_DTPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLD_LDST32_DTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLD_LDST64_DTPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLD_LDST64_DTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSIE_MOVW_GOTTPREL_G1", 16). elf_relocation_size("ARM64", "TLSIE_MOVW_GOTTPREL_G0_NC", 16). elf_relocation_size("ARM64", "TLSIE_ADR_GOTTPREL_PAGE21", 21). elf_relocation_size("ARM64", "TLSIE_LD64_GOTTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSIE_LD_GOTTPREL_PREL19", 19). elf_relocation_size("ARM64", "TLSLE_MOVW_TPREL_G2", 16). elf_relocation_size("ARM64", "TLSLE_MOVW_TPREL_G1", 16). elf_relocation_size("ARM64", "TLSLE_MOVW_TPREL_G1_NC", 16). elf_relocation_size("ARM64", "TLSLE_MOVW_TPREL_G0", 16). elf_relocation_size("ARM64", "TLSLE_MOVW_TPREL_G0_NC", 16). elf_relocation_size("ARM64", "TLSLE_ADD_TPREL_HI12", 12). elf_relocation_size("ARM64", "TLSLE_ADD_TPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLE_ADD_TPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLE_LDST8_TPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLE_LDST8_TPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLE_LDST16_TPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLE_LDST16_TPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLE_LDST32_TPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLE_LDST32_TPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLE_LDST64_TPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLE_LDST64_TPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSDESC_LD_PREL19", 19). elf_relocation_size("ARM64", "TLSDESC_ADR_PREL21", 21). elf_relocation_size("ARM64", "TLSDESC_ADR_PAGE21", 21). elf_relocation_size("ARM64", "TLSDESC_LD64_LO12_NC", 12). elf_relocation_size("ARM64", "TLSDESC_ADD_LO12_NC", 12). elf_relocation_size("ARM64", "TLSDESC_OFF_G1", 12). elf_relocation_size("ARM64", "TLSDESC_OFF_G0_NC", 12). elf_relocation_size("ARM64", "TLSDESC_LDR", 12). elf_relocation_size("ARM64", "TLSDESC_ADD", 12). elf_relocation_size("ARM64", "TLSDESC_CALL", 12). elf_relocation_size("ARM64", "TLSLE_LDST128_TPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLE_LDST128_TPREL_LO12_NC", 12). elf_relocation_size("ARM64", "TLSLD_LDST128_DTPREL_LO12", 12). elf_relocation_size("ARM64", "TLSLD_LDST128_DTPREL_LO12_NC", 12). elf_relocation_size("ARM64", "COPY", 64). elf_relocation_size("ARM64", "GLOB_DAT", 64). elf_relocation_size("ARM64", "JUMP_SLOT", 64). elf_relocation_size("ARM64", "RELATIVE", 64). elf_relocation_size("ARM64", "TLS_DTPREL64", 64). elf_relocation_size("ARM64", "TLS_DTPMOD64", 64). elf_relocation_size("ARM64", "TLS_TPREL64", 64). elf_relocation_size("ARM64", "TLSDESC", 64). elf_relocation_size("ARM64", "IRELATIVE", 64). elf_relocation_size("ARM", "NONE", 0). elf_relocation_size("ARM", "PC24", 24). elf_relocation_size("ARM", "ABS32", 32). elf_relocation_size("ARM", "REL32", 32). elf_relocation_size("ARM", "LDR_PC_G0", 32). elf_relocation_size("ARM", "ABS16", 16). elf_relocation_size("ARM", "ABS12", 12). elf_relocation_size("ARM", "THM_ABS5", 5). elf_relocation_size("ARM", "ABS8", 8). elf_relocation_size("ARM", "SBREL32", 32). elf_relocation_size("ARM", "THM_CALL", 25). elf_relocation_size("ARM", "THM_PC8", 8). elf_relocation_size("ARM", "BREL_ADJ", 32). elf_relocation_size("ARM", "TLS_DESC", 0). elf_relocation_size("ARM", "THM_SWI8", 0). elf_relocation_size("ARM", "XPC25", 25). elf_relocation_size("ARM", "THM_XPC22", 22). elf_relocation_size("ARM", "TLS_DTPMOD32", 32). elf_relocation_size("ARM", "TLS_DTPOFF32", 32). elf_relocation_size("ARM", "TLS_TPOFF32", 32). elf_relocation_size("ARM", "COPY", 32). elf_relocation_size("ARM", "GLOB_DAT", 32). elf_relocation_size("ARM", "JUMP_SLOT", 32). elf_relocation_size("ARM", "RELATIVE", 32). elf_relocation_size("ARM", "GOTOFF32", 32). elf_relocation_size("ARM", "BASE_PREL", 32). elf_relocation_size("ARM", "GOT_BREL", 32). elf_relocation_size("ARM", "PLT32", 24). elf_relocation_size("ARM", "CALL", 24). elf_relocation_size("ARM", "JUMP24", 24). elf_relocation_size("ARM", "THM_JUMP24", 24). elf_relocation_size("ARM", "BASE_ABS", 21). elf_relocation_size("ARM", "ALU_PCREL_7_0", 12). elf_relocation_size("ARM", "ALU_PCREL_15_8", 12). elf_relocation_size("ARM", "ALU_PCREL_23_15", 12). elf_relocation_size("ARM", "LDR_SBREL_11_0_NC", 12). elf_relocation_size("ARM", "ALU_SBREL_19_12_NC", 8). elf_relocation_size("ARM", "ALU_SBREL_27_20_CK", 8). elf_relocation_size("ARM", "TARGET1", 32). elf_relocation_size("ARM", "SBREL31", 32). elf_relocation_size("ARM", "V4BX", 32). elf_relocation_size("ARM", "TARGET2", 32). elf_relocation_size("ARM", "PREL31", 31). elf_relocation_size("ARM", "MOVW_ABS_NC", 16). elf_relocation_size("ARM", "MOVT_ABS", 16). elf_relocation_size("ARM", "MOVW_PREL_NC", 16). elf_relocation_size("ARM", "MOVT_PREL", 16). elf_relocation_size("ARM", "THM_MOVW_ABS_NC", 16). elf_relocation_size("ARM", "THM_MOVT_ABS", 16). elf_relocation_size("ARM", "THM_MOVW_PREL_NC", 16). elf_relocation_size("ARM", "THM_MOVT_PREL", 16). elf_relocation_size("ARM", "THM_JUMP19", 19). elf_relocation_size("ARM", "THM_JUMP6", 6). elf_relocation_size("ARM", "THM_ALU_PREL_11_0", 13). elf_relocation_size("ARM", "THM_PC12", 13). elf_relocation_size("ARM", "ABS32_NOI", 32). elf_relocation_size("ARM", "REL32_NOI", 32). elf_relocation_size("ARM", "ALU_PC_G0_NC", 32). elf_relocation_size("ARM", "ALU_PC_G0", 32). elf_relocation_size("ARM", "ALU_PC_G1_NC", 32). elf_relocation_size("ARM", "ALU_PC_G1", 32). elf_relocation_size("ARM", "ALU_PC_G2", 32). elf_relocation_size("ARM", "LDR_PC_G1", 32). elf_relocation_size("ARM", "LDR_PC_G2", 32). elf_relocation_size("ARM", "LDRS_PC_G0", 32). elf_relocation_size("ARM", "LDRS_PC_G1", 32). elf_relocation_size("ARM", "LDRS_PC_G2", 32). elf_relocation_size("ARM", "LDC_PC_G0", 32). elf_relocation_size("ARM", "LDC_PC_G1", 32). elf_relocation_size("ARM", "LDC_PC_G2", 32). elf_relocation_size("ARM", "ALU_SB_G0_NC", 32). elf_relocation_size("ARM", "ALU_SB_G0", 32). elf_relocation_size("ARM", "ALU_SB_G1_NC", 32). elf_relocation_size("ARM", "ALU_SB_G1", 32). elf_relocation_size("ARM", "ALU_SB_G2", 32). elf_relocation_size("ARM", "LDR_SB_G0", 32). elf_relocation_size("ARM", "LDR_SB_G1", 32). elf_relocation_size("ARM", "LDR_SB_G2", 32). elf_relocation_size("ARM", "LDRS_SB_G0", 32). elf_relocation_size("ARM", "LDRS_SB_G1", 32). elf_relocation_size("ARM", "LDRS_SB_G2", 32). elf_relocation_size("ARM", "LDC_SB_G0", 32). elf_relocation_size("ARM", "LDC_SB_G1", 32). elf_relocation_size("ARM", "LDC_SB_G2", 32). elf_relocation_size("ARM", "MOVW_BREL_NC", 16). elf_relocation_size("ARM", "MOVT_BREL", 16). elf_relocation_size("ARM", "MOVW_BREL", 16). elf_relocation_size("ARM", "THM_MOVW_BREL_NC", 16). elf_relocation_size("ARM", "THM_MOVT_BREL", 16). elf_relocation_size("ARM", "THM_MOVW_BREL", 16). elf_relocation_size("ARM", "TLS_GOTDESC", 0). elf_relocation_size("ARM", "TLS_CALL", 0). elf_relocation_size("ARM", "TLS_DESCSEQ", 0). elf_relocation_size("ARM", "THM_TLS_CALL", 0). elf_relocation_size("ARM", "PLT32_ABS", 32). elf_relocation_size("ARM", "GOT_ABS", 32). elf_relocation_size("ARM", "GOT_PREL", 32). elf_relocation_size("ARM", "GOT_BREL12", 12). elf_relocation_size("ARM", "GOTOFF12", 12). elf_relocation_size("ARM", "GOTRELAX", 12). elf_relocation_size("ARM", "GNU_VTENTRY", 0). elf_relocation_size("ARM", "GNU_VTINHERIT", 0). elf_relocation_size("ARM", "THM_JUMP11", 11). elf_relocation_size("ARM", "THM_JUMP8", 8). elf_relocation_size("ARM", "TLS_GD32", 32). elf_relocation_size("ARM", "TLS_LDM32", 32). elf_relocation_size("ARM", "TLS_LDO32", 32). elf_relocation_size("ARM", "TLS_IE32", 32). elf_relocation_size("ARM", "TLS_LE32", 32). elf_relocation_size("ARM", "TLS_LDO12", 12). elf_relocation_size("ARM", "TLS_LE12", 12). elf_relocation_size("ARM", "TLS_IE12GP", 12). elf_relocation_size("ARM", "PRIVATE_0", 0). elf_relocation_size("ARM", "PRIVATE_1", 0). elf_relocation_size("ARM", "PRIVATE_2", 0). elf_relocation_size("ARM", "PRIVATE_3", 0). elf_relocation_size("ARM", "PRIVATE_4", 0). elf_relocation_size("ARM", "PRIVATE_5", 0). elf_relocation_size("ARM", "PRIVATE_6", 0). elf_relocation_size("ARM", "PRIVATE_7", 0). elf_relocation_size("ARM", "PRIVATE_8", 0). elf_relocation_size("ARM", "PRIVATE_9", 0). elf_relocation_size("ARM", "PRIVATE_10", 0). elf_relocation_size("ARM", "PRIVATE_11", 0). elf_relocation_size("ARM", "PRIVATE_12", 0). elf_relocation_size("ARM", "PRIVATE_13", 0). elf_relocation_size("ARM", "PRIVATE_14", 0). elf_relocation_size("ARM", "PRIVATE_15", 0). elf_relocation_size("ARM", "ME_TOO", 0). elf_relocation_size("ARM", "THM_TLS_DESCSEQ16", 0). elf_relocation_size("ARM", "THM_TLS_DESCSEQ32", 0). elf_relocation_size("ARM", "IRELATIVE", 0). elf_relocation_size("ARM", "RXPC25", 25). elf_relocation_size("ARM", "RSBREL32", 32). elf_relocation_size("ARM", "THM_RPC22", 22). elf_relocation_size("ARM", "RREL32", 32). elf_relocation_size("ARM", "RPC24", 24). elf_relocation_size("ARM", "RBASE", 0). relocation_size(Type,Size):- binary_isa(ISA), binary_format("ELF"), elf_relocation_size(ISA,Type,Size). #line 26 "binary/elf/elf_binaries.dl" .decl elf_section_type(Name:symbol,Code:unsigned) elf_section_type("NULL",0). elf_section_type("PROGBITS",1). elf_section_type("SYMTAB",2). elf_section_type("STRTAB",3). elf_section_type("RELA",4). elf_section_type("HASH",5). elf_section_type("DYNAMIC",6). elf_section_type("NOTE",7). elf_section_type("NOBITS",8). elf_section_type("REL",9). elf_section_type("SHLIB",10). elf_section_type("DYNSYM",11). elf_section_type("INIT_ARRAY",14). elf_section_type("FINI_ARRAY",15). elf_section_type("PREINIT_ARRAY",16). elf_section_type("GROUP",17). elf_section_type("SYMTAB_SHNDX",18). elf_section_type("NUM",19). data_section(Name):- section_property(Name,"Loaded"), !section_property(Name,"Executable"), section_type(Name,Type), ( elf_section_type("PROGBITS",Type); elf_section_type("NOBITS",Type); elf_section_type("INIT_ARRAY",Type); elf_section_type("FINI_ARRAY",Type); elf_section_type("PREINIT_ARRAY",Type); elf_section_type("DYNAMIC",Type); elf_section_type("RELA",Type) ). exception_section(".eh_frame"). exception_section(".eh_frame_hdr"). exception_section(".gcc_except_table"). special_data_section(Section):- exception_section(Section). special_data_section(".dynamic"). special_data_section(".fini_array"). special_data_section(".got"). special_data_section(".got.plt"). special_data_section(".init_array"). special_data_section(".interp"). special_data_section(".jcr"). special_data_section(".tm_clone_table"). function_pointer_section(".init_array"):-binary_format("ELF"). function_pointer_section(".fini_array"):-binary_format("ELF"). function_pointer_section(".got.plt"):-binary_format("ELF"). .decl plt_section(name:symbol) plt_section(".plt"). plt_section(".plt.got"). plt_section(".plt.sec"). .decl got_section(name:symbol) got_section(".got"). got_section(".got.plt"). bss_section(Name):- binary_format("ELF"), section_property(Name,"Loaded"), !section_property(Name,"Initialized"). non_zero_data_section(Name):- data_section(Name), !bss_section(Name), Name != ".dynamic". .decl plt_entry(ea:address, function:symbol) plt_entry(EA,Function):- plt_section(SecName), loaded_section(Beg,End,SecName), EA >= Beg, EA < End, pc_relative_jump(EA,Got_entry), relocation(Got_entry,_,Function,_,_,_,_), Function != "". plt_entry(EA,Name):- plt_section(SecName), loaded_section(Beg,End,SecName), EA >= Beg, EA < End, pc_relative_jump(EA,Got_entry), relocation(Got_entry,"IRELATIVE","",Dest,_,_,_), ( defined_symbol(as(Dest,address),_,"GNU_IFUNC",_,_,_,_,_,Name); !defined_symbol(as(Dest,address),_,"GNU_IFUNC",_,_,_,_,_,_), ifunc_symbol(as(Dest,address),Name) ). plt_block(Block,Function):- plt_entry(EA,Function), code_in_block(EA,Block). plt_block(Block,Function):- plt_block(NextBlock,Function), must_fallthrough(EA,NextBlock), code_in_block(EA,Block), plt_section(SecName), loaded_section(Beg,End,SecName), Block >= Beg, EA < End. .decl plt_data_reference(ea:address) plt_data_reference(EA):- plt_block(Dest,_), symbolic_data(EA,_,Dest). #line 159 "binary/elf/elf_binaries.dl" .decl reg_has_got(EA:address,Reg:register) .output reg_has_got #line 166 "binary/elf/elf_binaries.dl" .decl got_reference_pointer(EA:address) .output got_reference_pointer got_reference_pointer(EA):- loaded_section(EA,_,".got.plt"). got_reference_pointer(EA):- loaded_section(EA,_,".got"), !loaded_section(_,_,".got.plt"). #line 186 "binary/elf/elf_binaries.dl" reg_has_got(EA,Reg):- value_reg(EA,Reg,_,"NONE",_,Offset,_), got_section(Name), loaded_section(as(Offset,address),_,Name). #line 195 "binary/elf/elf_binaries.dl" .decl got_relative_operand(EA:address,Index:operand_index,Dest:address) .output got_relative_operand got_relative_operand(EA,Index,Dest):- reg_has_got(EA_base,Reg), def_used(EA_base,Reg,EA,Index), instruction_get_op(EA,Index,Op), ( op_indirect_mapped(Op,"NONE",Reg,_,_,Offset,_); op_indirect_mapped(Op,"NONE",_,Reg,1,Offset,_) ), Offset != 0, got_reference_pointer(Got), Dest=Got+as(Offset,address). got_relative_operand(EA3,Index,as(Dest,address)):- reg_has_got(EA1,Reg1), def_used(EA1,Reg1,EA2,_), arch.reg_reg_arithmetic_operation(EA2,Reg3,Reg1,Reg2,Mult,0), def_used(EA2,Reg3,EA3,_), op_immediate_and_reg(EA3,_,Reg3,Index,_), value_reg(EA3,Reg3,_,Reg2,Mult,Dest,_). .decl get_pc_thunk(EA:address,Reg:register) .output get_pc_thunk get_pc_thunk(EA,Reg):- binary_isa("X86"), binary_format("ELF"), direct_call(_,EA), instruction(EA,Size,_,Operation,Op1,Op2,_,_,_,_), arch.move_operation(Operation), op_regdirect_contains_reg(Op2,Reg), op_indirect_mapped(Op1,"NONE","ESP","NONE",1,0,_), arch.return(EA+Size). got_reference(Got_entry,Symbol):- loaded_section(Beg,End,".got"), Got_entry >= Beg, Got_entry < End, relocation(Got_entry,RelType,Symbol,_,_,_,_), RelType != "RELATIVE", RelType != "DTPMOD64", symbol(_,_,_,_,_,_,_,_,Symbol). got_reference(Got_entry,Symbol):- loaded_section(Beg,End,".got"), Got_entry >= Beg, Got_entry < End, arch.pointer_size(Ptr), symbolic_expr(Got_entry,Ptr,Symbol,_). symbol_minus_symbol(Got_entry+8,8,Beg,Dest,1,0):- relocation(Got_entry,"DTPMOD64","",_,_,_,_), ( loaded_section(Beg,_,".tbss"); loaded_section(Beg,_,".tdata") ), data_word(Got_entry+8,8,Offset), Dest = as(as(Beg,number)+Offset,address). got_reference(Got_entry,DestName):- relocation(Got_entry,"DTPMOD64","",_,_,_,_), symbolic_expr_symbol_minus_symbol(Got_entry+8,8,_,DestName,_,_). .decl start_function(ea:address) start_function(EA):- binary_format("ELF"), function_symbol(EA,"_start"). start_function(Start_location):- binary_format("ELF"), !function_symbol(Start_location,"_start"), entry_point(Start_location). main_function(EA):- binary_format("ELF"), function_symbol(EA,"main"). #line 302 "binary/elf/elf_binaries.dl" .decl do_infer_main_function() do_infer_main_function():- binary_format("ELF"), !binary_type("REL"), !function_symbol(_,"main"). #line 312 "binary/elf/elf_binaries.dl" .decl inferred_main_function(Main_location:address) inferred_main_function(Main_location):- arch.inferred_main_in_reg(Main_load,Reg), def_used(EA_def,Reg,Main_load,_), value_reg(EA_def,Reg,_,"NONE",_,Offset,_), Main_location = as(Offset, address), code(Main_location). inferred_main_function(Main):- arch.inferred_main_in_reg(EA,Reg), instruction_get_op(EA,_,Op), op_indirect_contains_reg(Op,Reg), symbolic_operand(EA,_,Dest,"data"), address_in_data(Dest,Main). used(EA,Reg,0), used_for_address(EA,Reg):- arch.inferred_main_in_reg(EA,Reg). main_function(Main_location):- inferred_main_function(Main_location). inferred_special_symbol(EA,"_start","GLOBAL","FUNC","Beg"):- !binary_type("REL"), !symbol(EA,_,"FUNC",_,_,_,_,_,_), start_function(EA). inferred_special_symbol(EA,"__do_global_dtors_aux","LOCAL","FUNC","Beg"):- function_symbol(EA,"__do_global_dtors_aux"). inferred_special_symbol(EA,"__do_global_dtors_aux","LOCAL","FUNC","Beg"):- !function_symbol(EA,"__do_global_dtors_aux"), function_inference.function_entry(EA), address_in_data(FiniArray,EA), loaded_section(Beg,End,".fini_array"), FiniArray >= Beg, FiniArray < End, code_in_refined_block(EA_cmp,EA), instruction(EA_cmp,_,_,"CMP",Op1,_,0,0,_,_), op_immediate(Op1,0), pc_relative_operand(EA_cmp,2,DataRef), bss_section(SectionName), loaded_section(BegData,EndData,SectionName), DataRef >= BegData, DataRef <= EndData. inferred_special_symbol(EA,"_DYNAMIC","LOCAL","NONE","Beg"):- binary_format("ELF"), !symbol(EA,_,_,_,_,_,_,_,"_DYNAMIC"), loaded_section(EA,_,".dynamic"). inferred_special_symbol(EA,"_GLOBAL_OFFSET_TABLE_","LOCAL","NONE","Beg"):- !symbol(_,_,_,_,_,_,_,_,"_GLOBAL_OFFSET_TABLE_"), got_reference_pointer(EA). no_return_function("abort(@.*)?"):- binary_format("ELF"). no_return_function("_?exit(@.*)?"):- binary_format("ELF"). no_return_function("__chk_fail(@.*)?"):- binary_format("ELF"). no_return_function("__stack_chk_fail(@.*)?"):- binary_format("ELF"). no_return_function("__assert_fail(@.*)?"):- binary_format("ELF"). no_return_function("longjmp(@.*)?"):- binary_format("ELF"). no_return_function("__clang_call_terminate"):- binary_format("ELF"). relocation_adjustment(EA,as(Addend,number),"implicit-addend"):- binary_format("ELF"), relocation(EA,Type,_,_,_,_,"REL"), relocation_size(Type,Size), ( Size = 8, data_byte(EA,Addend); Size != 8, data_word(EA,Size/8,Addend) ). relocation_adjustment(EA+Offset,N,"distance-to-pc"):- ( binary_isa("X86"); binary_isa("X64") ), binary_type("REL"), code(EA), ( instruction(EA,Size,_,_,_,_,_,_,_,Offset); instruction(EA,Size,_,_,_,_,_,_,Offset,_) ), relocation(EA+Offset,Type,Symbol,_,SymbolIndex,_,_), ( Type = "PC32"; Type = "PLT32" ), symbol(_,_,_,_,_,_,_,SymbolIndex,Symbol), N = as(Size-Offset,number), N > 0. symbolic_expr_from_relocation(EA,Size/8,Symbol,Addend+Adjustment,TargetEA):- binary_format("ELF"), relocation(EA,Type,Symbol,Addend,SymbolIndex,_,_), relocation_size(Type,Size), ( Type = "R32"; Type = "R64"; Type = "R32S"; Type = "ABS64" ), relocation_adjustment_total(EA,Adjustment), symbol(TargetEA,_,_,_,_,_,_,SymbolIndex,Symbol), Symbol != "". symbolic_expr_from_relocation(EA,Size/8,Symbol,0,TargetEA):- binary_type("REL"), relocation(EA,Type,"",Addend,SymbolIndex,_,_), relocation_size(Type,Size), ( Type = "R32"; Type = "R64"; Type = "R32S" ), relocation_adjustment_total(EA,Adjustment), symbol(_,_,"SECTION",_,_,SectionIndex,_,SymbolIndex,_), section(_,_,Begin,_,SectionIndex), TargetEA = as(as(Begin,number)+Addend+Adjustment,address), ( symbol(TargetEA,_,_,_,_,_,_,_,Symbol); !symbol(TargetEA,_,_,_,_,_,_,_,_), Symbol = "" ). symbolic_expr_from_relocation(EA,Size,Symbol,Addend,TargetEA):- binary_format("ELF"), arch.pointer_size(Size), relocation(EA,"GLOB_DAT",Symbol,Addend,SymbolIndex,_,_), symbol(TargetEA,_,_,_,_,_,_,SymbolIndex,Symbol). symbolic_expr_from_relocation(EA,4,Symbol,Addend,TargetEA):- binary_type("REL"), relocation(EA,"TPOFF32",Symbol,Addend,_,_,_), symbol(TargetEA,_,_,_,_,_,_,_,Symbol). symbolic_expr_from_relocation(EA,4,Symbol,Addend+Adjustment,TargetEA):- binary_type("REL"), relocation(EA,Type,Symbol,Addend,SymbolIndex,_,_), ( Type = "PC32"; Type = "PLT32" ), relocation_adjustment_total(EA,Adjustment), symbol(TargetEA,_,_,_,_,_,_,SymbolIndex,Symbol), Symbol != "". .decl tls_segment(Start:address,End:address,Align:unsigned) tls_segment(Start,End,Align):- Start = min EA:{ tls_section(Name), loaded_section(Addr,_,Name), EA=Addr }, End = max EA:{ tls_section(Name), loaded_section(_,End,Name), EA=End }, Align = max X:{ tls_section(Name), section(Name,_,_,X,_) }. symbolic_operand_candidate(EA,Index,as(Reference+Offset,address),"data"):- code(EA), instruction_get_op(EA,Index,Op), op_indirect(Op,"FS","NONE","NONE",_,Offset,_), Offset < 0, tls_segment(_,TlsEnd,Align), Reference = as(TlsEnd,number) + as(TlsEnd % max(Align,1),number). symbolic_operand_candidate(EA_used,Index,as(Reference+Offset,address),"data"):- instruction_get_op(EA_def,_,Op_def), op_indirect(Op_def,"FS","NONE","NONE",_,0,_), def_used(EA_def,_,EA_used,Index), instruction_get_op(EA_used,Index,Op_used), op_indirect(Op_used,"NONE",_,_,_,Offset,_), Offset < 0, tls_segment(_,TlsEnd,Align), Reference = as(TlsEnd,number) + as(TlsEnd % max(Align,1),number). .decl ifunc_symbol(EA:address,Name:symbol) ifunc_symbol(DestAddr,NameFunc), inferred_special_symbol(DestAddr,NameFunc,"GLOBAL","GNU_IFUNC","Beg"), inferred_special_symbol(DestAddr,Name,"LOCAL","FUNC","Beg"):- relocation(_,"IRELATIVE","",Dest,_,_,_), DestAddr = as(Dest,address), !symbol(DestAddr,_,"GNU_IFUNC",_,_,_,_,_,_), NameFunc = cat("FUN_",to_string(Dest)), Name = cat(NameFunc,"_IFUNC"). inferred_special_symbol(Beg,"__rela_iplt_start","GLOBAL","NONE","Beg"):- loaded_section(Beg,_,".rela.plt"), !symbol(_,_,_,_,_,_,_,_,"__rela_iplt_start"). inferred_special_symbol(End,"__rela_iplt_end","GLOBAL","NONE","End"):- loaded_section(_,End,".rela.plt"), !symbol(_,_,_,_,_,_,_,_,"__rela_iplt_end"). abi_intrinsic(Beg,"__rela_iplt_start"), abi_intrinsic(End,"__rela_iplt_end"):- loaded_section(Beg,End,".rela.plt"). #line 548 "binary/elf/elf_binaries.dl" moved_label_class(EAStop,ImmIndexStop,"libc atexit"), moved_immediate_candidate(EAStop,ImmIndexStop,ImmediateStopAddr,ImmediateStartAddr):- arch.move_reg_imm(EAStart,_,ImmediateStart,_), code(EAStart), ImmediateStartAddr = as(ImmediateStart, address), defined_symbol(ImmediateStartAddr,_,_,_,_,_,_,_,"__start___libc_atexit"), next(EAStart,EAStop), arch.move_reg_imm(EAStop,_,ImmediateStop,ImmIndexStop), code(EAStop), ImmediateStopAddr = as(ImmediateStop, address), defined_symbol(ImmediateStopAddr,_,_,_,_,_,_,_,"__stop___libc_atexit"). #line 84 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "binary/pe/pe_binaries.dl" #line 24 "binary/pe/pe_binaries.dl" #line 1 "exceptions.dl" #line 29 "exceptions.dl" .decl reg_has_tib(EA:address,Reg:register) .output reg_has_tib reg_has_tib(EA,Reg):- binary_isa("X86"), binary_format("PE"), instruction_get_operation(EA,"MOV"), instruction_get_src_op(EA,_,Src), op_indirect(Src,"FS","NONE","NONE",1,0,_), instruction_get_dest_op(EA,_,Op), op_regdirect_contains_reg(Op,Reg). #line 77 "exceptions.dl" .decl pe_exception_handler(EA:address) .output pe_exception_handler pe_exception_handler(EA):- seh_handler_entry(_,EA), code(EA). #line 108 "exceptions.dl" .decl seh_handler_table(Beg:address,End:address) .output seh_handler_table seh_handler_table(Beg,End):- binary_isa("X86"), binary_format("PE"), pe_load_config("SEHandlerTable",Table), pe_load_config("SEHandlerCount",Count), Beg = as(Table,address), End = as(Beg+(Count*4),address). data_region(Beg,End-End):- seh_handler_table(Beg,End). .decl seh_handler_entry(EA:address,Handler:address) .output seh_handler_entry seh_handler_entry(EA,ImageBase+RVA):- base_address(ImageBase), seh_handler_table(EA,_), data_word(EA,4,Val), RVA = as(Val,address). seh_handler_entry(EA+4,ImageBase+RVA):- base_address(ImageBase), seh_handler_entry(EA,_), data_word(EA+4,4,Val), Val != 0, seh_handler_table(_,End), EA < End, RVA = as(Val,address). #line 25 "binary/pe/pe_binaries.dl" #line 1 "relocations.dl" #line 27 "relocations.dl" .decl pe_relocation_size(Type:symbol,Size:unsigned) pe_relocation_size("LOW", 16). pe_relocation_size("HIGH", 16). pe_relocation_size("HIGHADJ", 16). pe_relocation_size("HIGHLOW", 32). pe_relocation_size("DIR64", 64). pe_relocation_size("ABSOLUTE", 0). relocation_size(Type,Size):- binary_format("PE"), pe_relocation_size(Type,Size). #line 26 "binary/pe/pe_binaries.dl" .decl pe_data_directory(Type:symbol,Address:address,Size:unsigned) .input pe_data_directory .decl pe_import_entry(Address:address,Ordinal:number,Function:symbol,Library:symbol) .input pe_import_entry .decl pe_export_entry(Address:address,Ordinal:number,Name:symbol) .input pe_export_entry .decl pe_debug_data(Type:symbol,Address:address,Size:unsigned) .input pe_debug_data .decl pe_load_config(Name:symbol,Value:unsigned) .input pe_load_config #line 47 "binary/pe/pe_binaries.dl" .decl pe_section_characteristics(Name:symbol,Mask:unsigned) pe_section_characteristics("IMAGE_SCN_TYPE_NO_PAD",0x00000008). pe_section_characteristics("IMAGE_SCN_CNT_CODE",0x00000020). pe_section_characteristics("IMAGE_SCN_CNT_INITIALIZED_DATA",0x00000040). pe_section_characteristics("IMAGE_SCN_CNT_UNINITIALIZED_DATA",0x00000080). pe_section_characteristics("IMAGE_SCN_LNK_OTHER",0x00000100). pe_section_characteristics("IMAGE_SCN_LNK_INFO",0x00000200). pe_section_characteristics("IMAGE_SCN_LNK_REMOVE",0x00000800). pe_section_characteristics("IMAGE_SCN_LNK_COMDAT",0x00001000). pe_section_characteristics("IMAGE_SCN_GPREL",0x00008000). pe_section_characteristics("IMAGE_SCN_MEM_PURGEABLE",0x00020000). pe_section_characteristics("IMAGE_SCN_MEM_16BIT",0x00020000). pe_section_characteristics("IMAGE_SCN_MEM_LOCKED",0x00040000). pe_section_characteristics("IMAGE_SCN_MEM_PRELOAD",0x00080000). pe_section_characteristics("IMAGE_SCN_ALIGN_1BYTES",0x00100000). pe_section_characteristics("IMAGE_SCN_ALIGN_2BYTES",0x00200000). pe_section_characteristics("IMAGE_SCN_ALIGN_4BYTES",0x00300000). pe_section_characteristics("IMAGE_SCN_ALIGN_8BYTES",0x00400000). pe_section_characteristics("IMAGE_SCN_ALIGN_16BYTES",0x00500000). pe_section_characteristics("IMAGE_SCN_ALIGN_32BYTES",0x00600000). pe_section_characteristics("IMAGE_SCN_ALIGN_64BYTES",0x00700000). pe_section_characteristics("IMAGE_SCN_ALIGN_128BYTES",0x00800000). pe_section_characteristics("IMAGE_SCN_ALIGN_256BYTES",0x00900000). pe_section_characteristics("IMAGE_SCN_ALIGN_512BYTES",0x00A00000). pe_section_characteristics("IMAGE_SCN_ALIGN_1024BYTES",0x00B00000). pe_section_characteristics("IMAGE_SCN_ALIGN_2048BYTES",0x00C00000). pe_section_characteristics("IMAGE_SCN_ALIGN_4096BYTES",0x00D00000). pe_section_characteristics("IMAGE_SCN_ALIGN_8192BYTES",0x00E00000). pe_section_characteristics("IMAGE_SCN_LNK_NRELOC_OVFL",0x01000000). pe_section_characteristics("IMAGE_SCN_MEM_DISCARDABLE",0x02000000). pe_section_characteristics("IMAGE_SCN_MEM_NOT_CACHED",0x04000000). pe_section_characteristics("IMAGE_SCN_MEM_NOT_PAGED",0x08000000). pe_section_characteristics("IMAGE_SCN_MEM_SHARED",0x10000000). pe_section_characteristics("IMAGE_SCN_MEM_EXECUTE",0x20000000). pe_section_characteristics("IMAGE_SCN_MEM_READ",0x40000000). pe_section_characteristics("IMAGE_SCN_MEM_WRITE",0x80000000). data_section(Section):- binary_format("PE"), section_property(Section,"Loaded"), section_property(Section,"Initialized"), !section_property(Section,"Executable"). bss_section(Section), data_section(Section):- binary_format("PE"), section_property(Section,"Loaded"), !section_property(Section,"Initialized"), !section_property(Section,"Executable"). data_region(Begin,Size):- pe_data_directory(_,Begin,Size), Size > 0; pe_debug_data(_,Begin,Size), Size > 0. data_segment(0x7FFE0000,0x7FFE1000):- binary_format("PE"). data_segment(ImageBase,ImageBase+1024):- binary_format("PE"), base_address(ImageBase). inferred_special_symbol(0x7FFE0000,"KUSER_SHARED_DATA","LOCAL","NONE","Beg"), moved_label_class(EA,Op_index,"KUSER_SHARED_DATA"), moved_displacement_candidate(EA,Op_index,Dest,0x7FFE0000,Dest-0x7FFE0000):- binary_format("PE"), symbolic_operand(EA,Op_index,Dest,"data"), Dest > 0x7FFE0000, Dest < 0x7FFE1000. symbol(0,0,"NONE","EXTERN","DEFAULT",0,"none",0,Function), got_reference(Address,Function):- pe_import_entry(Address,_,Function,_). plt_block(EA,Function):- binary_format("PE"), pc_relative_jump(EA,Got_entry), unconditional_jump(EA), pe_import_entry(Got_entry,_,Function,_), code_in_block(EA,EA). symbol(EA,0,"NOTYPE","GLOBAL","DEFAULT",0,"export",as(Ordinal,unsigned),Function):- pe_export_entry(EA,Ordinal,Function). .decl reg_has_base_image(EA:address,Reg:register) .output reg_has_base_image reg_has_base_image(EA,Reg):- base_address(ImageBase), pc_relative_operand(EA,_,ImageBase), code(EA), def(EA,Reg), instruction_get_operation(EA,"LEA"). symbolic_expr_from_relocation(EA_data,Size,"__ImageBase",0,ImageBase), reg_has_base_image(EA_code,Reg):- binary_format("PE"), base_address(ImageBase), arch.pointer_size(Size), code(EA_code), arch.load(EA_code,_,_,_,_,_,_,_), pc_relative_operand(EA_code,_,EA_data), data_word(EA_data,Size,Value), ImageBase = as(Value,address), def(EA_code,Reg). reg_has_base_image(EA,Reg):- reg_has_base_image(EA2,Reg2), def_used(EA2,Reg2,EA,_), ( arch.move_reg_reg(EA,Reg,Reg2); arch.reg_reg_arithmetic_operation(EA,Reg,Reg2,_,Mult,0), Mult>1 ). .decl possible_rva_operand(EA:address,Index:operand_index,Dest:address) .output possible_rva_operand possible_rva_operand(EA,Op_index,RVA):- instruction_get_op(EA,Op_index,Op), op_indirect(Op,_,_,_,_,Value,_), Value >= 0, RVA = as(Value,address), base_address(ImageBase), loaded_section(Begin,End,_), (ImageBase + RVA) >= Begin, (ImageBase + RVA) < End. .decl base_relative_operand(EA:address,Index:operand_index,Dest:address) .output base_relative_operand base_relative_operand(EA_used,Op_index,RVA):- reg_has_base_image(EA_def,Reg), def_used(EA_def,Reg,EA_used,Op_index), possible_rva_operand(EA_used,Op_index,RVA). base_relative_operand(EA_def1,Op_index,as(Value,address)):- reg_has_base_image(EA_def2,Reg2), def_used(EA_def2,Reg2,EA,_), arch.reg_reg_arithmetic_operation(EA,Reg1,Reg1,Reg2,1,0), def_used(EA_def1,Reg1,EA,_), instruction_get_op(EA_def1,Op_index,Op), instruction_get_operation(EA_def1,"LEA"), op_indirect(Op,_,_,_,_,Value,_), Value > 0. base_relative_operand(EA_def1,Op_index,as(Value,address)):- reg_has_base_image(EA_def2,Reg2), def_used(EA_def2,Reg2,EA,Op_index_access), ( data_access(EA,Op_index_access,"NONE",Reg2,Reg1,1,0,_); data_access(EA,Op_index_access,"NONE",Reg1,Reg2,1,0,_) ), !instruction_get_operation(EA,"LEA"), def_used(EA_def1,Reg1,EA,_), instruction_get_op(EA_def1,Op_index,Op), instruction_get_operation(EA_def1,"LEA"), op_indirect(Op,_,_,_,_,Value,_), Value > 0. base_relative_operand(EA_def2,Op_index_access,RVA):- reg_has_base_image(EA_def1,Reg1), def_used(EA_def1,Reg1,EA,_), data_access(EA_def2,Op_index_access,"NONE","NONE",_,4,Offset,_), Offset > 0, def_used(EA_def2,Reg2,EA,_), possible_rva_operand(EA_def2,Op_index_access,RVA), ( data_access(EA,_,"NONE",Reg1,Reg2,1,_,_); data_access(EA,_,"NONE",Reg2,Reg1,1,_,_) ). .decl base_relative_symbolic_operand(EA:address,Index:operand_index,Dest:address) symbol_minus_symbol(EA+Disp_offset,Size/8,ImageBase,ImageBase+Value,1,0), base_relative_symbolic_operand(EA,Op_index,Value):- base_relative_operand(EA,Op_index,Value), !pc_relative_operand(EA,Op_index,_), instruction_displacement_offset(EA,Op_index,Disp_offset,_), instruction_get_op(EA,Op_index,Op), op_indirect(Op,_,_,_,_,_,Size), base_address(ImageBase). inferred_special_symbol(ImageBase,"__ImageBase","LOCAL","NONE","Beg"):- binary_format("PE"), base_address(ImageBase). inferred_special_symbol(Start,"__EntryPoint","GLOBAL","FUNC","Beg"):- binary_format("PE"), entry_point(Start). symbolic_operand_candidate(EA,Op_index,Dest,"data"):- code(EA), base_address(ImageBase), pc_relative_operand(EA,Op_index,Dest), Dest = ImageBase. .decl base_relative_operation(EA_relop:address,EA:address) .output base_relative_operation base_relative_operation(EA_relop,EA_inst):- base_relative_operand(EA_relop,_,_), def_used(EA_relop,_,EA_inst,_). base_relative_operation(EA_relop,EA_next):- base_relative_operand(EA_relop,_,_), def_used(EA_relop,_,EA_inst,_), def_used(EA_inst,_,EA_next,_). .decl base_relative_jump(EA_relop:address,EA:address) .output base_relative_jump base_relative_jump(EA_relop,EA):- reg_jump(EA,_), base_relative_operation(EA_relop,EA). labeled_data_candidate(ImageBase+Dest):- base_address(ImageBase), base_relative_symbolic_operand(_,_,Dest). .decl dos_header_symbolic_operand(EA:address,Dest:unsigned) .output dos_header_symbolic_operand symbolic_expr_from_relocation(EA+Disp_offset,Size/8,"__ImageBase",as(Dest-ImageBase,number),Dest), dos_header_symbolic_operand(EA,Dest):- binary_format("PE"), base_address(ImageBase), pc_relative_operand(EA,_,Dest), instruction_displacement_offset(EA,Op_index,Disp_offset,_), instruction_get_op(EA,Op_index,Op), op_indirect(Op,_,_,_,_,_,Size), Dest > ImageBase, Dest < ImageBase + 64. symbolic_expr_from_relocation(EA+Disp_offset,Size/8,"__ImageBase",as(Dest-ImageBase,number),Dest), dos_header_symbolic_operand(EA+Disp_offset,Dest):- binary_format("PE"), base_address(ImageBase), op_indirect(Op,_,_,_,1,Offset,Size), instruction_get_op(EA,Op_index,Op), instruction_displacement_offset(EA,Op_index,Disp_offset,_), Dest = as(Offset,address), Dest >= ImageBase, Dest <= ImageBase+64. symbolic_expr_from_relocation(EA+Disp_offset,Size/8,"__ImageBase",as(Dest-ImageBase,number),Dest), dos_header_symbolic_operand(EA+Disp_offset,Dest):- binary_format("PE"), base_address(ImageBase), op_immediate(Op,Offset), instruction_get_op(EA,Op_index,Op), instruction_immediate_offset(EA,Op_index,Disp_offset,_), Size = 8, Dest = as(Offset,address), Dest >= ImageBase, Dest <= ImageBase+64. .decl jump_table_prelude(EA:address,Steps:unsigned) jump_table_prelude(EA,0):- reg_jump(EA,_), possible_ea(EA). jump_table_prelude(EA,0):- reg_call(EA,_), possible_ea(EA). jump_table_prelude(EA_prev,Steps+1):- jump_table_prelude(EA,Steps), Steps < 6, must_fallthrough(EA_prev,EA). relative_address_start(Table,8,Ref,Dest,"first"):- jump_table_prelude(EA1,_), take_address(EA1,Table), next(EA1,EA2), arch.load(EA2,_,_,_,_,_,_,_), next(EA2,EA3), take_address(EA3,Ref), data_word(Table,8,Diff), RefSigned = as(Ref,number), Dest = as(RefSigned + Diff,address), possible_ea(Dest). relative_address_start(ImageBase+OffsetUnsigned,MultUnsigned,ImageBase,Dest,"first"):- base_address(ImageBase), jump_table_prelude(EA,_), instruction_get_operation(EA,"MOV"), instruction_get_src_op(EA,_,Op), op_indirect_mapped(Op,_,RegBase,RegIndex,Mult,Offset,Size), Offset > 0, MultUnsigned = as(Mult, unsigned), OffsetUnsigned = as(Offset,unsigned), MultUnsigned * 8 = Size, RegBase != "NONE", RegIndex != "NONE", (MultUnsigned = 4; MultUnsigned = 8), data_word(ImageBase+OffsetUnsigned,MultUnsigned,Diff), ImageBaseSigned = as(ImageBase, number), Dest = as(ImageBaseSigned + Diff,address), possible_ea(Dest). #line 382 "binary/pe/pe_binaries.dl" relative_address_start(IndexTableStart,1,TableStart,Dest,"first"):- arch.pointer_size(Pt_size), Mult = as(Pt_size,number), relative_address_start(TableStart,Pt_size,_,_,_), arch.jump(EA_jmp), instruction_get_op(EA_jmp,_,Op_jmp), op_indirect(Op_jmp,_,_,_,Mult,as(TableStart,number),_), ( next(EA_mov,EA_jmp) ; next(EA_pop1,EA_jmp), !arch.memory_access("LOAD",EA_pop1,_,_,_,_,_,_,_), next(EA_mov,EA_pop1) ; next(EA_pop2,EA_jmp), !arch.memory_access("LOAD",EA_pop2,_,_,_,_,_,_,_), next(EA_pop1,EA_pop2), !arch.memory_access("LOAD",EA_pop1,_,_,_,_,_,_,_), next(EA_mov,EA_pop1) ), arch.load(EA_mov,_,_,_,_,_,_,_), instruction_get_op(EA_mov,_,Op_mov), op_indirect(Op_mov,_,_,_,1,Offset0,8), ( Offset = Offset0 ; Offset = Offset0+4 ), IndexTableStart = as(Offset,address), data_byte(IndexTableStart,Byte), Dest = TableStart + Byte*4. relative_address_start(Table,1,Ref,Dest,"first"):- base_address(ImageBase), arch.load(EA1,_,_,_,_,_,_,_), instruction_get_src_op(EA1,_,Op1), op_indirect(Op1,_,_,_,1,Offset1,8), Offset1 > 0, Table = ImageBase+as(Offset1,unsigned), data_byte(Table,Byte), next(EA1,EA2), instruction_get_src_op(EA2,_,Op2), op_indirect(Op2,_,_,_,4,Offset2,32), Offset2 > 0, Ref = ImageBase+as(Offset2,unsigned), Dest = Ref + Byte. relative_address(EA+1,1,IndexTable,AddressTable,Dest,"first"):- binary_isa("X64"), base_address(ImageBase), relative_address(EA,1,IndexTable,AddressTable,_,"first"), data_byte(EA+1,Byte), Dest = AddressTable + Byte*4, data_word(Dest,4,Word), possible_ea(ImageBase+as(Word,unsigned)), !relative_address_start(EA+1,_,_,_,_). relative_address(EA+1,1,IndexTable,AddressTable,Dest,"first"):- binary_isa("X86"), ImageBase = 0, relative_address(EA,1,IndexTable,AddressTable,_,"first"), data_byte(EA+1,Byte), Dest = AddressTable + Byte*4, data_word(Dest,4,Word), possible_ea(ImageBase+as(Word,unsigned)), !relative_address_start(EA+1,_,_,_,_). relative_jump_table_entry_candidate(EA,TableStart,1,Ref,Dest,4,0):- relative_address(EA,1,TableStart,Ref,Dest,"first"), Dest < TableStart, relative_address_start(Ref,4,_,_,_), loaded_section(Start,End,_), Ref >= Start, Ref < End, Dest >= Start, Dest < End. main_function(EA):- code(EA1), direct_call(EA1,PLT_ARGC), plt_block(PLT_ARGC,"__p___argc"), next(EA1,Block), code_in_refined_block(EA_call_main,Block), direct_call(EA_call_main,EA). inferred_special_symbol(EA,"main","PUBLIC","NONE","Beg"):- binary_format("PE"), main_function(EA). is_padding(EA):- binary_format("PE"), instruction_get_operation(EA,"INT3"). discarded_block(EA,"code","PE padding considered data"):- binary_format("PE"), code_in_block_candidate_refined(EA,EA), instruction_get_operation(EA,"INT3"), !direct_jump(_,EA), !direct_call(_,EA), !must_fallthrough(_,EA). moved_label_class(EA,Op_index,"base-relative collides with pointer"), moved_data_label(EA+Disp_offset,Size,ImageBase+Dest,NewDest):- base_address(ImageBase), base_relative_symbolic_operand(EA,Op_index,Dest), instruction_displacement_offset(EA,Op_index,Disp_offset,_), symbol_minus_symbol(EA+Disp_offset,Size,_,_,_,_), arch.pointer_size(Pt_size), address_in_data_refined_range.overlap(ImageBase+Dest,Pt_size,NewDest), symbolic_data(NewDest,_,_). jump_table_start(EA_jump,4,TableStart,TableReference,1):- base_address(ImageBase), base_relative_jump(EA_base,EA_jump), base_relative_operand(EA_base,_,Value), TableStart=ImageBase+Value, TableReference=ImageBase. relative_address_start(TableStart,Size,0,Dest,"first"):- indirect_jump(EA), instruction_get_op(EA,_,Op), op_indirect(Op,"NONE","NONE",_,Mult,Offset,_), Size = as(Mult,unsigned), TableStart = as(Offset,address), data_word(TableStart,Size,TableEntry), Dest = as(TableEntry,address), arch.pointer_size(Pt_size), Pt_size = Size, possible_ea(Dest), data_word(TableStart+Size,Size,TableEntry2), Dest2 = as(TableEntry2,address), possible_ea(Dest2). symbolic_operand_candidate(EA,Op_index,as(Offset,address),"jump-table"), moved_label_class(EA,Op_index,"relax basic jump-table-start"), moved_label(EA,Op_index,as(Offset,address),TableStart), relative_address_start(TableStart,Size,0,Dest,"first"):- indirect_jump(EA), instruction_get_op(EA,Op_index,Op), op_indirect(Op,"NONE","NONE",_,Mult,Offset,_), Size = as(Mult,unsigned), !address_in_data(as(Offset,address),_), TableStart = as(Offset+Mult,address), data_word(TableStart,Size,TableEntry), Dest = as(TableEntry,address), arch.pointer_size(Pt_size), Pt_size = Size, possible_ea(Dest), data_word(TableStart+Size,Size,TableEntry2), Dest2 = as(TableEntry2,address), possible_ea(Dest2). relative_address_start(TableStart,4,0,Dest,"first"):- instruction(EA_load,_,_,"LEA",Op,_,_,_,_,_), op_indirect(Op,"NONE","NONE","NONE",_,Offset,_), TableStart = as(Offset,address), data_word(TableStart,4,TableEntry), Dest = as(TableEntry,address), possible_ea(Dest), data_word(TableStart+4,4,TableEntry2), Dest2 = as(TableEntry2,address), possible_ea(Dest2), next(EA_load,EA_mov), arch.load(EA_mov,_,_,_,_,_,_,_), next(EA_mov,EA_call), reg_call(EA_call,_). #line 603 "binary/pe/pe_binaries.dl" .decl npad(EA:address,Size:unsigned) .output npad npad(EA,Size):- instruction(EA,Size,_,"MOV",Op,Op,_,_,_,_), op_regdirect(Op,"EDI"), Size = 2. npad(EA,Size):- unconditional_jump(EA), direct_jump(EA,Dest), Size = Dest - EA, Size <= 15, npad(EA+2,_). is_padding(EA):- binary_format("PE"), npad(EA,_). .decl merged_data_region(Start:address,End:address) .output merged_data_region merged_data_region(DataStart,DataStart+DataSize):- binary_format("PE"), !loaded_section(_,_,".rdata"), ( pe_data_directory(_,DataStart,DataSize), DataSize > 0; pe_debug_data(_,DataStart,DataSize), DataSize > 0 ), entry_point(Entry), DataStart < Entry, loaded_section(SectionStart,SectionEnd,".text"), DataStart > SectionStart, DataStart < SectionEnd. data_region(Start,Size):- Last = max End:{merged_data_region(_,End)}, loaded_section(Start,_,".text"), Size = Last - Start. #line 85 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 87 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "arch/arch.dl" #line 31 "arch/arch.dl" #line 1 "../arm_binaries.dl" #line 31 "../arm_binaries.dl" .decl contains_implausible_instr_seq(Block:address) contains_implausible_instr_seq(0):- false. #line 42 "../arm_binaries.dl" .decl contains_plausible_instr_seq(Block:address,Weight:number,Type:symbol) .output contains_plausible_instr_seq #line 49 "../arm_binaries.dl" contains_plausible_instr_seq(Block,3,"cmp/conditional-branch"):- ( conditional_jump(EA) ; conditional_return(EA) ), code_in_block_candidate(EA,Block), next(PrevEA,EA), code_in_block_candidate(PrevEA,Block), instruction_get_operation(PrevEA,Operation), arch.cmp_operation(Operation). #line 69 "../arm_binaries.dl" .decl plausible_block(Block:address,Weight:number,Type:symbol,Block2:address) .output plausible_block plausible_block(0,0,"",0):- false. block_points(Block,"code",0,Weight,cat("plausible_block: ", Why)):- block_is_overlapping(Block,"code"), plausible_block(Block,Weight,Why,_). avoid_symbols("$d"). plt_entry(EA,Function):- plt_section(SecName), loaded_section(Beg,End,SecName), EA >= Beg, EA < End, arch.jump(EA), instruction_get_op(EA,_,Op), op_indirect(Op,_, _, _,_, Offset, _), Got_entry = as(as(65536+ EA,number) + Offset, address), relocation(Got_entry,_,Function,_,_,_,_). symbolic_operand_point(EA,Imm_index,-2,"invalid symbolic operand for mov"):- symbolic_operand_candidate(EA,Imm_index,_,_), !symbolic_operand_attribute(EA,_,_), instruction_get_operation(EA,Operation), Operation != "MOVT", Operation != "MOVW", contains("MOV",Operation). symbolic_operand_point(EA,Imm_index,-1,"unlikely to have symbolic operand"):- symbolic_operand_candidate(EA,Imm_index,_,_), instruction_get_operation(EA,Operation), ( arch.cmp_operation(Operation) ; arch.logic_operation(Operation) ). symbolic_operand_point(EA,2,-2,"arm: add r, r, n"):- instruction(EA,_,_,Operation,Op1,Op2,Op3,0,_,_), ( substr(Operation,0,3) = "ADD"; substr(Operation,0,3) = "SUB"; substr(Operation,0,3) = "RSB" ), op_regdirect_contains_reg(Op1,Reg), !arch.pc_reg(Reg), op_immediate(Op2,_), Op3 != 0, !symbolic_operand_attribute(EA,_,_). unlikely_have_symbolic_immediate(EA):- instruction_get_operation(EA, Operation), ( arch.logic_operation(Operation); Operation != "MOVT", Operation != "MOVW", contains("MOV",Operation); contains("CMP", Operation); contains("CMN", Operation); contains("SUB", Operation); contains("RSB", Operation) ). instruction_has_relocation(EA,EA-Mode):- binary_type("REL"), instruction(EA,_,_,_,_,_,_,_,_,_), Mode = EA band 1, relocation(EA-Mode,_,_,_,_,_,_). symbolic_expr_from_relocation(EA,4,Symbol,Addend,Dest):- binary_type("REL"), relocation(EA,"ABS32",Symbol,_,SymbolIndex,_,"REL"), symbol(Base,_,_,_,_,_,_,SymbolIndex,Symbol), data_word(EA,4,Value), S = as(Base,unsigned), A = as(Value,unsigned), T = as(Base band 1,unsigned), Dest = ((S + A) bor T), Addend = as(Base - Dest,number). symbolic_expr_attribute(EA,"GotRelPC"), symbolic_expr_from_relocation(EA,4,Symbol,Addend,EA+as(Addend,address)):- binary_type("REL"), relocation(EA,"GOT_BREL",Symbol,_,_,_,_), data_word(EA,4,Addend). #line 163 "../arm_binaries.dl" .decl condition_code_map(Suffix:symbol,CC:condition_code) condition_code_map("EQ","E"). condition_code_map("NE","NE"). condition_code_map("GT","G"). condition_code_map("LT","L"). condition_code_map("GE","GE"). condition_code_map("LE","LE"). condition_code_map("HS","AE"). condition_code_map("LO","B"). condition_code_map("MI","S"). condition_code_map("PL","NS"). condition_code_map("VS","O"). condition_code_map("VC","OV"). condition_code_map("HI","A"). condition_code_map("LS","BE"). #line 32 "arch/arch.dl" #line 1 "../arm64_binaries.dl" #line 28 "../arm64_binaries.dl" avoid_symbols("$x"). basic_target(Val):- defined_symbol(Val,_,_,_,_,_,_,_,"$x"). #line 36 "../arm64_binaries.dl" .decl split_load(ea:address, nextea:address, dest:address, type:symbol) .output split_load #line 43 "../arm64_binaries.dl" split_load(EA, NextEA, as(Base + Offset,address), "ADD") :- instruction_get_operation(EA,ADROperation), substr(ADROperation,0,3) = "ADR", instruction_get_op(EA, 1, BaseOp), op_immediate(BaseOp, Base), instruction_get_op(EA, 2, RegOp), op_regdirect_contains_reg(RegOp,Reg), ( next(EA, NextEA) ; next(EA, NextEA0), next(NextEA0, NextEA), instruction_get_dest_op(NextEA0,_,TmpOp), !op_regdirect_contains_reg(TmpOp,Reg) ), instruction_get_operation(NextEA, "ADD"), instruction_get_op(NextEA, 2, OffsetOp), op_immediate(OffsetOp, Offset), instruction_get_op(NextEA, 1, RegOp2), op_regdirect_contains_reg(RegOp2,Reg2), Reg = Reg2. #line 78 "../arm64_binaries.dl" split_load(EA, NextEA, as(Base + Offset,address), "LDR/STR") :- instruction_get_operation(EA,ADROperation), substr(ADROperation,0,3) = "ADR", instruction_get_op(EA, 1, BaseOp), op_immediate(BaseOp, Base), instruction_get_op(EA, 2, RegOp), op_regdirect_contains_reg(RegOp,Reg), ( next(EA,NextEA) ; next(EA,NextEA0), next(NextEA0,NextEA), NextEA0 != NextEA, instruction_get_dest_op(NextEA0,_,TmpOp), !op_regdirect_contains_reg(TmpOp,Reg) ), instruction_get_operation(NextEA, Operation), ( arch.load_operation(Operation) ; arch.store_operation(Operation) ), instruction_get_op(NextEA, 1, OffsetOp), op_indirect_mapped(OffsetOp,"NONE",Reg,"NONE",_,Offset,_). pc_relative_jump(EA, as(Dest,address)):- split_load(EA, _, Dest, "LDR/STR"). #line 135 "../arm64_binaries.dl" .decl adrp_used(EA:address,Reg:register,UsedEA:address,Dest:address) adrp_used(EA,Reg,UsedEA,Dest):- const_value_reg_used(UsedEA,EA,EARegDef,Reg,as(Dest,number)), arch.adr_dest(EA,_,Dest), Dest band 0xFFF = 0, instruction_get_operation(EARegDef,Operation), Operation != "ADD". #line 158 "../arm64_binaries.dl" .decl split_load_tail(EA:address,Offset:number,Reg:register,Type:symbol) split_load_tail(EA,Offset,Reg,Type):- arch.reg_arithmetic_operation(EA,_,Reg,1,Offset), !arch.memory_access(_,EA,_,_,_,_,_,_,_), Type = "ADD". split_load_tail(EA,Offset,Reg_nn,Type):- arch.memory_access(_,EA,_,_,_,Reg,"NONE",_,Offset), instruction(EA,_,_,_,_,Op2,Op3,_,_,_), !op_immediate(Op2,_), !op_immediate(Op3,_), reg_nonnull(Reg,Reg_nn), Type = "LDR/STR". #line 184 "../arm64_binaries.dl" .decl split_load_for_symbolization(ea:address, nextea:address, dest:address, type:symbol) .output split_load_for_symbolization split_load_for_symbolization(EA,UsedEA,as(as(Base,number)+Offset,address),Type):- adrp_used(EA,Reg,UsedEA,Base), split_load_tail(UsedEA,Offset,Reg,Type). split_load_operand(EA, 1, as(Dest,address)) :- split_load_for_symbolization(EA, _, Dest, _). split_load_operand(EA, 1, as(Dest,address)) :- split_load_for_symbolization(_, EA, Dest, "LDR/STR"). split_load_operand(EA, 2, as(Dest,address)) :- split_load_for_symbolization(_, EA, Dest, "ADD"). #line 220 "../arm64_binaries.dl" symbolic_operand_attribute(EA,1,"GotRef"), symbolic_operand_attribute(EA_ldr,1,"GotRef"), symbolic_operand_attribute(EA_ldr,1,"Lo12"):- split_load_for_symbolization(EA,EA_ldr,Dest,"LDR/STR"), !split_load_for_symbolization(EA,EA_ldr,Dest,"ADD"), relocation(Dest,_,_,_,_,_,_), loaded_section(Beg,End,".got"), Beg <= Dest, Dest < End. symbolic_operand_attribute(EA,1,"Lo12"):- split_load_for_symbolization(EA0,EA,Dest,"LDR/STR"), ( !relocation(Dest,_,_,_,_,_,_), EA0 = EA0 ; split_load_for_symbolization(EA0,_,Dest,"ADD") ; loaded_section(Beg,End,".got"), ( Beg > Dest, End = End ; Dest >= End, Beg = Beg ) ). symbolic_operand_attribute(EA,2,"Lo12"):- split_load_for_symbolization(_,EA,Dest,"ADD"), !relocation(as(Dest,address),"GLOB_DAT",_,_,_,_,_). value_reg(EA,Reg,EA,"NONE",0,Val,1):- split_load_for_symbolization(_,EA,RefAddr,_), arch.load(EA,OpIndex,_,Reg,_,_,_,_), track_register(Reg), instruction_get_op(EA,OpIndex,Op1), op_indirect(Op1,_,_,_,_,_,DataSize), data_word(RefAddr,DataSize/8,Val). value_reg(EA,Reg,EA,"NONE",0,Val,1):- instruction(EA,_,_,Operation,Op1,Op2,_,_,_,_), ( Operation = "ADRP"; Operation = "ADR" ), op_regdirect_contains_reg(Op2,Reg), track_register(Reg), op_immediate(Op1,Offset), Val = Offset. symbolic_operand_candidate(EA,1,Dest,Type):- code(EA), instruction_get_operation(EA, Operation), ( Operation = "ADR"; Operation = "ADRP" ), !split_load_operand(EA,1,_), instruction_get_op(EA, 1, OffsetOp), op_immediate(OffsetOp, Offset), Dest = as(Offset,address), ( code(Dest), Type="code" ; data_segment(Begin,End), Dest >= Begin, Dest <= End, Type = "data" ). unlikely_have_symbolic_immediate(EA):- instruction_get_operation(EA, Operation), contains("ADD", Operation), !split_load(_,EA,_,"ADD"). #line 33 "arch/arch.dl" #line 1 "arm64/arch_arm64.dl" #line 29 "arm64/arch_arm64.dl" .comp ARM64 : Arch { #line 31 "arm64/arch_arm64.dl" #line 1 "float_operations.dl" #line 27 "float_operations.dl" float_operation("MOVSS"). float_operation("MOVSD"). float_operation("MOVSD2"). float_operation("MOVUPS"). float_operation("MOVUPD"). float_operation("MOVAPS"). float_operation("MOVAPD"). float_operation("ADDSS"). float_operation("ADDSD"). float_operation("ADDPS"). float_operation("ADDPD"). float_operation("SUBSS"). float_operation("SUBSD"). float_operation("SUBPS"). float_operation("SUBPD"). float_operation("MULSS"). float_operation("MULSD"). float_operation("MULPS"). float_operation("MULPD"). float_operation("DIVSS"). float_operation("DIVSD"). float_operation("DIVPS"). float_operation("DIVPD"). float_operation("MINSS"). float_operation("MINSD"). float_operation("MINPS"). float_operation("MINPD"). float_operation("MAXSS"). float_operation("MAXSD"). float_operation("MAXPS"). float_operation("MAXPD"). float_operation("ROUNDSS"). float_operation("ROUNDSD"). float_operation("ROUNDPS"). float_operation("ROUNDPD"). float_operation("SQRTSS"). float_operation("SQRTSD"). float_operation("SQRTPS"). float_operation("SQRTPD"). #line 32 "arm64/arch_arm64.dl" #line 1 "jump_operations.dl" #line 28 "jump_operations.dl" jump_operation("B"). jump_operation("B.AL"). jump_operation("BR"). #line 35 "jump_operations.dl" .decl conditional_branch(Operation:symbol,CC:condition_code) conditional_branch(Operation,CC):- ( Base = "B."; Base = "BC." ), condition_code_map(Suffix,CC), Operation = cat(Base,Suffix). jump_operation(Operation), conditional_operation(Operation,CC):- conditional_branch(Operation,CC). #line 52 "jump_operations.dl" .decl test_jump_operation(Operation:symbol,JumpTargetIndex:operand_index,CC:condition_code) test_jump_operation("CBZ",1,"E"). test_jump_operation("CBNZ",1,"NE"). test_jump_operation("TBZ",2,"E"). test_jump_operation("TBNZ",2,"NE"). jump_operation(Operation), conditional_operation(Operation,CC):- test_jump_operation(Operation,_,CC). jump_operation_op_index(Operation,1):- jump_operation(Operation), !test_jump_operation(Operation,_,_). jump_operation_op_index(Operation,Index):- jump_operation(Operation), test_jump_operation(Operation,Index,_). call_operation_op_index(Operation,1):- call_operation(Operation). #line 33 "arm64/arch_arm64.dl" #line 1 "interrupt_operations.dl" #line 27 "interrupt_operations.dl" interrupt_operation("INT"). interrupt_operation("INTO"). interrupt_operation("INT1"). interrupt_operation("INT3"). #line 34 "arm64/arch_arm64.dl" #line 1 "registers.dl" #line 29 "registers.dl" register_size_bits(Reg32, 32), register_size_bits(Reg64, 64), reg_map_rule(Reg32, Reg64), general_purpose_reg(Reg64):- I = range(0,29), Reg32 = cat("W", to_string(I)), Reg64 = cat("X", to_string(I)). register_size_bits("W29", 32). register_size_bits("W30", 32). register_size_bits("WSP", 32). register_size_bits("FP", 64). register_size_bits("LR", 64). register_size_bits("SP", 64). reg_map_rule("W29", "FP"). reg_map_rule("W30", "LR"). reg_map_rule("WSP", "SP"). general_purpose_reg("FP"). general_purpose_reg("LR"). function_non_maintained_reg(Reg):- I = range(0,19), Reg = cat("X", to_string(I)). function_non_maintained_reg("FP"). pc_reg(""):- false. frame_pointer(""):- false. stack_pointer("SP"). return_reg("X0"). condition_flags_reg("NZCV"). integer_reg_param("X0",1). integer_reg_param("X1",2). integer_reg_param("X2",3). integer_reg_param("X3",4). integer_reg_param("X4",5). integer_reg_param("X5",6). integer_reg_param("X6",7). integer_reg_param("X7",8). #line 35 "arm64/arch_arm64.dl" #line 1 "memory_access.dl" #line 33 "memory_access.dl" memory_access(AccessType,EA,SrcIndex,DstIndex,DirectReg,BaseReg,"NONE",0,0), reg_arithmetic_operation(EA,BaseReg_nn,BaseReg_nn,1,Offset):- instruction(EA,_,_,Operation,Op1,Op2,Op3,0,_,_), instruction_writeback(EA), ( load_operation(Operation), AccessType = "LOAD", SrcIndex = 1, DstIndex = 3; store_operation(Operation), AccessType = "STORE", SrcIndex = 3, DstIndex = 1 ), op_indirect_mapped(Op1,"NONE",BaseReg,"NONE",_,0,_), reg_nonnull(BaseReg,BaseReg_nn), op_immediate(Op2,Offset), op_regdirect_contains_reg(Op3,DirectReg). memory_access(AccessType,EA,SrcIndex,DstIndex,DirectReg,BaseReg,"NONE",0,Offset), reg_arithmetic_operation(EA,BaseReg_nn,BaseReg_nn,1,Offset):- instruction(EA,_,_,Operation,Op1,Op2,0,0,_,_), instruction_writeback(EA), ( load_operation(Operation), AccessType = "LOAD", SrcIndex = 1, DstIndex = 2; store_operation(Operation), AccessType = "STORE", SrcIndex = 2, DstIndex = 1 ), op_indirect_mapped(Op1,"NONE",BaseReg,"NONE",_,Offset,_), reg_nonnull(BaseReg,BaseReg_nn), op_regdirect_contains_reg(Op2,DirectReg). memory_access(AccessType,EA,SrcIndex,DstIndex,DirectReg,BaseReg,"NONE",0,Offset):- instruction(EA,_,_,Operation,Op1,Op2,0,0,_,_), !instruction_writeback(EA), ( load_operation(Operation), AccessType = "LOAD", SrcIndex = 1, DstIndex = 2; store_operation(Operation), AccessType = "STORE", SrcIndex = 2, DstIndex = 1 ), op_indirect_mapped(Op1,"NONE",BaseReg,"NONE",_,Offset,_), reg_nonnull(BaseReg,_), op_regdirect_contains_reg(Op2,DirectReg). memory_access("LOAD",EA,1,2,DstReg,"NONE","NONE",0,Immediate):- instruction(EA,_,_,Operation,Op1,Op2,0,0,_,_), load_operation(Operation), op_immediate(Op1,Immediate), op_regdirect_contains_reg(Op2,DstReg). memory_access(AccessType,EA,SrcIndex,DstIndex,DirectReg,BaseReg,IndexReg,Mult,0):- instruction(EA,_,_,Operation,Op1,Op2,0,0,_,_), ( load_operation(Operation), AccessType = "LOAD", SrcIndex = 1, DstIndex = 2; store_operation(Operation), AccessType = "STORE", SrcIndex = 2, DstIndex = 1 ), op_indirect_mapped(Op1,"NONE",BaseReg,IndexReg,Mult,0,_), reg_nonnull(BaseReg,_), reg_nonnull(IndexReg,_), op_regdirect_contains_reg(Op2,DirectReg). memory_access(AccessType,EA,SrcIndex1,DstIndex1,DirectReg1,BaseReg,"NONE",0,0), memory_access(AccessType,EA,SrcIndex2,DstIndex2,DirectReg2,BaseReg,"NONE",0,as(SizeBits/8,number)), reg_arithmetic_operation(EA,BaseReg_nn,BaseReg_nn,1,Offset):- instruction(EA,_,_,Operation,Op1,Op2,Op3,Op4,_,_), instruction_writeback(EA), ( load_operation(Operation), AccessType = "LOAD", SrcIndex1 = 2, SrcIndex2 = 2, DstIndex1 = 1, DstIndex2 = 4; store_operation(Operation), AccessType = "STORE", SrcIndex1 = 1, SrcIndex2 = 4, DstIndex1 = 2, DstIndex2 = 2 ), op_regdirect(Op1,DirectReg2_unmapped), op_regdirect_contains_reg(Op1,DirectReg2), op_indirect_mapped(Op2,"NONE",BaseReg,"NONE",_,0,_), reg_nonnull(BaseReg,BaseReg_nn), op_immediate(Op3,Offset), op_regdirect_contains_reg(Op4,DirectReg1), register_size_bits(DirectReg2_unmapped,SizeBits). memory_access(AccessType,EA,SrcIndex1,DstIndex1,DirectReg1,BaseReg,"NONE",0,Offset), memory_access(AccessType,EA,SrcIndex2,DstIndex2,DirectReg2,BaseReg,"NONE",0,Offset+as(SizeBits/8,number)), reg_arithmetic_operation(EA,BaseReg_nn,BaseReg_nn,1,Offset):- instruction(EA,_,_,Operation,Op1,Op2,Op3,0,_,_), instruction_writeback(EA), ( load_operation(Operation), AccessType = "LOAD", SrcIndex1 = 2, SrcIndex2 = 2, DstIndex1 = 1, DstIndex2 = 3; store_operation(Operation), AccessType = "STORE", SrcIndex1 = 1, SrcIndex2 = 3, DstIndex1 = 2, DstIndex2 = 2 ), op_regdirect(Op1,DirectReg2_unmapped), op_regdirect_contains_reg(Op1,DirectReg2), op_indirect_mapped(Op2,"NONE",BaseReg,"NONE",_,Offset,_), reg_nonnull(BaseReg,BaseReg_nn), op_regdirect_contains_reg(Op3,DirectReg1), register_size_bits(DirectReg2_unmapped,SizeBits). memory_access(AccessType,EA,SrcIndex1,DstIndex1,DirectReg1,BaseReg,"NONE",0,Offset), memory_access(AccessType,EA,SrcIndex2,DstIndex2,DirectReg2,BaseReg,"NONE",0,Offset+as(SizeBits/8,number)):- instruction(EA,_,_,Operation,Op1,Op2,Op3,0,_,_), !instruction_writeback(EA), ( load_operation(Operation), AccessType = "LOAD", SrcIndex1 = 2, SrcIndex2 = 2, DstIndex1 = 1, DstIndex2 = 3; store_operation(Operation), AccessType = "STORE", SrcIndex1 = 1, SrcIndex2 = 3, DstIndex1 = 2, DstIndex2 = 2 ), op_regdirect(Op1,DirectReg2_unmapped), op_regdirect_contains_reg(Op1,DirectReg2), op_indirect_mapped(Op2,"NONE",BaseReg,"NONE",_,Offset,_), reg_nonnull(BaseReg,_), op_regdirect_contains_reg(Op3,DirectReg1), register_size_bits(DirectReg2_unmapped,SizeBits). #line 36 "arm64/arch_arm64.dl" move_operation(Operation) :- instruction_get_operation(_, Operation), contains("MOV", Operation). load_operation(Operation):- instruction_get_operation(_,Operation), ( contains("LDR", Operation) ; contains("LDP", Operation) ). load_word_operation(Operation):- instruction_get_operation(_,Operation), substr(Operation,0,3) = "LDR", ( strlen(Operation) = 3; strlen(Operation) = 5 ). store_operation(Operation):- instruction_get_operation(_,Operation), ( contains("STR", Operation) ; contains("STP", Operation) ). is_nop(EA):- instruction_get_operation(EA,Operation), ( Operation = "NOP"; Operation = "B.NV" ). arithmetic_operation("ADD"). arithmetic_operation("SUB"). arithmetic_operation("MUL"). arithmetic_operation("LSL"). arithmetic_operation("LSR"). arithmetic_operation("ASR"). arithmetic_operation("ROR"). arithmetic_operation("MVN"). multiplication_operation("MUL"). multiplication_operation("LSL"). shift_rotate_operation("ASR"). shift_rotate_operation("LSL"). shift_rotate_operation("LSR"). shift_rotate_operation("ROR"). logic_operation("AND"). logic_operation("XOR"). logic_operation("ORR"). logic_operation("EON"). logic_operation("ORN"). logic_operation("BIC"). pointer_size(8). call_operation("BL"). syscall_operation("SVC"). return_operation("RET"). halt_operation("HLT"). cmp_operation("CMP"). data_access_size(Operation,DestReg,Size):- instruction_get_operation(_,Operation), op_regdirect_contains_reg(_,DestReg), ( substr(Operation,0,4) = "LDRB", Size = 1; substr(Operation,0,5) = "LDRSB", Size = 1; substr(Operation,0,4) = "LDRH", Size = 2; substr(Operation,0,5) = "LDRSH", Size = 2 ). reg_arithmetic_operation(EA,Dst,Src,1,Immediate):- instruction(EA,_,_,"ADD",Op1,Op2,Op3,0,_,_), op_regdirect_contains_reg(Op1,Src), op_immediate(Op2,Immediate), op_regdirect_contains_reg(Op3,Dst). reg_reg_arithmetic_operation(EA,Dst,Src1,Src2,Sign*Mult,0):- instruction(EA,_,_,Operand,Op1,Op2,Op3,0,_,_), ( Operand = "ADD", Sign = 1; Operand = "SUB", Sign = -1 ), op_regdirect_contains_reg(Op1,Src1), op_regdirect_contains_reg(Op2,Src2), op_regdirect_contains_reg(Op3,Dst), ( op_shifted(EA,3,Shift,"LSL"), Mult=2^as(Shift,number); !op_shifted(EA,3,_,_), Mult = 1 ). inferred_main_in_reg(EA,"X0"):- inferred_main_dispatch(EA). #line 152 "arm64/arch_arm64.dl" .decl adr_dest(EA:address,Reg:register,Dest:address) adr_dest(EA,Reg,as(Dest,address)):- instruction(EA,_,_,Operation,ImmOp,RegOp,0,0,_,_), substr(Operation,0,3) = "ADR", op_immediate(ImmOp,Dest), op_regdirect_contains_reg(RegOp,Reg). pc_relative_addr(EA,Reg,Dest):- adr_dest(EA,Reg,Dest). #line 171 "arm64/arch_arm64.dl" .decl extend_type(Type:symbol,Signed:unsigned,SrcBits:unsigned) extend_type("UXTB",0,8). extend_type("UXTH",0,16). extend_type("UXTW",0,32). extend_type("UXTX",0,64). extend_type("SXTB",1,8). extend_type("SXTH",1,16). extend_type("SXTW",1,32). extend_type("SXTX",1,64). extend_reg(EA,Reg,Signed,SrcBits):- extend_type(ExtendType,Signed,SrcBits), op_shifted(EA,Index,_,ExtendType), instruction_get_op(EA,Index,Op), op_regdirect_contains_reg(Op,Reg). } #line 34 "arch/arch.dl" .init arch = ARM64 #line 83 "arch/arch.dl" .type condition_code <: symbol #line 88 "arch/arch.dl" .comp Arch { #line 97 "arch/arch.dl" .decl float_operation(Operation:symbol) .decl interrupt_operation(Operation:symbol) #line 105 "arch/arch.dl" .decl jump_operation(Operation:symbol) #line 110 "arch/arch.dl" .decl move_operation(Operation:symbol) .output move_operation .decl load_operation(Operation:symbol) .decl load_word_operation(Operation:symbol) load_word_operation(""):- false. .decl store_operation(Operation:symbol) .output store_operation .decl conditional_operation(Operation:symbol,CC:condition_code) .decl conditional(EA:address,CC:condition_code) .output conditional conditional(EA,CC):- instruction_get_operation(EA,Operation), arch.conditional_operation(Operation,CC). #line 134 "arch/arch.dl" .decl multiplication_operation(Operation:symbol) #line 140 "arch/arch.dl" .decl shift_rotate_operation(Operation:symbol) #line 146 "arch/arch.dl" .decl arithmetic_operation(Operation:symbol) .output arithmetic_operation #line 152 "arch/arch.dl" .decl logic_operation(Operation:symbol) .output logic_operation .decl call_operation(Operation:symbol) .output call_operation .decl syscall_operation(Operation:symbol) .decl return_operation(Operation:symbol) .decl halt_operation(Operation:symbol) .output halt_operation halt_operation(""):- false. #line 176 "arch/arch.dl" .decl cmp_operation(Operation:symbol) .output cmp_operation #line 185 "arch/arch.dl" .decl cmp_zero_operation(Operation:symbol) .output cmp_zero_operation cmp_zero_operation(""):- false. .decl jump_operation_op_index(Operation:symbol,operand_index:operand_index) .decl call_operation_op_index(Operation:symbol,operand_index:operand_index) #line 209 "arch/arch.dl" .decl move_reg_reg(EA:address,Dst:register,Src:register) move_reg_reg(EA,Dst,Src):- instruction(EA,_,_,Operation,Op1,Op2,0,0,_,_), move_operation(Operation), op_regdirect_contains_reg(Op1,Src), op_regdirect_contains_reg(Op2,Dst). #line 222 "arch/arch.dl" .decl move_reg_imm(EA:address,Dst:register,Imm:number,ImmIndex:operand_index) move_reg_imm(EA,Dst,Value,1):- instruction(EA,_,_,Operation,Op1,Op2,0,0,_,_), move_operation(Operation), op_immediate(Op1,Value), op_regdirect_contains_reg(Op2,Dst). .decl move(EA:address) move(EA):- ( move_reg_reg(EA,_,_); move_reg_imm(EA,_,_,_) ). .decl is_nop(EA:address) is_nop(EA):- reg_arithmetic_operation(EA,Reg,Reg,1,0). #line 247 "arch/arch.dl" .decl return(EA:address) overridable .output return return(EA):- instruction_get_operation(EA,Operation), return_operation(Operation). .decl jump(EA:address) overridable .output jump jump(EA):- instruction_get_operation(EA,Operation), jump_operation(Operation), !arch.return(EA). .decl call(EA:address,DestOperandIndex:operand_index) call(EA,DestOperandIndex):- instruction_get_operation(EA,Operation), call_operation(Operation), call_operation_op_index(Operation,DestOperandIndex). #line 278 "arch/arch.dl" .decl memory_access_aggregated(AccessType:symbol,EA:address, BaseReg:reg_nullable,IndexReg:reg_nullable,Mult:number,Offset:number, AccessSize:unsigned) .output memory_access_aggregated memory_access_aggregated("",0,"","",0,0,0):- false. #line 305 "arch/arch.dl" .decl memory_access(AccessType:symbol,EA:address,SrcOp:operand_index,DstOp:operand_index, DirectReg:register,BaseReg:reg_nullable,IndexReg:reg_nullable,Mult:number,Offset:number) .output memory_access #line 314 "arch/arch.dl" .decl load(EA:address,SrcOp:operand_index,DstOp:operand_index,DstReg:register, BaseReg:reg_nullable,IndexReg:reg_nullable,Mult:number,Offset:number) inline load(EA,SrcOp,DstOp,DstReg,BaseReg,IndexReg,Mult,Offset):- memory_access("LOAD",EA,SrcOp,DstOp,DstReg,BaseReg,IndexReg,Mult,Offset). #line 325 "arch/arch.dl" .decl store(EA:address,SrcOp:operand_index,DstOp:operand_index,SrcReg:register, BaseReg:reg_nullable,IndexReg:reg_nullable,Mult:number,Offset:number) inline store(EA,SrcOp,DstOp,SrcReg,BaseReg,IndexReg,Mult,Offset):- memory_access("STORE",EA,SrcOp,DstOp,SrcReg,BaseReg,IndexReg,Mult,Offset). .decl delay_slot(BranchEA:address,EA:address) .output delay_slot delay_slot(0,0):- false. #line 345 "arch/arch.dl" .decl data_access_size(Operation:symbol,DestReg:register,Size:unsigned) data_access_size("","NONE",0):- false. #line 352 "arch/arch.dl" .decl reg_arithmetic_operation(EA:address,Dst:register,Src:register,Mult:number,Offset:number) .output reg_arithmetic_operation reg_arithmetic_operation(EA,Dst,Src,Mult+1,Offset):- Mult != -1, arch.reg_reg_arithmetic_operation(EA,Dst,Src,Src,Mult,Offset). #line 365 "arch/arch.dl" .decl reg_reg_arithmetic_operation(EA:address,Dst:register,Src1:register,Src2:register,Mult:number,Offset:number) .output reg_reg_arithmetic_operation reg_reg_arithmetic_operation(EA,Dst,Reg2,Reg1,1,0):- reg_reg_arithmetic_operation(EA,Dst,Reg1,Reg2,1,0). #line 385 "arch/arch.dl" .decl reg_reg_bitwise_binary_op(EA:address,Dst:register,Src1:register,Src2:register,Op:symbol) .decl reg_imm_bitwise_binary_op(EA:address,Dst:register,Src:register,Imm:number,Op:symbol) reg_reg_bitwise_binary_op(0,"","","",""):- false. reg_imm_bitwise_binary_op(0,"","",0,""):- false. #line 402 "arch/arch.dl" .decl extend_reg(EA:address,Reg:register,Signed:unsigned,SrcBits:unsigned) .output extend_reg extend_reg(0,"",0,0):- false. #line 411 "arch/arch.dl" .decl extend_load(EA:address,Signed:unsigned,SrcBits:unsigned) .output extend_load extend_load(0,0,0):- false. #line 424 "arch/arch.dl" .decl register_access_override(EA:address,Register:register,Access:access_mode,Enable:unsigned) register_access_override(0,"","",0):- false. #line 436 "arch/arch.dl" .decl op_access_override(EA:address,Index:operand_index,Access:access_mode,Enable:unsigned) op_access_override(0,0,"",0):- false. #line 444 "arch/arch.dl" .decl inferred_main_in_reg(EA:address,Reg:register) #line 449 "arch/arch.dl" .decl inferred_main_dispatch(EA:address) overridable inferred_main_dispatch(CallEA):- do_infer_main_function(), CallEA = min EA:{ start_function(Entry), arch.call(EA,_), code_in_block(EA,_), EA >= Entry }. #line 468 "arch/arch.dl" .decl reg_map_rule(RegIn:input_reg,Reg:register) reg_map_rule("",""):- false. #line 477 "arch/arch.dl" .decl function_non_maintained_reg(Reg:register) #line 482 "arch/arch.dl" .decl pc_reg(Reg:register) #line 489 "arch/arch.dl" .decl frame_pointer(Reg:register) #line 494 "arch/arch.dl" .decl stack_pointer(Reg:register) #line 499 "arch/arch.dl" .decl return_reg(Reg:register) #line 504 "arch/arch.dl" .decl general_purpose_reg(Reg:register) #line 509 "arch/arch.dl" .decl zero_reg(Reg:register) zero_reg(""):- false. #line 518 "arch/arch.dl" .decl integer_reg_param(Reg:register,Index:unsigned) #line 523 "arch/arch.dl" .decl float_reg(Reg:register,Size:unsigned) float_reg("",0):- false. #line 530 "arch/arch.dl" .decl condition_flags_reg(Reg:register) #line 535 "arch/arch.dl" .decl pc_relative_addr(EA:address,Reg:register,Target:address) pc_relative_addr(0,"",0):- false. #line 542 "arch/arch.dl" .decl register_size_bits(Reg:input_reg,Size:unsigned) .decl loop_prefix(Prefix:symbol) loop_prefix(""):- false. .decl pointer_size(N:unsigned) inline } #line 88 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 90 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "data.dl" #line 27 "data.dl" .functor functor_data_exists(EA:address,Size:unsigned):unsigned .functor functor_data_u8(EA:address):unsigned .functor functor_data_u16(EA:address):unsigned .functor functor_data_u32(EA:address):unsigned .functor functor_data_u64(EA:address):unsigned .functor functor_data_s8(EA:address):number .functor functor_data_s16(EA:address):number .functor functor_data_s32(EA:address):number .functor functor_data_s64(EA:address):number .decl data_byte(EA:address,Value:unsigned) inline data_byte(EA,Value):- data_uword(EA,1,Value). #line 46 "data.dl" .decl data_uword(EA:address,Size:unsigned,Val:unsigned) inline data_uword(EA,Size,Value):- Size = 1, @functor_data_exists(EA,Size) = 1, Value = @functor_data_u8(EA). data_uword(EA,Size,Value):- Size = 2, @functor_data_exists(EA,Size) = 1, Value = @functor_data_u16(EA). data_uword(EA,Size,Value):- Size = 4, @functor_data_exists(EA,Size) = 1, Value = @functor_data_u32(EA). data_uword(EA,Size,Value):- Size = 8, @functor_data_exists(EA,Size) = 1, Value = @functor_data_u64(EA). #line 72 "data.dl" .decl data_word(EA:address,Size:unsigned,Val:number) inline data_word(EA,Size,Value):- Size = 1, @functor_data_exists(EA,Size) = 1, Value = @functor_data_s8(EA). data_word(EA,Size,Value):- Size = 2, @functor_data_exists(EA,Size) = 1, Value = @functor_data_s16(EA). data_word(EA,Size,Value):- Size = 4, @functor_data_exists(EA,Size) = 1, Value = @functor_data_s32(EA). data_word(EA,Size,Value):- Size = 8, @functor_data_exists(EA,Size) = 1, Value = @functor_data_s64(EA). #line 91 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 93 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "jump_tables.dl" #line 38 "jump_tables.dl" .decl jump_table_candidate(EA:address,DataEA:address,TargetEA:address) .output jump_table_candidate jump_table_candidate(0,0,0):- false. #line 54 "jump_tables.dl" .decl jump_table_candidate_refined(EA:address,DataEA:address,TargetEA:address) .output jump_table_candidate_refined jump_table_candidate_refined(EA,EntryAddr,TargetAddr):- jump_table_candidate(EA,EntryAddr,TargetAddr), code(EA), code(TargetAddr), !code(EntryAddr). #line 72 "jump_tables.dl" .decl jump_table_target(EA:address,Dest:address) jump_table_target(EA,Dest):- jump_table_candidate_refined(EA,_,Dest). jump_table_target(EA,Dest):- jump_table_start(EA,Size,TableStart,_,_), relative_jump_table_entry_candidate(_,TableStart,Size,_,Dest,_,_). #line 94 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "relative_jump_tables.dl" #line 27 "relative_jump_tables.dl" .decl take_address(Src:address,Address_taken:address) take_address(Src,Address):- pc_relative_operand(Src,1,Address), instruction_get_operation(Src,"LEA"). #line 43 "relative_jump_tables.dl" .decl relative_address(EA:address,Size:unsigned,TableStart:address,Reference:address,Dest:address,DestIsFirstOrSecond:symbol) .output relative_address .decl relative_address_start(EA:address,Size:unsigned,Reference:address,Dest:address, DestIsFirstOrSecond:symbol) relative_address_start(EA,Size,EA,Dest,DestIsFirstOrSecond):- take_address(_,EA), EASigned = as(EA,number), data_word(EA,Size,Diff), Diff != 0, (binary_format("PE"); EA % Size = 0), data_word(EA+Size,Size,Diff2), Diff2 != 0, ( Size = 4, Diff <= 0, Diff2 <= 0 ; Size = 8, !relocation(EA,_,_,_,_,_,_) ), ( Dest = as(EASigned-Diff,address), DestIsFirstOrSecond = "second", Dest2 = as(EASigned-Diff2,address) ; Dest = as(EASigned+Diff,address), DestIsFirstOrSecond = "first", Dest2 = as(EASigned+Diff2,address) ), possible_ea(Dest), possible_ea(Dest2). relative_address(EA,Size,EA,Ref,Dest,DestIsFirstOrSecond):- relative_address_start(EA,Size,Ref,Dest,DestIsFirstOrSecond). relative_address(EA+Size,Size,TableStart,Ref,Dest,DestIsFirstOrSecond):- relative_address(EA,Size,TableStart,Ref,_,DestIsFirstOrSecond), Size != 1, data_word(EA+Size,Size,Diff), Diff != 0, RefSigned = as(Ref,number), ( DestIsFirstOrSecond = "second", Dest = as(RefSigned-Diff,address),Size >= 4; DestIsFirstOrSecond = "first", Dest = as(RefSigned+Diff,address) ), possible_ea(Dest), !relative_address_start(EA+Size,_,_,_,_). .decl jump_table_element_access(EA:address,Size:unsigned,TableStart:address,RegIndex:register) jump_table_element_access(EA,Size,TableStartAddr,RegIndex_nn):- data_access(EA,_,"NONE","NONE",RegIndex,as(Size,number),TableStart,Size), reg_nonnull(RegIndex,RegIndex_nn), TableStartAddr = as(TableStart,address), data_segment(Beg,End), TableStartAddr >= Beg, TableStartAddr <= End. jump_table_element_access(EA,1,TableStartAddr,RegBase_nn):- data_access(EA,_,"NONE",RegBase,"NONE",_,TableStart,1), reg_nonnull(RegBase,RegBase_nn), TableStartAddr = as(TableStart,address), data_segment(Beg,End), TableStartAddr >= Beg, TableStartAddr <= End. jump_table_element_access(EA,Size,TableStartAddr,RegIndex_nn):- data_access(EA,_,"NONE",RegBase,RegIndex,as(Size,number),Offset,Size), reg_nonnull(RegBase,RegBase_nn), reg_nonnull(RegIndex,RegIndex_nn), const_value_reg_used(EA,_,_,RegBase_nn,Base), TableStartAddr = as(Base+Offset,address), data_segment(Beg,End), TableStartAddr >= Beg, TableStartAddr <= End. jump_table_element_access(EA,Size,TableStartAddr,RegBase_nn):- data_access(EA,_,"NONE",RegBase,RegIndex,1,0,Size), reg_nonnull(RegBase,RegBase_nn), reg_nonnull(RegIndex,RegIndex_nn), const_value_reg_used(EA,_,_,RegIndex_nn,TableStart), TableStartAddr = as(TableStart,address), data_segment(Beg,End), TableStartAddr >= Beg, TableStartAddr <= End. #line 142 "relative_jump_tables.dl" .decl jump_table_signed(TableStart:address,Signed:unsigned) .output jump_table_signed jump_table_signed(TableStart,Signed):- jump_table_element_access(EA,Size,TableStart,_), arch.extend_load(EA,Signed,8*Size). jump_table_signed(TableStart,Signed):- jump_table_element_access(EA,Size,TableStart,_), value_reg(EA_used,_,EA,Reg,_,_,_), arch.extend_reg(EA_used,Reg,Signed,8*Size). jump_table_signed(TableStart,Signed):- jump_table_element_access(EA,_,TableStart,_), instruction_get_dest_op(EA,_,DstOp), op_regdirect(DstOp,DefReg), reg_map(DefReg,DefRegMapped), value_reg(EA_used,_,EA,DefRegMapped,_,_,_), instruction_get_src_op(EA_used,_,Op), op_regdirect(Op,UsedReg), reg_map(UsedReg,DefRegMapped), arch.register_size_bits(DefReg,DefSize), arch.register_size_bits(UsedReg,UsedSize), UsedSize > DefSize, Signed = 0. jump_table_signed(TableStart,Signed):- jump_table_element_access(_,Size,TableStart,_), arch.pointer_size(PtrSize), Size = PtrSize, Signed = 1. #line 182 "relative_jump_tables.dl" .decl jump_table_max(TableStart:address,TableEnd:address) .output jump_table_max jump_table_max(TableStart,TableStart+as(Value,unsigned)*Size):- jump_table_element_access(EA,Size,TableStart,RegIndex), code_in_block(EA,Block), ( !block_last_def(EA,_,RegIndex), last_value_reg_limit(_,Block,RegIndex,Value,"MAX") ; block_last_def(EA,EA_def,RegIndex), Block = Block , last_value_reg_limit(EA_def,_,RegIndex,Value,"MAX") ), Value >= 0. #line 218 "relative_jump_tables.dl" jump_table_max(TableStart2,TableStart2+IndexValue*Size2):- jump_table_element_access(EA1,Size1,TableStart1,_), jump_table_max(TableStart1,TableEnd1), def_used(EA1,Reg,EA2,_), jump_table_element_access(EA2,Size2,TableStart2,Reg), TableAddress = range(TableStart1,TableEnd1+Size1,Size1), data_uword(TableAddress,Size1,IndexValue). #line 229 "relative_jump_tables.dl" .decl jump_table_start(EA_jump:address,Size:unsigned,TableStart:address,TableRef:address,Scale:number) .output jump_table_start jump_table_start(EA_jump,Size,TableStart,as(Base,address),Scale):- jump_table_element_access(EA,Size,TableStart,_), value_reg(EA_add,RegJump,EA,Reg,Scale,Base,_), Reg != "NONE", def_used(EA_add,RegJump,EA_jump,_), ( reg_call(EA_jump,_); reg_jump(EA_jump,_) ), code(EA_jump). jump_table_start(EA_jump,Size,TableStart,TableReferenceAddr,Scale):- reg_jump(EA_jump,_), code(EA_jump), def_used(EA_base,Reg,EA_jump,_), instruction_get_operation(EA_base,Operation), ( Operation = "ADD", Scale=1; Operation = "SUB", Scale=-1 ), jump_table_element_access(EA_base,Size,TableStart,_), const_value_reg_used(EA_base,_,_,Reg,TableReference), TableReferenceAddr = as(TableReference,address), ( code(TableReferenceAddr); TableStart=TableReferenceAddr ). jump_table_start(EA_jump,4,TableStart,TableReference,1):- binary_isa("X86"), got_reference_pointer(TableReference), got_relative_operand(EA_load,1,TableStart), def_used(EA_load,Reg_got,EA_base,_), arch.reg_reg_arithmetic_operation(EA_base,Reg_jump,Reg_got,_,1,0), def_used(EA_base,_,EA_jump,_), reg_jump(EA_jump,Reg_jump). jump_table_start(EA_jump,4,TableStart,TableReference,1):- binary_isa("X86"), got_reference_pointer(TableReference), got_relative_operand(EA_add,1,TableStart), instruction_get_operation(EA_add,"ADD"), def_used(EA_add,Reg_jump,EA_jump,_), reg_jump(EA_jump,Reg_jump). #line 297 "relative_jump_tables.dl" .decl relative_jump_table_entry_target(EA:address,TableStart:address,Size:unsigned,Reference:address,Dest:address,Scale:number) inline relative_jump_table_entry_target(EA,TableStart,Size,Reference,NewDest,Scale):- jump_table_signed(TableStart,Signed), ( Signed = 0, data_uword(EA,Size,UDiff), Dest = Reference + UDiff ; Signed = 1, data_word(EA,Size,SDiff), Reference_signed = as(Reference,number), Dest = as(Reference_signed + as(Scale,number)*SDiff,address) ), ( code(Dest), NewDest = Dest; is_padding(Dest), after_end(Dest,End), after_end(NewDest,End), !is_padding(NewDest), code(NewDest) ). #line 325 "relative_jump_tables.dl" .decl relative_jump_table_entry_candidate(EA:address,TableStart:address,Size:unsigned,Reference:address,Dest:address,Scale:number,Offset:number) .output relative_jump_table_entry_candidate relative_jump_table_entry_candidate(TableStart,TableStart,Size,Reference,Dest,Scale,0):- !binary_isa("ARM"), jump_table_start(_,Size,TableStart,Reference,Scale), relative_jump_table_entry_target(TableStart,TableStart,Size,Reference,Dest,Scale), loaded_section(SectionStart,SectionEnd,_), TableStart >= SectionStart, TableStart < SectionEnd. #line 351 "relative_jump_tables.dl" relative_jump_table_entry_candidate(EA,TableStart,Size,Reference,Dest,Scale,Offset):- !binary_isa("ARM"), relative_jump_table_entry_candidate(LastEA,TableStart,Size,Reference,_,Scale,Offset), EA = LastEA + Size, jump_table_max(TableStart,TableEnd), TableEnd >= EA, !symbol(EA,_,_,_,_,_,_,_,_), data_segment(BegData,EndData), BegData <= TableStart, EA+Size <= EndData, relative_jump_table_entry_target(EA,TableStart,Size,Reference,Dest,Scale). .decl discarded_jump_table_entry(TableStart:address,TableRef:address,EA:address) .output discarded_jump_table_entry discarded_jump_table_entry(TableStart,TableRef1,TableStart):- jump_table_start(_,_,TableStart,TableRef1,_), jump_table_start(_,_,TableStart,TableRef2,_), TableRef1 != TableStart, TableRef2 = TableStart. discarded_jump_table_entry(TableStart,Ref,EA):- relative_jump_table_entry_candidate(EA,TableStart,Size,Ref,_,_,_), data_limit(Limit), EA <= Limit, Limit < EA+Size, EA != TableStart. discarded_jump_table_entry(TableStart,Ref,EA):- discarded_jump_table_entry(TableStart,Ref,DiscardEA), jump_table_start(_,Size,TableStart,Ref,_), EA = DiscardEA + Size, relative_jump_table_entry_candidate(EA,TableStart,Size,Ref,_,_,_). #line 392 "relative_jump_tables.dl" .decl relative_jump_table_entry(EA:address,TableStart:address,Size:unsigned,Reference:address,Dest:address,Scale:number,Offset:number) .output relative_jump_table_entry relative_jump_table_entry(EA,TableStart,Size,Reference,Dest,Scale,Offset):- relative_jump_table_entry_candidate(EA,TableStart,Size,Reference,Dest,Scale,Offset), !discarded_jump_table_entry(TableStart,Reference,EA). #line 410 "relative_jump_tables.dl" relative_jump_table_entry(EA,TableStart,Size,Reference,Dest,Scale,Offset):- !binary_isa("ARM"), relative_jump_table_entry(LastEA,TableStart,Size,Reference,_,Scale,Offset), !jump_table_max(TableStart,_), EA = LastEA + Size, !symbol(EA,_,_,_,_,_,_,_,_), data_segment(BegData,EndData), BegData <= TableStart, EA+Size <= EndData, next_data_limit(Prev, Next), Prev < EA, Next >= EA+Size, relative_jump_table_entry_target(EA,TableStart,Size,Reference,Dest,Scale). #line 95 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 97 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "code_inference.dl" #line 46 "code_inference.dl" #line 1 "code_inference_postprocess.dl" #line 32 "code_inference_postprocess.dl" .decl code_in_refined_block(ea:address,block:address) .output code_in_refined_block .decl refined_block(block:address) .output refined_block .decl block_information(block:address,size:unsigned,endAddress:address) .output block_information .decl refined_block_last_instruction(block:address,EA:address) .decl refined_block_control_instruction(block:address,EA:address) .decl block_needs_splitting_at(EA:address) .decl code_in_split_block(ea:address,block:address) .decl split_block(block:address) block_needs_splitting_at(EA):- ( symbol_minus_symbol(_,_,_,EA,_,_); symbol_minus_symbol(_,_,EA,_,_,_) ), code_in_block(EA,Block), EA != Block. block_needs_splitting_at(EA):- binary_isa("MIPS"), padding_prefix_end(EA,_). block_needs_splitting_at(TargetAddr):- jump_table_candidate_refined(_,_,TargetAddr). split_block(Block):- block(Block). split_block(EA):- block_needs_splitting_at(EA). code_in_split_block(Block,Block):- split_block(Block). code_in_split_block(EA,Block):- code_in_split_block(PrevEA,Block), code_in_block(PrevEA,PrevBlock), next(PrevEA,EA), code_in_block(EA,PrevBlock), !block_needs_splitting_at(EA). .decl block_needs_merging(block:address) block_needs_merging(Block):- split_block(Block), must_fallthrough(Code,Block), code(Code), !symbolic_operand(_,_,Block,_), !code_pointer_in_data(_,Block), !symbol_minus_symbol(_,_,_,Block,_,_), !symbol_minus_symbol(_,_,Block,_,_,_), !moved_data_label(_,_,_,Block), !moved_label(_,_,_,Block), !function_symbol(Block,_), !defined_symbol(Block,_,_,_,_,_,_,_,_), !entry_point(Block), !instruction_has_loop_prefix(Block), !fde_addresses(Block,_), !fde_addresses(_,Block), !block_needs_splitting_at(Block). refined_block(Block):- split_block(Block), !block_needs_merging(Block). code_in_refined_block(EA,Block):- refined_block(Block), code_in_split_block(EA,Block). code_in_refined_block(EA,Block):- block_needs_merging(OldBlock), code_in_split_block(EA,OldBlock), must_fallthrough(Prev,OldBlock), code_in_refined_block(Prev,Block). refined_block_last_instruction(Block,EA):- code_in_refined_block(EA,Block), next(EA,Next), !code_in_refined_block(Next,Block). refined_block_control_instruction(Block,EA):- refined_block_last_instruction(Block,EA), !arch.delay_slot(EA,_). refined_block_control_instruction(Block,Branch):- refined_block_last_instruction(Block,EA), arch.delay_slot(Branch,EA). block_information(Block,BlockSize,LastEA+InsnSize):- refined_block_last_instruction(Block,LastEA), instruction(LastEA,InsnSize,_,_,_,_,_,_,_,_), BlockSize= LastEA+InsnSize - Block. #line 159 "code_inference_postprocess.dl" .decl next_refined_block_in_section(Block:address, NextBlock:address) next_refined_block_in_section(Block,NextBlock):- block_information(Block,_,NextBlock), block_information(NextBlock,_,_). next_refined_block_in_section(Block,NextBlock):- block_information(Block,_,BlockEndAddr), data_in_code(BlockEndAddr,NextBlock), block_information(NextBlock,_,_). .decl padding(EA:address,Size:unsigned) .output padding padding(EA,Size):- nop_block(EA), block_information(EA,Size,_). padding(EA,Size):- after_end(NonNop,End), !is_padding(NonNop), next(End,EA), Size = NonNop-EA, Size > 0. .decl block_has_non_nop(Block:address) block_has_non_nop(Block):- block_boundaries(Block,BegAddr,EndAddr), code_in_refined_block(EA,Block), EA >= BegAddr, EA < EndAddr, !arch.is_nop(EA). .decl nop_block(Block:address) nop_block(Block):- refined_block(Block), !block_has_non_nop(Block). .decl padding_prefix(EA:address,Block:address) padding_prefix(EA,Block):- code_in_block(EA,Block), arch.is_nop(EA), EA = Block. padding_prefix(EA,Block):- padding_prefix(PrevEA,Block), next(PrevEA,EA), code_in_block(EA,Block), arch.is_nop(EA). .decl padding_prefix_end(EA:address,Block:address) .output padding_prefix_end padding_prefix_end(EA,Block):- code_in_block(EA,Block), !arch.is_nop(EA), next(PrevEA,EA), padding_prefix(PrevEA,Block). #line 47 "code_inference.dl" #line 49 "code_inference.dl" #line 1 "cfg.dl" #line 27 "cfg.dl" .decl cfg_edge(src:address,dest:address,conditional:symbol,indirect:symbol,type:symbol) .output cfg_edge .decl cfg_edge_to_top(src:address,conditional:symbol,type:symbol) .output cfg_edge_to_top .decl cfg_edge_to_symbol(Src:address,Symbol:symbol,Type:symbol) .output cfg_edge_to_symbol .decl jump_table(Src:address,Data:address) jump_table(EA,Initial_memory):- code(EA), indirect_jump(EA), arch.pointer_size(Pt_size), data_access_pattern(Initial_memory,Pt_size,as(Pt_size,number),EA), symbolic_data(Initial_memory,Pt_size,Dest_block), refined_block(Dest_block). jump_table(EA,Initial_memory):- code(EA), indirect_jump(EA), arch.pointer_size(Pt_size), symbolic_operand(EA,1,Initial_memory,"data"), symbolic_data(Initial_memory,Pt_size,Dest_block), refined_block(Dest_block). jump_table(EA,Memory+Pt_size):- jump_table(EA,Memory), arch.pointer_size(Pt_size), symbolic_data(Memory+Pt_size,Pt_size,Dest_block), refined_block(Dest_block), !data_access_pattern(Memory+Pt_size,_,_,_). jump_table(EA,Memory+Pt_size):- jump_table(EA,Memory), arch.pointer_size(Pt_size), symbolic_data(Memory,Pt_size,Content_prev), symbolic_data(Memory+Pt_size,Pt_size,Content_next), refined_block(Content_next), data_access_pattern(Memory+Pt_size,Pt_size,as(Pt_size,number),EA), ( EA < Content_prev, EA < Content_next ; EA > Content_prev, EA > Content_next ). .decl resolved_jump(Src:address,Dest:address) .output resolved_jump resolved_jump(EA,Dest):- jump_table(EA,Memory), code(EA), symbolic_data(Memory,_,Dest), refined_block(Dest). resolved_jump(EA,Dest):- jump_table_start(EA,Size,TableStart,_,_), relative_jump_table_entry(_,TableStart,Size,_,Dest,_,_). resolved_jump(Src,Dest):- jump_table_candidate_refined(Src,_,Dest). cfg_edge(Src,Dest,Conditional,Indirect,EdgeType):- refined_block_control_instruction(Src,EA), ( direct_jump(EA,Dest), Indirect = "false"; pc_relative_jump(EA,Dest), Indirect = "false"; resolved_jump(EA,Dest), Indirect = "true" ), refined_block(Dest), ( arch.jump(EA),EdgeType="branch"; arch.call(EA,_),EdgeType="call" ), ( !arch.conditional(EA,_),Conditional = "false"; arch.conditional(EA,_),Conditional = "true" ). cfg_edge(Src,Dest,"false","false","call"):- refined_block_control_instruction(Src,EA), ( direct_call(EA,Dest); direct_call_resolved(EA,Dest); pc_relative_call(EA,Dest) ), !pc_load_call(EA,_), refined_block(Dest). cfg_edge(Src,Dest,"false","false","fallthrough"):- refined_block_control_instruction(Src,EA), may_fallthrough(EA,Dest), !no_return_call_propagated(EA), !nop_block(Src), code_in_refined_block(Dest,Dest), next_refined_block_in_section(Src,Dest), !plt_block(Src,_). cfg_edge(Src,Dest,"false","false","fallthrough"):- cfg_edge(_,Src,_,_,_), nop_block(Src), next_refined_block_in_section(Src,Dest). cfg_edge(Src,Dest,"false","false","fallthrough"):- nop_block(Src), cfg_edge(_,Src,_,_,_), next_refined_block_in_section(Src,Dest). cfg_edge(ReturnBlock,NextBlock,Conditional,"false","return"):- cfg_edge(Caller,Block,_,_,"call"), cfg_edge(Caller,NextBlock,_,_,"fallthrough"), function_inference.in_function(Block,FunctionEntry), function_inference.in_function(ReturnBlock,FunctionEntry), refined_block_control_instruction(ReturnBlock,Insn), ( unconditional_return(Insn), Conditional = "false"; conditional_return(Insn), Conditional = "true" ). cfg_edge_to_top(Src,Conditional,"branch"):- refined_block_control_instruction(Src,EA), ( reg_jump(EA,_); indirect_jump(EA) ), !resolved_jump(EA,_), ( unconditional_jump(EA), Conditional = "false"; conditional_jump(EA), Conditional = "true" ). cfg_edge_to_top(Src,"false","call"):- refined_block_control_instruction(Src,EA), ( reg_call(EA,_); indirect_call(EA) ). cfg_edge_to_top(Src,Conditional,"return"):- refined_block_control_instruction(Src,Insn), ( unconditional_return(Insn), Conditional = "false"; conditional_return(Insn), Conditional = "true" ), !cfg_edge(Src,_,_,_,"return"). cfg_edge_to_symbol(Src,Symbol,"branch"):- refined_block(Src), plt_block(Src,Symbol), !defined_symbol(_,_,_,_,_,_,_,_,Symbol), !inferred_special_symbol(_,Symbol,_,_,_). cfg_edge_to_symbol(Src,Symbol,"branch"):- refined_block_control_instruction(Src,EA), arch.jump(EA), instruction_has_relocation(EA,Rel), relocation(Rel,_,Symbol,_,_,_,_), !defined_symbol(_,_,_,_,_,_,_,_,Symbol), Symbol != "". cfg_edge_to_symbol(Src,Symbol,"call"):- refined_block_control_instruction(Src,EA), arch.call(EA,_), instruction_has_relocation(EA,Rel), relocation(Rel,_,Symbol,_,_,_,_), !defined_symbol(_,_,_,_,_,_,_,_,Symbol), Symbol != "". cfg_edge_to_top(Src,Conditional,"branch"):- refined_block_control_instruction(Src,EA), pc_relative_jump(EA,Dest), !refined_block(Dest), ( unconditional_jump(EA), Conditional = "false"; !unconditional_jump(EA),Conditional = "true" ). #line 50 "code_inference.dl" #line 58 "code_inference.dl" .decl code_in_block(EA:address,Block:address) .output code_in_block #line 64 "code_inference.dl" .decl block(Block:address) #line 68 "code_inference.dl" .decl code(EA:address) inline #line 73 "code_inference.dl" .decl block_last_instruction(Block:address,EA:address) #line 80 "code_inference.dl" .decl block_boundaries(block:address,BegAddr:address,EndAddr:address) #line 87 "code_inference.dl" .decl overlapping_instruction(EA:address, EA2: address) .output overlapping_instruction #line 93 "code_inference.dl" .decl data_in_code(Begin:address,End:address) #line 98 "code_inference.dl" .type block_type <: symbol #line 103 "code_inference.dl" .decl block_still_overlap(Block1:address,Type1:block_type,Block2:address,Type2:block_type) .output block_still_overlap .decl may_fallthrough(o:address,d:address) may_fallthrough(From,To):- next(From,To), arch.delay_slot(From,To). may_fallthrough(From,To):- next(From,To), arch.delay_slot(Prev,From), !unconditional_return(Prev), !unconditional_jump(Prev). may_fallthrough(From,To):- next(From,To), !arch.delay_slot(_,From), !unconditional_return(From), !unconditional_jump(From), !halt(From), !no_return_call(From). .decl must_fallthrough(From:address,To:address) must_fallthrough(From,To):- next(From,To), arch.delay_slot(From,To). must_fallthrough(From,To):- may_fallthrough(From,To), instruction_get_operation(From,Operation), !arch.call_operation(Operation), !arch.syscall_operation(Operation), !arch.interrupt_operation(Operation), !instruction_has_loop_prefix(From), !conditional_jump(From), !conditional_return(From), !arch.delay_slot(_,From). .decl may_have_symbolic_immediate(src:address,dest:address) may_have_symbolic_immediate(Src,as(Dest,address)):- instruction_immediate_offset(Src,Index,Offset,_), instruction_get_op(Src,Index,Op), op_immediate(Op,Dest), ( binary_type("DYN"), relocation(Src+Offset,_,_,_,_,_,_) ; binary_type("REL"), relocation(Src+Offset,_,_,_,_,_,_) ; binary_type("EXEC"), !binary_isa("ARM"), instruction_get_operation(Src,Operation), !arch.logic_operation(Operation), Offset = Offset ). .decl unlikely_have_symbolic_immediate(EA:address) unlikely_have_symbolic_immediate(0):- false. .decl invalid(EA:address,Type:symbol) .output invalid invalid(EA,Type):- invalid_op_code(EA), Type = "invalid_op_code". invalid(EA,Type):- ( direct_call(EA,Dest), Type = "direct_call to invalid"; direct_jump(EA,Dest), Type = "direct_jump to invalid"; must_fallthrough(EA,Dest), Type = "must_fallthrough to invalid" ), ( !instruction(Dest,_,_,_,_,_,_,_,_,_); defined_symbol(Dest,_,"OBJECT",_,_,_,_,_,_) ), Dest != 0. invalid(From,"propagate from invalid"):- invalid(To,_), ( must_fallthrough(From,To); direct_jump(From,To); direct_call(From,To); pc_relative_jump(From,To); pc_relative_call(From,To) ). invalid(EA,"known data region"):- data_region(Begin,Size), instruction(EA,_,_,_,_,_,_,_,_,_), Size > 0, EA >= Begin, EA < (Begin + Size). .decl possible_ea(EA:address) inline possible_ea(EA):- instruction(EA,_,_,_,_,_,_,_,_,_), !invalid(EA,_). .decl basic_target(ea:address) basic_target(Val):- ( relative_address(_,_,_,_,Val,_) ; binary_type("DYN"), address_in_data(EA,Val), relocation(EA,_,_,_,_,_,_) ; binary_type("REL"), address_in_data(EA,Val), relocation(EA,_,_,_,_,_,_) ; binary_type("EXEC"), address_in_data(_,Val), !impossible_jump_target(Val) ; entry_point(Val) ; code_section(Name), loaded_section(Val,_,Name) ; !binary_isa("ARM"), defined_symbol(Val,_,Type,_,_,_,_,_,_), Type != "OBJECT" ; fde_addresses(Val,_) ; lsda_callsite_addresses(Val, _, _) ; lsda_callsite_addresses(_, _, Val) ; seh_handler_entry(_,Val) ). .decl block_limit(EA:address) block_limit(as(EA,address)):- ( op_immediate(_,EA); pc_relative_operand(_,_,EA); basic_target(EA); instruction_has_loop_prefix(EA); fde_addresses(_,EA); lsda_callsite_addresses(_,EA, _) ). .decl must_access_data(EA:address, Dest:address) must_access_data(0,0):- false. .decl possible_target_from(dest:address,src:address) possible_target_from(Dest,Src):- code_in_block_candidate(Src,_), ( may_have_symbolic_immediate(Src,Dest), !must_access_data(Src,Dest) ; direct_jump(Src,Dest); direct_call(Src,Dest); jump_table_candidate(Src,_,Dest); pc_relative_jump(Src,Dest); pc_relative_call(Src,Dest); pc_relative_operand(Src,_,Dest), !must_access_data(Src,Dest) ). .decl possible_target(Target:address) .decl code_in_block_candidate(EA:address,EA_block:address) .output code_in_block_candidate possible_target(EA):- basic_target(EA). possible_target(EA):- possible_target_from(EA,_). #line 312 "code_inference.dl" .decl aligned_address_in_data(EA:address,Value:address) aligned_address_in_data(EA,Value):- address_in_data(EA,Value), arch.pointer_size(Pt_size), EA % Pt_size = 0. code_in_block_candidate(EA,EA):- possible_target(EA), possible_ea(EA). code_in_block_candidate(EA,Start):- code_in_block_candidate(EA2,Start), must_fallthrough(EA2,EA), !block_limit(EA). code_in_block_candidate(EA,EA):- code_in_block_candidate(EA2,_), may_fallthrough(EA2,EA), ( !must_fallthrough(EA2,EA); block_limit(EA) ), possible_ea(EA). .decl after_end(EA:address,End:address) after_end(Next,End):- code_in_block_candidate(End,_), next(End,Next), !may_fallthrough(End,Next). after_end(Next,End):- after_end(EA,End), is_padding(EA), !block_limit(EA), next(EA,Next). after_end(Next,End):- relative_address(End,Size,_,_,_,_), Next=End+Size, !relative_address(Next,_,_,_,_,_), is_padding(Next). possible_target(EA):- after_end(EA,_), ( !is_padding(EA); block_limit(EA) ). .decl common_tail(EA:address) common_tail(EA):- code_in_block_candidate(EA,Block), code_in_block_candidate(EA,Block2), Block != Block2, next(EA_prev,EA), code_in_block_candidate(EA_prev,Block), !code_in_block_candidate(EA_prev,Block2). .decl code_in_block_candidate_refined(EA:address,Block:address) .output code_in_block_candidate_refined code_in_block_candidate_refined(Block,Block):- code_in_block_candidate(Block,Block). code_in_block_candidate_refined(Block,Block):- common_tail(Block). code_in_block_candidate_refined(EA_next,Block):- code_in_block_candidate_refined(EA,Block), next(EA,EA_next), code_in_block_candidate(EA_next,OldBlock), code_in_block_candidate(EA,OldBlock), !code_in_block_candidate(EA_next,EA_next), !common_tail(EA_next). #line 407 "code_inference.dl" .decl data_block_candidate(Block:address,Size:unsigned) data_block_candidate(Block,Size):- relative_address(Block,Size,_,_,_,_). #line 417 "code_inference.dl" .decl block_candidate_boundaries(Block:address,Type:block_type,BegAddr:address,EndAddr:address) .output block_candidate_boundaries block_candidate_boundaries(Block,"code",Block,Next):- !binary_isa("ARM"), code_in_block_candidate_refined(EA,Block), next(EA,Next), !code_in_block_candidate_refined(Next,Block). block_candidate_boundaries(Block,"code", BegAddr,EndAddr):- binary_isa("ARM"), code_in_block_candidate_refined(EA,Block), next(EA,Next), !code_in_block_candidate_refined(Next,Block), BegAddr = Block - (Block band 1), EndAddr = Next - (Next band 1). block_candidate_boundaries(Block,"data",Block,Block+Size):- data_block_candidate(Block,Size). .decl multiple_fallthrough_to(Block:address) multiple_fallthrough_to(Block):- may_fallthrough(EA,Block), code_in_block_candidate_refined(EA,BlockPred), may_fallthrough(EA2,Block), code_in_block_candidate_refined(EA2,BlockPred2), BlockPred != BlockPred2. .decl block_overlap(Block1:address,Type1:block_type,Block2:address,Type2:block_type) .output block_overlap block_overlap(Block1,Type1,Block2,Type2):- block_candidate_boundaries(Block1,Type1,BegAddr1,EndAddr1), block_candidate_boundaries(Block2,Type2,BegAddr2,_), ( Block1 != Block2 ; Block1 = Block2, Type1 != Type2 ), BegAddr1 <= BegAddr2, BegAddr2 < EndAddr1. .decl block_is_overlapping(Block:address,Type:block_type) block_is_overlapping(Block,Type):- ( block_overlap(Block,Type,_,_); block_overlap(_,_,Block,Type) ). .decl block_total_points(Block:address,Type:block_type, points:number) block_total_points(Block,Type,Points):- block_is_overlapping(Block,Type), Points = sum X:{block_points(Block,Type,_,X,_)}. .decl discarded_block(Block:address,Type:block_type,Reason:symbol) .output discarded_block discarded_block(Block1,Type1,"less points"):- ( block_overlap(Block1,Type1,Block2,Type2); block_overlap(Block2,Type2,Block1,Type1) ), block_total_points(Block1,Type1,Points1), block_total_points(Block2,Type2,Points2), ( Points1 < Points2 ; Points1 = Points2, Type1 = "data", Type2 = "code" ). discarded_block(Block,Type,"negative points"):- block_total_points(Block,Type,Points), Points < 0. discarded_block(Block,"code","propagated"):- discarded_block(Block2,"code",_), !overlapping_instruction(Block2,_), ( direct_jump(EA,Block2); direct_call(EA,Block2); must_fallthrough(EA,Block2) ), code_in_block_candidate_refined(EA,Block). overlapping_instruction(Block2,Block), discarded_block(Block2,"code","first instruction overlap"):- block_overlap(Block,"code",Block2,"code"), instruction(Block,Size,"LOCK",OpCode,Op1,Op2,Op3,Op4,_,_), Block2 = Block + 1, instruction(Block2,Size2,"",OpCode,Op1,Op2,Op3,Op4,_,_), Block2 - Block = Size - Size2. .decl candidate_block_is_not_padding(Block:address) candidate_block_is_not_padding(Block):- code_in_block_candidate_refined(EA,Block), !is_padding(EA). .decl candidate_block_is_padding(Block:address) .output candidate_block_is_padding candidate_block_is_padding(Block):- code_in_block_candidate_refined(_,Block), !candidate_block_is_not_padding(Block). #line 552 "code_inference.dl" .decl block_points(Block:address,Type:block_type,Predecessor:address,Importance:number,HeuristicName:symbol) .output block_points .decl transitive_points(HeuristicName:symbol) transitive_points("start point"). transitive_points("code section start"). transitive_points("function symbol"). transitive_points("direct jump"). transitive_points("direct call"). transitive_points("must-fallthrough"). transitive_points("may-fallthrough"). transitive_points("fits"). transitive_points("fde-entry"). transitive_points("landing-pad"). transitive_points("exc-region"). transitive_points("relative jump table target"). transitive_points("seh handler"). block_points(Block,"data",0,6,"relative-jump-table"):- data_block_candidate(Block,Size), relative_address(Block,Size,_,_,_,_). block_points(Block,"data",0,3,"relative-jump-table-start"):- data_block_candidate(Block,_), relative_address_start(Block,_,_,_,_). block_is_overlapping(Block,"code"), block_points(Block,"code",0,-3,"overlaps with relocation"):- ( binary_isa("X86"); binary_isa("X64") ), code_in_block_candidate_refined(EA,Block), ( relocation_size(Type,Size), relocation(Target,Type,_,_,_,_,_), EA >= Target, EA < Target + (Size/8) ; instruction(EA,Size,_,_,_,_,_,_,_,_), relocation(Target,_,_,_,_,_,_), Target > EA, Target < EA + (Size/8), !instruction_immediate_offset(EA,_,Target-EA,_), !instruction_displacement_offset(EA,_,Target-EA,_) ). block_points(Block,"code",0,0,"basic point"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(_,Block). block_points(Block,"code",0,20,"start point"):- block_is_overlapping(Block,"code"), entry_point(Block). block_points(Block,"code",0,1,"code section start"):- block_is_overlapping(Block,"code"), code_section(Section), loaded_section(Block,_,Section). block_points(Block,"code",0,20,"function symbol"):- block_is_overlapping(Block,"code"), function_symbol(Block,_). block_points(Block,"code",0,1,"address in data"):- !binary_isa("X86"), !binary_isa("ARM"), block_is_overlapping(Block,"code"), address_in_data(Address,Block), !address_in_data_is_printable(Address). block_points(Block,"code",0,1,"aligned address in data"):- !binary_isa("X86"), !binary_isa("ARM"), block_is_overlapping(Block,"code"), aligned_address_in_data(_,Block). block_points(Block,"code",0,1,"address in data array"):- !binary_isa("ARM"), block_is_overlapping(Block,"code"), address_in_data(Address,Block), arch.pointer_size(Pt_size), ( binary_format("PE"); Address % Pt_size = 0 ), ( address_in_data(Address+Pt_size,_), address_in_data(Address+Pt_size*2,_) ; address_in_data(Address-Pt_size,_), address_in_data(Address-Pt_size*2,_) ; address_in_data(Address+Pt_size,_), address_in_data(Address-Pt_size,_) ). block_points(Block,"code",BlockPred,6,"direct jump"):- block_is_overlapping(Block,"code"), direct_jump(EA,Block), code_in_block_candidate_refined(EA,BlockPred), BlockPred != Block, !block_is_overlapping(BlockPred,_). block_points(Block,"code",BlockPred,6,"direct call"):- block_is_overlapping(Block,"code"), direct_call(EA,Block), code_in_block_candidate_refined(EA,BlockPred), BlockPred != Block, !block_is_overlapping(BlockPred,_). block_points(Block,"code",BlockPred,2,"must-fallthrough"):- block_is_overlapping(Block,"code"), must_fallthrough(EA,Block), code_in_block_candidate_refined(EA,BlockPred), !candidate_block_is_padding(BlockPred), !block_is_overlapping(BlockPred,_). block_points(Block,"code",BlockPred,7,"may-fallthrough"):- block_is_overlapping(Block,"code"), may_fallthrough(EA,Block), code_in_block_candidate_refined(EA,BlockPred), !candidate_block_is_padding(BlockPred), !block_is_overlapping(BlockPred,_). block_points(Block,Type,BlockPred,3,"fits"):- block_is_overlapping(Block,Type), after_end(Block,EA), code_in_block_candidate_refined(EA,BlockPred), !block_is_overlapping(BlockPred,_). block_points(Block,Type,BlockPred,1,"fits"):- block_is_overlapping(Block,Type), next(EA,Block), code_in_block_candidate_refined(EA,BlockPred), candidate_block_is_padding(BlockPred), !block_is_overlapping(BlockPred,_). block_points(Block,Type,0,1,"better fit"):- block_is_overlapping(Block,Type), next(EAPrev,Block), code_in_block_candidate_refined(EAPrev,BlockPrev), Block != BlockPrev. block_points(Block,"code",0,3,"appears"):- block_is_overlapping(Block,"code"), possible_target_from(Block,EA), !unlikely_have_symbolic_immediate(EA), !direct_jump(EA,Block), !direct_call(EA,Block), code_in_block_candidate_refined(EA,BlockPred), BlockPred != Block, !block_is_overlapping(BlockPred,_). block_points(Block,"code",0,3,"relative jump table target"):- block_is_overlapping(Block,"code"), relative_address(EA,_,_,_,Block,_), count :{ relative_address(EA,_,_,_,_,_) } = 1, !relative_address(Block,_,_,_,_,_). block_points(Block,"code",Block_succ,1,"fallthrough_to"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(EA,Block), may_fallthrough(EA,Block_succ), code_in_block_candidate_refined(_,Block_succ), !block_is_overlapping(Block_succ,_), !is_padding(Block_succ). block_points(Block,"code",BlockPred,Points,Why):- block_is_overlapping(Block,"code"), may_fallthrough(EA,Block), code_in_block_candidate_refined(EA,BlockPred), block_is_overlapping(BlockPred,"code"), ( Why = "may-fallthrough" ; !block_overlap(BlockPred,"code",_,"data"), !block_overlap(_,"data",BlockPred,"code") ), block_points(BlockPred,"code",_,Points,Why), transitive_points(Why), Points != 0. block_points(Block,"code",BlockPred,Points2,Why):- !binary_isa("ARM"), block_is_overlapping(Block,"code"), after_end(Block,EA), code_in_block_candidate_refined(EA,BlockPred), block_is_overlapping(BlockPred,"code"), !block_overlap(BlockPred,"code",_,"data"), !block_overlap(_,"data",BlockPred,"code"), !block_overlap(Block,"code",_,"data"), !block_overlap(_,"data",Block,"code"), block_points(BlockPred,"code",_,Points,Why), transitive_points(Why), ( Points > 2, Points2 = Points-2 ; Points < -2, Points2 = Points+2 ). block_points(Block,"code",BlockPred,Points,Why):- !binary_isa("ARM"), block_is_overlapping(Block,"code"), direct_jump(EA,Block), !may_fallthrough(EA,Block), code_in_block_candidate_refined(EA,BlockPred), block_is_overlapping(BlockPred,"code"), !block_overlap(BlockPred,"code",_,"data"), !block_overlap(_,"data",BlockPred,"code"), block_points(BlockPred,"code",_,Points,Why), transitive_points(Why), Points != 0. block_points(Block,"code",BlockPred,Points,Why):- !binary_isa("ARM"), block_is_overlapping(Block,"code"), direct_call(EA,Block), code_in_block_candidate_refined(EA,BlockPred), block_is_overlapping(BlockPred,"code"), !block_overlap(BlockPred,"code",_,"data"), !block_overlap(_,"data",BlockPred,"code"), block_points(BlockPred,"code",_,Points,Why), transitive_points(Why), Points != 0. block_points(Block,"code",0,1,"has well-defined jump"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(EA,Block), direct_jump(EA,BlockDest), !block_is_overlapping(BlockDest,"code"). block_points(Block,"code",0,1,"has well-defined call"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(EA,Block), direct_call(EA,BlockDest), !block_is_overlapping(BlockDest,"code"). block_points(Block,"code",0,3,"has well-defined call to a function symbol"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(EA,Block), direct_call(EA,BlockDest), function_symbol(BlockDest,_). block_points(Block,"code",0,1,"plt call"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(EA,Block), direct_call(EA,BlockDest), plt_entry(BlockDest,_). block_points(Block,"code",0,20,"fde-entry"):- block_is_overlapping(Block,"code"), fde_addresses(Block,_). block_points(Block,"code",0,2,"padding nop block"):- block_is_overlapping(Block,"code"), fde_addresses(_,Block), arch.is_nop(Block). block_points(Block,"code",0,-1,"overlap long nop"):- block_is_overlapping(Block,"code"), block_overlap(Block,"code",Block2,"code"), code_in_block_candidate_refined(EA_nop,Block2), arch.is_nop(EA_nop). block_points(Block,"code",0,3,"exc-region"):- block_is_overlapping(Block,"code"), lsda_callsite_addresses(Block, _, _). block_points(Block,"code",0,10,"landing-pad"):- block_is_overlapping(Block,"code"), lsda_callsite_addresses( _, _, Block). block_points(Block,"code",0,-2,"conditional jump/return: fallthrough to invalid"):- code_in_block_candidate(EA,Block), ( conditional_jump(EA); conditional_return(EA) ), next(EA,Invalid), invalid(Invalid,_). data_block_candidate(Block,Size), block_points(Block,"data",0,7,"object symbol"):- defined_symbol(Block,Size,"OBJECT",_,_,_,_,_,_). #line 862 "code_inference.dl" block_points(Block,"code",0,-5,"must-fallthrough to object"):- block_is_overlapping(Block,"code"), code_in_block_candidate_refined(EA,Block), must_fallthrough(EA,EASucc), symbol(EASucc,_,"OBJECT",_,_,_,_,_,_). block_is_overlapping(Block,"code"), block_points(Block,"code",0,-1,"jump to string"):- ascii_string(Beg,End), direct_jump(EA,Dest), Dest >= Beg, Dest < End, ( symbol(Beg,_,_,_,_,_,_,_,_) ; aligned_address_in_data(_,Beg) ), code_in_block_candidate(EA,Block). block_points(Block,"code",0,5,"seh handler"):- block_is_overlapping(Block,"code"), seh_handler_entry(_,Block). code_in_block(EA,Block):- code_in_block_candidate_refined(EA,Block), !discarded_block(Block,"code",_). code_in_block(EA,Block):- overlapping_instruction(EA,Block), code_in_block(Block,Block). block_last_instruction(Block,EA):- code_in_block(EA,Block), next(EA,Next), !code_in_block(Next,Block). block_boundaries(Block,BegAddr,EndAddr), block(Block):- code_in_block(_,Block), block_candidate_boundaries(Block,"code",BegAddr,EndAddr). code(EA):- code_in_block(EA,_). block_still_overlap(Block1,Type1,Block2,Type2):- block_overlap(Block1,Type1,Block2,Type2), !discarded_block(Block1,Type1,_), !discarded_block(Block2,Type2,_), (Type1 = "code"; Type2 = "code"). .decl data_in_code_propagate(Current:address,Initial:address,SectionLimit:address) data_in_code_propagate(BlockEndAddr,BlockEndAddr,SectionLimit):- block_boundaries(_,BlockBegAddr,BlockEndAddr), !block_boundaries(_,BlockEndAddr,_), loaded_section(AddrSection,SectionLimit,_), AddrSection <= BlockBegAddr, BlockEndAddr < SectionLimit. data_in_code_propagate(EA+1,Begin,SectionLimit):- data_in_code_propagate(EA,Begin,SectionLimit), !block_boundaries(_,EA+1,_), EA+1 < SectionLimit. data_in_code(Begin,End+1):- data_in_code_propagate(End,Begin,_), !data_in_code_propagate(End+1,Begin,_). data_in_code(Begin,Block-1):- loaded_section(Begin,EndSect,".text"), Block = min EA:{ block_boundaries(_,EA,_), EA >= Begin, EA < EndSect}, Block > Begin. .decl next_block_in_section(Block:address,NextBlock:address) next_block_in_section(Block,NextBlock):- block_boundaries(Block,_,NextBlockBeg), block_boundaries(NextBlock,NextBlockBeg,_). next_block_in_section(Block,NextBlock):- block_boundaries(Block,_,BlockEndAddr), data_in_code(BlockEndAddr,NextBlockBeg), block_boundaries(NextBlock,NextBlockBeg,_). #line 98 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 100 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "symbols.dl" #line 40 "symbols.dl" .type symbol_position <: symbol #line 45 "symbols.dl" .decl inferred_symbol(EA:address,SymbolName:symbol,Scope:symbol,Type:symbol,Pos:symbol_position) .output inferred_symbol #line 53 "symbols.dl" .decl inferred_special_symbol(EA:address,SymbolName:symbol,Scope:symbol,Type:symbol,Pos:symbol_position) inferred_special_symbol(EA,"main","GLOBAL","FUNC","Beg"):- binary_format("ELF"), main_function(EA). inferred_symbol(EA,SymbolName,Scope,Type,Pos), symbol_score(EA,SymbolName,Type,Pos,1):- inferred_special_symbol(EA,SymbolName,Scope,Type,Pos). #line 68 "symbols.dl" .decl best_symexpr_symbol(EA:address,SymbolName:symbol,Pos:symbol_position) .output best_symexpr_symbol #line 74 "symbols.dl" .decl best_func_symbol(EA:address,SymbolName:symbol) .output best_func_symbol #line 82 "symbols.dl" .decl symbol_score(EA:address,SymbolName:symbol,Type:symbol,Pos:symbol_position,Score:unsigned) .output symbol_score symbol_score(EA,SymbolName,Type,Pos,Score):- defined_symbol(EA,_,Type,Scope,Visibility,_,_,TableIndex,SymbolName), !ambiguous_symbol(SymbolName), !avoid_symbols(SymbolName), Type !="SECTION", ( symbol_at_section_end(EA,SymbolName), Pos = "End"; !symbol_at_section_end(EA,SymbolName), Pos = "Beg" ), ( relocation(EA,"COPY",SymbolName,_,_,_,_), RelocScore = 1; !relocation(EA,"COPY",SymbolName,_,_,_,_), RelocScore = 0 ), ( Type != "NOTYPE", TypeScore = 1; Type = "NOTYPE", TypeScore = 0 ), ( Scope = "GLOBAL", ScopeScore = 1; Scope != "GLOBAL", ScopeScore = 0 ), ( Visibility != "HIDDEN", VisibilityScore = 1; Visibility = "HIDDEN", VisibilityScore = 0 ), Score = (RelocScore bshl 35) bor (TypeScore bshl 34) bor (ScopeScore bshl 33) bor (VisibilityScore bshl 32) bor as(TableIndex,unsigned). #line 125 "symbols.dl" .decl avoid_symbols(SymbolName:symbol) avoid_symbols(Name):- binary_format("ELF"), elf_avoid_symbols(Name). #line 135 "symbols.dl" .decl elf_avoid_symbols(SymbolName:symbol) elf_avoid_symbols("__bss_start"). elf_avoid_symbols("__data_start"). elf_avoid_symbols("__dso_handle"). elf_avoid_symbols("_fp_hw"). elf_avoid_symbols("_IO_stdin_used"). elf_avoid_symbols("__TMC_END__"). best_func_symbol(EA,SymbolName):- symbol_score(EA,SymbolName,"FUNC","Beg",Score), Score = max S: {symbol_score(EA,_,"FUNC","Beg",S)}. inferred_symbol(EA,SymbolName,Scope,"FUNC","Beg"), best_func_symbol(EA,SymbolName):- function_inference.function_entry(EA), !symbol_score(EA,_,"FUNC","Beg",_), SymbolName = cat("FUN_",to_string(EA)), ( binary_isa("MIPS"), Scope = "GLOBAL"; !binary_isa("MIPS"), Scope = "LOCAL" ). best_symexpr_symbol(EA,SymbolName,Pos):- symbol_score(EA,SymbolName,_,Pos,Score), Score = max S: {symbol_score(EA,_,_,Pos,S)}. best_symexpr_symbol(EA,SymbolName,"Beg"):- labeled_ea(EA), !symbol_score(EA,_,_,"Beg",_), best_func_symbol(EA,SymbolName). inferred_symbol(EA,SymbolName,"LOCAL","NONE","Beg"), best_symexpr_symbol(EA,SymbolName,"Beg"):- labeled_ea(EA), !symbol_score(EA,_,_,"Beg",_), !best_func_symbol(EA,_), SymbolName = cat(".L_",to_string(EA)). inferred_symbol(EA,SymbolName,"LOCAL","NONE","End"), best_symexpr_symbol(EA,SymbolName,"End"):- labeled_ea(EA), boundary_sym_expr(_,EA), !symbol_score(EA,_,_,"End",_), SymbolName = cat(cat(".L_",to_string(EA)),"_END"). #line 200 "symbols.dl" .decl symbol_at_section_end(EA:address,SymbolName:symbol) .output symbol_at_section_end #line 207 "symbols.dl" .decl symbol_at_end(EA:address,SymbolName:symbol) .output symbol_at_end symbol_at_end(EA,SymbolName), symbol_at_section_end(EA,SymbolName):- symbol(EA,_,_,_,_,SectionIndex,_,_,SymbolName), section(_,Size,Beg,_,SectionIndex), EA = Beg + Size. symbol_at_end(EA,SymbolName):- inferred_symbol(EA,SymbolName,_,_,"End"). #line 223 "symbols.dl" .decl symbol_before_section_beg(EA:address,SymbolName:symbol,NewEA:address) .output symbol_before_section_beg symbol_before_section_beg(EA,SymbolName,Beg):- symbol(EA,_,_,_,_,SectionIndex,_,_,SymbolName), SectionIndex != 0, section(_,_,Beg,_,SectionIndex), EA < Beg. #line 101 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 102 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "symbolization.dl" #line 57 "symbolization.dl" #line 1 "empty_range.dl" #line 30 "empty_range.dl" .comp empty_range{ .decl in_ea(ea:address) .decl overlap(ea:address,size:unsigned,Where:address) inline overlap(EA,2,EA-1):- data_byte(EA,_), in_ea(EA-1). overlap(EA,4,Where):- data_byte(EA,_), ( in_ea(EA-1),Where=EA-1; in_ea(EA-2),Where=EA-2; in_ea(EA-3),Where=EA-3 ). overlap(EA,8,Where):- data_byte(EA,_), ( in_ea(EA-1),Where=EA-1; in_ea(EA-2),Where=EA-2; in_ea(EA-3),Where=EA-3; in_ea(EA-4),Where=EA-4; in_ea(EA-5),Where=EA-5; in_ea(EA-6),Where=EA-6; in_ea(EA-7),Where=EA-7 ). overlap(EA,16,Where):- data_byte(EA,_), ( in_ea(EA-1),Where=EA-1; in_ea(EA-2),Where=EA-2; in_ea(EA-3),Where=EA-3; in_ea(EA-4),Where=EA-4; in_ea(EA-5),Where=EA-5; in_ea(EA-6),Where=EA-6; in_ea(EA-7),Where=EA-7; in_ea(EA-8),Where=EA-8; in_ea(EA-9),Where=EA-9; in_ea(EA-10),Where=EA-10; in_ea(EA-11),Where=EA-11; in_ea(EA-12),Where=EA-12; in_ea(EA-13),Where=EA-13; in_ea(EA-14),Where=EA-14; in_ea(EA-15),Where=EA-15 ). .decl no_overlap(ea:address,size:unsigned) inline no_overlap(EA,2):- data_byte(EA,_), !in_ea(EA-1). no_overlap(EA,4):- data_byte(EA,_), !in_ea(EA-1), !in_ea(EA-2), !in_ea(EA-3). no_overlap(EA,8):- data_byte(EA,_), !in_ea(EA-1), !in_ea(EA-2), !in_ea(EA-3), !in_ea(EA-4), !in_ea(EA-5), !in_ea(EA-6), !in_ea(EA-7). no_overlap(EA,16):- data_byte(EA,_), !in_ea(EA-1), !in_ea(EA-2), !in_ea(EA-3), !in_ea(EA-4), !in_ea(EA-5), !in_ea(EA-6), !in_ea(EA-7), !in_ea(EA-8), !in_ea(EA-9), !in_ea(EA-10), !in_ea(EA-11), !in_ea(EA-12), !in_ea(EA-13), !in_ea(EA-14), !in_ea(EA-15). } #line 58 "symbolization.dl" #line 1 "bitmasks.dl" #line 29 "bitmasks.dl" .decl low_pass_mask(Mask:number) low_pass_mask((2^N)-1):- arch.pointer_size(Pt_size), N = range(1,8*as(Pt_size,number)). .decl low_pass_filter(EA:address) low_pass_filter(EA):- code(EA), op_immediate_and_reg(EA,"AND",_,_,Imm), low_pass_mask(Imm). .decl is_xor_reset(EA:address) is_xor_reset(EA):- instruction(EA,_,_,"XOR",Op1,Op2,0,0,_,_), op_regdirect_contains_reg(Op1,Reg), op_regdirect_contains_reg(Op2,Reg). #line 59 "symbolization.dl" #line 1 "noreturn.dl" #line 29 "noreturn.dl" .decl incomplete_block(Block:address) .output incomplete_block incomplete_block(Block):- block_last_instruction(Block,BlockEnd), ( indirect_jump(BlockEnd); reg_jump(BlockEnd,_); arch.return(BlockEnd) ). .decl direct_or_pcrel_jump(Src:address,Dest:address) direct_or_pcrel_jump(Src,Dest):- direct_jump(Src,Dest); pc_relative_jump(Src,Dest). #line 54 "noreturn.dl" .decl segment_target_range(Beg:address,End:address,Tmax:address) .output segment_target_range segment_target_range(Beg,End,MaxTgt):- function_inference.function_entry_initial(Block), !incomplete_block(Block), block_boundaries(Block,Beg,End), block_last_instruction(Block,BlockEnd), ( !direct_or_pcrel_jump(BlockEnd,_), MaxTgt = Beg ; direct_or_pcrel_jump(BlockEnd,MaxTgt) ), MaxTgt >= Beg. segment_target_range(Beg,End,MaxTgt):- segment_target_range(Beg,PrevEnd,PrevMaxTgt), block_boundaries(PrevBlock,_,PrevEnd), next_block_in_section(PrevBlock,Block), block_boundaries(Block,_,End), !incomplete_block(Block), !function_inference.function_entry_initial(Block), block_last_instruction(Block,BlockEnd), ( !direct_or_pcrel_jump(BlockEnd,_), MaxTgt = PrevMaxTgt ; direct_or_pcrel_jump(BlockEnd,MaxTgt2), !inter_procedural_edge(BlockEnd,_), MaxTgt2 >= Beg, MaxTgt = max(PrevMaxTgt,MaxTgt2) ; direct_or_pcrel_jump(BlockEnd,InterTarget), inter_procedural_edge(BlockEnd,_), no_return_block(InterTarget), MaxTgt = PrevMaxTgt ), MaxTgt >= Beg. .decl self_contained_segment(Beg:address,End:address) self_contained_segment(Beg,End):- segment_target_range(Beg,End,MaxTgt), MaxTgt < End. #line 114 "noreturn.dl" .decl no_return_block(EA:address) no_return_block(Block):- self_contained_segment(Beg,End), block_boundaries(LastBlock,_,End), block_last_instruction(LastBlock,BlockEnd), ( !may_fallthrough(BlockEnd,_); no_return_call_propagated(BlockEnd) ), block_boundaries(Block,Beg,EndBlock), EndBlock <= End. no_return_block(Func):- direct_call(Call,Func), may_fallthrough(Call,Fallthrough), ( !candidate_block_is_padding(Fallthrough), Next = Fallthrough, From = Call ; candidate_block_is_padding(Fallthrough), block_last_instruction(Fallthrough,From), may_fallthrough(From,Next) ), inter_procedural_edge(From,Next). #line 154 "noreturn.dl" .decl no_return_call_refined(EA:address) no_return_call_refined(EA):- no_return_call(EA). no_return_call_refined(EA):- direct_call(EA,Dest), plt_block(Dest,Function), no_return_function(Pattern), match(Pattern,Function). no_return_block(Block):- no_return_call_refined(BlockEnd), block_last_instruction(Block,BlockEnd). #line 173 "noreturn.dl" .decl no_return_call_propagated(EA:address) .output no_return_call_propagated no_return_call_propagated(EA):- no_return_call_refined(EA). no_return_call_propagated(EA):- direct_call(EA,Block), no_return_block(Block), !pc_load_call(EA,Block). #line 60 "symbolization.dl" #line 1 "use_def_analysis.dl" #line 42 "use_def_analysis.dl" .decl def(EA:address,Reg:register) #line 47 "use_def_analysis.dl" .decl used(EA:address,Reg:register,Index:operand_index) #line 53 "use_def_analysis.dl" .decl used_before_code_inference(EA:address,Reg:register,Index:operand_index) .decl def_used(ea_def:address,reg:register,ea_used:address,index_used:operand_index) .output def_used .decl flow_def(EA:address,Reg:register,EA_next:address,Value:number) .decl local_next(ea:address,ea_next:address) inline local_next(EA,EA_next):- code_in_block(EA,Block), may_fallthrough(EA,EA_next), code_in_block(EA_next,Block). .decl inter_procedural_edge(Src:address,Dest:address) inter_procedural_edge(Src,Dest):- unconditional_jump(Src), direct_jump(Src,Dest), function_inference.function_entry_initial(Between), Src < Between, Between <= Dest. inter_procedural_edge(Src,Dest):- may_fallthrough(Src,Dest), !pc_load_call(Src,Dest), function_inference.function_entry_initial(Dest). .decl block_next(Block:address,BlockEnd:address,NextBlock:address) .output block_next block_next(Block,EA,Block2):- block_last_instruction(Block,EA), may_fallthrough(EA,Block2), !no_return_call_propagated(EA), !inter_procedural_edge(EA,Block2), block(Block2). block_next(Block,EA,EA_next):- block_last_instruction(Block,EA), !arch.delay_slot(_,EA), direct_jump(EA,EA_next), !inter_procedural_edge(EA,EA_next). block_next(Block,EA,EA_next):- block_last_instruction(Block,EA), arch.delay_slot(JumpEA,EA), direct_jump(JumpEA,EA_next), !inter_procedural_edge(JumpEA,EA_next). block_next(Block,EA,Dest):- block_last_instruction(Block,EA), jump_table_target(EA,Dest). block_next(Block,EA,Block2):- lsda_callsite_addresses(Beg,End, Block2), block_last_instruction(Block,EA), EA >= Beg, EA < End, block(Block2). #line 125 "use_def_analysis.dl" .decl track_register(Reg:register) track_register(Reg):- arch.general_purpose_reg(Reg); arch.frame_pointer(Reg); arch.stack_pointer(Reg); arch.return_reg(Reg); arch.condition_flags_reg(Reg). def(EA,Reg):- ( register_access(EA,RegIn,"W"), reg_map(RegIn,Reg), !arch.register_access_override(EA,Reg,"W",0) ; arch.register_access_override(EA,Reg,"W",1) ), track_register(Reg). def(EA,Reg):- arch.call(EA,_), !arch.delay_slot(EA,_), arch.return_reg(Reg). def(EA,Reg):- arch.call(Call,_), arch.delay_slot(Call,EA), arch.return_reg(Reg). def(EA,Reg):- direct_call(EA,EA_pc_thunk), get_pc_thunk(EA_pc_thunk,Reg), track_register(Reg). flow_def(EA_jump,Reg,EA_target,Immediate):- code(EA), cmp_immediate_to_reg(EA,Reg,_,Immediate), track_register(Reg), next(EA,EA_jump), direct_jump(EA_jump,EA_target), arch.jump(EA_jump), arch.conditional(EA_jump,"E"). flow_def(EA_jump,Reg,EA_target,Immediate):- code(EA), cmp_immediate_to_reg(EA,Reg,_,Immediate), track_register(Reg), next(EA,EA_jump), direct_jump(EA_jump,_), next(EA_jump,EA_target), arch.jump(EA_jump), arch.conditional(EA_jump,"NE"). .decl must_def(EA:address,Reg:register) inline must_def(EA,Reg):- def(EA,Reg), !arch.conditional(EA,_). .decl defined_in_block(EA:address,Reg:register) defined_in_block(Block,Reg):- def(EA,Reg), code_in_block(EA,Block). #line 196 "use_def_analysis.dl" .decl used_explicit(EA:address,Reg:register,Index:operand_index) used_explicit(EA,Reg,Index):- instruction_get_src_op(EA,Index,Op), op_regdirect_contains_reg(Op,Reg), track_register(Reg), !is_xor_reset(EA). used_explicit(EA,Reg,Index):- instruction_get_op(EA,Index,Op), op_indirect_contains_reg(Op,Reg), track_register(Reg). used_before_code_inference(EA,Reg,Index):- used_explicit(EA,Reg,Index). used_before_code_inference(EA,Reg,0):- ( register_access(EA,RegIn,"R"), reg_map(RegIn,Reg), !arch.register_access_override(EA,Reg,"R",0) ; arch.register_access_override(EA,Reg,"R",1) ), track_register(Reg), !used_explicit(EA,Reg,_), !is_xor_reset(EA). .decl used_in_block(Block:address,EA_used:address,Reg:register,Index:operand_index) used_in_block(Block,EA_used,Reg,Index):- used(EA_used,Reg,Index), code_in_block(EA_used,Block). used(EA,Reg,Index):- used_before_code_inference(EA,Reg,Index). #line 237 "use_def_analysis.dl" .decl block_last_def(EA:address,EA_def:address,Reg:register) block_last_def(EA_next,EA,Reg):- def(EA,Reg), local_next(EA,EA_next). block_last_def(EA_next,EA_def,Reg):- block_last_def(EA,EA_def,Reg), !must_def(EA,Reg), local_next(EA,EA_next). #line 253 "use_def_analysis.dl" .decl last_def_in_block(Block:address,EA_def:address,Reg:register) last_def_in_block(Block,EA_def,Reg):- block_last_instruction(Block,BlockEnd), ( def(BlockEnd,Reg), EA_def=BlockEnd ; !must_def(BlockEnd,Reg), block_last_def(BlockEnd,EA_def,Reg) ). #line 268 "use_def_analysis.dl" .decl reg_in_block(Block:address,Reg:register) reg_in_block(Block,Reg):- defined_in_block(Block,Reg); used_in_block(Block,_,Reg,_). #line 277 "use_def_analysis.dl" .decl return_val_used(EA_call:address,Callee:address,Reg:register,EA_used:address,Index_used:operand_index) return_val_used(EA_call,Callee,Reg,EA_used,Index_used):- arch.return_reg(Reg), def_used(EA_call,Reg,EA_used,Index_used), direct_call(EA_call,Callee). #line 288 "use_def_analysis.dl" .decl return_block_end(Callee:address,CalleeEnd:address,Block:address,BlockEnd:address) return_block_end(Callee,CalleeEnd,Block,BlockEnd):- direct_call(_,Callee), fde_addresses(Callee,CalleeEnd), arch.return(CalleeReturn), Callee <= CalleeReturn, CalleeReturn < CalleeEnd, code_in_block(CalleeReturn,Block), block_last_instruction(Block,BlockEnd). #line 309 "use_def_analysis.dl" .decl live_reg_used(Block:address,Reg:register,EA_used:address) live_reg_used(Block,Reg,EA_used):- used_in_block(Block,EA_used,Reg,_), !block_last_def(EA_used,_,Reg). live_reg_used(RetBlock,Reg,EA_used):- return_block_end(Callee,_,RetBlock,RetBlockEnd), !block_last_def(RetBlockEnd,_,Reg), return_val_used(_,Callee,Reg,EA_used,_). #line 339 "use_def_analysis.dl" .decl live_reg_at_block_end(Block:address,BlockUsed:address,Reg:register) live_reg_at_block_end(PrevBlock,Block,Reg):- block_next(PrevBlock,PrevBlockEnd,Block), live_reg_used(Block,Reg,_), !flow_def(PrevBlockEnd,Reg,Block,_). live_reg_at_block_end(PrevBlock,BlockUsed,Reg):- live_reg_at_block_end(Block,BlockUsed,Reg), !reg_in_block(Block,Reg), block_next(PrevBlock,_,Block). #line 360 "use_def_analysis.dl" .decl live_reg_at_prior_used(EA_used:address,BlockUsed:address,Reg:register) live_reg_at_prior_used(EA_used,BlockUsed,Reg):- live_reg_at_block_end(Block,BlockUsed,Reg), used_in_block(Block,EA_used,Reg,_), !defined_in_block(Block,Reg). def_used(EA_def,Reg,EA_used,Index):- used(EA_used,Reg,Index), block_last_def(EA_used,EA_def,Reg). def_used(EA_def,Reg,EA_used,Index):- return_val_used(_,Callee,Reg,EA_used,Index), return_block_end(Callee,_,_,BlockEnd), block_last_def(BlockEnd,EA_def,Reg). def_used(EA_def,Reg,EA_used,Index):- live_reg_at_block_end(Block,BlockUsed,Reg), last_def_in_block(Block,EA_def,Reg), live_reg_used(BlockUsed,Reg,EA_used), used(EA_used,Reg,Index). def_used(EA_def,Reg,EA_used,Index):- live_reg_at_block_end(Block,BlockUsed,Reg), !defined_in_block(Block,Reg), flow_def(EA_def,Reg,Block,_), live_reg_used(BlockUsed,Reg,EA_used), used(EA_used,Reg,Index). def_used(EA_def,Reg,Next_EA_used,NextIndex):- live_reg_at_prior_used(EA_used,NextUsedBlock,Reg), def_used(EA_def,Reg,EA_used,_), live_reg_used(NextUsedBlock,Reg,Next_EA_used), used(Next_EA_used,Reg,NextIndex), !block_last_def(Next_EA_used,_,Reg). #line 404 "use_def_analysis.dl" .decl used_for_address(EA:address,Reg:register) .output used_for_address used_for_address(EA,Reg):- used(EA,Reg,Index), instruction_get_op(EA,Index,Op), op_indirect_contains_reg(Op,Reg). used_for_address(EA,Reg):- reg_jump(EA,Reg), used(EA,Reg,_). used_for_address(EA,Reg):- reg_call(EA,Reg), used(EA,Reg,_). #line 424 "use_def_analysis.dl" .decl def_used_for_address(EA_def:address,Reg:register) .output def_used_for_address def_used_for_address(EA_def,Reg):- def_used(EA_def,Reg,EA,_), used_for_address(EA,Reg). def_used_for_address(EA_def,Reg):- def_used_for_address(EA_used,_), def_used(EA_def,Reg,EA_used,_). def_used_for_address(EA,Reg):- arch.pc_relative_addr(EA,Reg,_). .decl straight_line_last_def(EA:address,EA_def:address,Reg:register) straight_line_last_def(EA_next,EA,Reg):- def(EA,Reg), possible_ea(EA), must_fallthrough(EA,EA_next), possible_ea(EA_next). straight_line_last_def(EA_next,EA_def,Reg):- straight_line_last_def(EA,EA_def,Reg), !must_def(EA,Reg), must_fallthrough(EA,EA_next), possible_ea(EA_next). .decl straight_line_def_used(EA_def:address,Reg:register,EA_used:address,Index:unsigned) .output straight_line_def_used straight_line_def_used(EA_def,Reg,EA_used,Index):- used_before_code_inference(EA_used,Reg,Index), straight_line_last_def(EA_used,EA_def,Reg). #line 61 "symbolization.dl" #line 1 "value_analysis.dl" #line 61 "value_analysis.dl" .decl value_reg_edge(EA:address,Reg:register, EA_reg1:address,Reg1:register,Multiplier:number,Offset:number) .output value_reg_edge .decl value_reg(EA:address,Reg:register, EA_reg1:address,Reg1:reg_nullable,Multiplier:number,Offset:number,Steps:unsigned) .output value_reg .decl best_value_reg(EA:address,Reg:register,EA_from:address,Multiplier:number,Offset:number,type:symbol) .output best_value_reg #line 75 "value_analysis.dl" .decl stack_frame(EA:address,BaseReg:register) stack_frame(EA,BaseReg):- def_used_for_address(EA,BaseReg), ( arch.frame_pointer(BaseReg); arch.stack_pointer(BaseReg) ). .decl reg_stored_in_stack(EA:address,Reg:register,Base:register,StackPos:number,StackFrameDefinedAt:address) .output reg_stored_in_stack reg_stored_in_stack(EA,Reg,Base,StackPos,StackFrameDefinedAt):- stack_frame(StackFrameDefinedAt,Base), def_used(StackFrameDefinedAt,Base,EA,_), arch.store(EA,_,_,Reg,Base,"NONE",_,StackPos), track_register(Reg). .decl reg_loaded_from_stack(EA:address,Reg:register,Base:register,StackPos:number,StackFrameDefinedAt:address) .output reg_loaded_from_stack reg_loaded_from_stack(EA,Reg,Base,StackPos,StackFrameDefinedAt):- stack_frame(StackFrameDefinedAt,Base), def_used(StackFrameDefinedAt,Base,EA,_), arch.load(EA,_,_,Reg,Base,"NONE",_,StackPos), track_register(Reg). #line 110 "value_analysis.dl" .decl stack_var_used_for_address(StackFrameDefinedAt:address,Base:register,StackPos:number) stack_var_used_for_address(StackFrameDefinedAt,Base,StackPos):- reg_stored_in_stack(EAStore,StoreReg,Base,StackPos,StackFrameDefinedAt), def_used(EADef,StoreReg,EAStore,_), def_used_for_address(EADef,StoreReg). stack_var_used_for_address(StackFrameDefinedAt,Base,StackPos):- reg_loaded_from_stack(EA,Reg,Base,StackPos,StackFrameDefinedAt), def_used_for_address(EA,Reg). #line 130 "value_analysis.dl" .decl stack_load_store_pair(StoreEA:address,LoadEA:address,StoreReg:register,LoadReg:register) stack_load_store_pair(EAStore,EALoad,StoreReg,LoadReg):- stack_var_used_for_address(StackFrameDefinedAt,Base,StackPos), reg_stored_in_stack(EAStore,StoreReg,Base,StackPos,StackFrameDefinedAt), reg_loaded_from_stack(EALoad,LoadReg,Base,StackPos,StackFrameDefinedAt). #line 140 "value_analysis.dl" .decl adjacent_stack_frame(PrevAt:address,NextAt:address,BaseReg:register,Offset:number) adjacent_stack_frame(PrevEA,NextEA,BaseReg,Offset):- def_used(PrevEA,BaseReg,NextEA,_), ( arch.frame_pointer(BaseReg); arch.stack_pointer(BaseReg) ), arch.reg_arithmetic_operation(NextEA,BaseReg,BaseReg,1,Offset). stack_load_store_pair(EAStore,EALoad,StoreReg,LoadReg):- adjacent_stack_frame(PrevStackFrame,NextStackFrame,Base,Offset), reg_loaded_from_stack(EALoad,LoadReg,Base,StackPos,NextStackFrame), reg_stored_in_stack(EAStore,StoreReg,Base,StackPos+Offset,PrevStackFrame). value_reg_edge(EALoad,Reg2,EAPrev,Reg1,1,0):- stack_load_store_pair(EAStore,EALoad,Reg1,Reg2), def_used(EAPrev,Reg1,EAStore,_). value_reg_edge(EA,Reg,EA_prev,Reg_origin,1,0):- def_used_for_address(EA_prev,Reg_origin), def_used(EA_prev,Reg_origin,EA,_), arch.move_reg_reg(EA,Reg,Reg_origin), track_register(Reg), EA != EA_prev. value_reg_edge(EA,Dst,EA_prev,Src,Mult,Immediate):- def_used_for_address(EA_prev,Src), def_used(EA_prev,Src,EA,_), arch.reg_arithmetic_operation(EA,Dst,Src,Mult,Immediate), track_register(Dst). #line 185 "value_analysis.dl" .decl value_reg_unsupported(EA:address, Reg:register) value_reg_unsupported(EA,Reg):- def_used_for_address(EA,Reg), arch.load(EA,_,_,Reg,RegBase,RegIndex,_,_), ( RegBase != "NONE", RegIndex = RegIndex ; RegIndex != "NONE", RegBase = RegBase ). value_reg_unsupported(EA,Reg):- def_used_for_address(EA,Reg), arch.move_reg_reg(EA,Dst,Src), track_register(Dst), !track_register(Src). value_reg_unsupported(EA,Reg):- def_used_for_address(EA,Reg), arch.call(EA,_). value_reg(EA,Reg,EA,"NONE",0,Immediate,1):- def_used_for_address(EA,Reg), arch.move_reg_imm(EA,Reg,Immediate,_). value_reg(EA,Reg,EA,"NONE",0,0,1):- def_used_for_address(EA,Reg), is_xor_reset(EA). value_reg(EA,Reg,EA,"NONE",0,Immediate,1):- def_used_for_address(EA,Reg), flow_def(EA,Reg,_,Immediate). value_reg(EA,Reg,EA,"NONE",0,Address,1):- code(EA), instruction(EA,Size,_,"LEA",Op1,Op2,0,0,_,_), op_indirect_mapped(Op1,_,PcReg,"NONE",_,Offset,_), arch.pc_reg(PcReg), op_regdirect_contains_reg(Op2,Reg), track_register(Reg), Address = as(EA+Size,number)+Offset. value_reg(EA,Reg,EA,"NONE",0,Address,1):- got_relative_operand(EA,1,Offset), instruction(EA,_,_,"LEA",_,Op2,0,0,_,_), op_regdirect_contains_reg(Op2,Reg), track_register(Reg), Address = as(Offset,number). value_reg(EA,Reg,EA,"NONE",0,as(Val,number),1):- arch.pc_relative_addr(EA,Reg,Val), track_register(Reg). value_reg(EA,Reg,EA,"NONE",0,Val,1):- def_used_for_address(EA,Reg), arch.load(EA,_,_,Reg,"NONE","NONE",_,Offset), Offset >= 0, Offset_addr = as(Offset,address), data_word(Offset_addr,4,Val), Val >= 0. value_reg(EA,Reg,EA,"NONE",0,Val,1):- def_used_for_address(EA,Reg), arch.load(EA,_,_,_,_,_,_,_), instruction(EA,_,_,_,Op1,Op2,0,0,_,_), op_regdirect_contains_reg(Op2,Reg), op_indirect(Op1,_,_,_,_,_,32), pc_relative_operand(EA,1,Offset), data_word(Offset,4,Val), Val >= 0. #line 276 "value_analysis.dl" value_reg(EA,DstReg,EA,"NONE",0,Val,Steps3):- step_limit(StepLimit), arch.reg_reg_bitwise_binary_op(EA,DstReg,SrcReg1,SrcReg2,Op), def_used(EA_def1,SrcReg1,EA,_), def_used(EA_def2,SrcReg2,EA,_), value_reg(EA_def1,SrcReg1,EA_def1,"NONE",0,SrcVal1,Steps1), Steps1 <= StepLimit-3, value_reg(EA_def2,SrcReg2,EA_def2,"NONE",0,SrcVal2,Steps2), Steps2 <= StepLimit-3, ( Op = "ASR", Val = SrcVal1 bshr SrcVal2; Op = "LSL", Val = SrcVal1 bshl SrcVal2; Op = "AND", Val = SrcVal1 band SrcVal2; Op = "OR", Val = SrcVal1 bor SrcVal2; Op = "XOR", Val = SrcVal1 bxor SrcVal2 ), Steps3 = max(Steps1,Steps2)+2. #line 301 "value_analysis.dl" value_reg(EA,DstReg,EA,"NONE",0,Val,Steps+1):- step_limit(StepLimit), arch.reg_imm_bitwise_binary_op(EA,DstReg,SrcReg,Imm,Op), def_used(EA_def,SrcReg,EA,_), value_reg(EA_def,SrcReg,EA_def,"NONE",0,SrcVal,Steps), Steps <= StepLimit-1, ( Op = "ASR", Val = SrcVal bshr Imm; Op = "LSL", Val = SrcVal bshl Imm; Op = "AND", Val = SrcVal band Imm; Op = "OR", Val = SrcVal bor Imm; Op = "XOR", Val = SrcVal bxor Imm ). .decl step_limit(Limit:unsigned) step_limit(12). value_reg(EA,Reg,EA_reg1,Reg1,Multiplier,Offset,Steps1) <= value_reg(EA,Reg,EA_reg1,Reg1,Multiplier,Offset,Steps2):- Steps2 <= Steps1. value_reg(EA,Reg,EA,Reg,1,0,1):- def_used_for_address(EA,Reg), value_reg_unsupported(EA,Reg). value_reg(EA,Reg,EA,Reg,1,0,1):- arch.stack_pointer(Reg), value_reg_edge(_,Reg,EA,Reg,1,_). value_reg(EA,Reg,EA_from,"Unknown",Immediate,Base,Steps+1):- step_limit(StepLimit), value_reg(EA,Reg,EA_from,"NONE",0,Base,Steps), Steps <= StepLimit-2, value_reg_edge(EA,Reg,EA,Reg,1,Immediate), Immediate != 0. #line 355 "value_analysis.dl" .decl reg_reg_arithmetic_operation_defs(EA:address,Reg_def:register,EA_def1:address,Reg1:register,EA_def2:address,Reg2:register,Mult:number,Offset:number) reg_reg_arithmetic_operation_defs(EA,Reg_def,EA_def1,Reg1,EA_def2,Reg2,Mult,Offset):- arch.reg_reg_arithmetic_operation(EA,Reg_def,Reg1,Reg2,Mult,Offset), Reg1 != Reg2, def_used_for_address(EA,Reg_def), def_used(EA_def1,Reg1,EA,_), def_used(EA_def2,Reg2,EA,_), EA != EA_def1, EA != EA_def2. value_reg(EA,Reg_def,EA_third,Reg3,Mult1+(Mult*Mult2),Offset+Offset1+Offset2*Mult,Steps3):- step_limit(StepLimit), reg_reg_arithmetic_operation_defs(EA,Reg_def,EA_def1,Reg1,EA_def2,Reg2,Mult,Offset), value_reg(EA_def1,Reg1,EA_third,Reg3,Mult1,Offset1,Steps1), Steps1 <= StepLimit-3, EA != EA_third, value_reg(EA_def2,Reg2,EA_third,Reg3,Mult2,Offset2,Steps2), Steps2 <= StepLimit-3, Steps3 = max(Steps1,Steps2)+2. value_reg(EA,Reg_def,EA_third,Reg3,Mult*Mult2,Offset+Offset1+Offset2*Mult,Steps3):- step_limit(StepLimit), reg_reg_arithmetic_operation_defs(EA,Reg_def,EA_def1,Reg1,EA_def2,Reg2,Mult,Offset), value_reg(EA_def1,Reg1,_,"NONE",_,Offset1,Steps1), Steps1 <= StepLimit-3, value_reg(EA_def2,Reg2,EA_third,Reg3,Mult2,Offset2,Steps2), Steps2 <= StepLimit-3, EA != EA_third, Reg3 != "NONE", Steps3 = max(Steps1,Steps2)+2. value_reg(EA,Reg_def,EA_third,Reg3,Mult1,Offset+Offset1+Offset2*Mult,Steps3):- step_limit(StepLimit), reg_reg_arithmetic_operation_defs(EA,Reg_def,EA_def1,Reg1,EA_def2,Reg2,Mult,Offset), value_reg(EA_def2,Reg2,_,"NONE",_,Offset2,Steps2), Steps2 <= StepLimit-3, value_reg(EA_def1,Reg1,EA_third,Reg3,Mult1,Offset1,Steps1), Steps1 <= StepLimit-3, Reg3 != "NONE", EA != EA_third, Steps3 = max(Steps1,Steps2)+2. value_reg(EA1,Reg1,EA3,Reg3,Multiplier*Multiplier2,(Offset2*Multiplier)+Offset,Steps+1):- step_limit(StepLimit), value_reg(EA2,Reg2,EA3,Reg3,Multiplier2,Offset2,Steps), Steps <= StepLimit - 2, value_reg_edge(EA1,Reg1,EA2,Reg2,Multiplier,Offset), EA1 > EA2. value_reg(EA1,Reg1,EA3,Reg3,Multiplier*Multiplier2,(Offset2*Multiplier)+Offset,Steps+5):- step_limit(StepLimit), value_reg(EA2,Reg2,EA3,Reg3,Multiplier2,Offset2,Steps), Steps <= StepLimit - 6, value_reg_edge(EA1,Reg1,EA2,Reg2,Multiplier,Offset), EA1 < EA2. best_value_reg(EA,Reg,EA_from,Multiplier,MinOffset,"loop"):- value_reg(EA,Reg,EA_from,"Unknown",Multiplier,MinOffset,_), MinOffset <= min Offset:{value_reg(EA,Reg,EA_from,"Unknown",Multiplier,Offset,_)}. best_value_reg(EA,Reg,EA_from,Multiplier,MaxOffset,"loop"):- value_reg(EA,Reg,EA_from,"Unknown",Multiplier,MaxOffset,_), MaxOffset >= max Offset:{value_reg(EA,Reg,EA_from,"Unknown",Multiplier,Offset,_)}. best_value_reg(EA,Reg,EA_from,Multiplier,Offset,"complete"):- value_reg(EA,Reg,EA_from,"NONE",Multiplier,Offset,_), !value_reg(EA,Reg,_,"Unknown",_,_,_). .decl value_reg_max_mult(EA:address,Reg:register,MaxMult:number) value_reg_max_mult(EA,Reg,MaxMult):- def(EA,Reg), !value_reg(EA,Reg,_,"Unknown",_,_,_), MaxMult = max Multiplier:{value_reg(EA,Reg,_,_,Multiplier,_,_)}. best_value_reg(EA,Reg,0,MaxMultiplier,Offset,"incomplete"):- value_reg_max_mult(EA,Reg,MaxMultiplier), value_reg(EA,Reg,_,OtherReg,MaxMultiplier,Offset,_), OtherReg != "NONE". #line 450 "value_analysis.dl" .decl const_value_reg_used(UsedEA:address,EADef:address,EARegDef:address,Reg:register,Value:number) const_value_reg_used(UsedEA,EADef,EARegDef,Reg,Value):- value_reg(EARegDef,Reg,EADef,"NONE",0,Value,_), def_used(EARegDef,Reg,UsedEA,_). #line 62 "symbolization.dl" #line 1 "boundary_value_analysis.dl" #line 46 "boundary_value_analysis.dl" .decl flags_and_jump_pair(EA_flags:address,EA_jmp:address,CC:condition_code) .output flags_and_jump_pair flags_and_jump_pair(EA_flags,EA_jmp,CC):- arch.condition_flags_reg(Reg), def_used(EA_flags,Reg,EA_jmp,_), arch.jump(EA_jmp), arch.conditional(EA_jmp,CC). #line 59 "boundary_value_analysis.dl" .decl compare_and_jump_immediate(EA_cmp:address,EA_jmp:address,CC:condition_code,Reg:register,Immediate:number) .output compare_and_jump_immediate compare_and_jump_immediate(EA_cmp,EA_jmp,CC,Reg,Immediate):- flags_and_jump_pair(EA_cmp,EA_jmp,CC), instruction_get_operation(EA_cmp,Operation), arch.cmp_operation(Operation), cmp_immediate_to_reg(EA_cmp,Reg,_,Immediate). compare_and_jump_immediate(EA,EA,CC,Reg,0):- instruction_get_operation(EA,Operation), arch.cmp_zero_operation(Operation), arch.jump(EA), arch.conditional(EA,CC), instruction_get_op(EA,_,Op), ( op_regdirect_contains_reg(Op,Reg) ; register_access(EA,RegIn,"R"), reg_map(RegIn,Reg), !op_regdirect_contains_reg(Op,Reg) ). #line 90 "boundary_value_analysis.dl" .decl compare_and_jump_register(EA_cmp:address,EA_jmp:address,CC:condition_code,Reg1:register,Reg2:register) compare_and_jump_register(EA_cmp,EA_jmp,CC,Reg1,Reg2):- flags_and_jump_pair(EA_cmp,EA_jmp,CC), cmp_reg_to_reg(EA_cmp,Reg1,Reg2). compare_and_jump_register(EA,EA,CC,Reg1,Reg2):- cmp_reg_to_reg(EA,Reg1,Reg2), arch.jump(EA), arch.conditional(EA,CC). #line 107 "boundary_value_analysis.dl" .decl compare_and_jump_indirect(EA_cmp:address,EA_jmp:address,CC:condition_code,IndirectOp:operand_code,Immediate:number) compare_and_jump_indirect(EA_cmp,EA_jmp,CC,IndirectOp,Immediate):- flags_and_jump_pair(EA_cmp,EA_jmp,CC), instruction_get_operation(EA_cmp,CmpOperation), arch.cmp_operation(CmpOperation), instruction_get_op(EA_cmp,_,IndirectOp), op_indirect(IndirectOp,_,_,_,_,_,_), instruction_get_op(EA_cmp,_,ImmOp), op_immediate(ImmOp,Immediate). #line 121 "boundary_value_analysis.dl" .type limit_type <: symbol #line 126 "boundary_value_analysis.dl" .decl limit_type_map(CC:condition_code,BranchLT:limit_type,FallthroughLT:limit_type,BranchOffset:number,FallthroughOffset:number) limit_type_map("A","MIN","MAX",1,0). limit_type_map("G","MIN","MAX",1,0). limit_type_map("AE","MIN","MAX",0,-1). limit_type_map("GE","MIN","MAX",0,-1). limit_type_map("B","MAX","MIN",-1,0). limit_type_map("L","MAX","MIN",-1,0). limit_type_map("BE","MAX","MIN",0,1). limit_type_map("LE","MAX","MIN",0,1). #line 143 "boundary_value_analysis.dl" .decl value_reg_limit(From:address,To:address,Reg:register,Value:number,LimitType:limit_type) .output value_reg_limit value_reg_limit(EA_jmp,EA_branch,Reg,BranchValue,BranchLT), value_reg_limit(EA_jmp,EA_fallthrough,Reg,FallthroughValue,FallthroughLT):- compare_and_jump_immediate(_,EA_jmp,CC,Reg,Immediate), track_register(Reg), limit_type_map(CC,BranchLT,FallthroughLT,BranchOffset,FallthroughOffset), direct_jump(EA_jmp,EA_branch), may_fallthrough(EA_jmp,EA_fallthrough), BranchValue = Immediate + BranchOffset, FallthroughValue = Immediate + FallthroughOffset. value_reg_limit(EA_jmp,EA_branch,Reg,BranchValue,BranchLT), value_reg_limit(EA_jmp,EA_fallthrough,Reg,FallthroughValue,FallthroughLT):- compare_and_jump_register(EA_cmp,EA_jmp,CC,Reg1,Reg2), limit_type_map(CC,LT1,LT2,Offset1,Offset2), ( ConstReg=Reg1, Reg=Reg2, BranchLT=LT1, FallthroughLT=LT2, BranchOffset=Offset1, FallthroughOffset=Offset2 ; ConstReg=Reg2, Reg=Reg1, BranchLT=LT2, FallthroughLT=LT1, BranchOffset=Offset2, FallthroughOffset=Offset1 ), block_last_def(EA_cmp,EA_regdef,ConstReg), arch.move_reg_imm(EA_regdef,ConstReg,Immediate,_), track_register(Reg), direct_jump(EA_jmp,EA_branch), may_fallthrough(EA_jmp,EA_fallthrough), BranchValue = Immediate + BranchOffset, FallthroughValue = Immediate + FallthroughOffset. value_reg_limit(EA_target,EA_limited,Reg,Value,LimitType):- compare_and_jump_indirect(EA_cmp,EA_jmp,CC,IndirectOp,Immediate), limit_type_map(CC,BranchLT,FallthroughLT,BranchOffset,FallthroughOffset), next(EA_cmp,EA_jmp), ( direct_jump(EA_jmp,EA_target), LimitType = BranchLT, Value = Immediate + BranchOffset, FallthroughLT = FallthroughLT , FallthroughOffset = FallthroughOffset ; may_fallthrough(EA_jmp,EA_target), LimitType = FallthroughLT, Value = Immediate + FallthroughOffset, BranchLT = BranchLT , BranchOffset = BranchOffset ), arch.load(EA_target,_,_,Reg,_,_,_,_), track_register(Reg), instruction_get_op(EA_target,_,IndirectOp), local_next(EA_target,EA_limited). #line 215 "boundary_value_analysis.dl" .decl cmp_defines(EA_jmp:address,EA_dst:address,Reg:register) cmp_defines(EA_jmp,EA_dst,Reg):- compare_and_jump_immediate(_,EA_jmp,"E",Reg,_), direct_jump(EA_jmp,EA_dst). cmp_defines(EA_jmp,EA_dst,Reg):- compare_and_jump_immediate(_,EA_jmp,"NE",Reg,_), may_fallthrough(EA_jmp,EA_dst). #line 228 "boundary_value_analysis.dl" .decl no_value_reg_limit(EA_jmp:address) .output no_value_reg_limit no_value_reg_limit(EA_jmp):- compare_and_jump_immediate(_,EA_jmp,CC,_,_), ( CC="O"; CC="NO"; CC="P"; CC="PE"; CC="S"; CC="NS" ). no_value_reg_limit(EA_jmp):- compare_and_jump_register(EA_cmp,EA_jmp,_,Reg1,Reg2), ( !block_last_def(EA_cmp,_,Reg1), !block_last_def(EA_cmp,_,Reg2) ; block_last_def(EA_cmp,EA,Reg1), !arch.move_reg_imm(EA,Reg1,_,_), !block_last_def(EA_cmp,_,Reg2) ; block_last_def(EA_cmp,EA,Reg2), !arch.move_reg_imm(EA,Reg2,_,_), !block_last_def(EA_cmp,_,Reg1) ; block_last_def(EA_cmp,EA,Reg1), !arch.move_reg_imm(EA,Reg1,_,_), block_last_def(EA_cmp,_,Reg2), !arch.move_reg_imm(EA,Reg2,_,_) ). no_value_reg_limit(EA_jmp):- flags_and_jump_pair(EA_cmp,EA_jmp,_), instruction_get_operation(EA_cmp,Operation), !arch.cmp_operation(Operation). #line 281 "boundary_value_analysis.dl" .decl last_value_reg_limit(From:address,To:address,Reg:register,Value:number,LimitType:limit_type) .output last_value_reg_limit last_value_reg_limit(From,To,Reg,Value,LimitType):- value_reg_limit(From,To,Reg,Value,LimitType). last_value_reg_limit(BlockEnd,BlockNext,PropagatedReg,PropagatedVal,PropagatedType):- last_value_reg_limit(_,EA,PropagatedReg,PropagatedVal,PropagatedType), code_in_block(EA,Block), block_next(Block,BlockEnd,BlockNext), !defined_in_block(Block,PropagatedReg), ( !conditional_jump(BlockEnd); no_value_reg_limit(BlockEnd); cmp_defines(BlockEnd,BlockNext,Reg), Reg != PropagatedReg; cmp_defines(BlockEnd,DefinedNext,PropagatedReg), BlockNext != DefinedNext; value_reg_limit(BlockEnd,BlockNext,Reg,Val,Type), ( Reg != PropagatedReg, Val = Val , Type = Type ; Reg = PropagatedReg, PropagatedType = "MAX", Type = "MAX", PropagatedVal < Val; Reg = PropagatedReg, PropagatedType = "MIN", Type = "MIN", PropagatedVal > Val ) ). last_value_reg_limit(EA_mov,EA_next,DstReg,PropagatedVal,PropagatedType):- last_value_reg_limit(From,EA,SrcReg,PropagatedVal,PropagatedType), code_in_block(EA,Block), block_last_instruction(Block,BlockEnd), code_in_block(EA_mov,EA), arch.move_reg_reg(EA_mov,DstReg,SrcReg), ( EA_mov != BlockEnd, local_next(EA_mov,EA_next) ; EA_mov = BlockEnd, block_next(Block,BlockEnd,EA_next) ), ( !block_last_def(EA_mov,_,SrcReg), From = From ; block_last_def(EA_mov,From,SrcReg) ). #line 63 "symbolization.dl" #line 1 "data_access_analysis.dl" #line 45 "data_access_analysis.dl" .decl instruction_memory_access_size(EA:address,Op_index:operand_index,Size:unsigned) instruction_memory_access_size(EA,Index,SizeAccess):- !invalid(EA,_), instruction_get_operation(EA,Operation), instruction_get_op(EA,Index,Op), op_indirect(Op,_,_,_,_,_,Size), ( instruction_get_dest_op(EA,_,DestOp), op_regdirect_contains_reg(DestOp,DestReg), arch.data_access_size(Operation,DestReg,SizeAccess), Size = Size ; !arch.data_access_size(Operation,_,_), SizeAccess = Size/8 ). .decl data_access(EA:address,Op_index:operand_index,RegSegment:reg_nullable,RegBase:reg_nullable,RegIndex:reg_nullable,Mult:number,Offset:number,Size:unsigned) .output data_access data_access(EA,Op_index,RegSegment,RegBase,RegIndex,Mult,Offset,Size):- code(EA), instruction_get_op(EA,Op_index,Op), op_indirect_mapped(Op,RegSegment,RegBase,RegIndex,Mult,Offset,_), instruction_memory_access_size(EA,Op_index,Size). .decl value_reg_at_operand(EA:address,Op_index:operand_index,Reg:reg_nullable,EA_from:address,Mult:number,Offset:number,Type:symbol) .decl value_reg_at_operand_loop(EA:address,Op_index:operand_index,Reg:reg_nullable,EA_from:address,Mult:number,Offset:number,Type:symbol) value_reg_at_operand(EA,Op_index,Reg,EA_from,Mult,BaseAddress,"loop"), value_reg_at_operand_loop(EA,Op_index,Reg,EA_from,Mult,BaseAddress,"loop"):- data_access(EA,Op_index,_,Reg2,Reg3,_,_,_), ( Reg = Reg2, Reg3 = Reg3 ; Reg = Reg3, Reg2 = Reg2 ), reg_nonnull(Reg,Reg_nn), def_used(EA_def,Reg_nn,EA,Op_index), best_value_reg(EA_def,Reg_nn,EA_from,Mult,Offset,"loop"), ( !def_used(EA_from,Reg_nn,EA,Op_index), BaseAddress = Offset ; def_used(EA_from,Reg_nn,EA,Op_index), BaseAddress = Offset-Mult ). value_reg_at_operand(EA,Op_index,Reg,EA_from,Mult,Offset_final,Type):- data_access(EA,Op_index,_,Reg2,Reg3,_,_,_), ( Reg = Reg2, Reg3 = Reg3 ; Reg = Reg3, Reg2 = Reg2 ), reg_nonnull(Reg,Reg_nn), !value_reg_at_operand_loop(EA,Op_index,Reg,_,_,_,_), def_used(EA_def,Reg_nn,EA,Op_index), best_value_reg(EA_def,Reg_nn,EA_from,Mult,Offset,Type), ( Offset_final = max(Offset,0) ; Type = "incomplete", Offset_final = 0, Offset = Offset ). value_reg_at_operand(EA,Op_index,Reg,0,1,0,"incomplete"):- data_access(EA,Op_index,_,Reg2,Reg3,_,_,_), ( Reg = Reg2, Reg3 = Reg3 ; Reg = Reg3, Reg2 = Reg2 ), reg_nonnull(Reg,Reg_nn), !def_used(_,Reg_nn,EA,Op_index). value_reg_at_operand(EA,Op_index,Reg,0,0,0,"complete"):- data_access(EA,Op_index,_,Reg2,Reg3,_,_,_), ( Reg = Reg2, Reg3 = Reg3 ; Reg = Reg3, Reg2 = Reg2 ), Reg = "NONE". #line 156 "data_access_analysis.dl" .decl data_access_pattern(Address:address,Size:unsigned,Multiplier:number,FromWhere:address) .output data_access_pattern #line 162 "data_access_analysis.dl" .decl data_access_pattern_candidate(Address:address,Size:unsigned,Multiplier:number,FromWhere:address) .output data_access_pattern_candidate #line 170 "data_access_analysis.dl" .decl preferred_data_access(EA:address,Size:unsigned,AccessEA:address) .output preferred_data_access data_access_pattern_candidate(Address,Size,0,EA):- data_access(EA,_,"NONE","NONE","NONE",_,Offset,Size), Address = as(Offset,address), data_segment(Beg,End), Address >= Beg, Address <= End. data_access_pattern_candidate(Address,Size,0,EA):- code(EA), ( pc_relative_operand(EA,Op_index,Address); split_load_operand(EA,Op_index,Address) ), instruction_memory_access_size(EA,Op_index,Size), data_segment(Beg,End), Address >= Beg, Address <= End. data_access_pattern_candidate(Address,Size,Mult*Mult2,EA):- data_access(EA,Op_index,"NONE",RegBase,RegMult,Mult,Offset1,Size), !pc_relative_operand(EA,Op_index,_), !split_load_operand(EA,Op_index,_), RegMult != "NONE", RegMult != RegBase, value_reg_at_operand(EA,Op_index,RegMult,_,Mult2,Offset2,_), value_reg_at_operand(EA,Op_index,RegBase,_,0,Offset3,"complete"), ( Mult*Mult2 > 0, as(Size,number) <= Mult*Mult2; Mult*Mult2 = 0; Mult*Mult2 < 0, as(Size,number) <= -(Mult*Mult2) ), Address = as(Offset1+(Offset2*Mult)+Offset3,address), data_segment(Beg,End), Address >= Beg, Address <= End. data_access_pattern_candidate(Address,Size,Mult,EA):- data_access(EA,Op_index,"NONE",RegBase,RegMult,Mult2,Offset1,Size), !pc_relative_operand(EA,Op_index,_), !split_load_operand(EA,Op_index,_), RegMult != RegBase, value_reg_at_operand(EA,Op_index,RegMult,_,0,Offset2,"complete"), value_reg_at_operand(EA,Op_index,RegBase,_,Mult,Offset3,_), ( Mult > 0, as(Size,number) <= Mult; Mult = 0; Mult < 0, as(Size,number) <= -Mult ), Address = as(Offset1+Offset2*Mult2+Offset3,address), data_segment(Beg,End), Address >= Beg, Address <= End. data_access_pattern_candidate(Address,Size,FinalMult,EA):- data_access(EA,Op_index,"NONE",Reg,Reg,Mult,Offset1,Size), Reg != "NONE", value_reg_at_operand(EA,Op_index,Reg,_,Mult2,Offset2,_), FinalMult = Mult*Mult2+Mult2, (as(Size,number) <= FinalMult; FinalMult = 0), Address = as(Offset1+(Offset2*Mult)+Offset2, address), data_segment(Beg,End), Address >= Beg, Address <= End. #line 252 "data_access_analysis.dl" .decl data_access_pattern_candidate_refined(Address:address,Size:unsigned,Multiplier:number,FromWhere:address) data_access_pattern_candidate_refined(Address,Size,Multiplier,From):- data_access_pattern_candidate(Address,Size,Multiplier,From), instruction_get_operation(From,Operation), Operation != "LEA", ( address_in_data(Address,_); !indirect_jump(From), !indirect_call(From) ). #line 270 "data_access_analysis.dl" .decl dap_location(Address:address,Size:unsigned) dap_location(Address,Size):- data_access_pattern_candidate_refined(Address,Size,_,_). #line 278 "data_access_analysis.dl" .decl dap_max_mult(Address:address,Size:unsigned,Max:number) dap_max_mult(Address,Size,Max):- dap_location(Address,Size), Max = max Mult : data_access_pattern_candidate_refined(Address,Size,Mult,_). data_access_pattern(Address,Size,Multiplier,From):- data_access_pattern_candidate_refined(Address,Size,Multiplier,From), dap_max_mult(Address,Size,Multiplier). data_access_pattern(Address,Size,Multiplier,From):- data_access_pattern_candidate_refined(Address,Size,Multiplier,From), Multiplier = as(Size,number). #line 300 "data_access_analysis.dl" .decl data_limit(EA:address) data_limit(EA):- labeled_data_candidate(EA); data_segment(_,EA); data_segment(EA,_). #line 310 "data_access_analysis.dl" .decl next_data_limit(EA:address,Next:address) next_data_limit(EA,Next):- data_limit(EA), data_segment(Beg,End), EA >= Beg, EA < End, Next = min Next : {data_limit(Next), Next > EA}, Next <= End. #line 322 "data_access_analysis.dl" .decl data_limit_after_access(Access:address,DataLimit:address) data_limit_after_access(Access,DataLimit):- data_access_pattern(Access,_,_,_), data_segment(Beg,End), Access >= Beg, Access < End, DataLimit = min DataLimit : {data_limit(DataLimit), DataLimit > Access}, DataLimit <= End. #line 334 "data_access_analysis.dl" .decl next_data_access(EA:address,Next:address) next_data_access(EA,Next):- data_access_pattern(EA,_,_,_), data_segment(Beg,End), EA >= Beg, EA < End, Next = min Next : {data_access_pattern(Next,_,_,_), Next > EA}, Next <= End. .decl data_access_pattern_non_zero(Address:address,Size:unsigned,Multiplier:unsigned,FromWhere:address) data_access_pattern_non_zero(Address,Size,as(Mult,unsigned),FromWhere):- data_access_pattern(Address,Size,Mult,FromWhere), Mult > 0. #line 370 "data_access_analysis.dl" .decl synchronous_access(RefAccess:address,LastEA:address) .output synchronous_access synchronous_access(EA,EA2):- data_access_pattern_non_zero(EA,Size,Mult,From), next_data_access(EA,EA2), data_access_pattern(EA2,Size2,Mult2_s,From2), Mult2 = as(Mult2_s,unsigned), Rem = (EA2 - EA) % Mult, Size <= Rem, Rem + Size2 <= Mult, ( Mult2 = 0, From2 = From, Size2 = Size, Rem = 0 ; Mult2 = Mult ). synchronous_access(EA,EA2):- synchronous_access(EA,EA_inter), data_access_pattern_non_zero(EA,Size,Mult,From), next_data_access(EA_inter,EA2), data_access_pattern(EA2,Size2,Mult2_s,From2), Mult2 = as(Mult2_s,unsigned), Rem = (EA2 - EA) % Mult, Size <= Rem, Rem + Size2 <= Mult, ( Mult2 = 0, From2 = From, Size2 = Size, Rem = 0 ; Mult2 = Mult ). #line 415 "data_access_analysis.dl" .decl first_synchronous_access(Ref:address,Access:address) first_synchronous_access(Ref,Access):- synchronous_access(_,Access), Ref = min Ref: {synchronous_access(Ref,Access)}. #line 426 "data_access_analysis.dl" .decl next_dyssynchronous_data_access(EA:address,Next:address) .output next_dyssynchronous_data_access next_dyssynchronous_data_access(EA,Next):- data_access_pattern(EA,_,_,_), ( synchronous_access(EA,End), next_data_access(End,Next), !synchronous_access(EA,Next) ; !synchronous_access(EA,_), next_data_access(EA,Next) ). preferred_data_access(EA,Size,EA):- data_access_pattern(EA,Size,0,_), data_byte(EA,_). preferred_data_access(EA_prop,Size,EA_access):- data_access_pattern_non_zero(EA_access,Size,Mult,_), data_byte(EA_access,_), ( next_dyssynchronous_data_access(EA_access,Next_access), Limit = min(Next_access,Next_limit) ; !next_dyssynchronous_data_access(EA_access,_), Limit = Next_limit ), data_limit_after_access(EA_access,Next_limit), EA_prop = range(EA_access,Limit,Mult). #line 64 "symbolization.dl" #line 1 "pointer_reatribution.dl" #line 59 "pointer_reatribution.dl" .decl moved_data_label(EA:address,Size:unsigned,Dest:address,NewDest:address) .output moved_data_label #line 67 "pointer_reatribution.dl" .decl moved_label(EA:address,Index:operand_index,Dest:address,NewDest:address) .output moved_label #line 75 "pointer_reatribution.dl" .decl boundary_sym_expr(EA:address,Dest:address) .decl moved_label_class(EA:address,Index:operand_index,Reason:symbol) .output moved_label_class moved_data_label(EA,Size,Dest,NewDest):- symbolic_data(EA,Size,Dest), address_in_data_refined_range.overlap(Dest,8,NewDest), symbolic_data(NewDest,8,_). moved_data_label(EA,SizePointer,Dest,Address):- symbolic_data(EA,SizePointer,Dest), !code(Dest), symbol(Address,Size,_,_,_,_,_,_,Name), !function_symbol(Address,Name), Address < Dest, Dest < Address+Size. moved_data_label(EA,SizePointer,Dest,Address):- symbolic_data(EA,SizePointer,Dest), overlapping_instruction(Dest,Address). .decl moved_pc_relative_candidate(EA:address,Index:operand_index,Val:address,NewVal:address,Diff:unsigned) moved_pc_relative_candidate(EA_def2,Op_index,Dest,NewDest,Diff):- binary_format("ELF"), cmp_reg_to_reg(EA,Reg1,Reg2), def_used(EA_def1,Reg1,EA,_), dest_enlarged_data_section(EA_def1,Reg1,NewDest,Beg,End,OldBeg,OldEnd), def_used(EA_def2,Reg2,EA,_), pc_relative_operand(EA_def2,Op_index,Dest), instruction_get_operation(EA_def2,"LEA"), Beg <= Dest, Dest <= End, ( OldBeg > Dest, OldEnd = OldEnd ; Dest > OldEnd, OldBeg = OldBeg ), Diff = max(NewDest-Dest,Dest-NewDest). moved_pc_relative_candidate(EA,Op_index,Dest,NewDest,Diff):- code(EA), binary_format("ELF"), binary_isa("X64"), pc_relative_operand(EA,Op_index,Dest), !symbolic_operand(EA,Op_index,_,_), regular_data_section(Name), loaded_section(Base,End,Name), ( Base > Dest, NewDest = Base, End = End ; Dest > End, NewDest = End, Base = Base ), Diff = max(NewDest,Dest) - min(NewDest,Dest). moved_pc_relative_candidate(EA,Op_index,Dest,NewDest,Diff):- code(EA), pc_relative_operand(EA,Op_index,Dest), !symbolic_operand(EA,Op_index,_,_), exception_section(Name), loaded_section(Base,_,Name), ( cie_entry(Dest, _,_,_); fde_entry(Dest,_,_,_,_,_) ), NewDest = Base, Diff = max(NewDest,Dest) - min(NewDest,Dest). moved_label_class(EA,Op_index,"pc-relative miss data-sections"), moved_label(EA,Op_index,Dest,NewDest):- moved_pc_relative_candidate(EA,Op_index,Dest,NewDest,Diff), Diff_min = min X:moved_pc_relative_candidate(EA,Op_index,Dest,_,X), Diff <= Diff_min. moved_label_class(EA,Op_index,"collides with pointer"), moved_label(EA,Op_index,Dest,NewDest):- binary_type("EXEC"), symbolic_operand(EA,Op_index,Dest,"data"), arch.pointer_size(Pt_size), address_in_data_refined_range.overlap(Dest,Pt_size,NewDest), symbolic_data(NewDest,_,_). moved_label_class(EA,Op_index,"indirect wrong section"), moved_displacement_candidate(EA,Op_index,Dest,NewDest,Diff):- binary_type("EXEC"), symbolic_operand(EA,Op_index,Dest,_), data_access(EA,Op_index,_,_,_,_,_,_), data_access_pattern_candidate(Access_dest,_,Mult,EA), Access_dest != Dest, NewDest = Access_dest, Diff = max(Access_dest-Dest, Dest-Access_dest), loaded_section(Base,End,Name), Dest >= Base, Dest <= End, regular_data_section(Name2), Name2 != Name, loaded_section(Base2,End2,Name2), NewDest >= Base2, NewDest <= End2, Dest != Base2, ( Mult > 0, NewDest > Dest ; Mult <= 0 ). .decl moved_displacement_candidate(EA:address,Op_index:operand_index,Dest:address,NewDest:address,Priority:unsigned) .output moved_displacement_candidate moved_label_class(EA,Op_index,"miss section with access"), moved_displacement_candidate(EA,Op_index,as(Dest,address),AccessDest,1):- binary_type("EXEC"), data_access(EA,Op_index,_,_,_,_,Dest,Size), Dest >= 0, Size != 0, DestAddr = as(Dest,address), !symbolic_operand(EA,Op_index,_,_), !pc_relative_operand(EA,Op_index,_), !split_load_operand(EA,Op_index,_), data_access_pattern_candidate(AccessDest,_,_,EA), regular_data_section(Name), loaded_section(Base,End,Name), AccessDest >= Base, AccessDest < End, Diff = max(AccessDest,DestAddr) - min(AccessDest,DestAddr), 10*DestAddr >= Base, @functor_data_exists(Diff,1) = 0, bss_section_limits(BssBeg,BssEnd), ( Diff < BssBeg, BssEnd = BssEnd ; Diff > BssEnd, BssBeg = BssBeg ). moved_label_class(EA,Op_index,"constant + multiplied reg"), moved_displacement_candidate(EA,Op_index,DestAddr,NewDest,Distance):- binary_type("EXEC"), !binary_isa("X86"), data_access(EA,Op_index,"NONE","NONE",RegMult,Mult,Dest,_), Dest >= 0, DestAddr = as(Dest,address), !instruction_get_operation(EA,"LEA"), !symbolic_operand(EA,Op_index,_,_), !pc_relative_operand(EA,Op_index,_), !split_load_operand(EA,Op_index,_), ( Mult > 1, RegMult = RegMult ; value_reg_at_operand(EA,Op_index,RegMult,_,Mult2,0,_), Mult2 > 1, Mult = Mult ), regular_data_section(Name), loaded_section(Base,End,Name), ( DestAddr < Base, Distance = Base-DestAddr, NewDest = Base, 10*DestAddr > Base, End = End ; DestAddr > End, Distance = DestAddr-End, NewDest = End ). moved_label_class(EA,Op_index,"constant + multiplied reg2"), moved_displacement_candidate(EA,Op_index,DestAddr,NewDest,Distance):- binary_type("EXEC"), data_access(EA,Op_index,"NONE",Reg,"NONE",_,Dest,_), Dest >= 0, DestAddr = as(Dest,address), !instruction_get_operation(EA,"LEA"), !symbolic_operand(EA,Op_index,_,_), !pc_relative_operand(EA,Op_index,_), !split_load_operand(EA,Op_index,_), value_reg_at_operand(EA,Op_index,Reg,_,Mult2,0,_), Mult2>1, regular_data_section(Name), loaded_section(Base,End,Name), ( DestAddr < Base, Distance = Base-DestAddr, NewDest = Base, 10*DestAddr > Base, End = End ; DestAddr > End, Distance = DestAddr-End, NewDest = End, Base = Base ). moved_label_class(EA,Op_index,"constant + repeated reg"), moved_displacement_candidate(EA,Op_index,DestAddr,NewDest,Distance):- binary_type("EXEC"), !binary_isa("X86"), data_access(EA,Op_index,"NONE",Reg,Reg,_,Dest,_), Dest >= 0, DestAddr = as(Dest,address), !instruction_get_operation(EA,"LEA"), !symbolic_operand(EA,Op_index,_,_), regular_data_section(Name), loaded_section(Base,End,Name), ( DestAddr < Base, Distance = Base-DestAddr, NewDest = Base, 10*DestAddr > Base, End = End ; DestAddr > End, Distance = DestAddr-End, NewDest = End, Base = Base ). .decl discarded_moved_displacement_candidate(EA:address,Op_index:operand_index,Dest:address,NewDest:address,Distance:unsigned) discarded_moved_displacement_candidate(EA,Op_index,Dest,NewDest,Distance1):- moved_displacement_candidate(EA,Op_index,Dest,NewDest,Distance1), moved_displacement_candidate(EA,Op_index,_,_,Distance2), Distance2 < Distance1. moved_label(EA,Op_index,Dest,NewDest):- moved_displacement_candidate(EA,Op_index,Dest,NewDest,Distance), !discarded_moved_displacement_candidate(EA,Op_index,Dest,NewDest,Distance). .decl cmp_reg_to_reg(EA:address,Reg1:register,Reg2:register) .decl moved_immediate_candidate(EA:address,Op_index:operand_index,Immediate:address,New_immmediate:address) .decl mov_pc_relative_immediate_to_reg(EA:address,Reg:register,Imm_index:operand_index,Immediate:number) mov_pc_relative_immediate_to_reg(EA,Reg,1,Immediate):- code(EA), instruction_get_operation(EA,"LEA"), pc_relative_operand(EA,1,Dest), Immediate = as(Dest,number), instruction_get_dest_op(EA,_,Op), op_regdirect_contains_reg(Op,Reg). cmp_reg_to_reg(EA,Reg1,Reg2):- code(EA), instruction_get_operation(EA,Operation), arch.cmp_operation(Operation), instruction_get_op(EA,_,Op1), op_regdirect_contains_reg(Op1,Reg1), instruction_get_op(EA,_,Op2), Op2!=Op1, op_regdirect_contains_reg(Op2,Reg2). .decl dest_enlarged_data_section(EA:address,Reg:register,NewDest:address, Beg:address,End:address,OldBeg:address,OldEnd:address) .output dest_enlarged_data_section dest_enlarged_data_section(EA_def,Reg,NewDestAddr,Beg-MultAbs,End+MultAbs,Beg,End):- best_value_reg(EA_def,Reg,_,Mult,NewDest,"loop"), NewDest >= 0, NewDestAddr = as(NewDest,address), MultAbs = as(max(Mult,-Mult),unsigned), regular_data_section(Name), loaded_section(Beg,End,Name), NewDestAddr >= Beg, NewDestAddr <= End. dest_enlarged_data_section(EA_def,Reg,NewDestAddr,Beg-MultAbs-OffsetAddr,End+MultAbs-OffsetAddr,Beg,End):- best_value_reg(EA_def,Reg,EA_from,Mult,_,"loop"), def_used(EA_def,Reg,EA_used,Op_index), value_reg_at_operand_loop(EA_used,Op_index,Reg,EA_from,Mult,NewDest,"loop"), NewDest >= 0, data_access(EA_used,Op_index,"NONE",Reg,"NONE",_,Offset,_), Offset > 0, OffsetAddr = as(Offset,address), @functor_data_exists(OffsetAddr,1) = 0, NewDestAddr = as(NewDest,address), MultAbs = as(max(Mult,-Mult),unsigned), regular_data_section(Name), loaded_section(Beg,End,Name), NewDestAddr >= Beg, NewDestAddr <= End. moved_label_class(EA_from,Imm_index,"immediate used to access memory"), moved_immediate_candidate(EA_from,Imm_index,ImmediateAddr,NewDest):- data_access(EA_access,Op_index,_,Reg2,Reg3,_,_,_), data_access_pattern_candidate(NewDest,_,Mult,EA_access), regular_data_section(Name), loaded_section(Beg,End,Name), NewDest >= Beg, NewDest < End, ( Reg = Reg2, Reg3 = Reg3 ; Reg = Reg3, Reg2 = Reg2 ), value_reg_at_operand(EA_access,Op_index,Reg,EA_from,_,_,Type), Type != "incomplete", ( binary_type("EXEC"), arch.move_reg_imm(EA_from,Reg,Immediate,Imm_index), code(EA_from), Immediate >= 0 ; mov_pc_relative_immediate_to_reg(EA_from,Reg,Imm_index,Immediate), Immediate >= 0 ), ImmediateAddr = as(Immediate,address), as(Beg,number)-Mult <= Immediate, Immediate <= as(End,number)+Mult, (ImmediateAddr < Beg ; ImmediateAddr > End). moved_label_class(EA,Imm_index,"immediate loop bound"), moved_immediate_candidate(EA,Imm_index,ImmediateAddr,NewDest):- binary_type("EXEC"), cmp_immediate_to_reg(EA,Reg,Imm_index,Immediate), Immediate >= 0, ImmediateAddr = as(Immediate,address), def_used(EA_def,Reg,EA,_), dest_enlarged_data_section(EA_def,Reg,NewDest,Beg,End,OldBeg,OldEnd), Beg <= ImmediateAddr, ImmediateAddr <= End, ( OldBeg > ImmediateAddr, OldEnd = OldEnd ; ImmediateAddr >= OldEnd, OldBeg = OldBeg ). moved_label_class(EA_def2,Imm_index,"loaded immediate loop bound"), moved_immediate_candidate(EA_def2,Imm_index,ImmediateAddr,NewDest):- cmp_reg_to_reg(EA,Reg1,Reg2), def_used(EA_def1,Reg1,EA,_), dest_enlarged_data_section(EA_def1,Reg1,NewDest,Beg,End,OldBeg,OldEnd), def_used(EA_def2,Reg2,EA,_), ( binary_type("EXEC"), arch.move_reg_imm(EA_def2,Reg2,Immediate,Imm_index), code(EA_def2), Immediate >= 0 ; mov_pc_relative_immediate_to_reg(EA_def2,Reg2,Imm_index,Immediate), Immediate >= 0 ), ImmediateAddr = as(Immediate,address), Beg <= ImmediateAddr,ImmediateAddr <= End, ( OldBeg > ImmediateAddr, OldEnd = OldEnd ; ImmediateAddr >= OldEnd, OldBeg = OldBeg ). moved_label_class(EA,Op_index,"pie relocation"), moved_immediate_candidate(EA,Op_index,DestAddr,SymbolAddr):- !binary_type("EXEC"), !binary_type("REL"), code(EA), instruction_immediate_offset(EA,Op_index,ImmediateOffset,_), instruction_get_src_op(EA,Op_index,Op), op_immediate(Op,Dest), Dest >= 0, DestAddr = as(Dest,address), relocation(EA+ImmediateOffset,_,Symbol,_,_,_,_), symbol(SymbolAddr,_,_,_,_,_,_,_,Symbol), SymbolAddr != DestAddr. moved_label(EA,Op_index,Dest,NewDest):- moved_immediate_candidate(EA,Op_index,Dest,NewDest). moved_label_class(EA,Op_index,"middle of symbol"), moved_label(EA,Op_index,Dest,Address):- ( symbolic_operand(EA,Op_index,Dest,"data"); got_relative_operand(EA,Op_index,Dest) ), !moved_displacement_candidate(EA,Op_index,_,_,_), !moved_immediate_candidate(EA,Op_index,_,_), defined_symbol(Address,Size,_,_,_,_,_,_,Name), !function_symbol(Address,Name), Address < Dest, Dest < Address+Size. moved_label_class(EA,Op_index,"overlapping instruction"), moved_label(EA,Op_index,Dest,Block):- symbolic_operand(EA,Op_index,Dest,"code"), overlapping_instruction(Dest,Block). moved_label(EA,Op_index,Src,Dst):- first_synchronous_access(Dst,Src), Dst != Src, symbolic_operand(EA,Op_index,Src,"data"), symbolic_operand(_,_,Dst,"data"). moved_label_class(EA,Op_index,"pe header"), moved_label(EA,Op_index,Dest,ImageBase):- binary_format("PE"), base_address(ImageBase), symbolic_operand(EA,Op_index,Dest,"data"), Dest >= ImageBase, Dest <= ImageBase + 1024. boundary_sym_expr(EA+InstrOffset,Dest):- symbolic_operand(EA,Index,Dest,"data"), instruction_immediate_offset(EA,Index,InstrOffset,_), arch.move_reg_imm(EA,_,as(Dest,number),Index), code(EA), value_reg(_,_,EA,"Unknown",Mult,_,_), Mult < 0, loaded_section(Dest,_,_), loaded_section(_,Dest,_). #line 65 "symbolization.dl" #line 1 "register_type_analysis.dl" #line 24 "register_type_analysis.dl" .decl def_register_is_not_base_address(EA:address,Reg:register) def_register_is_not_base_address(EA_def,Reg):- def_used(EA_def,Reg,EA,_), cmp_immediate_to_reg(EA,Reg,Imm_index,_), !symbolic_operand_candidate(EA,Imm_index,_,_). def_register_is_not_base_address(EA_def,Reg):- def_used(EA_def,Reg,_,_), instruction_get_operation(EA_def,Operation), ( arch.multiplication_operation(Operation) ; arch.shift_rotate_operation(Operation) ). def_register_is_not_base_address(EA_def,Reg):- def_used(EA_def,Reg,EA,_), instruction_get_operation(EA,Operation), arch.multiplication_operation(Operation). #line 66 "symbolization.dl" #line 75 "symbolization.dl" .decl symbolic_operand(EA:address,Index:operand_index,Value:address,Type:symbol) .output symbolic_operand #line 86 "symbolization.dl" .decl symbolic_data(EA:address,Size:unsigned,Value:address) .output symbolic_data #line 96 "symbolization.dl" .decl symbol_minus_symbol(EA:address,Size:unsigned,Symbol1:address,Symbol2:address,Scale:unsigned,Offset:number) .output symbol_minus_symbol #line 107 "symbolization.dl" .decl symbolic_expr_from_relocation(EA:address,Size:unsigned,Symbol:symbol,Offset:number,TargetEA:address) .output symbolic_expr_from_relocation #line 118 "symbolization.dl" .decl symbol_minus_symbol_from_relocation(EA:address,Size:unsigned,Symbol1:symbol,Symbol2:symbol,Scale:unsigned,Offset:number) .output symbol_minus_symbol_from_relocation symbol_minus_symbol_from_relocation(0,0,"","",1,0):- false. #line 136 "symbolization.dl" .decl symbolic_expr(EA:address,Size:unsigned,Symbol:symbol,Offset:number) .output symbolic_expr #line 144 "symbolization.dl" .decl symbolic_expr_symbol_minus_symbol(EA:address,Size:unsigned,Symbol:symbol,Symbol2:symbol,Scale:unsigned,Offset:number) .output symbolic_expr_symbol_minus_symbol #line 151 "symbolization.dl" .decl symbolic_operand_attribute(EA:address,Index:unsigned,Attribute:symbol) .output symbolic_operand_attribute symbolic_operand_attribute(0,0,""):- false. #line 160 "symbolization.dl" .decl symbolic_expr_attribute(ea:address,attribute:symbol) .output symbolic_expr_attribute #line 167 "symbolization.dl" .decl code_pointer_in_data(EA:address,Val:address) #line 173 "symbolization.dl" .decl labeled_ea(Ea:address) .output labeled_ea .decl data_object_boundary(EA:address) .output data_object_boundary .decl bss_data(ea:address) .output bss_data .decl symbolic_operand_candidate(ea:address,operand_index:operand_index,Dest:address,Type:symbol) .output symbolic_operand_candidate .decl symbolic_operand_point(ea:address,operand_index:operand_index,points:number,why:symbol) .output symbolic_operand_point .decl symbolic_operand_total_points(ea:address,operand_index:operand_index,points:number) inline symbolic_operand_candidate(EA,Op_index,Dest_addr,Type):- binary_type("EXEC"), code(EA), instruction_get_op(EA,Op_index,Op), ( op_immediate(Op,Dest), Dest_addr = as(Dest,address), !split_load_operand(EA,Op_index,_) ; pc_relative_operand(EA,Op_index,Dest_addr), Op = Op ; split_load_operand(EA,Op_index,Dest_addr), Op = Op ; op_indirect(Op,_,_,_,_,Dest,_), Dest_addr = as(Dest,address), !pc_relative_operand(EA,Op_index,_), !split_load_operand(EA,Op_index,_) ), ( code(Dest_addr), Type="code" ; data_segment(Begin,End), Dest_addr >= Begin, Dest_addr <= End, Type = "data" ). symbolic_operand_candidate(EA,Op_index,Dest,Type):- !binary_type("EXEC"), code(EA), ( !binary_type("REL"), instruction_immediate_offset(EA,Op_index,ImmediateOffset,_), relocation(EA+ImmediateOffset,_,Symbol,Addend,_,_,_), symbol(SymbolAddr,_,_,_,_,_,_,_,Symbol), Dest = as(as(SymbolAddr,number)+Addend,address) ; !binary_type("REL"), instruction_displacement_offset(EA,Op_index,DisplacementOffset,_), relocation(EA+DisplacementOffset,_,Symbol,Addend,_,_,_), symbol(SymbolAddr,_,_,_,_,_,_,_,Symbol), Dest = as(as(SymbolAddr,number)+Addend,address) ; direct_call(EA,Dest), arch.call(EA,Op_index) ; direct_jump(EA,Dest), !instruction_has_loop_prefix(EA), instruction_get_operation(EA,Operation), arch.jump_operation_op_index(Operation,Op_index) ; pc_relative_operand(EA,Op_index,Dest) ; split_load_operand(EA,Op_index,Dest) ), ( code(Dest), Type = "code" ; data_segment(Begin,End), Dest >= Begin, Dest <= End, Type = "data" ). symbolic_operand_candidate(EA,Index,Dest,Type):- binary_format("PE"), code(EA), ( instruction_immediate_offset(EA,Index,Offset,_), instruction_get_op(EA,Index,Op), op_immediate(Op,Value) ; instruction_displacement_offset(EA,Index,Offset,_), instruction_get_op(EA,Index,Op), op_indirect(Op,_,_,_,1,Value,_) ), relocation(EA+Offset,_,_,_,_,_,_), Dest = as(Value,address), ( code(Dest), Type = "code" ; data_segment(Begin,End), Dest >= Begin, Dest <= End, Type = "data" ). symbolic_operand_point(EA,Index,10,"pie code"):- !binary_type("EXEC"), symbolic_operand_candidate(EA,Index,_,_). symbolic_operand_point(EA,Imm_index,-1,"compared to non-address"):- cmp_immediate_to_reg(EA,Reg,Imm_index,_), def_used(EA_def,Reg,EA,_), def_register_is_not_base_address(EA_def,Reg). symbolic_operand_point(EA,Imm_index,-1,"immediate is bitmask"):- symbolic_operand_candidate(EA,Imm_index,_,_), instruction_get_op(EA,Imm_index,Op), op_immediate(Op,_), instruction_get_operation(EA,Operation), arch.logic_operation(Operation). symbolic_operand_point(EA,Imm_index,-2,"point to exception section"):- symbolic_operand_candidate(EA,Imm_index,Dest,_), exception_section(Name), loaded_section(Base,End,Name), Base <= Dest, Dest < End. symbolic_operand_point(EA,Imm_index,-1,"operated on logical operation result"):- op_immediate_and_reg(EA,_,Reg,Imm_index,_), !arch.jump(EA), def_used(EA_def,Reg,EA,_), instruction_get_operation(EA_def,Operation), arch.logic_operation(Operation), !low_pass_filter(EA_def), !is_xor_reset(EA_def). symbolic_operand_point(EA,1,-1,"result of LEA not base address"):- binary_format("ELF"), symbolic_operand_candidate(EA,1,_,_), instruction(EA,_,_,"LEA",Op1,Op2,0,0,_,_), op_regdirect_contains_reg(Op2,Reg_def), op_indirect(Op1,_,_,_,_,_,_), def_register_is_not_base_address(EA,Reg_def). symbolic_operand_point(EA,Op_index,-1,"moved/compared-with-different-size"):- symbolic_operand_candidate(EA,Op_index,_,_), instruction_get_op(EA,Op_index,Op), op_immediate(Op,_), instruction_get_op(EA,_,Op2), op_indirect(Op2,_,_,_,_,_,Size), arch.pointer_size(Pt_size), Size/8 < Pt_size. symbolic_operand_point(EA,Op_index,1,"used-for-address"):- symbolic_operand_candidate(EA,Op_index,_,_), instruction_get_op(EA,Op_index,Op), op_immediate(Op,_), def_used_for_address(EA,_). symbolic_operand_total_points(EA,Operand,Points):- symbolic_operand_candidate(EA,Operand,_,_), ( Points = sum X:{symbolic_operand_point(EA,Operand,X,_)}; !symbolic_operand_point(EA,Operand,_,_), Points = 0 ). symbolic_operand(EA,Op_index,Value,Type):- symbolic_operand_candidate(EA,Op_index,Value,Type), symbolic_operand_total_points(EA,Op_index,Points), Points >= 0. .decl labeled_data_candidate(EA:address) .output labeled_data_candidate labeled_data_candidate(EA):- !binary_isa("ARM"), symbol(EA,_,_,_,_,_,_,_,_). labeled_data_candidate(EA):- symbolic_operand(_,_,EA,"data"). labeled_data_candidate(Val):- address_in_data_refined(EA,Val), arch.pointer_size(Pt_size), EA % Pt_size = 0. #line 377 "symbolization.dl" .decl symbol_minus_symbol_candidate(EA:address,Size:unsigned,Symbol1:address,Symbol2:address,Scale:unsigned,Offset:number) .output symbol_minus_symbol_candidate symbol_minus_symbol_candidate(EA,Size,Symbol1,Symbol2,as(Scale,unsigned),Offset):- relative_jump_table_entry(EA,_,Size,Reference,Dest,Scale,Offset), ( Scale > 0, Symbol1 = Reference, Symbol2 = Dest; Scale < 0, Symbol1 = Dest, Symbol2 = Reference ), Symbol1 != 0. #line 396 "symbolization.dl" .decl address_in_data_is_printable(EA:address) address_in_data_is_printable(EA):- arch.pointer_size(Pt_size), ascii_string(EAString,End), address_in_data(EA,_), EAString <= EA, EA <= End - Pt_size. .decl address_in_data_refined(EA:address,Val:address) address_in_data_refined(EA,Val):- binary_type("DYN"), address_in_data(EA,Val), relocation(EA,_,_,_,_,_,_), data_segment(Beg,End), Val >= Beg, Val <= End. address_in_data_refined(EA,Val):- binary_type("DYN"), address_in_data(EA,Val), relocation(EA,_,_,_,_,_,_), block(Val). address_in_data_refined(EA,Val):- binary_type("EXEC"), address_in_data(EA,Val), data_segment(Beg,End), Val >= Beg, Val <= End, data_segment(Beg0,End0), arch.pointer_size(PtSize), EA >= Beg0, EA + PtSize <= End0. address_in_data_refined(EA,Val):- binary_type("EXEC"), address_in_data(EA,Val), block(Val), data_segment(Beg0,End0), arch.pointer_size(PtSize), EA >= Beg0, EA + PtSize <= End0. .init address_in_data_refined_range=empty_range address_in_data_refined_range.in_ea(EA):- address_in_data_refined(EA,_). #line 452 "symbolization.dl" .decl string(EA:address,End:address,Encoding:symbol) .output string .decl string_candidate(EA:address,End:address,Encoding:symbol) .output string_candidate .decl string_candidate_refined(EA:address,End:address,Encoding:symbol) .output string_candidate_refined string_candidate(EA,End,"ascii"):- ascii_string(Beg,End), ( labeled_data_candidate(EA); preferred_data_access(_,_,EA) ), EA >= Beg, EA < End, data_segment(DataBeg,DataEnd), EA >= DataBeg, End <= DataEnd. string_candidate(EA,End,"ascii"):- string_candidate(_,EA,"ascii"), ascii_string(EA,End). #line 491 "symbolization.dl" string_candidate_refined(EA,End,"string"):- string_candidate(_,End,"ascii"), data_byte(End-1,0), EA = max EA : { string_candidate(EA,End,"ascii") }. string_candidate_refined(EA,End,"ascii"):- string_candidate_refined(Tail,TailEnd,"string"), string_candidate(EA,TailEnd,"ascii"), EA < Tail, End = min Next : { string_candidate(Next,TailEnd,"ascii"), Next > EA }. string(EA,End,Encoding):- data_object(EA,Size,"string"), string_candidate_refined(EA,End,Encoding), Size = End-EA. .decl data_object_candidate(ea:address,size:unsigned,type:symbol) .output data_object_candidate .decl data_object_point(ea:address,size:unsigned,type:symbol,points:number,why:symbol) .output data_object_point .decl data_object_conflict(ea:address,size:unsigned,type:symbol,ea2:address,size2:unsigned,type2:symbol) .output data_object_conflict .decl discarded_data_object(ea:address,size:unsigned,type:symbol) .decl data_object(ea:address,size:unsigned,type:symbol) data_object_candidate(EA,Size,"symbol-symbol"):- symbol_minus_symbol_candidate(EA,Size,_,_,_,_). data_object_candidate(EA,Pt_size,"symbol"):- arch.pointer_size(Pt_size), address_in_data_refined(EA,_). data_object_candidate(EA,Size,"string"):- string_candidate_refined(EA,End,_), Size = End-EA. data_object_candidate(EA,Size,"other"):- preferred_data_access(EA,Size,_), !address_in_data_refined(EA,_), !symbol_minus_symbol_candidate(EA,Size,_,_,_,_). .decl after_address_in_data(EA:address,EA_next:address) after_address_in_data(EA,EA+Pt_size):- address_in_data_refined(EA,_), arch.pointer_size(Pt_size), data_byte(EA+Pt_size,_), !labeled_data_candidate(EA+Pt_size). after_address_in_data(EA,EA_aux+1):- after_address_in_data(EA,EA_aux), !address_in_data_refined(EA_aux,_), data_byte(EA_aux+1,_), !labeled_data_candidate(EA_aux+1). .decl next_address_in_data(EA:address,EA_next:address) next_address_in_data(EA,EA_next):- address_in_data_refined(EA,_), after_address_in_data(EA,EA_next), address_in_data_refined(EA_next,_). #line 565 "symbolization.dl" .decl address_array_aux(EA:address,Distance:unsigned,type:symbol,InitialEA:address) address_array_aux(EA,Diff,"code",EA):- address_in_data_refined(EA,Dest1),code(Dest1), ( binary_format("PE"); arch.pointer_size(Pt_size), EA % Pt_size = 0 ), next_address_in_data(EA,EA_next), Diff = EA_next-EA, ( !next_address_in_data(EA-Diff,EA) ; next_address_in_data(EA-Diff,EA), address_in_data_refined(EA-Diff,Dest_prev), !code(Dest_prev) ), address_in_data_refined(EA+Diff,Dest2),code(Dest2), next_address_in_data(EA+Diff,EA+(2*Diff)), address_in_data_refined(EA+(2*Diff),Dest3),code(Dest3). address_array_aux(EA,Diff,"data",EA):- address_in_data_refined(EA,Dest1),data_byte(Dest1,_), arch.pointer_size(Pt_size), EA % Pt_size = 0, next_address_in_data(EA,EA_next), Diff = EA_next-EA, data_segment(Begin,End), Begin <= Dest1, Dest1 <= End, ( !next_address_in_data(EA-Diff,EA) ; next_address_in_data(EA-Diff,EA), address_in_data_refined(EA-Diff,Dest_prev), (Dest_prev < Begin ; Dest_prev > End) ), address_in_data_refined(EA+Diff,Dest2),data_byte(Dest2,_), next_address_in_data(EA+Diff,EA+(2*Diff)), address_in_data_refined(EA+(2*Diff),Dest3),data_byte(Dest3,_), Begin <= Dest2, Dest2 <= End, Begin <= Dest3, Dest3 <= End. address_array_aux(EA+Diff,Diff,"code",InitialEA):- address_array_aux(EA,Diff,"code",InitialEA), next_address_in_data(EA,EA+Diff), address_in_data_refined(EA+Diff,Dest),code(Dest). address_array_aux(EA+Diff,Diff,"data",InitialEA):- address_array_aux(EA,Diff,"data",InitialEA), address_in_data_refined(EA,Dest1), next_address_in_data(EA,EA+Diff), address_in_data_refined(EA+Diff,Dest2),data_byte(Dest2,_), data_segment(Begin,End), Begin <= Dest1, Dest1 <= End, Begin <= Dest2, Dest2 <= End. #line 643 "symbolization.dl" .decl address_array(EA:address,Distance:unsigned,InitialEA:address) address_array(EA,Distance,InitialEA):- address_array_aux(EA,Distance,_,InitialEA). .init address_array_range=empty_range address_array_range.in_ea(EA):- address_array(EA,_,_). data_object_point(EA,Pt_size,Type,-2,"data object bias"):- data_object_candidate(EA,Pt_size,Type). data_object_point(EA,Size,Type,-100,"in-exception-section"):- data_object_candidate(EA,Size,Type), exception_section(Name), loaded_section(Base,End,Name), EA >= Base, EA < End. data_object_point(EA,8,"symbol-symbol",5,"quad symbol-symbol"):- data_object_candidate(EA,8,"symbol-symbol"). data_object_point(EA,Size,"symbol-symbol",4,"symbol-symbol"):- data_object_candidate(EA,Size,"symbol-symbol"), Size <= 4. data_object_point(EA,Pt_size,"symbol",3,"pointer array"):- data_object_candidate(EA,Pt_size,"symbol"), address_array(EA,_,_). data_object_point(EA,Size,Type,2,"pointed by pointer array"), data_object_point(EA2,Size2,Type,2,"pointed by pointer array"), data_object_point(EA3,Size3,Type,2,"pointed by pointer array"), data_object_point(EA4,Size4,Type,2,"pointed by pointer array"):- address_array(EA_array,Distance,InitialEA), address_in_data(EA_array,EA), data_object_candidate(EA,Size,Type), address_array(EA_array+Distance,Distance,InitialEA), address_in_data(EA_array+Distance,EA2), data_object_candidate(EA2,Size2,Type), address_array(EA_array+2*Distance,Distance,InitialEA), address_in_data(EA_array+2*Distance,EA3), data_object_candidate(EA3,Size3,Type), address_array(EA_array+3*Distance,Distance,InitialEA), address_in_data(EA_array+3*Distance,EA4), data_object_candidate(EA4,Size4,Type). data_object_point(EA,Pt_size,"symbol",5,"data access"):- data_object_candidate(EA,Pt_size,"symbol"), ( preferred_data_access(EA,Pt_size,_); preferred_data_access(EA,0,_) ). data_object_point(EA,Pt_size,"symbol",-2,"multiple conflict"):- data_object_candidate(EA,Pt_size,"symbol"), data_object_conflict(EA,Pt_size,"symbol",EA2,_,"other"), data_object_conflict(EA,Pt_size,"symbol",EA3,_,"other"), EA2 != EA3. .decl label_conflict(EA:address,Size:unsigned,Kind:symbol) label_conflict(EA,Pt_size,"symbol"):- data_object_candidate(EA,Pt_size,"symbol"), labeled_data_candidate(EA2), EA2 > EA, EA2 < EA+Pt_size. data_object_point(EA,Pt_size,"symbol",1,"no label conflicts"):- data_object_candidate(EA,Pt_size,"symbol"), !label_conflict(EA,Pt_size,"symbol"). data_object_point(EA,Pt_size,"symbol",2,"aligned"):- data_object_candidate(EA,Pt_size,"symbol"), EA % Pt_size = 0. data_object_point(EA,Pt_size,"symbol",-2,"point-to-exception-section"):- data_object_candidate(EA,Pt_size,"symbol"), address_in_data_refined(EA,Dest), exception_section(Name), loaded_section(Base,End,Name), Dest >= Base, Dest < End. data_object_point(EA,Pt_size,"symbol",-1,"point-to-special-section"):- data_object_candidate(EA,Pt_size,"symbol"), address_in_data_refined(EA,Dest), special_data_section(Name), loaded_section(Base,End,Name), Dest >= Base, Dest < End. data_object_point(EA,Pt_size,"symbol",10,"has relocation"):- data_object_candidate(EA,Pt_size,"symbol"), relocation(EA,Type,_,_,_,_,_), Type != "ABSOLUTE". data_object_point(EA,Pt_size,"symbol",-10,"has no relocation"):- !binary_type("EXEC"), data_object_candidate(EA,Pt_size,"symbol"), !relocation(EA,_,_,_,_,_,_). data_object_point(EA,Size,"string",2,"string basic point"):- data_object_candidate(EA,Size,"string"). data_object_point(EA,Size,"string",3,"long string"):- data_object_candidate(EA,Size,"string"), string_candidate(EA,End,_), string_candidate(Beg,End,_), End-Beg > 5. data_object_point(EA,Size,"string",-2,"string in jump table"):- data_object_candidate(EA,Size,"string"), preferred_data_access(EA,_,EA_ref), jump_table_start(_,_,EA_ref,_,_). data_object_point(EA,Size,"other",4,"data access"):- data_object_candidate(EA,Size,"other"), Size < 16. data_object_point(EA,Size,"other",1,"data access xmm"):- data_object_candidate(EA,Size,"other"), Size >= 16. data_object_conflict(EA,Size,Type,EA2,Size2,Type2):- data_object_candidate(EA,Size,Type), data_object_candidate(EA2,Size2,Type2), EA2 > EA, EA2 < EA+Size. data_object_conflict(EA,Size,Type,EA,Size2,Type2):- data_object_candidate(EA,Size,Type), data_object_candidate(EA,Size2,Type2), Size2 > Size. data_object_conflict(EA,Size,Type,EA,Size,Type2):- data_object_candidate(EA,Size,Type), data_object_candidate(EA,Size,Type2), Type != Type2. data_object_conflict(EA,Size,Type,EA2,Size2,Type2):- binary_format("PE"), binary_isa("X86"), data_object_candidate(EA,Size,Type), address_in_data_refined(EA,Val), data_object_candidate(EA2,Size2,Type2), Val > EA2, Val < EA2+Size2. .decl data_object_total_points(EA:address,Size:unsigned,Type:symbol,Points:number) .output data_object_total_points data_object_total_points(EA,Size,Type,Points):- data_object_candidate(EA,Size,Type), Points = sum X:{data_object_point(EA,Size,Type,X,_)}. data_object(EA,Size,Type):- data_object_total_points(EA,Size,Type,Points), !discarded_data_object(EA,Size,Type), Points >= 0. discarded_data_object(EA_f,Size_f,Type_f):- data_object_conflict(EA,Size,Type,EA2,Size2,Type2), data_object_total_points(EA,Size,Type,Points1), data_object_total_points(EA2,Size2,Type2,Points2), ( Points1 < Points2, EA_f = EA, Size_f = Size, Type_f = Type ; Points1 > Points2, EA_f = EA2, Size_f = Size2, Type_f = Type2 ). symbolic_data(EA,Size,as(Val,address)):- data_object(EA,Size,"symbol"), address_in_data_refined(EA,Val). symbol_minus_symbol(EA,Size,Symbol1,Symbol2,Scale,Offset):- data_object(EA,Size,"symbol-symbol"), symbol_minus_symbol_candidate(EA,Size,Symbol1,Symbol2,Scale,Offset). code_pointer_in_data(EA,Val):- symbolic_data(EA,_,Val), block(Val). labeled_ea(EA):- !binary_isa("ARM"), defined_symbol(EA,_,Type,_,_,_,_,_,_), Type != "SECTION", EA != 0. labeled_ea(EA):- symbolic_operand(Src,_,EA,_), !moved_label(Src,_,EA,_). labeled_ea(EA):- symbolic_data(Src,_,EA), !moved_data_label(Src,_,EA,_). labeled_ea(EA_moved):- moved_label(_,_,_,EA_moved). labeled_ea(New_dest):- moved_data_label(_,_,_,New_dest). labeled_ea(EA):- symbol_minus_symbol(Src,_,EA,_,_,_), !moved_data_label(Src,_,EA,_). labeled_ea(EA):- symbol_minus_symbol(Src,_,_,EA,_,_), !moved_data_label(Src,_,EA,_). labeled_ea(EA):- fde_entry(_,_,_,_,_,EA). labeled_ea(TargetEA):- symbolic_expr_from_relocation(_,_,"",_,TargetEA). data_object_boundary(EA):- labeled_ea(EA); symbolic_data(EA,_,_); string(EA,_,_); symbol_minus_symbol(EA,_,_,_,_,_); symbolic_expr_from_relocation(EA,_,_,_,_); moved_data_label(EA,_,_,_). bss_data(Base), bss_data(End):- bss_section(SectionName), loaded_section(Base,End,SectionName). bss_data(EA):- labeled_ea(EA), bss_section(SectionName), loaded_section(Base,End,SectionName), EA >= Base, EA < End. symbolic_expr(EA,Size,Symbol,Offset):- symbolic_expr_from_relocation(EA,Size,Symbol,Offset,_), Symbol != "". symbolic_expr(EA,Size,Symbol,Offset):- symbolic_expr_from_relocation(EA,Size,"",Offset,TargetEA), best_symexpr_symbol(TargetEA,Symbol,_). symbolic_expr_symbol_minus_symbol(EA,Size,SymbolName1,SymbolName2,Scale,Offset):- symbol_minus_symbol_from_relocation(EA,Size,SymbolName1,SymbolName2,Scale,Offset). symbolic_expr_symbol_minus_symbol(EA,Size,SymbolName1,SymbolName2,Scale,FinalOffset):- symbol_minus_symbol(EA,Size,Symbol1,Symbol2,Scale,Offset), !symbolic_expr_from_relocation(EA,_,_,_,_), !symbol_minus_symbol_from_relocation(EA,_,_,_,_,_), ( moved_data_label(EA,Size,Symbol1,NewSymbol1), Offset1 = Offset + as(NewSymbol1,number)- as(Symbol1,number) ; !moved_data_label(EA,_,Symbol1,_), NewSymbol1 = Symbol1, Offset1 = Offset ), ( moved_data_label(EA,Size,Symbol2,NewSymbol2), FinalOffset = Offset1 + as(Symbol2,number) - as(NewSymbol2,number) ; !moved_data_label(EA,_,Symbol2,_), NewSymbol2 = Symbol2, FinalOffset = Offset1 ), best_symexpr_symbol(NewSymbol1,SymbolName1,"Beg"), ( boundary_sym_expr(EA,NewSymbol2), Symbol2Loc = "End" ; !boundary_sym_expr(EA,NewSymbol2), Symbol2Loc = "Beg" ), best_symexpr_symbol(NewSymbol2,SymbolName2,Symbol2Loc). symbolic_expr(EA+InstrOffset,Size,SymbolName,Offset):- moved_label(EA,Index,Dest,FinalDest), ( instruction_immediate_offset(EA,Index,InstrOffset,Size); instruction_displacement_offset(EA,Index,InstrOffset,Size) ), !symbolic_expr_from_relocation(EA+InstrOffset,_,_,_,_), !symbol_minus_symbol_from_relocation(EA+InstrOffset,_,_,_,_,_), !symbol_minus_symbol(EA+InstrOffset,_,_,_,_,_), Offset = as(Dest,number) - as(FinalDest,number), best_symexpr_symbol(FinalDest,SymbolName,"Beg"). symbolic_expr(EA+InstrOffset,Size,SymbolName,0):- symbolic_operand(EA,Index,Dest,_), !moved_label(EA,Index,_,_), ( instruction_immediate_offset(EA,Index,InstrOffset,Size); instruction_displacement_offset(EA,Index,InstrOffset,Size) ), !symbolic_expr_from_relocation(EA+InstrOffset,_,_,_,_), !symbol_minus_symbol_from_relocation(EA+InstrOffset,_,_,_,_,_), !symbol_minus_symbol(EA+InstrOffset,_,_,_,_,_), ( boundary_sym_expr(EA+InstrOffset,Dest), SymbolLoc = "End" ; !boundary_sym_expr(EA+InstrOffset,Dest), SymbolLoc = "Beg" ), best_symexpr_symbol(Dest,SymbolName,SymbolLoc). symbolic_expr(EA,Size,SymbolName,Offset):- moved_data_label(EA,Size,Dest,FinalDest), !symbolic_expr_from_relocation(EA,_,_,_,_), !symbol_minus_symbol_from_relocation(EA,_,_,_,_,_), !symbol_minus_symbol(EA,_,_,_,_,_), Offset = as(Dest,number) - as(FinalDest,number), best_symexpr_symbol(FinalDest,SymbolName,"Beg"). symbolic_expr(EA,Size,SymbolName,0):- symbolic_data(EA,Size,Dest), !symbolic_expr_from_relocation(EA,_,_,_,_), !symbol_minus_symbol_from_relocation(EA,_,_,_,_,_), !symbol_minus_symbol(EA,_,_,_,_,_), !moved_data_label(EA,_,_,_), ( boundary_sym_expr(EA,Dest), SymbolLoc = "End" ; !boundary_sym_expr(EA,Dest), SymbolLoc = "Beg" ), best_symexpr_symbol(Dest,SymbolName,SymbolLoc). symbolic_expr_attribute(EA+InstrOffset,Attr):- symbolic_operand_attribute(EA,Index,Attr), ( instruction_immediate_offset(EA,Index,InstrOffset,_); instruction_displacement_offset(EA,Index,InstrOffset,_) ). #line 103 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 105 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "basic_function_inference.dl" #line 27 "basic_function_inference.dl" .comp basic_function_inference{ .decl function_entry(Block:address) .output function_entry .decl function_entry_name(Block:address,Name:symbol) .output function_entry_name .decl in_function(Block:address,Function:address) .output in_function .decl function_without_callframe(Block:address) .output function_without_callframe #line 44 "basic_function_inference.dl" .decl function_entry_initial(EA:address) function_entry_initial(EA):- fde_addresses(EA,_), block(EA). function_entry_initial(EA):- block(EA), ( entry_point(EA); function_symbol(EA,_); start_function(EA); loaded_section(EA,_,_); direct_call(EA_caller,EA), code(EA_caller), !pc_load_call(EA_caller,EA) ). function_entry_name(EA,SymbolName):- function_entry(EA), best_func_symbol(EA,SymbolName). function_entry(EA):- function_entry_initial(EA), refined_block(EA). function_entry(EA):- direct_call_resolved(EA_caller,EA), code(EA_caller), refined_block(EA). function_entry(EA):- main_function(EA), refined_block(EA), !fde_addresses(EA,_). function_entry(EA):- code_pointer_in_data(Src,EA), function_pointer_section(Name), loaded_section(Base,End,Name), Src >= Base, Src < End. function_without_callframe(EA):- function_entry(EA), !fde_addresses(EA,_). .decl in_function_initial(Block:address,Function:address) in_function_initial(Block,Block):- function_entry(Block). in_function_initial(Block,Begin):- function_entry(Begin), fde_addresses(Begin,End), refined_block(Block), Begin <= Block, Block < End. .decl not_in_function_initial(Block:address) not_in_function_initial(Block):- refined_block(Block), !in_function_initial(Block,_). in_function(Block,Function):- in_function_initial(Block,Function). in_function(Function,Function):- function_without_callframe(Function). in_function(Block,Function):- in_function(Block_prev,Function), function_without_callframe(Function), next_refined_block_in_section(Block_prev,Block), not_in_function_initial(Block), !function_without_callframe(Block). } #line 106 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 108 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "debug_stats.dl" #line 25 "debug_stats.dl" .decl discarded_aligned_pointer(ea:address) .output discarded_aligned_pointer .decl discarded_aligned_pointer_to_text(ea:address) .output discarded_aligned_pointer_to_text .decl unaligned_pointer(ea:address) .output unaligned_pointer discarded_aligned_pointer_to_text(EA):- aligned_address_in_data(EA,_), !address_in_data_refined(EA,_). discarded_aligned_pointer(EA):- discarded_data_object(EA,Pt_size,"symbol"), EA % Pt_size = 0. unaligned_pointer(EA):- data_object(EA,Pt_size,"symbol"), EA % Pt_size != 0. .decl immediate_symbol(ea:address,op_index:operand_index,dest:address) .output immediate_symbol immediate_symbol(EA,Op_index,DestAddr):- code(EA), may_have_symbolic_immediate(EA,DestAddr), instruction_get_op(EA,Op_index,Op), !direct_jump(EA,_), !direct_call(EA,_), op_immediate(Op,Dest), DestAddr = as(Dest,address). .decl missed_jump_table(EA_jump:address) .output missed_jump_table missed_jump_table(EA):- reg_jump(EA,_), code(EA), def_used(EA_base,Reg,EA,_), arch.reg_reg_arithmetic_operation(EA_base,Reg,Reg,_,_,0), !jump_table_start(EA,_,_,_,_). missed_jump_table(EA):- reg_call(EA,_), code(EA), def_used(EA_base,Reg,EA,_), arch.reg_reg_arithmetic_operation(EA_base,Reg,Reg,_,_,0), !jump_table_start(EA,_,_,_,_). #line 82 "debug_stats.dl" .decl used_relocation(EA:address) .output used_relocation used_relocation(EA):- binary_format("PE"), pe_relocation_size(Type,Size), Size > 0, relocation(EA,Type,_,_,_,_,_), data_object(EA,Size,"symbol"). used_relocation(EA+Offset):- binary_format("PE"), symbolic_operand(EA,_,_,_), ( instruction(EA,_,_,_,_,_,_,_,Offset,_); instruction(EA,_,_,_,_,_,_,_,_,Offset) ), relocation(EA+Offset,_,_,_,_,_,_). used_relocation(EA):- binary_format("PE"), symbolic_expr_from_relocation(EA,_,_,_,_), relocation(EA,_,_,_,_,_,_). #line 108 "debug_stats.dl" .decl discarded_relocation(EA:address) .output discarded_relocation discarded_relocation(EA):- binary_format("PE"), relocation(EA,Type,_,_,_,_,_), !used_relocation(EA), Type != "ABSOLUTE". #line 109 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" #line 1 "self_diagnose.dl" .decl false_negative(EA:address) .decl false_positive(EA:address) .output false_negative .output false_positive .decl relocation_in_operand(EA:address,Index:operand_index,Rel:address,InsnOffset:unsigned) relocation_in_operand(EA,Index,Location,Offset):- code(EA), instruction_immediate_offset(EA,Index,Offset,_), relocation(Location,_,_,_,_,_,_), Location = EA+Offset. relocation_in_operand(EA,Index,Location,Offset):- code(EA), instruction_displacement_offset(EA,Index,Offset,_), relocation(Location,_,_,_,_,_,_), Location = EA+Offset. .decl trivial_relocation(EA:address) trivial_relocation(EA):- relocation(EA,_,Symbol,0,_,_,_), symbol(0,_,_,_,_,0,_,_,Symbol), Symbol != "". trivial_relocation(EA):- relocation(EA,_,"__TMC_END__",7,_,_,_). .decl bad_symbol_constant(EA:address,cnt:number) .output bad_symbol_constant bad_symbol_constant(EA,Cnt):- relocation_in_operand(EA,Index,Rel,InsnOffset), relocation(Rel,_,_,Cnt,_,_,_), ( pc_relative_operand(EA,Index,_), instruction(EA,InsnSize,_,_,_,_,_,_,_,_), Cnt2 = Cnt+ as(InsnSize-InsnOffset,number) ; !pc_relative_operand(EA,Index,_), Cnt2 = Cnt, InsnOffset = InsnOffset ), symbolic_operand(EA,Index,Dest,_), !moved_label(EA,Index,_,_), loaded_section(Base,End,Name), Dest >= Base, Dest < End, loaded_section(Base2,End2,Name2), Name2 != Name, Dest_minus_cnt2 = as(as(Dest,number)-Cnt2,unsigned), Dest_minus_cnt2 >= Base2, Dest_minus_cnt2 < End2, Dest_minus_cnt2 != End. bad_symbol_constant(EA,Cnt):- relocation_in_operand(EA,Index,Rel,InsnOffset), relocation(Rel,_,_,Cnt,_,_,_), ( pc_relative_operand(EA,Index,_), instruction(EA,InsnSize,_,_,_,_,_,_,_,_), Cnt2 = Cnt+ as(InsnSize-InsnOffset,number) ; !pc_relative_operand(EA,Index,_), Cnt2 = Cnt, InsnOffset = InsnOffset ), moved_label(EA,Index,Orig,Dest), loaded_section(Base,End,Name), Dest >= Base, Dest < End, loaded_section(Base2,End2,Name2), Name2 != Name, Orig_minus_cnt2 = as(as(Orig,number)-Cnt2,unsigned), Orig_minus_cnt2 >= Base2, Orig_minus_cnt2 < End2, Orig_minus_cnt2 != End. false_negative(Location):- relocation_in_operand(EA,Index,Rel,_), !trivial_relocation(Rel), !symbolic_operand(EA,Index,_,_), !moved_label(EA,Index,_,_), ( instruction_immediate_offset(EA,Index,Offset,_); instruction_displacement_offset(EA,Index,Offset,_) ), Location = EA+Offset. false_positive(Location):- code(EA), ( symbolic_operand(EA,Index,_,_); moved_label(EA,Index,_,_) ), !pc_relative_operand(EA,Index,_), !direct_jump(EA,_), !direct_call(EA,_), !relocation_in_operand(EA,Index,_,_), ( instruction_immediate_offset(EA,Index,Offset,_); instruction_displacement_offset(EA,Index,Offset,_) ), Location=EA+Offset. .decl zero_relocation(EA:address) zero_relocation(EA):- relocation(EA,_,_,_,_,_,_), data_word(EA,8,0). false_negative(EA):- data_byte(EA,_), relocation(EA,_,_,_,_,_,_), !zero_relocation(EA), !symbolic_data(EA,_,_), !symbol_minus_symbol(EA,_,_,_,_,_), regular_data_section(Sect), loaded_section(BegSect,EndSect,Sect), EA >= BegSect, EA < EndSect. false_positive(EA):- ( symbolic_data(EA,_,_); symbol_minus_symbol(EA,Size,_,_,_,_), Size>4 ), !relocation(EA,_,_,_,_,_,_), regular_data_section(Sect), loaded_section(BegSect,EndSect,Sect), EA >= BegSect, EA < EndSect. #line 110 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl entry_point(ea:address) .input entry_point .decl endianness(End:symbol) .input endianness .decl base_address(ea:address) .input base_address .decl symbol(ea:address,size:unsigned,type:symbol,scope:symbol,visibility:symbol,sectionIndex:unsigned,originTable:symbol,tableIndex:unsigned,name:symbol) .input symbol .decl section(Name:symbol,Size:unsigned,EA:address,Align:unsigned,Index:unsigned) .input section .decl section_property(Name:symbol,Property:symbol) .input section_property .decl section_type(Name:symbol,Type:unsigned) .input section_type .decl relocation(EA:address,Type:symbol,Name:symbol,Addend:number,SymbolIndex:unsigned,Section:symbol,RelType:symbol) .input relocation .decl relocation_size(Type:symbol,Size:unsigned) #line 144 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl relocation_adjustment(EA:address,Adjustment:number,Reason:symbol) .output relocation_adjustment #line 149 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl relocation_adjustment_total(EA:address,Adjustment:number) .output relocation_adjustment_total relocation_adjustment_total(EA,0):- relocation(EA,_,_,_,_,_,_), !relocation_adjustment(EA,_,_). relocation_adjustment_total(EA,Adjustment):- relocation(EA,_,_,_,_,_,_), Adjustment = sum N:{relocation_adjustment(EA,N,_)}. .decl binary_type(Type:symbol) .input binary_type .decl binary_format(Format:symbol) .input binary_format .decl binary_isa(isa:symbol) .input binary_isa .decl option(Option:symbol) .input option .decl dynamic_entry(tag:symbol, value:unsigned) .input dynamic_entry .decl instruction(ea:address,size:unsigned,prefix:symbol,opcode:symbol, op1:operand_code,op2:operand_code,op3:operand_code,op4:operand_code, immOffset:unsigned,displacementOffset:unsigned) .input instruction #line 185 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_writeback(EA:address) .input instruction_writeback #line 191 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_cond_code(EA:address,CondCode:symbol) .input instruction_cond_code .type access_mode <: symbol #line 201 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl register_access(EA:address,Register:input_reg,AccessMode:access_mode) .input register_access #line 207 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_op_access(EA:address,Index:operand_index,AccessMode:access_mode) .input instruction_op_access #line 213 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl op_register_bitfield(code:operand_code,Index:unsigned,register_name:input_reg) .input op_register_bitfield .decl invalid_op_code(ea:address) .input invalid_op_code .decl op_regdirect(code:operand_code,register_name:input_reg) .input op_regdirect .decl op_fp_immediate(code:operand_code,imm:float) .input op_fp_immediate .decl op_immediate(code:operand_code,offset:number) .input op_immediate .decl op_special(code:operand_code,type:symbol,value:symbol) .input op_special .output op_special .decl op_indirect(code:operand_code,reg1:input_reg,reg2:input_reg,reg3:input_reg, multiplier:number,offset:number,size_value:unsigned) .input op_indirect #line 242 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl op_shifted(EA:address,Index:unsigned,Shift:unsigned,Type:symbol) .input op_shifted #line 250 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl op_shifted_w_reg(EA:address,Index:unsigned,Reg:input_reg,Type:symbol) .input op_shifted_w_reg #line 256 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl address_in_data(EA:address,Value:address) .input address_in_data .decl data_region(Begin:address,Size:unsigned) .input data_region #line 266 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl ascii_string(EA:address,End:address) .input ascii_string .init function_inference = basic_function_inference #line 283 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl reg_map_nullable(RegIn:input_reg,Reg:reg_nullable) reg_map_nullable(RegIn,Reg):- arch.reg_map_rule(RegIn,Reg). reg_map_nullable(Reg,as(Reg,reg_nullable)):- ( op_regdirect(_,Reg); op_register_bitfield(_,_,Reg); op_indirect(_,_,Reg,_,_,_,_); op_indirect(_,_,_,Reg,_,_,_); register_access(_,Reg,_); op_shifted_w_reg(_,_,Reg,_) ), !arch.reg_map_rule(Reg,_). .decl reg_nonnull(RegNullable:reg_nullable,Reg:register) inline reg_nonnull(RegNullable,Reg):- RegNullable != "NONE", Reg = as(RegNullable,register). .decl reg_map(RegIn:input_reg,Reg:register) reg_map(RegIn,Reg):- reg_map_nullable(RegIn,RegNullable), reg_nonnull(RegNullable,Reg). #line 322 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_immediate_offset(EA:address,Index:operand_index,Offset:unsigned,Size:unsigned) .output instruction_immediate_offset instruction_immediate_offset(EA,Index,ImmediateOffset,Size-ImmediateOffset):- instruction(EA,Size,_,_,_,_,_,_,ImmediateOffset,_), instruction_get_op(EA,Index,Op), op_immediate(Op,_). #line 337 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_displacement_offset(EA:address,Index:operand_index,Offset:unsigned,Size:unsigned) .output instruction_displacement_offset instruction_displacement_offset(EA,Index,DisplacementOffset,DispSize):- instruction(EA,Size,_,_,_,_,_,_,ImmediateOffset,DisplacementOffset), instruction_get_op(EA,Index,Op), op_indirect(Op,_,_,_,_,_,_), ( ImmediateOffset > DisplacementOffset, DispSize = ImmediateOffset - DisplacementOffset, Size = Size ; ImmediateOffset <= DisplacementOffset, DispSize = Size - DisplacementOffset ). .decl instruction_get_operation(ea:address,operation:symbol) inline instruction_get_operation(EA,Operation):- instruction(EA,_,_,Operation,_,_,_,_,_,_). .decl instruction_get_op(ea:address, index:operand_index, operator:operand_code) instruction_get_op(EA,Index,Op):- instruction(EA,_,_,_,Op1,Op2,Op3,Op4,_,_), ( Op1 != 0, Op = Op1, Index = 1, Op2 = Op2, Op3 = Op3, Op4 = Op4 ; Op2 != 0, Op = Op2, Index = 2, Op1 = Op1, Op3 = Op3, Op4 = Op4 ; Op3 != 0, Op = Op3, Index = 3, Op1 = Op1, Op2 = Op2, Op4 = Op4 ; Op4 != 0, Op = Op4, Index = 4, Op1 = Op1, Op2 = Op2, Op3 = Op3 ). #line 387 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_get_src_op(EA:address,Index:operand_index,Op:operand_code) instruction_get_src_op(EA,Index,Op):- instruction_op_access(EA,Index,"R"), !arch.op_access_override(EA,Index,"R",0), instruction_get_op(EA,Index,Op). instruction_get_src_op(EA,Index,Op):- arch.op_access_override(EA,Index,"R",1), instruction_get_op(EA,Index,Op). #line 401 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_get_dest_op(EA:address,Index:operand_index,Op:operand_code) instruction_get_dest_op(EA,Index,Op):- instruction_op_access(EA,Index,"W"), !arch.op_access_override(EA,Index,"W",0), instruction_get_op(EA,Index,Op). instruction_get_dest_op(EA,Index,Op):- arch.op_access_override(EA,Index,"W",1), instruction_get_op(EA,Index,Op). .decl next(n:address,m:address) next(EA,EA+Size):- instruction(EA,Size,_,_,_,_,_,_,_,_). .decl pc_relative_operand(src:address,index:operand_index, dest:address) .output pc_relative_operand pc_relative_operand(EA,Index,Dest):- binary_isa("X64"), instruction_get_op(EA,Index,Op), op_indirect_mapped(Op,"NONE",Reg,"NONE",1,Offset,_), arch.pc_reg(Reg), next(EA,EANext), Dest = as(as(EANext,number)+Offset,address), !instruction_has_relocation(EA,_). pc_relative_operand(EA,Index,Dest):- binary_isa("X64"), instruction_displacement_offset(EA,Index,Offset,_), relocation(EA+Offset,"PC32",_,Addend,SymbolIndex,_,_), symbol(Base,_,"SECTION",_,_,_,_,SymbolIndex,_), instruction(EA,Size,_,_,_,_,_,_,_,_), Dest = Base + as(as(Size-Offset,number)+Addend,unsigned). .decl split_load_operand(src:address,index:operand_index, dest:address) .output split_load_operand split_load_operand(0,0,0):- false. .decl instruction_has_loop_prefix(EA:address) instruction_has_loop_prefix(EA):- instruction(EA,_,Prefix,_,_,_,_,_,_,_), arch.loop_prefix(Prefix). #line 455 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl instruction_has_relocation(EA:address,Rel:address) .output instruction_has_relocation instruction_has_relocation(EA,EA+Offset):- ( binary_isa("X86"); binary_isa("X64") ), ( instruction_immediate_offset(EA,_,Offset,_); instruction_displacement_offset(EA,_,Offset,_) ), relocation(EA+Offset,_,_,_,_,_,_). .decl unconditional_jump(n:address) unconditional_jump(EA):- arch.jump(EA), !arch.conditional(EA,_). .decl conditional_jump(src:address) conditional_jump(EA):- arch.jump(EA), arch.conditional(EA,_). .decl direct_jump(src:address, dest:address) .output direct_jump direct_jump(EA,as(Dest,address)):- arch.jump(EA), instruction_get_operation(EA,Operation), arch.jump_operation_op_index(Operation,Index), instruction_get_op(EA,Index,Op), op_immediate(Op,Dest), !instruction_has_relocation(EA,_). direct_jump(EA,as(Dest,address)):- arch.jump(EA), instruction_immediate_offset(EA,_,_,_), instruction_has_relocation(EA,Rel), relocation(Rel,_,_,_,SymbolIndex,_,_), defined_symbol(Dest,_,_,_,_,_,_,SymbolIndex,_). direct_jump(EA,EA):- instruction_has_loop_prefix(EA). .decl impossible_jump_target(EA:address) impossible_jump_target(0):- false. .decl pc_relative_jump(src:address, dest:address) .output pc_relative_jump pc_relative_jump(EA,Dest):- arch.jump(EA), pc_relative_operand(EA,1,Dest). .decl reg_jump(src:address,Reg:register) reg_jump(EA,Reg):- arch.jump(EA), instruction_get_operation(EA,Operation), arch.jump_operation_op_index(Operation,TargetOpIndex), instruction_get_op(EA,TargetOpIndex,TargetOp), op_regdirect_contains_reg(TargetOp,Reg), !arch.pc_reg(Reg). .decl indirect_jump(src:address) indirect_jump(EA):- arch.jump(EA), instruction_get_operation(EA,Operation), arch.jump_operation_op_index(Operation,TargetOpIndex), instruction_get_op(EA,TargetOpIndex,TargetOp), op_indirect(TargetOp,_,_,_, _,_,_), !pc_relative_jump(EA,_). .decl direct_call(EA:address,Dest:address) .output direct_call direct_call(EA,as(Dest,address)):- !binary_isa("ARM"), arch.call(EA,Index), instruction_get_op(EA,Index,Op), op_immediate(Op,Dest), !instruction_has_relocation(EA,_). direct_call(EA,Dest):- !binary_isa("ARM"), arch.call(EA,_), instruction_immediate_offset(EA,_,_,_), instruction_has_relocation(EA,Rel), relocation(Rel,_,_,_,SymbolIndex,_,_), defined_symbol(Dest,_,_,_,_,_,_,SymbolIndex,_). .decl direct_call_resolved(src:address, dest:address) .output direct_call_resolved direct_call_resolved(0,0):- false. .decl pc_relative_call(src:address,dest:address) .output pc_relative_call pc_relative_call(Src,Dest):- arch.call(Src,_), pc_relative_operand(Src,1,Dest). .decl reg_call(src:address,reg:register) .output reg_call reg_call(EA,Reg):- arch.call(EA,TargetOpIndex), instruction_get_op(EA,TargetOpIndex,TargetOp), op_regdirect_contains_reg(TargetOp,Reg). .decl indirect_call(src:address) .output indirect_call indirect_call(EA):- arch.call(EA,TargetOpIndex), instruction_get_op(EA,TargetOpIndex,TargetOp), op_indirect(TargetOp,_,_,_,_,_,_), !pc_relative_call(EA,_), !direct_call_resolved(EA,_), !arch.return(EA). #line 602 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl pc_load_call(Src:address,Dest:address) .output pc_load_call pc_load_call(Src,Dest):- ( binary_isa("X86"); binary_isa("X64") ), direct_call(Src,Dest), next(Src,Dest), instruction_get_operation(Dest,"POP"). .decl halt(EA:address) halt(EA):- arch.halt_operation(Operation), instruction_get_operation(EA,Operation). #line 626 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl alignment(EA:address,AlignInBits:unsigned) .output alignment alignment(0,0):- false. .decl op_indirect_contains_reg(Op:operand_code,Reg:register) .output op_indirect_contains_reg op_indirect_contains_reg(Op,Reg):- op_indirect(Op,_,RegIn,_,_,_,_), reg_map(RegIn,Reg). op_indirect_contains_reg(Op,Reg):- op_indirect(Op,_,_,RegIn,_,_,_), reg_map(RegIn,Reg). .decl op_indirect_mapped(Op:operand_code,Reg1:reg_nullable,Reg2:reg_nullable,Reg3:reg_nullable,Mult:number,Offset:number,Size:unsigned) op_indirect_mapped(Op,Reg1,Reg2,Reg3,Mult,Offset,Size):- op_indirect(Op,RegIn1,RegIn2,RegIn3,Mult,Offset,Size), reg_map_nullable(RegIn1,Reg1), reg_map_nullable(RegIn2,Reg2), reg_map_nullable(RegIn3,Reg3). .decl op_regdirect_contains_reg(Op:operand_code,Reg:register) .output op_regdirect_contains_reg op_regdirect_contains_reg(Op,Reg):- ( op_regdirect(Op,RegIn) ; op_register_bitfield(Op,_,RegIn) ), reg_map(RegIn,Reg). .decl op_immediate_and_reg(EA:address,Operation:symbol,Reg:register,Imm_index:operand_index,Immediate:number) op_immediate_and_reg(EA,Operation,Reg,Imm_index,Immediate):- instruction_get_operation(EA,Operation), instruction_get_op(EA,Imm_index,Op), op_immediate(Op,Immediate), instruction_get_op(EA,_,Op2), op_regdirect_contains_reg(Op2,Reg). .decl cmp_immediate_to_reg(EA:address,Reg:register,Imm_index:operand_index,Immediate:number) cmp_immediate_to_reg(EA,Reg,Imm_index,Immediate):- op_immediate_and_reg(EA,Operation,Reg,Imm_index,Immediate), arch.cmp_operation(Operation), ( !arch.jump(EA); arch.jump(EA), arch.jump_operation_op_index(Operation,JumpTargetIndex), Imm_index != JumpTargetIndex ). .decl symbol_set(ea:address,size:unsigned,type:symbol,scope:symbol,visibility:symbol,sectionIndex:unsigned,name:symbol) symbol_set(EA,Size,Type,Scope,Visibility,SectIndex,Name):- symbol(EA,Size,Type,Scope,Visibility,SectIndex,_,_,Name). .decl ambiguous_symbol(name:symbol) .output ambiguous_symbol ambiguous_symbol(Name):- symbol_set(_,_,_,_,_,_,Name), 1 < count :{symbol_set(_,_,_,_,_,_,Name)}. .decl function_symbol(ea:address,name:symbol) .output function_symbol function_symbol(EA,Name):- symbol(EA,_,"FUNC",_,_,_,_,_,Name). function_symbol(EA,Name):- symbol(EA,_,"GNU_IFUNC",_,_,_,_,_,Name). .decl defined_symbol(ea:address,size:unsigned,type:symbol,scope:symbol,visibility:symbol,sectionIndex:unsigned,originTable:symbol,tableIndex:unsigned,name:symbol) defined_symbol(EA,Size,Type,Scope,Visibility,SectIndex,OriginTable,TableIndex,Name):- symbol(EA,Size,Type,Scope,Visibility,SectIndex,OriginTable,TableIndex,Name), (SectIndex != 0; EA != 0), ( SectIndex < 0xff00; SectIndex = 0xfff1; SectIndex > 0xffff ), Type != "FILE". .decl loaded_section(Beg:address,End:address,Name:symbol) .output loaded_section .decl data_section(name:symbol) .output data_section .decl exception_section(name:symbol) .decl special_data_section(name:symbol) .decl regular_data_section(name:symbol) .decl code_section(name:symbol) .output code_section .decl tls_section(name:symbol) .output tls_section .decl bss_section(name:symbol) .output bss_section loaded_section(Beg,Beg+Size,Name):- section(Name,Size,Beg,_,_), section_property(Name,"Loaded"). code_section(Section):- section(Section,_,_,_,_), section_property(Section,"Executable"). tls_section(Section):- data_section(Section), section_property(Section,"ThreadLocal"). regular_data_section(Name):- data_section(Name), !special_data_section(Name). .decl non_zero_data_section(name:symbol) .output non_zero_data_section .decl bss_section_limits(Begin:address,End:address) .output bss_section_limits bss_section_limits(0,0):- !bss_section(_). bss_section_limits(Begin,End):- Begin = min X:{ bss_section(Name),loaded_section(X,_,Name)}, End = max X:{ bss_section(Name),loaded_section(_,X,Name)}. #line 777 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl initialized_data_segment(Begin:address,End:address) .output initialized_data_segment initialized_data_segment(Begin,End):- non_zero_data_section(Section), loaded_section(Begin,End,Section). initialized_data_segment(Begin,End):- data_in_code(Begin,End). .decl data_segment(Begin:address,End:address) data_segment(Begin,End):- data_section(Section), loaded_section(Begin,End,Section). data_segment(Begin,End):- initialized_data_segment(Begin,End). .decl plt_block(block:address,function:symbol) .output plt_block .decl got_reference(Got_entry:address,Symbol:symbol) .output got_reference .decl main_function(ea:address) .decl conditional_return(EA:address) conditional_return(EA):- arch.return(EA), arch.conditional(EA,_). .decl unconditional_return(EA:address) unconditional_return(EA):- arch.return(EA), !arch.conditional(EA,_). #line 825 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl no_return_call(EA:address) .decl function_pointer_section(Name:symbol) .decl no_return_function(Name:symbol) no_return_call(EA):- direct_call(EA,Dest), plt_entry(Dest,Function), no_return_function(Pattern), match(Pattern,Function). no_return_call(EA):- direct_call(EA,Dest), defined_symbol(Dest,_,_,_,_,_,_,_,Name), no_return_function(Pattern), match(Pattern,Name). no_return_call(EA):- direct_call(EA,_), instruction_immediate_offset(EA,_,Offset,_), relocation(EA+Offset,_,_,_,SymbolIndex,_,_), symbol(_,_,_,_,_,_,_,SymbolIndex,Name), no_return_function(Pattern), match(Pattern,Name). .decl is_padding(EA:address) is_padding(EA):- arch.is_nop(EA). #line 859 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl printable_char(N:unsigned) printable_char(0x9). printable_char(0xA). printable_char(0xC). printable_char(0xD). printable_char(N):- N = range(0x20,0x7E+1,1). #line 871 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl align_addr(AddrAligned:address,AddrOrig:address) inline align_addr(AddrAligned,AddrOrig):- AddrAligned = AddrOrig - (AddrOrig band 3). #line 881 ".tree-sitter-souffle/ddisasm/src/datalog/main.dl" .decl abi_intrinsic(EA:address,Name:symbol) .output abi_intrinsic