(
&mut self,
fixup: MachLabelFixup<I>,
force_veneers: ForceVeneers,
forced_threshold: CodeOffset,
)
| 1494 | } |
| 1495 | |
| 1496 | fn handle_fixup( |
| 1497 | &mut self, |
| 1498 | fixup: MachLabelFixup<I>, |
| 1499 | force_veneers: ForceVeneers, |
| 1500 | forced_threshold: CodeOffset, |
| 1501 | ) { |
| 1502 | let MachLabelFixup { |
| 1503 | label, |
| 1504 | offset, |
| 1505 | kind, |
| 1506 | } = fixup; |
| 1507 | let start = offset as usize; |
| 1508 | let end = (offset + kind.patch_size()) as usize; |
| 1509 | let label_offset = self.resolve_label_offset(label); |
| 1510 | |
| 1511 | if label_offset != UNKNOWN_LABEL_OFFSET { |
| 1512 | // If the offset of the label for this fixup is known then |
| 1513 | // we're going to do something here-and-now. We're either going |
| 1514 | // to patch the original offset because it's an in-bounds jump, |
| 1515 | // or we're going to generate a veneer, patch the fixup to jump |
| 1516 | // to the veneer, and then keep going. |
| 1517 | // |
| 1518 | // If the label comes after the original fixup, then we should |
| 1519 | // be guaranteed that the jump is in-bounds. Otherwise there's |
| 1520 | // a bug somewhere because this method wasn't called soon |
| 1521 | // enough. All forward-jumps are tracked and should get veneers |
| 1522 | // before their deadline comes and they're unable to jump |
| 1523 | // further. |
| 1524 | // |
| 1525 | // Otherwise if the label is before the fixup, then that's a |
| 1526 | // backwards jump. If it's past the maximum negative range |
| 1527 | // then we'll emit a veneer that to jump forward to which can |
| 1528 | // then jump backwards. |
| 1529 | let veneer_required = if label_offset >= offset { |
| 1530 | assert!((label_offset - offset) <= kind.max_pos_range()); |
| 1531 | false |
| 1532 | } else { |
| 1533 | (offset - label_offset) > kind.max_neg_range() |
| 1534 | }; |
| 1535 | trace!( |
| 1536 | " -> label_offset = {}, known, required = {} (pos {} neg {})", |
| 1537 | label_offset, |
| 1538 | veneer_required, |
| 1539 | kind.max_pos_range(), |
| 1540 | kind.max_neg_range() |
| 1541 | ); |
| 1542 | |
| 1543 | if (force_veneers == ForceVeneers::Yes && kind.supports_veneer()) || veneer_required { |
| 1544 | self.emit_veneer(label, offset, kind); |
| 1545 | } else { |
| 1546 | let slice = &mut self.data[start..end]; |
| 1547 | trace!( |
| 1548 | "patching in-range! slice = {slice:?}; offset = {offset:#x}; label_offset = {label_offset:#x}" |
| 1549 | ); |
| 1550 | kind.patch(slice, offset, label_offset); |
| 1551 | } |
| 1552 | } else { |
| 1553 | // If the offset of this label is not known at this time then |
no test coverage detected