Loading...
--- dyld/dyld-1340/mach_o/Instructions.cpp
+++ dyld/dyld-1285.19/mach_o/Instructions.cpp
@@ -25,7 +25,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <cassert>
#include "Instructions.h"
@@ -217,22 +216,16 @@
//
-bool Instructions::arm::isBranch24(uint32_t instruction, uint32_t instructionAddr, BranchKind& kind, uint32_t& targetAddr, bool& isCond)
-{
- // 4 top bits are used to encode the
- // 0xE0000000 -> no condition
- // 0xF0000000 -> blx/bx variants
- // other values are used to encode a code for the conditional execution
- if ( ((instruction & 0xF0000000) != 0xF0000000) && (instruction & 0x0F000000) == 0x0B000000 ) {
- kind = bl;
- isCond = (instruction & 0xF0000000) != 0xE0000000;
- } else if ( (instruction & 0xFE000000) == 0xFA000000 ) {
- kind = blx;
- isCond = false;
- } else if ( ((instruction & 0x0F000000) == 0x0A000000) && ((instruction & 0xF0000000) != 0xF0000000 )) {
- kind = b;
- isCond = (instruction & 0xF0000000) != 0xE0000000;
- }
+bool Instructions::arm::isBranch24(uint32_t instruction, uint32_t instructionAddr, BranchKind& kind, uint32_t& targetAddr)
+{
+ // NOTE: b and bl can have 4-bit condition, but blx cannot.
+ // we do not support conditions because you cannot transform bl to blx
+ if ( (instruction & 0xFF000000) == 0xEB000000 )
+ kind = bl;
+ else if ( (instruction & 0xFE000000) == 0xFA000000 )
+ kind = blx;
+ else if ( (instruction & 0x0F000000) == 0x0A000000 )
+ kind = b;
else
return false;
@@ -292,20 +285,13 @@
if ( kind != b ) {
if ( targetIsThumb ) {
- uint32_t maskedCond = instruction & 0xF0000000;
- assert(((maskedCond == 0xF0000000) || (maskedCond == 0xE0000000)) && "ARM can't branch to thumb with non-blx instruction");
uint32_t opcode = 0xFA000000; // blx
uint32_t disp = (uint32_t)(delta >> 2) & 0x00FFFFFF;
uint32_t h_bit = (uint32_t)(delta << 23) & 0x01000000;
instruction = opcode | h_bit | disp;
}
else {
- // preserve branch condition
- uint32_t maskedCond = (instruction & 0xF0000000);
- // except 0xf, that's an encoding for blx
- if ( maskedCond == 0xF0000000 )
- maskedCond = 0xE0000000; // unconditional
- uint32_t opcode = 0x0B000000 | maskedCond; // bl
+ uint32_t opcode = 0xEB000000; // bl
uint32_t disp = (uint32_t)(delta >> 2) & 0x00FFFFFF;
instruction = opcode | disp;
}
@@ -316,7 +302,7 @@
}
else {
// simple arm-to-arm branch
- uint32_t opcode = 0x0A000000 | (instruction & 0xF0000000); // b
+ uint32_t opcode = 0xEA000000; // b
instruction = (opcode & 0xFF000000) | ((uint32_t)(delta >> 2) & 0x00FFFFFF);
return true;
}
@@ -325,19 +311,6 @@
bool Instructions::arm::makeThumbBranch22(BranchKind kind, uint64_t instructionAddr, uint64_t targetAddr, bool targetIsThumb, uint32_t& instruction)
{
- if ( targetIsThumb ) {
- // Thumb to thumb branch, we will be generating a bl instruction.
- // Delta is always even, so mask out thumb bit in target.
- targetAddr &= ~1ULL;
- } else {
- // Target is not thumb, we will be generating a blx instruction
- // Since blx cannot have the low bit set, set bit[1] of the target to
- // bit[1] of the base address, so that the difference is a multiple of
- // 4 bytes.
- targetAddr &= ~2ULL;
- targetAddr |= (instructionAddr & 2ULL);
- }
-
int64_t delta = targetAddr - (instructionAddr + 4); // pcrel to start of BL instruction + 4
const int64_t b22Limit = 0x00FFFFFF; // Note: thumb1 has only a +/-4MB range. We only support thumb2 which has a +/-16MB branch range
if ( (delta > b22Limit) || (delta < (-b22Limit)) )
@@ -620,7 +593,7 @@
bool Instructions::riscv::setLUITarget(uint32_t& instruction, uint64_t targetAddr)
{
- const int64_t fourGBLimit = 0xFFFFF000; // Note: riscv32 will always be in range, riscv64 might not be
+ const int64_t fourGBLimit = 0x7FFFF000; // Note: riscv32 will always be in range, riscv64 might not be
if ( targetAddr > fourGBLimit )
return false;