| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f3d7fae commit 7dff6cc
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -167,11 +167,13 @@ set_bits(uint32_t *loc, uint8_t loc_start, uint64_t value, uint8_t value_start, | |||
| 167 | 167 | ||
| 168 | 168 | // See https://developer.arm.com/documentation/ddi0602/2023-09/Base-Instructions | |
| 169 | 169 | // for instruction encodings: | |
| 170 | - #define IS_AARCH64_ADD_OR_SUB(I) (((I) & 0x11C00000) == 0x11000000) | ||
| 171 | - #define IS_AARCH64_ADRP(I) (((I) & 0x9F000000) == 0x90000000) | ||
| 172 | - #define IS_AARCH64_BRANCH(I) (((I) & 0x7C000000) == 0x14000000) | ||
| 173 | - #define IS_AARCH64_LDR_OR_STR(I) (((I) & 0x3B000000) == 0x39000000) | ||
| 174 | - #define IS_AARCH64_MOV(I) (((I) & 0x9F800000) == 0x92800000) | ||
| 170 | + #define IS_AARCH64_ADD_OR_SUB(I) (((I) & 0x11C00000) == 0x11000000) | ||
| 171 | + #define IS_AARCH64_ADRP(I) (((I) & 0x9F000000) == 0x90000000) | ||
| 172 | + #define IS_AARCH64_BRANCH(I) (((I) & 0x7C000000) == 0x14000000) | ||
| 173 | + #define IS_AARCH64_BRANCH_COND(I) (((I) & 0x7C000000) == 0x54000000) | ||
| 174 | + #define IS_AARCH64_TEST_AND_BRANCH(I) (((I) & 0x7E000000) == 0x36000000) | ||
| 175 | + #define IS_AARCH64_LDR_OR_STR(I) (((I) & 0x3B000000) == 0x39000000) | ||
| 176 | + #define IS_AARCH64_MOV(I) (((I) & 0x9F800000) == 0x92800000) | ||
| 175 | 177 | ||
| 176 | 178 | // LLD is a great reference for performing relocations... just keep in | |
| 177 | 179 | // mind that Tools/jit/build.py does filtering and preprocessing for us! | |
@@ -332,6 +334,37 @@ patch_aarch64_21rx(unsigned char *location, uint64_t value) | |||
| 332 | 334 | patch_aarch64_21r(location, value); | |
| 333 | 335 | } | |
| 334 | 336 | ||
| 337 | + | ||
| 338 | + // 21-bit relative branch. | ||
| 339 | + void | ||
| 340 | + patch_aarch64_19r(unsigned char *location, uint64_t value) | ||
| 341 | + { | ||
| 342 | + uint32_t *loc32 = (uint32_t *)location; | ||
| 343 | + assert(IS_AARCH64_BRANCH_COND(*loc32)); | ||
| 344 | + value -= (uintptr_t)location; | ||
| 345 | + // Check that we're not out of range of 21 signed bits: | ||
| 346 | + assert((int64_t)value >= -(1 << 20)); | ||
| 347 | + assert((int64_t)value < (1 << 20)); | ||
| 348 | + // Since instructions are 4-byte aligned, only use 19 bits: | ||
| 349 | + assert(get_bits(value, 0, 2) == 0); | ||
| 350 | + set_bits(loc32, 5, value, 2, 19); | ||
| 351 | + } | ||
| 352 | + | ||
| 353 | + // 16-bit relative branch. | ||
| 354 | + void | ||
| 355 | + patch_aarch64_14r(unsigned char *location, uint64_t value) | ||
| 356 | + { | ||
| 357 | + uint32_t *loc32 = (uint32_t *)location; | ||
| 358 | + assert(IS_AARCH64_TEST_AND_BRANCH(*loc32)); | ||
| 359 | + value -= (uintptr_t)location; | ||
| 360 | + // Check that we're not out of range of 16 signed bits: | ||
| 361 | + assert((int64_t)value >= -(1 << 15)); | ||
| 362 | + assert((int64_t)value < (1 << 15)); | ||
| 363 | + // Since instructions are 4-byte aligned, only use 14 bits: | ||
| 364 | + assert(get_bits(value, 0, 2) == 0); | ||
| 365 | + set_bits(loc32, 5, value, 2, 14); | ||
| 366 | + } | ||
| 367 | + | ||
| 335 | 368 | // 28-bit relative branch. | |
| 336 | 369 | void | |
| 337 | 370 | patch_aarch64_26r(unsigned char *location, uint64_t value) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,6 +39,41 @@ | |||
| 39 | 39 | # Update with all of the inverted branches, too: | |
| 40 | 40 | _X86_BRANCHES |= {v: k for k, v in _X86_BRANCHES.items() if v} | |
| 41 | 41 | ||
| 42 | + _AARCH64_COND_CODES = { | ||
| 43 | + # https://developer.arm.com/documentation/dui0801/b/CJAJIHAD?lang=en | ||
| 44 | + "eq": "ne", | ||
| 45 | + "ne": "eq", | ||
| 46 | + "lt": "ge", | ||
| 47 | + "ge": "lt", | ||
| 48 | + "gt": "le", | ||
| 49 | + "le": "gt", | ||
| 50 | + "vs": "vc", | ||
| 51 | + "vc": "vs", | ||
| 52 | + "mi": "pl", | ||
| 53 | + "pl": "mi", | ||
| 54 | + "cs": "cc", | ||
| 55 | + "cc": "cs", | ||
| 56 | + "hs": "lo", | ||
| 57 | + "lo": "hs", | ||
| 58 | + "hi": "ls", | ||
| 59 | + "ls": "hi", | ||
| 60 | + } | ||
| 61 | + # Branches are either b.{cond} or bc.{cond} | ||
| 62 | + _AARCH64_BRANCHES = { | ||
| 63 | + "b." + cond: ("b." + inverse if inverse else None) | ||
| 64 | + for (cond, inverse) in _AARCH64_COND_CODES.items() | ||
| 65 | + } | { | ||
| 66 | + "bc." + cond: ("bc." + inverse if inverse else None) | ||
| 67 | + for (cond, inverse) in _AARCH64_COND_CODES.items() | ||
| 68 | + } | ||
| 69 | + # And four compare and branch instructions | ||
| 70 | + _AARCH64_BRANCHES |= { | ||
| 71 | + "cbz": "cbnz", | ||
| 72 | + "cbnz": "cbz", | ||
| 73 | + "tbz": "tbnz", | ||
| 74 | + "tbnz": "tbz", | ||
| 75 | + } | ||
| 76 | + | ||
| 42 | 77 | ||
| 43 | 78 | @dataclasses.dataclass | |
| 44 | 79 | class _Block: | |
@@ -286,8 +321,15 @@ def run(self) -> None: | |||
| 286 | 321 | class OptimizerAArch64(Optimizer): # pylint: disable = too-few-public-methods | |
| 287 | 322 | """aarch64-apple-darwin/aarch64-pc-windows-msvc/aarch64-unknown-linux-gnu""" | |
| 288 | 323 | ||
| 324 | + _branches = _AARCH64_BRANCHES | ||
| 325 | + _re_branch = re.compile( | ||
| 326 | + rf"\s*(?P<instruction>{'|'.join(_AARCH64_BRANCHES)})\s+(.+,\s+)*(?P<target>[\w.]+)" | ||
| 327 | + ) | ||
| 328 | + | ||
| 289 | 329 | # https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/B--Branch- | |
| 290 | 330 | _re_jump = re.compile(r"\s*b\s+(?P<target>[\w.]+)") | |
| 331 | + # https://developer.arm.com/documentation/ddi0602/2025-09/Base-Instructions/RET--Return-from-subroutine- | ||
| 332 | + _re_return = re.compile(r"\s*ret\b") | ||
| 291 | 333 | ||
| 292 | 334 | ||
| 293 | 335 | class OptimizerX86(Optimizer): # pylint: disable = too-few-public-methods | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,13 +20,15 @@ | |||
| 20 | 20 | "R_AARCH64_ADR_GOT_PAGE", | |
| 21 | 21 | "R_AARCH64_ADR_PREL_PG_HI21", | |
| 22 | 22 | "R_AARCH64_CALL26", | |
| 23 | + "R_AARCH64_CONDBR19", | ||
| 23 | 24 | "R_AARCH64_JUMP26", | |
| 24 | 25 | "R_AARCH64_ADD_ABS_LO12_NC", | |
| 25 | 26 | "R_AARCH64_LD64_GOT_LO12_NC", | |
| 26 | 27 | "R_AARCH64_MOVW_UABS_G0_NC", | |
| 27 | 28 | "R_AARCH64_MOVW_UABS_G1_NC", | |
| 28 | 29 | "R_AARCH64_MOVW_UABS_G2_NC", | |
| 29 | 30 | "R_AARCH64_MOVW_UABS_G3", | |
| 31 | + "R_AARCH64_TSTBR14", | ||
| 30 | 32 | "R_X86_64_64", | |
| 31 | 33 | "R_X86_64_GOTPCREL", | |
| 32 | 34 | "R_X86_64_GOTPCRELX", | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,12 +74,14 @@ class HoleValue(enum.Enum): | |||
| 74 | 74 | "R_AARCH64_ADR_GOT_PAGE": "patch_aarch64_21rx", | |
| 75 | 75 | "R_AARCH64_ADR_PREL_PG_HI21": "patch_aarch64_21r", | |
| 76 | 76 | "R_AARCH64_CALL26": "patch_aarch64_26r", | |
| 77 | + "R_AARCH64_CONDBR19": "patch_aarch64_19r", | ||
| 77 | 78 | "R_AARCH64_JUMP26": "patch_aarch64_26r", | |
| 78 | 79 | "R_AARCH64_LD64_GOT_LO12_NC": "patch_aarch64_12x", | |
| 79 | 80 | "R_AARCH64_MOVW_UABS_G0_NC": "patch_aarch64_16a", | |
| 80 | 81 | "R_AARCH64_MOVW_UABS_G1_NC": "patch_aarch64_16b", | |
| 81 | 82 | "R_AARCH64_MOVW_UABS_G2_NC": "patch_aarch64_16c", | |
| 82 | 83 | "R_AARCH64_MOVW_UABS_G3": "patch_aarch64_16d", | |
| 84 | + "R_AARCH64_TSTBR14": "patch_aarch64_14r", | ||
| 83 | 85 | # x86_64-unknown-linux-gnu: | |
| 84 | 86 | "R_X86_64_64": "patch_64", | |
| 85 | 87 | "R_X86_64_GOTPCRELX": "patch_x86_64_32rx", | |
| Back | FazBrowse Home | New Git URL |
0 commit comments