* Allocates a chunk of virtual address space of size `size` and within the * range [lb..ub]. Returns the allocation, or nullptr on failure. */
| 559 | * range [lb..ub]. Returns the allocation, or nullptr on failure. |
| 560 | */ |
| 561 | const Alloc *allocate(Binary *B, intptr_t lb, intptr_t ub, |
| 562 | const Trampoline *T, const Instr *I, bool same_page) |
| 563 | { |
| 564 | Allocator &allocator = B->allocator; |
| 565 | if (!verify(lb, ub + TRAMPOLINE_MAX)) |
| 566 | return nullptr; |
| 567 | int presize = getTrampolinePrologueSize(B, I); |
| 568 | int tmpsize = getTrampolineSize(B, T, I); |
| 569 | if (tmpsize < 0) |
| 570 | return nullptr; |
| 571 | lb -= (intptr_t)presize; |
| 572 | ub += (intptr_t)tmpsize; |
| 573 | size_t size = (size_t)presize + (size_t)tmpsize; |
| 574 | uint32_t flags = (same_page? FLAG_SAME_PAGE: 0); |
| 575 | Node *n = nullptr; |
| 576 | const intptr_t target = 0x70C00000; |
| 577 | if (option_Oorder && ub > target) |
| 578 | n = insert(allocator.tree.root, lb, target, size, flags | FLAG_RIGHT); |
| 579 | if (n == nullptr) |
| 580 | n = insert(allocator.tree.root, lb, ub, size, flags); |
| 581 | if (n == nullptr) |
| 582 | return nullptr; |
| 583 | if (allocator.tree.root == nullptr) |
| 584 | allocator.tree.root = n; |
| 585 | rebalanceInsert(&allocator.tree, n); |
| 586 | |
| 587 | Alloc *A = &n->alloc; |
| 588 | A->T = T; |
| 589 | A->I = I; |
| 590 | A->entry = (unsigned)presize; |
| 591 | return A; |
| 592 | } |
| 593 | |
| 594 | /* |
| 595 | * Reserves a chunk of the virtual address space spanning the range [lb..ub]. |
no test coverage detected