diff options
author | David L. Jones <dlj@google.com> | 2017-11-15 01:40:05 +0000 |
---|---|---|
committer | David L. Jones <dlj@google.com> | 2017-11-15 01:40:05 +0000 |
commit | d5c2cca72463233df77a065f201db31b140eb44d (patch) | |
tree | 3f9a978131033302a58b7db7db1ecf2a4622bad2 /tools/llvm-objcopy/Object.cpp | |
parent | ce7676b8db6bac096dad4c4ad62e9e6bb8aa1064 (diff) | |
parent | dcf64df89bc6d775e266ebd6b0134d135f47a35b (diff) | |
download | llvm-testing.tar.gz |
Creating branches/google/testing and tags/google/testing/2017-11-14 from r317716testing
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/testing@318248 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-objcopy/Object.cpp')
-rw-r--r-- | tools/llvm-objcopy/Object.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/tools/llvm-objcopy/Object.cpp b/tools/llvm-objcopy/Object.cpp index 22ae47f1cace..5f9864d9cc04 100644 --- a/tools/llvm-objcopy/Object.cpp +++ b/tools/llvm-objcopy/Object.cpp @@ -685,6 +685,19 @@ template <class ELFT> void ELFObject<ELFT>::sortSections() { CompareSections); } +static uint64_t alignToAddr(uint64_t Offset, uint64_t Addr, uint64_t Align) { + // Calculate Diff such that (Offset + Diff) & -Align == Addr & -Align. + if (Align == 0) + Align = 1; + auto Diff = + static_cast<int64_t>(Addr % Align) - static_cast<int64_t>(Offset % Align); + // We only want to add to Offset, however, so if Diff < 0 we can add Align and + // (Offset + Diff) & -Align == Addr & -Align will still hold. + if (Diff < 0) + Diff += Align; + return Offset + Diff; +} + template <class ELFT> void ELFObject<ELFT>::assignOffsets() { // We need a temporary list of segments that has a special order to it // so that we know that anytime ->ParentSegment is set that segment has @@ -728,7 +741,7 @@ template <class ELFT> void ELFObject<ELFT>::assignOffsets() { Segment->Offset = Parent->Offset + Segment->OriginalOffset - Parent->OriginalOffset; } else { - Offset = alignTo(Offset, Segment->Align == 0 ? 1 : Segment->Align); + Offset = alignToAddr(Offset, Segment->VAddr, Segment->Align); Segment->Offset = Offset; } Offset = std::max(Offset, Segment->Offset + Segment->FileSize); @@ -829,8 +842,9 @@ template <class ELFT> void BinaryObject<ELFT>::finalize() { uint64_t Offset = 0; for (auto &Segment : this->Segments) { - if (Segment->Type == PT_LOAD && Segment->firstSection() != nullptr) { - Offset = alignTo(Offset, Segment->Align); + if (Segment->Type == llvm::ELF::PT_LOAD && + Segment->firstSection() != nullptr) { + Offset = alignToAddr(Offset, Segment->VAddr, Segment->Align); Segment->Offset = Offset; Offset += Segment->FileSize; } |