| 2664 | } |
| 2665 | |
| 2666 | void MachoView::ParseRebaseTable(BinaryReader& reader, MachOHeader& header, uint32_t tableOffset, uint32_t tableSize) |
| 2667 | { |
| 2668 | if (tableSize == 0 || tableOffset == 0) |
| 2669 | return; |
| 2670 | |
| 2671 | std::function segmentActualLoadAddress = [&](uint64_t segmentIndex) { |
| 2672 | if (segmentIndex >= header.segments.size()) |
| 2673 | throw ReadException(); |
| 2674 | return header.segments[segmentIndex].vmaddr; |
| 2675 | }; |
| 2676 | std::function segmentActualEndAddress = [&](uint64_t segmentIndex) { |
| 2677 | if (segmentIndex >= header.segments.size()) |
| 2678 | throw ReadException(); |
| 2679 | return header.segments[segmentIndex].vmaddr + header.segments[segmentIndex].vmsize; |
| 2680 | }; |
| 2681 | |
| 2682 | try { |
| 2683 | reader.Seek(tableOffset); |
| 2684 | auto table = reader.Read(tableSize); |
| 2685 | |
| 2686 | BNRelocationInfo rebaseRelocation; |
| 2687 | |
| 2688 | uint64_t segmentIndex = 0; |
| 2689 | uint64_t address = segmentActualLoadAddress(0); |
| 2690 | uint64_t segmentStartAddress = segmentActualLoadAddress(0); |
| 2691 | uint64_t segmentEndAddress = segmentActualEndAddress(0); |
| 2692 | uint64_t count; |
| 2693 | uint64_t skip; |
| 2694 | bool done = false; |
| 2695 | size_t i = 0; |
| 2696 | while ( !done && (i < tableSize)) |
| 2697 | { |
| 2698 | uint8_t opAndIm = table[i]; |
| 2699 | uint8_t opcode = opAndIm & RebaseOpcodeMask; |
| 2700 | uint64_t immediate = opAndIm & RebaseImmediateMask; |
| 2701 | m_logger->LogDebug("Rebase opcode 0x%llx (im: 0x%llx)", opcode, immediate); |
| 2702 | i++; |
| 2703 | switch (opcode) |
| 2704 | { |
| 2705 | case RebaseOpcodeDone: |
| 2706 | done = true; |
| 2707 | break; |
| 2708 | case RebaseOpcodeSetTypeImmediate: |
| 2709 | break; |
| 2710 | case RebaseOpcodeSetSegmentAndOffsetUleb: |
| 2711 | segmentIndex = immediate; |
| 2712 | address = segmentActualLoadAddress(segmentIndex) + readLEB128(table, tableSize, i); |
| 2713 | segmentStartAddress = segmentActualLoadAddress(segmentIndex); |
| 2714 | segmentEndAddress = segmentActualEndAddress(segmentIndex); |
| 2715 | break; |
| 2716 | case RebaseOpcodeAddAddressUleb: |
| 2717 | address += readLEB128(table, tableSize, i); |
| 2718 | break; |
| 2719 | case RebaseOpcodeAddAddressImmediateScaled: |
| 2720 | address += immediate * m_addressSize; |
| 2721 | break; |
| 2722 | case RebaseOpcodeDoRebaseImmediateTimes: |
| 2723 | count = immediate; |
nothing calls this directly
no test coverage detected