parent
be61720c4e
commit
05a3dd2cba
|
@ -22,6 +22,7 @@ struct Configuration {
|
|||
bool Shared = false;
|
||||
bool DiscardAll = false;
|
||||
bool DiscardLocals = false;
|
||||
bool ExportDynamic = false;
|
||||
};
|
||||
|
||||
extern Configuration *Config;
|
||||
|
|
|
@ -88,6 +88,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
|||
if (Args.hasArg(OPT_discard_locals))
|
||||
Config->DiscardLocals = true;
|
||||
|
||||
if (Args.hasArg(OPT_export_dynamic))
|
||||
Config->ExportDynamic = true;
|
||||
|
||||
// Create a list of input files.
|
||||
std::vector<MemoryBufferRef> Inputs;
|
||||
|
||||
|
|
|
@ -27,3 +27,6 @@ def discard_locals : Flag<["-"], "discard-locals">,
|
|||
|
||||
def alias_discard_locals: Flag<["-"], "X">,
|
||||
Alias<discard_locals>;
|
||||
|
||||
def export_dynamic : Flag<["--"], "export-dynamic">,
|
||||
HelpText<"Put symbols in the dynamic symbol table">;
|
||||
|
|
|
@ -272,6 +272,12 @@ bool lld::elf2::includeInSymtab(const SymbolBody &B) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool lld::elf2::includeInDynamicSymtab(const SymbolBody &B) {
|
||||
if (Config->ExportDynamic || Config->Shared)
|
||||
return true;
|
||||
return B.isUsedInDynamicReloc();
|
||||
}
|
||||
|
||||
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
const OutputSection<ELFT> *Out = nullptr;
|
||||
const InputSection<ELFT> *Section = nullptr;
|
||||
|
@ -315,8 +321,10 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
SymbolBody *Body = Sym->Body;
|
||||
if (!includeInSymtab(*Body))
|
||||
continue;
|
||||
const Elf_Sym &InputSym = cast<ELFSymbolBody<ELFT>>(Body)->Sym;
|
||||
if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
|
||||
continue;
|
||||
|
||||
const Elf_Sym &InputSym = cast<ELFSymbolBody<ELFT>>(Body)->Sym;
|
||||
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
|
||||
ESym->st_name = StrTabSec.getFileOff(Name);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ getLocalSymVA(const typename llvm::object::ELFFile<ELFT>::Elf_Sym *Sym,
|
|||
const ObjectFile<ELFT> &File);
|
||||
|
||||
bool includeInSymtab(const SymbolBody &B);
|
||||
bool includeInDynamicSymtab(const SymbolBody &B);
|
||||
|
||||
// This represents a section in an output file.
|
||||
// Different sub classes represent different types of sections. Some contain
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
bool isLazy() const { return SymbolKind == LazyKind; }
|
||||
bool isShared() const { return SymbolKind == SharedKind; }
|
||||
bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
|
||||
bool isUsedInDynamicReloc() const { return IsUsedInDynamicReloc; }
|
||||
void setUsedInDynamicReloc() { IsUsedInDynamicReloc = true; }
|
||||
|
||||
// Returns the symbol name.
|
||||
StringRef getName() const { return Name; }
|
||||
|
@ -97,12 +99,14 @@ protected:
|
|||
: SymbolKind(K), IsWeak(IsWeak), MostConstrainingVisibility(Visibility),
|
||||
Name(Name) {
|
||||
IsUsedInRegularObj = K != SharedKind && K != LazyKind;
|
||||
IsUsedInDynamicReloc = 0;
|
||||
}
|
||||
|
||||
const unsigned SymbolKind : 8;
|
||||
const unsigned IsWeak : 1;
|
||||
unsigned MostConstrainingVisibility : 2;
|
||||
unsigned IsUsedInRegularObj : 1;
|
||||
unsigned IsUsedInDynamicReloc : 1;
|
||||
unsigned DynamicSymbolTableIndex = 0;
|
||||
unsigned GotIndex = -1;
|
||||
unsigned PltIndex = -1;
|
||||
|
|
|
@ -267,6 +267,7 @@ void Writer<ELFT>::scanRelocs(
|
|||
continue;
|
||||
GotSec.addEntry(Body);
|
||||
}
|
||||
S->setUsedInDynamicReloc();
|
||||
RelaDynSec.addReloc({C, RI});
|
||||
}
|
||||
}
|
||||
|
@ -302,28 +303,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
|||
return Sec;
|
||||
};
|
||||
|
||||
// FIXME: Try to avoid the extra walk over all global symbols.
|
||||
const SymbolTable &Symtab = SymTabSec.getSymTable();
|
||||
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
|
||||
for (auto &P : Symtab.getSymbols()) {
|
||||
StringRef Name = P.first;
|
||||
SymbolBody *Body = P.second->Body;
|
||||
if (Body->isStrongUndefined())
|
||||
error(Twine("undefined symbol: ") + Name);
|
||||
|
||||
if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
|
||||
CommonSymbols.push_back(C);
|
||||
if (!includeInSymtab(*Body))
|
||||
continue;
|
||||
SymTabSec.addSymbol(Name);
|
||||
|
||||
// FIXME: This adds way too much to the dynamic symbol table. We only
|
||||
// need to add the symbols use by dynamic relocations when producing
|
||||
// an executable (ignoring --export-dynamic).
|
||||
if (needsDynamicSections())
|
||||
HashSec.addSymbol(Body);
|
||||
}
|
||||
|
||||
for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.getObjectFiles()) {
|
||||
auto &File = cast<ObjectFile<ELFT>>(*FileB);
|
||||
if (!Config->DiscardAll) {
|
||||
|
@ -345,6 +325,24 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: Try to avoid the extra walk over all global symbols.
|
||||
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
|
||||
for (auto &P : Symtab.getSymbols()) {
|
||||
StringRef Name = P.first;
|
||||
SymbolBody *Body = P.second->Body;
|
||||
if (Body->isStrongUndefined())
|
||||
error(Twine("undefined symbol: ") + Name);
|
||||
|
||||
if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
|
||||
CommonSymbols.push_back(C);
|
||||
if (!includeInSymtab(*Body))
|
||||
continue;
|
||||
SymTabSec.addSymbol(Name);
|
||||
|
||||
if (needsDynamicSections() && includeInDynamicSymtab(*Body))
|
||||
HashSec.addSymbol(Body);
|
||||
}
|
||||
|
||||
BSSSec = getSection(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
||||
SymTabSec.setBssSec(BSSSec);
|
||||
DynSymSec.setBssSec(BSSSec);
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
|
||||
// RUN: lld -flavor gnu2 -shared %t2.o -o %t2.so
|
||||
// RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s
|
||||
// RUN: lld -flavor gnu2 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar %t.o %t2.so -o %t
|
||||
// RUN: lld -flavor gnu2 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
|
||||
// RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s
|
||||
// RUN: lld -flavor gnu2 %t.o %t2.so -o %t2
|
||||
// RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s
|
||||
// REQUIRES: x86
|
||||
|
||||
// Make sure .symtab is properly aligned.
|
||||
|
@ -195,6 +197,36 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
// DONT_EXPORT: DynamicSymbols [
|
||||
// DONT_EXPORT-NEXT: Symbol {
|
||||
// DONT_EXPORT-NEXT: Name: @ (0)
|
||||
// DONT_EXPORT-NEXT: Value: 0x0
|
||||
// DONT_EXPORT-NEXT: Size: 0
|
||||
// DONT_EXPORT-NEXT: Binding: Local (0x0)
|
||||
// DONT_EXPORT-NEXT: Type: None (0x0)
|
||||
// DONT_EXPORT-NEXT: Other: 0
|
||||
// DONT_EXPORT-NEXT: Section: Undefined (0x0)
|
||||
// DONT_EXPORT-NEXT: }
|
||||
// DONT_EXPORT-NEXT: Symbol {
|
||||
// DONT_EXPORT-NEXT: Name: bar@
|
||||
// DONT_EXPORT-NEXT: Value: 0x0
|
||||
// DONT_EXPORT-NEXT: Size: 0
|
||||
// DONT_EXPORT-NEXT: Binding: Global
|
||||
// DONT_EXPORT-NEXT: Type: Function
|
||||
// DONT_EXPORT-NEXT: Other: 0
|
||||
// DONT_EXPORT-NEXT: Section: Undefined
|
||||
// DONT_EXPORT-NEXT: }
|
||||
// DONT_EXPORT-NEXT: Symbol {
|
||||
// DONT_EXPORT-NEXT: Name: zed@
|
||||
// DONT_EXPORT-NEXT: Value: 0x0
|
||||
// DONT_EXPORT-NEXT: Size: 0
|
||||
// DONT_EXPORT-NEXT: Binding: Global
|
||||
// DONT_EXPORT-NEXT: Type: None
|
||||
// DONT_EXPORT-NEXT: Other: 0
|
||||
// DONT_EXPORT-NEXT: Section: Undefinedx
|
||||
// DONT_EXPORT-NEXT: }
|
||||
// DONT_EXPORT-NEXT: ]
|
||||
|
||||
// CHECK: DynamicSection [
|
||||
// CHECK-NEXT: Tag Type Name/Value
|
||||
// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
|
||||
|
|
Loading…
Reference in New Issue