diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2014-03-24 14:09:17 +0000 | 
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2014-03-24 14:09:17 +0000 | 
| commit | 1ebfb22638f45b01606b054510d15b4f065a843e (patch) | |
| tree | 149fd8341e47283e4d2b08e33c0fe07e18e9fedc /lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp | |
| parent | a771fefb72a052b2f15b3ef65ffc7a0b1a9a525b (diff) | |
| download | bcm5719-llvm-1ebfb22638f45b01606b054510d15b4f065a843e.tar.gz bcm5719-llvm-1ebfb22638f45b01606b054510d15b4f065a843e.zip | |
[Mips] Sort R_MIPS_LO16 / R_MIPS_HI16 / R_MIPS_GOT16 before finding
pairs and calculate AHL addend.
llvm-svn: 204606
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp | 38 | 
1 files changed, 29 insertions, 9 deletions
| diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index 1cf3493b456..ee2ab033ca5 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -266,27 +266,47 @@ inline int64_t calcAHL(int64_t AHI, int64_t ALO) {  template <typename ELFT>  void RelocationPass<ELFT>::calculateAHLs(const DefinedAtom &atom) { -  std::vector<Reference *> references; +  std::vector<const Reference *> lo16Refs; +  std::vector<Reference *> hi16Refs;    for (const auto &ref : atom) {      if (ref->kindNamespace() != lld::Reference::KindNamespace::ELF)        continue;      assert(ref->kindArch() == Reference::KindArch::Mips);      switch (ref->kindValue()) {      case R_MIPS_HI16: -      references.push_back(const_cast<Reference *>(ref)); +      hi16Refs.push_back(const_cast<Reference *>(ref)); +    case R_MIPS_LO16: +      lo16Refs.push_back(ref);        break;      case R_MIPS_GOT16:        if (isLocal(ref->target())) -        references.push_back(const_cast<Reference *>(ref)); -      break; -    case R_MIPS_LO16: -      for (auto &sr : references) -        sr->setAddend(calcAHL(sr->addend(), ref->addend())); -      references.clear(); +        hi16Refs.push_back(const_cast<Reference *>(ref));        break;      }    } -  assert(references.empty()); + +  std::sort(lo16Refs.begin(), lo16Refs.end(), +            [](const Reference *a, const Reference *b) { +    return a->offsetInAtom() < b->offsetInAtom(); +  }); +  std::sort(hi16Refs.begin(), hi16Refs.end(), +            [](const Reference *a, const Reference *b) { +    return a->offsetInAtom() < b->offsetInAtom(); +  }); + +  // Iterate over R_MIPS_LO16 relocations sorted by theirs offsets in the atom. +  // Calculate AHL addend for each R_MIPS_HI16 amd R_MIPS_GOT16 relocation +  // precedes the current R_MIPS_LO16 one. + +  auto hic = hi16Refs.begin(); +  for (const auto &lo : lo16Refs) { +    for (; hic != hi16Refs.end(); ++hic) { +      if ((*hic)->offsetInAtom() > lo->offsetInAtom()) +        break; +      (*hic)->setAddend(calcAHL((*hic)->addend(), lo->addend())); +    } +  } +  assert(hic == hi16Refs.end());  }  template <typename ELFT> | 

