| 2617 | } |
| 2618 | |
| 2619 | void BlContext::WriteOutSection(BlOutSection* outSection, DataStream* st) |
| 2620 | { |
| 2621 | int startPos = st->GetPos(); |
| 2622 | |
| 2623 | auto _FillBytes = [&](int size) |
| 2624 | { |
| 2625 | if ((outSection->mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0) |
| 2626 | { |
| 2627 | uint64 fillData = 0xCCCCCCCCCCCCCCCCLL; |
| 2628 | int alignLeft = size; |
| 2629 | while (alignLeft > 0) |
| 2630 | { |
| 2631 | int alignWrite = std::min(alignLeft, 8); |
| 2632 | st->Write(&fillData, alignWrite); |
| 2633 | alignLeft -= alignWrite; |
| 2634 | } |
| 2635 | } |
| 2636 | else |
| 2637 | { |
| 2638 | st->WriteZeros(size); |
| 2639 | } |
| 2640 | }; |
| 2641 | |
| 2642 | for (auto sect : outSection->mSegments) |
| 2643 | { |
| 2644 | int curPos = st->GetPos(); |
| 2645 | int wantPos = (curPos + (sect->mAlign - 1)) & ~(sect->mAlign - 1); |
| 2646 | _FillBytes(wantPos - curPos); |
| 2647 | |
| 2648 | int sectStartPos = wantPos; |
| 2649 | BF_ASSERT(outSection->mRVA + sectStartPos - startPos == sect->mRVA); |
| 2650 | |
| 2651 | BlReloc* nextReloc = NULL; |
| 2652 | int curRelocIdx = 0; |
| 2653 | if (!sect->mRelocs.empty()) |
| 2654 | nextReloc = §->mRelocs[0]; |
| 2655 | int curSectOfs = 0; |
| 2656 | |
| 2657 | for (auto& chunk : sect->mChunks) |
| 2658 | { |
| 2659 | BF_ASSERT(st->GetPos() == sectStartPos + curSectOfs); |
| 2660 | _FillBytes(chunk.mAlignPad); |
| 2661 | |
| 2662 | curSectOfs += chunk.mAlignPad; |
| 2663 | |
| 2664 | BF_ASSERT((chunk.mOffset == curSectOfs) || (chunk.mOffset == -1)); |
| 2665 | |
| 2666 | uint8* data = (uint8*)chunk.mData; |
| 2667 | int sizeLeft = chunk.mSize; |
| 2668 | |
| 2669 | while (sizeLeft > 0) |
| 2670 | { |
| 2671 | if (nextReloc != NULL) |
| 2672 | { |
| 2673 | int relocOfs = nextReloc->mOutOffset - curSectOfs; |
| 2674 | BF_ASSERT(relocOfs >= 0); |
| 2675 | if (relocOfs < sizeLeft) |
| 2676 | { |