Move more logic to getSymVA to avoid code duplication.

llvm-svn: 248599
This commit is contained in:
Rafael Espindola
2015-09-25 18:19:03 +00:00
parent f743b838cb
commit cd076f0113
4 changed files with 48 additions and 53 deletions

View File

@@ -47,42 +47,22 @@ void InputSection<ELFT>::relocate(
continue;
SymVA = getLocalSymVA(Sym, File);
} else {
const SymbolBody *Body = File.getSymbolBody(SymIndex);
if (!Body)
continue;
uint32_t OrigType = Type;
switch (Body->kind()) {
case SymbolBody::DefinedRegularKind:
SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
break;
case SymbolBody::DefinedAbsoluteKind:
SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;
break;
case SymbolBody::DefinedCommonKind: {
auto *DC = cast<DefinedCommon<ELFT>>(Body);
SymVA = BssSec.getVA() + DC->OffsetInBSS;
break;
}
case SymbolBody::SharedKind:
const auto &Body =
*cast<ELFSymbolBody<ELFT>>(File.getSymbolBody(SymIndex));
SymVA = getSymVA<ELFT>(Body, BssSec);
if (Target->relocNeedsPlt(Type))
SymVA = PltSec.getEntryAddr(Body);
else if (Target->relocNeedsGot(Type))
SymVA = GotSec.getEntryAddr(Body);
if (Body.kind() == SymbolBody::SharedKind) {
if (Target->relocNeedsPlt(Type))
Type = Target->getPCRelReloc();
else if (Target->relocNeedsGot(Type))
Type = Target->getPCRelReloc();
else
continue;
break;
case SymbolBody::UndefinedKind:
assert(Body->isWeak() && "Undefined symbol reached writer");
SymVA = 0;
break;
case SymbolBody::LazyKind:
llvm_unreachable("Lazy symbol reached writer");
}
if (Target->relocNeedsPlt(OrigType))
SymVA = PltSec.getEntryAddr(*Body);
else if (Target->relocNeedsGot(OrigType))
SymVA = GotSec.getEntryAddr(*Body);
}
Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,

View File

@@ -292,10 +292,25 @@ void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) {
template <class ELFT>
typename ELFFile<ELFT>::uintX_t
lld::elf2::getSymVA(const DefinedRegular<ELFT> *DR) {
const InputSection<ELFT> *SC = &DR->Section;
OutputSection<ELFT> *OS = SC->getOutputSection();
return OS->getVA() + SC->getOutputSectionOff() + DR->Sym.st_value;
lld::elf2::getSymVA(const ELFSymbolBody<ELFT> &S,
const OutputSection<ELFT> &BssSec) {
switch (S.kind()) {
case SymbolBody::DefinedAbsoluteKind:
return S.Sym.st_value;
case SymbolBody::DefinedRegularKind: {
const auto &DR = cast<DefinedRegular<ELFT>>(S);
const InputSection<ELFT> *SC = &DR.Section;
OutputSection<ELFT> *OS = SC->getOutputSection();
return OS->getVA() + SC->getOutputSectionOff() + DR.Sym.st_value;
}
case SymbolBody::DefinedCommonKind:
return BssSec.getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS;
case SymbolBody::SharedKind:
case SymbolBody::UndefinedKind:
return 0;
case SymbolBody::LazyKind:
llvm_unreachable("Lazy symbol reached writer");
}
}
template <class ELFT>
@@ -410,16 +425,17 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
continue;
const Elf_Sym &InputSym = cast<ELFSymbolBody<ELFT>>(Body)->Sym;
const auto &EBody = *cast<ELFSymbolBody<ELFT>>(Body);
const Elf_Sym &InputSym = EBody.Sym;
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
ESym->st_name = StrTabSec.getFileOff(Name);
const OutputSection<ELFT> *Out = nullptr;
const InputSection<ELFT> *Section = nullptr;
switch (Body->kind()) {
switch (EBody.kind()) {
case SymbolBody::DefinedRegularKind:
Section = &cast<DefinedRegular<ELFT>>(Body)->Section;
Section = &cast<DefinedRegular<ELFT>>(EBody).Section;
break;
case SymbolBody::DefinedCommonKind:
Out = &BssSec;
@@ -434,7 +450,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
ESym->setBindingAndType(InputSym.getBinding(), InputSym.getType());
ESym->st_size = InputSym.st_size;
ESym->setVisibility(Body->getMostConstrainingVisibility());
ESym->setVisibility(EBody.getMostConstrainingVisibility());
if (InputSym.isAbsolute()) {
ESym->st_shndx = SHN_ABS;
ESym->st_value = InputSym.st_value;
@@ -443,17 +459,10 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
if (Section)
Out = Section->getOutputSection();
if (Out) {
ESym->st_value = getSymVA(EBody, BssSec);
if (Out)
ESym->st_shndx = Out->getSectionIndex();
uintX_t VA = Out->getVA();
if (Section)
VA += Section->getOutputSectionOff();
if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
VA += C->OffsetInBSS;
else
VA += InputSym.st_value;
ESym->st_value = VA;
}
Buf += sizeof(Elf_Sym);
}
@@ -514,13 +523,17 @@ template class SymbolTableSection<ELF32BE>;
template class SymbolTableSection<ELF64LE>;
template class SymbolTableSection<ELF64BE>;
template ELFFile<ELF32LE>::uintX_t getSymVA(const DefinedRegular<ELF32LE> *DR);
template ELFFile<ELF32LE>::uintX_t
getSymVA(const ELFSymbolBody<ELF32LE> &S, const OutputSection<ELF32LE> &BssSec);
template ELFFile<ELF32BE>::uintX_t getSymVA(const DefinedRegular<ELF32BE> *DR);
template ELFFile<ELF32BE>::uintX_t
getSymVA(const ELFSymbolBody<ELF32BE> &S, const OutputSection<ELF32BE> &BssSec);
template ELFFile<ELF64LE>::uintX_t getSymVA(const DefinedRegular<ELF64LE> *DR);
template ELFFile<ELF64LE>::uintX_t
getSymVA(const ELFSymbolBody<ELF64LE> &S, const OutputSection<ELF64LE> &BssSec);
template ELFFile<ELF64BE>::uintX_t getSymVA(const DefinedRegular<ELF64BE> *DR);
template ELFFile<ELF64BE>::uintX_t
getSymVA(const ELFSymbolBody<ELF64BE> &S, const OutputSection<ELF64BE> &BssSec);
template ELFFile<ELF32LE>::uintX_t
getLocalSymVA(const ELFFile<ELF32LE>::Elf_Sym *Sym,

View File

@@ -30,10 +30,11 @@ template <class ELFT> class InputSection;
template <class ELFT> class OutputSection;
template <class ELFT> class ObjectFile;
template <class ELFT> class DefinedRegular;
template <class ELFT> class ELFSymbolBody;
template <class ELFT>
typename llvm::object::ELFFile<ELFT>::uintX_t
getSymVA(const DefinedRegular<ELFT> *DR);
getSymVA(const ELFSymbolBody<ELFT> &S, const OutputSection<ELFT> &BssSec);
template <class ELFT>
typename llvm::object::ELFFile<ELFT>::uintX_t

View File

@@ -495,7 +495,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_machine = FirstObj.getEMachine();
EHdr->e_version = EV_CURRENT;
SymbolBody *Entry = Symtab.getEntrySym();
EHdr->e_entry = Entry ? getSymVA(cast<DefinedRegular<ELFT>>(Entry)) : 0;
EHdr->e_entry =
Entry ? getSymVA(cast<ELFSymbolBody<ELFT>>(*Entry), BssSec) : 0;
EHdr->e_phoff = ProgramHeaderOff;
EHdr->e_shoff = SectionHeaderOff;
EHdr->e_ehsize = sizeof(Elf_Ehdr);