Make it possible to create common symbols from bitcode.
Since the only missing bit was the size, I just replaced the Elf_Sym with the size. llvm-svn: 256384
This commit is contained in:
parent
02ce26a1b4
commit
1119191c4f
@ -286,7 +286,9 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
|
||||
case SHN_UNDEF:
|
||||
return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym);
|
||||
case SHN_COMMON:
|
||||
return new (this->Alloc) DefinedCommon<ELFT>(Name, *Sym);
|
||||
return new (this->Alloc) DefinedCommon(
|
||||
Name, Sym->st_size, Sym->st_value,
|
||||
Sym->getBinding() == llvm::ELF::STB_WEAK, Sym->getVisibility());
|
||||
}
|
||||
|
||||
switch (Sym->getBinding()) {
|
||||
|
||||
@ -800,7 +800,7 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) {
|
||||
return SC->OutSec->getVA() + SC->getOffset(DR.Sym);
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
return Out<ELFT>::Bss->getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS;
|
||||
return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(S).OffsetInBSS;
|
||||
case SymbolBody::SharedKind: {
|
||||
auto &SS = cast<SharedSymbol<ELFT>>(S);
|
||||
if (SS.NeedsCopy)
|
||||
@ -1370,6 +1370,9 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
|
||||
if (const Elf_Sym *InputSym = getElfSym<ELFT>(*Body)) {
|
||||
Type = InputSym->getType();
|
||||
Size = InputSym->st_size;
|
||||
} else if (auto *C = dyn_cast<DefinedCommon>(Body)) {
|
||||
Type = STT_OBJECT;
|
||||
Size = C->Size;
|
||||
}
|
||||
|
||||
ESym->setBindingAndType(getSymbolBinding(Body), Type);
|
||||
|
||||
@ -58,10 +58,10 @@ template <class ELFT> int SymbolBody::compare(SymbolBody *Other) {
|
||||
if (isCommon()) {
|
||||
if (!Other->isCommon())
|
||||
return -1;
|
||||
auto *ThisC = cast<DefinedCommon<ELFT>>(this);
|
||||
auto *OtherC = cast<DefinedCommon<ELFT>>(Other);
|
||||
auto *ThisC = cast<DefinedCommon>(this);
|
||||
auto *OtherC = cast<DefinedCommon>(Other);
|
||||
uintX_t Align = std::max(ThisC->MaxAlignment, OtherC->MaxAlignment);
|
||||
if (ThisC->Sym.st_size >= OtherC->Sym.st_size) {
|
||||
if (ThisC->Size >= OtherC->Size) {
|
||||
ThisC->MaxAlignment = Align;
|
||||
return 1;
|
||||
}
|
||||
@ -101,6 +101,13 @@ DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
|
||||
: Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT, false),
|
||||
Value(Value), Section(Section) {}
|
||||
|
||||
DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
|
||||
bool IsWeak, uint8_t Visibility)
|
||||
: Defined(SymbolBody::DefinedCommonKind, N, IsWeak, Visibility, false) {
|
||||
MaxAlignment = Alignment;
|
||||
this->Size = Size;
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> Lazy::getMember() {
|
||||
MemoryBufferRef MBRef = File->getMember(&Sym);
|
||||
|
||||
|
||||
@ -57,9 +57,9 @@ public:
|
||||
enum Kind {
|
||||
DefinedFirst,
|
||||
DefinedRegularKind = DefinedFirst,
|
||||
DefinedCommonKind,
|
||||
SharedKind,
|
||||
DefinedElfLast = SharedKind,
|
||||
DefinedCommonKind,
|
||||
DefinedSyntheticKind,
|
||||
DefinedLast = DefinedSyntheticKind,
|
||||
UndefinedElfKind,
|
||||
@ -154,15 +154,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <class ELFT> class DefinedCommon : public DefinedElf<ELFT> {
|
||||
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
|
||||
|
||||
class DefinedCommon : public Defined {
|
||||
public:
|
||||
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
|
||||
DefinedCommon(StringRef N, const Elf_Sym &Sym)
|
||||
: DefinedElf<ELFT>(SymbolBody::DefinedCommonKind, N, Sym) {
|
||||
MaxAlignment = Sym.st_value;
|
||||
}
|
||||
DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, bool IsWeak,
|
||||
uint8_t Visibility);
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == SymbolBody::DefinedCommonKind;
|
||||
@ -170,10 +165,12 @@ public:
|
||||
|
||||
// The output offset of this common symbol in the output bss. Computed by the
|
||||
// writer.
|
||||
uintX_t OffsetInBSS;
|
||||
uint64_t OffsetInBSS;
|
||||
|
||||
// The maximum alignment we have seen for this symbol.
|
||||
uintX_t MaxAlignment;
|
||||
uint64_t MaxAlignment;
|
||||
|
||||
uint64_t Size;
|
||||
};
|
||||
|
||||
// Regular defined symbols read from object file symbol tables.
|
||||
|
||||
@ -65,7 +65,7 @@ private:
|
||||
int getPhdrsNum() const;
|
||||
|
||||
OutputSection<ELFT> *getBSS();
|
||||
void addCommonSymbols(std::vector<DefinedCommon<ELFT> *> &Syms);
|
||||
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
|
||||
void addSharedCopySymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
|
||||
|
||||
std::unique_ptr<llvm::FileOutputBuffer> Buffer;
|
||||
@ -472,27 +472,24 @@ template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBSS() {
|
||||
// Until this function is called, common symbols do not belong to any section.
|
||||
// This function adds them to end of BSS section.
|
||||
template <class ELFT>
|
||||
void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon<ELFT> *> &Syms) {
|
||||
void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) {
|
||||
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
|
||||
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
|
||||
|
||||
if (Syms.empty())
|
||||
return;
|
||||
|
||||
// Sort the common symbols by alignment as an heuristic to pack them better.
|
||||
std::stable_sort(
|
||||
Syms.begin(), Syms.end(),
|
||||
[](const DefinedCommon<ELFT> *A, const DefinedCommon<ELFT> *B) {
|
||||
return A->MaxAlignment > B->MaxAlignment;
|
||||
});
|
||||
std::stable_sort(Syms.begin(), Syms.end(),
|
||||
[](const DefinedCommon *A, const DefinedCommon *B) {
|
||||
return A->MaxAlignment > B->MaxAlignment;
|
||||
});
|
||||
|
||||
uintX_t Off = getBSS()->getSize();
|
||||
for (DefinedCommon<ELFT> *C : Syms) {
|
||||
const Elf_Sym &Sym = C->Sym;
|
||||
for (DefinedCommon *C : Syms) {
|
||||
uintX_t Align = C->MaxAlignment;
|
||||
Off = RoundUpToAlignment(Off, Align);
|
||||
C->OffsetInBSS = Off;
|
||||
Off += Sym.st_size;
|
||||
Off += C->Size;
|
||||
}
|
||||
|
||||
Out<ELFT>::Bss->setSize(Off);
|
||||
@ -751,7 +748,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
||||
|
||||
addIRelocMarkers<ELFT>(Symtab, isOutputDynamic());
|
||||
|
||||
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
|
||||
std::vector<DefinedCommon *> CommonSymbols;
|
||||
std::vector<SharedSymbol<ELFT> *> SharedCopySymbols;
|
||||
for (auto &P : Symtab.getSymbols()) {
|
||||
SymbolBody *Body = P.second->Body;
|
||||
@ -759,7 +756,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
||||
if (!U->isWeak() && !U->canKeepUndefined())
|
||||
reportUndefined<ELFT>(Symtab, *Body);
|
||||
|
||||
if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
|
||||
if (auto *C = dyn_cast<DefinedCommon>(Body))
|
||||
CommonSymbols.push_back(C);
|
||||
if (auto *SC = dyn_cast<SharedSymbol<ELFT>>(Body))
|
||||
if (SC->NeedsCopy)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user