diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-03-29 06:26:49 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-03-29 06:26:49 +0000 |
| commit | 5904e12bfae8f613b8fe050644da47a6ecfccd53 (patch) | |
| tree | 52d3be5a9b67de88c8e0dde953b90339c12465a5 /llvm/lib/MC/MCAssembler.cpp | |
| parent | 19be506a5efea9d4698c9f93d6e9d1475d2784a2 (diff) | |
| download | bcm5719-llvm-5904e12bfae8f613b8fe050644da47a6ecfccd53.tar.gz bcm5719-llvm-5904e12bfae8f613b8fe050644da47a6ecfccd53.zip | |
Completely rewrite ELFObjectWriter::RecordRelocation.
I started trying to fix a small issue, but this code has seen a small fix too
many.
The old code was fairly convoluted. Some of the issues it had:
* It failed to check if a symbol difference was in the some section when
converting a relocation to pcrel.
* It failed to check if the relocation was already pcrel.
* The pcrel value computation was wrong in some cases (relocation-pc.s)
* It was missing quiet a few cases where it should not convert symbol
relocations to section relocations, leaving the backends to patch it up.
* It would not propagate the fact that it had changed a relocation to pcrel,
requiring a quiet nasty work around in ARM.
* It was missing comments.
llvm-svn: 205076
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
| -rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index fcf1b50a4f7..5536087bd0c 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -779,20 +779,22 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, Layout.getSectionAddressSize(SD)); } - -uint64_t MCAssembler::handleFixup(const MCAsmLayout &Layout, - MCFragment &F, - const MCFixup &Fixup) { +std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout, + MCFragment &F, + const MCFixup &Fixup) { // Evaluate the fixup. MCValue Target; uint64_t FixedValue; + bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) { // The fixup was unresolved, we need a relocation. Inform the object // writer of the relocation, and give it an opportunity to adjust the // fixup value if need be. - getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, FixedValue); + getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, IsPCRel, + FixedValue); } - return FixedValue; + return std::make_pair(FixedValue, IsPCRel); } void MCAssembler::Finish() { @@ -856,9 +858,11 @@ void MCAssembler::Finish() { for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(), ie3 = F->fixup_end(); it3 != ie3; ++it3) { MCFixup &Fixup = *it3; - uint64_t FixedValue = handleFixup(Layout, *F, Fixup); + uint64_t FixedValue; + bool IsPCRel; + std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup); getBackend().applyFixup(Fixup, F->getContents().data(), - F->getContents().size(), FixedValue); + F->getContents().size(), FixedValue, IsPCRel); } } } |

