forked from OSchip/llvm-project
Recommit r275161 "[ELF] - Move section factory out from writer to make it reusable."
With fix: * fixed compilation error under linux: template <class ELFT> class OutputSectionFactory { ... typedef typename SectionKey<ELFT::Is64Bits> Key; changed to: template <class ELFT> class OutputSectionFactory { ... typedef typename elf::SectionKey<ELFT::Is64Bits> Key; llvm-svn: 275166
This commit is contained in:
parent
dc15f1d7b8
commit
6892afaa2d
|
@ -1751,6 +1751,92 @@ void MipsOptionsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
|
|||
S->OutSec = this;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::pair<OutputSectionBase<ELFT> *, bool>
|
||||
OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName) {
|
||||
SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
|
||||
OutputSectionBase<ELFT> *&Sec = Map[Key];
|
||||
if (Sec)
|
||||
return {Sec, false};
|
||||
|
||||
switch (C->SectionKind) {
|
||||
case InputSectionBase<ELFT>::Regular:
|
||||
Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
|
||||
break;
|
||||
case InputSectionBase<ELFT>::EHFrame:
|
||||
return {Out<ELFT>::EhFrame, false};
|
||||
case InputSectionBase<ELFT>::Merge:
|
||||
Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags,
|
||||
Key.Alignment);
|
||||
break;
|
||||
case InputSectionBase<ELFT>::MipsReginfo:
|
||||
Sec = new MipsReginfoOutputSection<ELFT>();
|
||||
break;
|
||||
case InputSectionBase<ELFT>::MipsOptions:
|
||||
Sec = new MipsOptionsOutputSection<ELFT>();
|
||||
break;
|
||||
}
|
||||
return {Sec, true};
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
OutputSectionBase<ELFT> *OutputSectionFactory<ELFT>::lookup(StringRef Name,
|
||||
uint32_t Type,
|
||||
uintX_t Flags) {
|
||||
return Map.lookup({Name, Type, Flags, 0});
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
SectionKey<ELFT::Is64Bits>
|
||||
OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName) {
|
||||
const Elf_Shdr *H = C->getSectionHdr();
|
||||
uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED;
|
||||
|
||||
// For SHF_MERGE we create different output sections for each alignment.
|
||||
// This makes each output section simple and keeps a single level mapping from
|
||||
// input to output.
|
||||
uintX_t Alignment = 0;
|
||||
if (isa<MergeInputSection<ELFT>>(C))
|
||||
Alignment = std::max(H->sh_addralign, H->sh_entsize);
|
||||
|
||||
uint32_t Type = H->sh_type;
|
||||
return SectionKey<ELFT::Is64Bits>{OutsecName, Type, Flags, Alignment};
|
||||
}
|
||||
|
||||
template <bool Is64Bits>
|
||||
typename lld::elf::SectionKey<Is64Bits>
|
||||
DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getEmptyKey() {
|
||||
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0, 0};
|
||||
}
|
||||
|
||||
template <bool Is64Bits>
|
||||
typename lld::elf::SectionKey<Is64Bits>
|
||||
DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getTombstoneKey() {
|
||||
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 0,
|
||||
0};
|
||||
}
|
||||
|
||||
template <bool Is64Bits>
|
||||
unsigned
|
||||
DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getHashValue(const Key &Val) {
|
||||
return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment);
|
||||
}
|
||||
|
||||
template <bool Is64Bits>
|
||||
bool DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::isEqual(const Key &LHS,
|
||||
const Key &RHS) {
|
||||
return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) &&
|
||||
LHS.Type == RHS.Type && LHS.Flags == RHS.Flags &&
|
||||
LHS.Alignment == RHS.Alignment;
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
template struct DenseMapInfo<SectionKey<true>>;
|
||||
template struct DenseMapInfo<SectionKey<false>>;
|
||||
}
|
||||
|
||||
namespace lld {
|
||||
namespace elf {
|
||||
template class OutputSectionBase<ELF32LE>;
|
||||
|
@ -1877,5 +1963,10 @@ template class BuildIdHexstring<ELF32LE>;
|
|||
template class BuildIdHexstring<ELF32BE>;
|
||||
template class BuildIdHexstring<ELF64LE>;
|
||||
template class BuildIdHexstring<ELF64BE>;
|
||||
|
||||
template class OutputSectionFactory<ELF32LE>;
|
||||
template class OutputSectionFactory<ELF32BE>;
|
||||
template class OutputSectionFactory<ELF64LE>;
|
||||
template class OutputSectionFactory<ELF64BE>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -661,6 +661,35 @@ template <class ELFT> struct Out {
|
|||
static OutputSectionBase<ELFT> *ProgramHeaders;
|
||||
};
|
||||
|
||||
template <bool Is64Bits> struct SectionKey {
|
||||
typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
|
||||
StringRef Name;
|
||||
uint32_t Type;
|
||||
uintX_t Flags;
|
||||
uintX_t Alignment;
|
||||
};
|
||||
|
||||
// This class knows how to create an output section for a given
|
||||
// input section. Output section type is determined by various
|
||||
// factors, including input section's sh_flags, sh_type and
|
||||
// linker scripts.
|
||||
template <class ELFT> class OutputSectionFactory {
|
||||
typedef typename ELFT::Shdr Elf_Shdr;
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
typedef typename elf::SectionKey<ELFT::Is64Bits> Key;
|
||||
|
||||
public:
|
||||
std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName);
|
||||
|
||||
OutputSectionBase<ELFT> *lookup(StringRef Name, uint32_t Type, uintX_t Flags);
|
||||
|
||||
private:
|
||||
Key createKey(InputSectionBase<ELFT> *C, StringRef OutsecName);
|
||||
|
||||
llvm::SmallDenseMap<Key, OutputSectionBase<ELFT> *> Map;
|
||||
};
|
||||
|
||||
template <class ELFT> BuildIdSection<ELFT> *Out<ELFT>::BuildId;
|
||||
template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
|
||||
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
|
||||
|
@ -692,4 +721,15 @@ template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ProgramHeaders;
|
|||
} // namespace elf
|
||||
} // namespace lld
|
||||
|
||||
#endif // LLD_ELF_OUTPUT_SECTIONS_H
|
||||
namespace llvm {
|
||||
template <bool Is64Bits> struct DenseMapInfo<lld::elf::SectionKey<Is64Bits>> {
|
||||
typedef typename lld::elf::SectionKey<Is64Bits> Key;
|
||||
|
||||
static Key getEmptyKey();
|
||||
static Key getTombstoneKey();
|
||||
static unsigned getHashValue(const Key &Val);
|
||||
static bool isEqual(const Key &LHS, const Key &RHS);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -264,37 +264,6 @@ template <class ELFT> void Writer<ELFT>::run() {
|
|||
check(Buffer->commit());
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <bool Is64Bits> struct SectionKey {
|
||||
typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
|
||||
StringRef Name;
|
||||
uint32_t Type;
|
||||
uintX_t Flags;
|
||||
uintX_t Alignment;
|
||||
};
|
||||
}
|
||||
namespace llvm {
|
||||
template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> {
|
||||
static SectionKey<Is64Bits> getEmptyKey() {
|
||||
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0,
|
||||
0};
|
||||
}
|
||||
static SectionKey<Is64Bits> getTombstoneKey() {
|
||||
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0,
|
||||
0, 0};
|
||||
}
|
||||
static unsigned getHashValue(const SectionKey<Is64Bits> &Val) {
|
||||
return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment);
|
||||
}
|
||||
static bool isEqual(const SectionKey<Is64Bits> &LHS,
|
||||
const SectionKey<Is64Bits> &RHS) {
|
||||
return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) &&
|
||||
LHS.Type == RHS.Type && LHS.Flags == RHS.Flags &&
|
||||
LHS.Alignment == RHS.Alignment;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
|
||||
if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
|
||||
|
@ -555,79 +524,6 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
|
|||
DefinedSynthetic<ELFT>::SectionEnd);
|
||||
}
|
||||
|
||||
// This class knows how to create an output section for a given
|
||||
// input section. Output section type is determined by various
|
||||
// factors, including input section's sh_flags, sh_type and
|
||||
// linker scripts.
|
||||
namespace {
|
||||
template <class ELFT> class OutputSectionFactory {
|
||||
typedef typename ELFT::Shdr Elf_Shdr;
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName);
|
||||
|
||||
OutputSectionBase<ELFT> *lookup(StringRef Name, uint32_t Type,
|
||||
uintX_t Flags) {
|
||||
return Map.lookup({Name, Type, Flags, 0});
|
||||
}
|
||||
|
||||
private:
|
||||
SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName);
|
||||
|
||||
SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSectionBase<ELFT> *> Map;
|
||||
};
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::pair<OutputSectionBase<ELFT> *, bool>
|
||||
OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName) {
|
||||
SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
|
||||
OutputSectionBase<ELFT> *&Sec = Map[Key];
|
||||
if (Sec)
|
||||
return {Sec, false};
|
||||
|
||||
switch (C->SectionKind) {
|
||||
case InputSectionBase<ELFT>::Regular:
|
||||
Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
|
||||
break;
|
||||
case InputSectionBase<ELFT>::EHFrame:
|
||||
return {Out<ELFT>::EhFrame, false};
|
||||
case InputSectionBase<ELFT>::Merge:
|
||||
Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags,
|
||||
Key.Alignment);
|
||||
break;
|
||||
case InputSectionBase<ELFT>::MipsReginfo:
|
||||
Sec = new MipsReginfoOutputSection<ELFT>();
|
||||
break;
|
||||
case InputSectionBase<ELFT>::MipsOptions:
|
||||
Sec = new MipsOptionsOutputSection<ELFT>();
|
||||
break;
|
||||
}
|
||||
return {Sec, true};
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
SectionKey<ELFT::Is64Bits>
|
||||
OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *C,
|
||||
StringRef OutsecName) {
|
||||
const Elf_Shdr *H = C->getSectionHdr();
|
||||
uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED;
|
||||
|
||||
// For SHF_MERGE we create different output sections for each alignment.
|
||||
// This makes each output section simple and keeps a single level mapping from
|
||||
// input to output.
|
||||
uintX_t Alignment = 0;
|
||||
if (isa<MergeInputSection<ELFT>>(C))
|
||||
Alignment = std::max(H->sh_addralign, H->sh_entsize);
|
||||
|
||||
uint32_t Type = H->sh_type;
|
||||
return SectionKey<ELFT::Is64Bits>{OutsecName, Type, Flags, Alignment};
|
||||
}
|
||||
|
||||
// The linker is expected to define some symbols depending on
|
||||
// the linking result. This function defines such symbols.
|
||||
template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
|
||||
|
|
Loading…
Reference in New Issue