From 748c0a331ed666914abb4f8164718944dcc70529 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Tue, 25 Dec 2018 09:39:41 -0500 Subject: [PATCH] updating for pcrel on arm --- SConscript | 7 +-- push64_relocs.cpp | 133 ++++++++++++++++++++++++++++------------------ 2 files changed, 82 insertions(+), 58 deletions(-) diff --git a/SConscript b/SConscript index 5563464dc..5d33b7f9f 100644 --- a/SConscript +++ b/SConscript @@ -20,11 +20,6 @@ myenv.Replace(ZIPR_SDK=os.environ['ZIPR_SDK']) myenv.Replace(ZIPR_INSTALL=os.environ['ZIPR_INSTALL']) myenv.Replace(do_cgc=ARGUMENTS.get("do_cgc",0)) -if 'do_cgc' in env and int(env['do_cgc']) == 1: - myenv.Append(CFLAGS=" -DCGC ") - myenv.Append(CCFLAGS=" -DCGC ") - - files= ''' @@ -50,7 +45,7 @@ libpath=''' ''' if sysname != "SunOS": - myenv.Append(CCFLAGS=" -Wall -Werror ") + myenv.Append(CCFLAGS=" -Wall -Werror -fmax-errors=2") myenv.Append(CXXFLAGS=" -std=c++11 ") myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpath), SHLIBSUFFIX=".zpi", SHLIBPREFIX="") diff --git a/push64_relocs.cpp b/push64_relocs.cpp index d4ba500e5..c68932900 100644 --- a/push64_relocs.cpp +++ b/push64_relocs.cpp @@ -314,18 +314,7 @@ void Push64Relocs_t::UpdatePush64Adds() // caution, side effect in if statement. else if ( (reloc = FindPcrelRelocation(insn)) != NULL && reloc->GetWRT()==NULL) { -// would consider updating this if statement to be a function call for simplicity/readability. - uint8_t memory_offset = 0; - int32_t existing_offset = 0; - int32_t new_offset = 0; - uint32_t insn_addr = 0; - int existing_offset_size = 0; - uint8_t *insn_bytes = NULL; - int insn_bytes_len = 0; - //DISASM d; - //ARGTYPE *arg=NULL; -#if 1 - insn_addr = final_insn_locations[insn]; + const auto insn_addr = final_insn_locations[insn]; if (insn_addr == 0) { if (m_verbose) @@ -334,51 +323,91 @@ void Push64Relocs_t::UpdatePush64Adds() } assert(insn_addr != 0); - insn_bytes_len = sizeof(uint8_t)*insn->GetDataBits().length(); - insn_bytes=(uint8_t*)malloc(insn_bytes_len); + const auto insn_bytes_len = sizeof(uint8_t)*insn->GetDataBits().length(); + uint8_t insn_bytes[insn_bytes_len]={}; memcpy(insn_bytes, insn->GetDataBits().c_str(), insn_bytes_len); - DecodedInstruction_t d(insn); - /* Disassemble(insn,d); - - if(arg_has_relative(d.Argument1)) - arg=&d.Argument1; - if(arg_has_relative(d.Argument2)) - arg=&d.Argument2; - if(arg_has_relative(d.Argument3)) - arg=&d.Argument3; - assert(arg); - */ + const auto d=DecodedInstruction_t(insn); const auto operands=d.getOperands(); - const auto arg_it=find_if(ALLOF(operands),[](const DecodedOperand_t& op) { return op.isMemory() && op.isPcrel(); }); + const auto arg_it=find_if(ALLOF(operands),[](const DecodedOperand_t& op) { return op.isPcrel(); }); assert(arg_it!=operands.end()); const auto arg=*arg_it; - - memory_offset = d.getMemoryDisplacementOffset(arg, insn); // arg->Memory.DisplacementAddr-d.EIP; - existing_offset_size = arg.getMemoryDisplacementEncodingSize(); // arg->Memory.DisplacementSize; - assert(memory_offset>=0 && memory_offset <=15 && - (existing_offset_size==1 || - existing_offset_size==2 || - existing_offset_size==4 || - existing_offset_size==8)); - - memcpy((uint8_t*)&existing_offset, - (uint8_t*)&insn_bytes[memory_offset], - existing_offset_size); - - new_offset = existing_offset-insn_addr; - if (m_verbose) - cout << "Relocating a pcrel relocation with 0x" - << std::hex << existing_offset - << " existing offset at 0x" - << insn_addr << "." << endl - << "Based on: " << d.getDisassembly() /*CompleteInstr*/ << endl - << "New address: 0x" << std::hex << new_offset << endl; - - m_memory_space.PlopBytes(insn_addr+memory_offset, - (const char*)&new_offset, - existing_offset_size); -#endif + const auto mt=m_firp.GetArchitecture()->getMachineType(); + + if(mt==admtX86_64 || mt==admtI386) + { + assert(arg.isMemory()); // only memory operands have pcrel in x86. + auto memory_offset = d.getMemoryDisplacementOffset(arg, insn); + auto existing_offset_size = arg.getMemoryDisplacementEncodingSize(); + assert(memory_offset>=0 && memory_offset <=15); + assert(existing_offset_size==1 || existing_offset_size==2 || existing_offset_size==4 || existing_offset_size==8); + int32_t existing_offset=0; + memcpy((uint8_t*)&existing_offset, + (uint8_t*)&insn_bytes[memory_offset], + existing_offset_size); + + auto new_offset = existing_offset-insn_addr; + if (m_verbose) + { + cout << "Relocating a pcrel relocation with 0x" + << hex << existing_offset + << " existing offset at 0x" + << insn_addr << "." << endl; + cout << "Based on: " << d.getDisassembly() << endl + << "New address: 0x" << hex << new_offset << endl; + } + + m_memory_space.PlopBytes(insn_addr+memory_offset, + (const char*)&new_offset, + existing_offset_size); + } + else if(mt==admtAarch64) + { + const auto mnemonic=d.getMnemonic(); + const auto is_adr_type=mnemonic=="adr" || mnemonic=="adrp"; + const auto full_insn=*(uint32_t*)insn_bytes; + const auto mask2 =(1<< 2)-1; + const auto mask5 =(1<< 5)-1; + const auto mask12=(1<<12)-1; + const auto mask19=(1<<19)-1; + + if(is_adr_type) + { + // adr : 0 immlo2 10000 immhi19 Rd5 + // adrp: 1 immlo2 10000 immhi19 Rd5 + const auto op_byte=insn_bytes[3]; + assert((op_byte&mask5) == 0x10); // sanity check adr(p) opcode bytes. + const auto immlo2=(op_byte >> 5)&mask2; // gram immlo2 + const auto immhi19=(full_insn >> 5)&mask19; // gram immhi19 + const auto imm21=immhi19<<2 | immlo2; // get full immediate in one field. + const auto imm21_ext=(((int64_t)imm21)<<43) >> 43; // sign extend to 64-bit + const auto orig_insn_addr=insn->GetAddress()->GetVirtualOffset(); + const auto orig_insn_pageno=(orig_insn_addr>>12); + const auto new_insn_pageno =( insn_addr>>12); + const auto new_imm21_ext = imm21_ext + orig_insn_pageno - new_insn_pageno + reloc->GetAddend(); + // make sure no overflow. + assert( ((new_imm21_ext << 43) >> 43) == new_imm21_ext); + const auto new_immhi19=new_imm21_ext >> 2; + const auto new_immlo2 =new_imm21_ext & mask2; + const auto clean_new_insn= full_insn & ~(mask2<<29) & ~ (mask19 << 5); + const auto new_insn=clean_new_insn | (new_immlo2 << 29) | (new_immhi19<<5); + // put the new instruction in the output + m_memory_space.PlopBytes(insn_addr, (const char*)&new_insn, 4); + + if (m_verbose) + { + cout << "Relocating a pcrel relocation with orig_pageno=" << hex + << (orig_insn_pageno << 12) << " offset=(page-pc+" << imm21_ext << ")" << endl; + cout << "Based on: " << d.getDisassembly() << " originally at " << orig_insn_addr + << " now located at : 0x" << hex << insn_addr << " with offset=(page-pc + " + << new_imm21_ext << ")" << endl; + } + } + else + assert(0); + } + else + assert(0); } } } -- GitLab