[ELF] Cache contentType and permissions.

llvm-svn: 178269
This commit is contained in:
Michael J. Spencer 2013-03-28 18:58:50 +00:00
parent 1067ff61e6
commit 8759beb424
2 changed files with 31 additions and 18 deletions

View File

@ -179,7 +179,9 @@ public:
, _referenceStartIndex(referenceStart)
, _referenceEndIndex(referenceEnd)
, _referenceList(referenceList)
, _targetAtomHandler(nullptr) {}
, _targetAtomHandler(nullptr)
, _contentType(typeUnknown)
, _permissions(permUnknown) {}
virtual const ELFFile<ELFT> &file() const {
return _owningFile;
@ -260,6 +262,9 @@ public:
}
virtual ContentType contentType() const {
if (_contentType != typeUnknown)
return _contentType;
ContentType ret = typeUnknown;
uint64_t flags = _section->sh_flags;
@ -272,20 +277,20 @@ public:
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}
return _targetAtomHandler->contentType(this);
return _contentType = _targetAtomHandler->contentType(this);
}
if (_section->sh_flags ==
(llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS)) {
return _section->sh_type == llvm::ELF::SHT_NOBITS ? typeTLVInitialZeroFill
return _contentType = _section->sh_type == llvm::ELF::SHT_NOBITS ? typeTLVInitialZeroFill
: typeTLVInitialData;
}
if (_symbol->getType() == llvm::ELF::STT_GNU_IFUNC)
return typeResolver;
return _contentType = typeResolver;
if (_symbol->st_shndx == llvm::ELF::SHN_COMMON)
return typeZeroFill;
return _contentType = typeZeroFill;
switch (_section->sh_type) {
case llvm::ELF::SHT_PROGBITS:
@ -321,7 +326,7 @@ public:
break;
}
return ret;
return _contentType = ret;
}
virtual Alignment alignment() const {
@ -374,6 +379,9 @@ public:
}
virtual ContentPermissions permissions() const {
if (_permissions != permUnknown)
return _permissions;
uint64_t flags = _section->sh_flags;
// Treat target defined symbols
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
@ -383,14 +391,14 @@ public:
TargetHandler<ELFT> &TargetHandler = eti.getTargetHandler<ELFT>();
_targetAtomHandler = &TargetHandler.targetAtomHandler();
}
return (_targetAtomHandler->contentPermissions(this));
return _permissions = _targetAtomHandler->contentPermissions(this);
}
switch (_section->sh_type) {
// permRW_L is for sections modified by the runtime
// loader.
case llvm::ELF::SHT_REL:
case llvm::ELF::SHT_RELA:
return permRW_L;
return _permissions = permRW_L;
case llvm::ELF::SHT_DYNAMIC:
case llvm::ELF::SHT_PROGBITS:
@ -399,31 +407,31 @@ public:
switch (flags) {
// Code
case llvm::ELF::SHF_EXECINSTR:
return permR_X;
return _permissions = permR_X;
case (llvm::ELF::SHF_WRITE|llvm::ELF::SHF_EXECINSTR):
return permRWX;
return _permissions = permRWX;
// Data
case llvm::ELF::SHF_WRITE:
return permRW_;
return _permissions = permRW_;
// Strings
case llvm::ELF::SHF_MERGE:
case llvm::ELF::SHF_STRINGS:
return permR__;
return _permissions = permR__;
default:
if (flags & llvm::ELF::SHF_WRITE)
return permRW_;
return permR__;
return _permissions = permRW_;
return _permissions = permR__;
}
case llvm::ELF::SHT_NOBITS:
return permRW_;
return _permissions = permRW_;
case llvm::ELF::SHT_INIT_ARRAY:
return permRW_;
return _permissions = permRW_;
default:
return perm___;
return _permissions = perm___;
}
}
@ -489,6 +497,8 @@ private:
std::vector<ELFReference<ELFT> *> &_referenceList;
// Cached size of the TLS segment.
mutable TargetAtomHandler<ELFT> *_targetAtomHandler;
mutable ContentType _contentType;
mutable ContentPermissions _permissions;
};
/// \brief This atom stores mergeable Strings

View File

@ -598,9 +598,12 @@ private:
}
// Create the DefinedAtom and add it to the list of DefinedAtoms.
return new (_readerStorage) ELFDefinedAtom<
auto ret = new (_readerStorage) ELFDefinedAtom<
ELFT>(*this, symbolName, sectionName, symbol, section, content,
referenceStart, _references.size(), _references);
ret->permissions();
ret->contentType();
return ret;
}
llvm::BumpPtrAllocator _readerStorage;