[ELF][Layout] Provide a proper way to get the TLS segment size.

llvm-svn: 174427
This commit is contained in:
Michael J. Spencer 2013-02-05 19:14:43 +00:00
parent 359b6ff6bb
commit 7fec00b20e
2 changed files with 13 additions and 13 deletions

View File

@ -247,6 +247,13 @@ public:
return _relocationTable; return _relocationTable;
} }
uint64_t getTLSSize() const {
for (const auto &phdr : *_programHeader)
if (phdr->p_type == llvm::ELF::PT_TLS)
return phdr->p_memsz;
return 0;
}
private: private:
SectionMapT _sectionMap; SectionMapT _sectionMap;
MergedSectionMapT _mergedSectionMap; MergedSectionMapT _mergedSectionMap;
@ -316,6 +323,10 @@ StringRef DefaultLayout<ELFT>::getSectionName(
return ".text"; return ".text";
if (name.startswith(".rodata")) if (name.startswith(".rodata"))
return ".rodata"; return ".rodata";
if (name.startswith(".tdata"))
return ".tdata";
if (name.startswith(".tbss"))
return ".tbss";
return name; return name;
} }

View File

@ -78,19 +78,8 @@ ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
case R_X86_64_TPOFF64: case R_X86_64_TPOFF64:
case R_X86_64_DTPOFF32: case R_X86_64_DTPOFF32:
case R_X86_64_TPOFF32: { case R_X86_64_TPOFF32: {
// Get the start and end of the TLS segment. _tlsSize = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
if (_tlsSize == 0) { .getTLSSize();
auto tdata = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
.findOutputSection(".tdata");
auto tbss = _targetInfo.getTargetHandler<X86_64ELFType>().targetLayout()
.findOutputSection(".tbss");
// HACK: The tdata and tbss sections end up together to from the TLS
// segment. This should actually use the TLS program header entry.
if (tdata)
_tlsSize = tdata->memSize();
if (tbss)
_tlsSize += tbss->memSize();
}
if (ref.kind() == R_X86_64_TPOFF32 || ref.kind() == R_X86_64_DTPOFF32) { if (ref.kind() == R_X86_64_TPOFF32 || ref.kind() == R_X86_64_DTPOFF32) {
int32_t result = (int32_t)(targetVAddress - _tlsSize); int32_t result = (int32_t)(targetVAddress - _tlsSize);
*reinterpret_cast<llvm::support::little32_t *>(location) = result; *reinterpret_cast<llvm::support::little32_t *>(location) = result;