summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2013-08-28 22:27:05 +0000
committerRui Ueyama <ruiu@google.com>2013-08-28 22:27:05 +0000
commit184a4b83d801e13b83596f40194c34bdf73242eb (patch)
tree5be43bb9b4ac826477f178ef43443c862f795002
parent38874731f6e16d860d5916a197a99304c14a05d6 (diff)
downloadbcm5719-llvm-184a4b83d801e13b83596f40194c34bdf73242eb.tar.gz
bcm5719-llvm-184a4b83d801e13b83596f40194c34bdf73242eb.zip
[PECOFF] Do not scan the symbol table twice but instead cache aux symbols.
We scanned the symbol table twice; first to gather all regular symbols, and second to process aux symbols. That's a bit inefficient and complicated. We can instead cache aux symbols in the first pass, to eliminate the need of the second pass. llvm-svn: 189525
-rw-r--r--lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp33
1 files changed, 19 insertions, 14 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
index 1e1f559e5f5..144fbdc090d 100644
--- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
@@ -187,8 +187,18 @@ private:
return ec;
_symbolName[sym] = name;
- // Skip aux symbols.
- i += sym->NumberOfAuxSymbols;
+ // Symbol may be followed by auxiliary symbol table records. The aux
+ // record can be in any format, but the size is always the same as the
+ // regular symbol. The aux record supplies additional information for the
+ // standard symbol. We do not interpret the aux record here, but just
+ // store it to _auxSymbol.
+ if (sym->NumberOfAuxSymbols > 0) {
+ const coff_symbol *aux = nullptr;
+ if (error_code ec = _obj->getAuxSymbol(i + 1, aux))
+ return ec;
+ _auxSymbol[sym] = aux;
+ i += sym->NumberOfAuxSymbols;
+ }
}
return error_code::success();
}
@@ -304,18 +314,12 @@ private:
// Cache the COMDAT attributes, which indicate whether the symbols in the
// section can be merged or not.
error_code cacheSectionAttributes() {
- const llvm::object::coff_file_header *header = nullptr;
- if (error_code ec = _obj->getHeader(header))
- return ec;
-
// The COMDAT section attribute is not an attribute of coff_section, but is
// stored in the auxiliary symbol for the first symbol referring a COMDAT
// section. It feels to me that it's unnecessarily complicated, but this is
// how COFF works.
- for (uint32_t i = 0, e = header->NumberOfSymbols; i != e; ++i) {
- const coff_symbol *sym;
- if (error_code ec = _obj->getSymbol(i, sym))
- return ec;
+ for (auto i : _auxSymbol) {
+ const coff_symbol *sym = i.first;
if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE ||
sym->SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED)
continue;
@@ -331,10 +335,8 @@ private:
if (sym->NumberOfAuxSymbols == 0)
return llvm::object::object_error::parse_failed;
- const coff_aux_section_definition *aux = nullptr;
- if (error_code ec = _obj->getAuxSymbol(i + 1, aux))
- return ec;
-
+ const coff_aux_section_definition *aux = reinterpret_cast<
+ const coff_aux_section_definition *>(i.second);
_merge[sec] = getMerge(aux);
}
@@ -619,6 +621,9 @@ private:
// A map from symbol to its resultant atom.
std::map<const coff_symbol *, Atom *> _symbolAtom;
+ // A map from symbol to its aux symbol.
+ std::map<const coff_symbol *, const coff_symbol *> _auxSymbol;
+
// A map from section to its atoms.
std::map<const coff_section *, vector<COFFDefinedFileAtom *>> _sectionAtoms;
OpenPOWER on IntegriCloud