From f6e90afbf4bfee9894fed71656969bdee410b1d4 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 2 Aug 2013 22:27:15 +0000 Subject: [PATCH] [PECOFF] Remove COFFDefinedFileAtom::originalOffset(). The aim of this patch is to reduce the dependency from COFFDefinedAtom to COFF structs defined in llvm/Object/COFF.h. Currently many attributes of the atom are computed in the atom. That provide a simple interface but does not work well in some cases. There are some cases that the same type atom is created from different parts of a COFF file. One example is the BSS atom, which can be created from the defined symbol in the .bss section or from the undefined symbol. Computing attributes from different sources in the atom complicates the code. We should compute it outside the atom. In the next patch, I'll move more code from Atoms.h to ReaderCOFF.cpp. llvm-svn: 187681 --- lld/lib/ReaderWriter/PECOFF/Atoms.h | 1 - lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp | 39 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lld/lib/ReaderWriter/PECOFF/Atoms.h b/lld/lib/ReaderWriter/PECOFF/Atoms.h index badcff2..49d7788 100644 --- a/lld/lib/ReaderWriter/PECOFF/Atoms.h +++ b/lld/lib/ReaderWriter/PECOFF/Atoms.h @@ -164,7 +164,6 @@ public: _ordinal(ordinal) {} virtual uint64_t ordinal() const { return _ordinal; } - uint64_t originalOffset() const { return _symbol->Value; } virtual StringRef getSectionName() const { return _sectionName; } static bool classof(const COFFBaseDefinedAtom *atom) { diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index 4212857..c9cd43d 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -268,8 +268,10 @@ private: // Create an atom for the entire section. if (symbols.empty()) { ArrayRef Data(secData.data(), secData.size()); - atoms.push_back(new (_alloc) COFFDefinedAtom( - *this, "", nullptr, section, Data, sectionName, 0)); + auto *atom = new (_alloc) COFFDefinedAtom(*this, "", nullptr, section, + Data, sectionName, 0); + atoms.push_back(atom); + _definedAtomLocations[section][0] = atom; return error_code::success(); } @@ -278,8 +280,10 @@ private: if (symbols[0]->Value != 0) { uint64_t size = symbols[0]->Value; ArrayRef data(secData.data(), size); - atoms.push_back(new (_alloc) COFFDefinedAtom( - *this, "", nullptr, section, data, sectionName, ++ordinal)); + auto *atom = new (_alloc) COFFDefinedAtom( + *this, "", nullptr, section, data, sectionName, ++ordinal); + atoms.push_back(atom); + _definedAtomLocations[section][0] = atom; } for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) { @@ -293,6 +297,7 @@ private: *this, _symbolName[*si], *si, section, data, sectionName, ++ordinal); atoms.push_back(atom); _symbolAtom[*si] = atom; + _definedAtomLocations[section][(*si)->Value] = atom; } return error_code::success(); } @@ -320,14 +325,16 @@ private: return error_code::success(); } - /// Find the atom that is at \p targetOffset in \p section. It is assumed - /// that \p atoms are sorted by position in the section. - error_code findAtomAt(uint32_t targetOffset, - const vector &atoms, - COFFDefinedFileAtom *&result) const { - for (COFFDefinedFileAtom *atom : atoms) { - if (targetOffset < atom->originalOffset() + atom->size()) { + /// Find the atom that is at \p targetAddress in \p section. + error_code findAtomAt(const coff_section *section, uint32_t targetAddress, + COFFDefinedFileAtom *&result, uint32_t &offsetInAtom) { + for (auto i : _definedAtomLocations[section]) { + uint32_t atomAddress = i.first; + COFFDefinedAtom *atom = i.second; + if (atomAddress <= targetAddress && + targetAddress < atomAddress + atom->size()) { result = atom; + offsetInAtom = targetAddress - atomAddress; return error_code::success(); } } @@ -364,10 +371,9 @@ private: return ec; COFFDefinedFileAtom *atom; - if (error_code ec = findAtomAt(rel->VirtualAddress, atoms, atom)) + uint32_t offsetInAtom; + if (error_code ec = findAtomAt(section, itemAddress, atom, offsetInAtom)) return ec; - uint32_t offsetInAtom = itemAddress - atom->originalOffset(); - assert(offsetInAtom < atom->size()); atom->addReference(std::unique_ptr( new COFFReference(targetAtom, offsetInAtom, rel->Type))); return error_code::success(); @@ -470,6 +476,11 @@ private: // A map from section to its atoms. std::map> _sectionAtoms; + // A sorted map to find an atom from a section and an offset within + // the section. + std::map> _definedAtomLocations; + mutable llvm::BumpPtrAllocator _alloc; const TargetInfo &_targetInfo; }; -- 2.7.4