summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2018-01-30 16:29:29 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2018-01-30 16:29:29 +0000
commitb36fbbc3ec9fe0e1636c16d38083c65aefbafa7e (patch)
treee4a489e2da9b07654a99ce57df8dacb7456aef50 /llvm/tools/llvm-readobj
parentf1d01645a76285e53dff50feca1a5791685d946f (diff)
downloadbcm5719-llvm-b36fbbc3ec9fe0e1636c16d38083c65aefbafa7e.tar.gz
bcm5719-llvm-b36fbbc3ec9fe0e1636c16d38083c65aefbafa7e.zip
CodeGen: support an extension to pass linker options on ELF
Introduce an extension to support passing linker options to the linker. These would be ignored by older linkers, but newer linkers which support this feature would be able to process the linker. Emit a special discarded section `.linker-option`. The content of this section is a pair of strings (key, value). The key is a type identifier for the parameter. This allows for an argument free parameter that will be processed by the linker with the value being the parameter. As an example, `lib` identifies a library to be linked against, traditionally the `-l` argument for Unix-based linkers with the parameter being the library name. Thanks to James Henderson, Cary Coutant, Rafael Espinolda, Sean Silva for the valuable discussion on the design of this feature. llvm-svn: 323783
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp37
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h1
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp7
3 files changed, 45 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index dfc5560cc7a..dd81c0b4562 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -164,6 +164,8 @@ public:
void printNotes() override;
+ void printELFLinkerOptions() override;
+
private:
std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
@@ -316,6 +318,7 @@ public:
virtual void printProgramHeaders(const ELFFile<ELFT> *Obj) = 0;
virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
virtual void printNotes(const ELFFile<ELFT> *Obj) = 0;
+ virtual void printELFLinkerOptions(const ELFFile<ELFT> *Obj) = 0;
virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;
virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0;
const ELFDumper<ELFT> *dumper() const { return Dumper; }
@@ -345,6 +348,7 @@ public:
void printProgramHeaders(const ELFO *Obj) override;
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
+ void printELFLinkerOptions(const ELFFile<ELFT> *Obj) override;
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
@@ -405,6 +409,7 @@ public:
void printProgramHeaders(const ELFO *Obj) override;
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
void printNotes(const ELFFile<ELFT> *Obj) override;
+ void printELFLinkerOptions(const ELFFile<ELFT> *Obj) override;
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override;
@@ -1501,6 +1506,10 @@ template <class ELFT> void ELFDumper<ELFT>::printNotes() {
ELFDumperStyle->printNotes(Obj);
}
+template <class ELFT> void ELFDumper<ELFT>::printELFLinkerOptions() {
+ ELFDumperStyle->printELFLinkerOptions(Obj);
+}
+
#define LLVM_READOBJ_TYPE_CASE(name) \
case DT_##name: return #name
@@ -2694,6 +2703,8 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
return "SYMTAB SECTION INDICES";
case SHT_LLVM_ODRTAB:
return "LLVM_ODRTAB";
+ case SHT_LLVM_LINKER_OPTIONS:
+ return "LLVM_LINKER_OPTIONS";
// FIXME: Parse processor specific GNU attributes
case SHT_GNU_ATTRIBUTES:
return "ATTRIBUTES";
@@ -3555,6 +3566,11 @@ void GNUStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
}
template <class ELFT>
+void GNUStyle<ELFT>::printELFLinkerOptions(const ELFFile<ELFT> *Obj) {
+ OS << "printELFLinkerOptions not implemented!\n";
+}
+
+template <class ELFT>
void GNUStyle<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
size_t Bias = ELFT::Is64Bits ? 8 : 0;
auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) {
@@ -4063,6 +4079,27 @@ void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
}
template <class ELFT>
+void LLVMStyle<ELFT>::printELFLinkerOptions(const ELFFile<ELFT> *Obj) {
+ ListScope L(W, "LinkerOptions");
+
+ for (const Elf_Shdr &Shdr : unwrapOrError(Obj->sections())) {
+ if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS)
+ continue;
+
+ ArrayRef<uint8_t> Contents = unwrapOrError(Obj->getSectionContents(&Shdr));
+ for (const uint8_t *P = Contents.begin(), *E = Contents.end(); P < E; ) {
+ StringRef Key = StringRef(reinterpret_cast<const char *>(P));
+ StringRef Value =
+ StringRef(reinterpret_cast<const char *>(P) + Key.size() + 1);
+
+ W.printString(Key, Value);
+
+ P = P + Key.size() + Value.size() + 2;
+ }
+ }
+}
+
+template <class ELFT>
void LLVMStyle<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) {
auto PrintEntry = [&](const Elf_Addr *E) {
W.printHex("Address", Parser.getGotAddress(E));
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 2648eea9f31..2bf4dfe5a40 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -48,6 +48,7 @@ public:
virtual void printGroupSections() {}
virtual void printHashHistogram() {}
virtual void printNotes() {}
+ virtual void printELFLinkerOptions() {}
// Only implemented for ARM ELF at this time.
virtual void printAttributes() { }
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 5b7b227aa36..1d87b87d437 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -229,6 +229,11 @@ namespace opts {
COFFLoadConfig("coff-load-config",
cl::desc("Display the PE/COFF load config"));
+ // -elf-linker-options
+ cl::opt<bool>
+ ELFLinkerOptions("elf-linker-options",
+ cl::desc("Display the ELF .linker-options section"));
+
// -macho-data-in-code
cl::opt<bool>
MachODataInCode("macho-data-in-code",
@@ -419,6 +424,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
if (opts::VersionInfo)
Dumper->printVersionInfo();
if (Obj->isELF()) {
+ if (opts::ELFLinkerOptions)
+ Dumper->printELFLinkerOptions();
if (Obj->getArch() == llvm::Triple::arm)
if (opts::ARMAttributes)
Dumper->printAttributes();
OpenPOWER on IntegriCloud