| 169 | BUILD_BYTES, // Build bytes (buf != nullptr) |
| 170 | }; |
| 171 | static int buildBreak(const Binary *B, const Instr *I, intptr_t addr, |
| 172 | BuildMode mode = BUILD_SIZE, const BreakInfo *breaks = nullptr, |
| 173 | Buffer *buf = nullptr) |
| 174 | { |
| 175 | if (mode == BUILD_SIZE) |
| 176 | return /*sizeof(jmpq)=*/5; |
| 177 | |
| 178 | intptr_t target = I->addr + I->size; |
| 179 | if (breaks != nullptr) |
| 180 | { |
| 181 | auto i = breaks->find(I->addr); |
| 182 | if (i != breaks->end()) |
| 183 | target = i->second; |
| 184 | } |
| 185 | off_t rel = target - (addr + /*sizeof(jmpq)=*/5); |
| 186 | assert(rel >= INT32_MIN && rel <= INT32_MAX); |
| 187 | int32_t rel32 = (int32_t)rel; |
| 188 | uint8_t *bytes = buf->bytes(); |
| 189 | buf->push(/*jmpq opcode=*/0xE9); |
| 190 | buf->push((const uint8_t *)&rel32, sizeof(rel32)); |
| 191 | |
| 192 | const Instr *J = I->succ(); |
| 193 | if (option_Opeephole && J != nullptr && buf->bytes() != nullptr) |
| 194 | saveJump(B, addr, bytes, /*sizeof(jmpq)=*/5); |
| 195 | |
| 196 | return /*sizeof(jmpq)=*/5; |
| 197 | } |
| 198 | |
| 199 | /* |
| 200 | * Build a $break/$BREAK operation from a trampoline back to the main code. |
no test coverage detected