mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
Move more logic to getSymVA to avoid code duplication.
llvm-svn: 248599
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user