Skip to content

Commit

Permalink
Include version string into ".comment" section.
Browse files Browse the repository at this point in the history
Summary:
This patch adds a ".comment" section to an output. The comment
section contains the linker's version string. You can now
find out whether a binary is created by LLD or not using objdump
command like this.

  $ objdump -s -j .comment foo

  foo:     file format elf64-x86-64

  Contents of section .comment:
   0000 00474343 3a202855 62756e74 7520342e  .GCC: (Ubuntu 4.
   0010 382e342d 32756275 6e747531 7e31342e  8.4-2ubuntu1~14.
   ...
   00c0 766d2f74 72756e6b 20323835 38343629  vm/trunk 285846)
   00d0 004c696e 6b65723a 204c4c44 20342e30  .Linker: LLD 4.0
   00e0 2e302028 7472756e 6b203238 36343036  .0 (trunk 286406
   00f0 2900                                 ).

Compilers emits .comment section as well, so the output contains
both compiler and linker information.

Alternative considered:

I first tried to add a SHT_NOTE section because GNU gold does that.
A NOTE section starts with a header which contains content type.
It turned out that ld.gold sets type NT_GNU_GOLD_VERSION to their
NOTE section. So the NOTE type is only for GNU gold (surprise!)

Next, I tried to create ".linker-version" section. However, it seems
that reusing the existing ".comment" section is better because 1)
other tools already know about .comment section and is able to strip
it and 2) the result contans not only linker info but also compiler
info.

Differential Revision: https://reviews.llvm.org/D26487

llvm-svn: 286496
  • Loading branch information
rui314 committed Nov 10, 2016
1 parent 4a86af0 commit 3da3f06
Show file tree
Hide file tree
Showing 25 changed files with 275 additions and 120 deletions.
37 changes: 37 additions & 0 deletions lld/ELF/SyntheticSections.cpp
Expand Up @@ -25,12 +25,14 @@
#include "Target.h"
#include "Writer.h"

#include "lld/Config/Version.h"
#include "lld/Core/Parallel.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/RandomNumberGenerator.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/xxhash.h"
#include <cstdlib>

using namespace llvm;
using namespace llvm::ELF;
Expand Down Expand Up @@ -78,6 +80,36 @@ template <class ELFT> InputSection<ELFT> *elf::createCommonSection() {
return Ret;
}

// Returns an LLD version string.
static ArrayRef<uint8_t> getVersion() {
// Check LLD_VERSION first for ease of testing.
// You can get consitent output by using the environment variable.
// This is only for testing.
StringRef S = getenv("LLD_VERSION");
if (S.empty())
S = Saver.save(Twine("Linker: ") + getLLDVersion());

// +1 to include the terminating '\0'.
return {(const uint8_t *)S.data(), S.size() + 1};
};

// Creates a .comment section containing LLD version info.
// With this feature, you can identify LLD-generated binaries easily
// by "objdump -s -j .comment <file>".
// The returned object is a mergeable string section.
template <class ELFT> MergeInputSection<ELFT> *elf::createCommentSection() {
typename ELFT::Shdr Hdr = {};
Hdr.sh_flags = SHF_MERGE | SHF_STRINGS;
Hdr.sh_type = SHT_PROGBITS;
Hdr.sh_entsize = 1;
Hdr.sh_addralign = 1;

auto *Ret = make<MergeInputSection<ELFT>>(/*file=*/nullptr, &Hdr, ".comment");
Ret->Data = getVersion();
Ret->splitIntoPieces();
return Ret;
}

// Iterate over sections of the specified type. For each section call
// provided function. After that "kill" the section by turning off
// "Live" flag, so that they won't be included in the final output.
Expand Down Expand Up @@ -352,6 +384,11 @@ template InputSection<ELF32BE> *elf::createInterpSection();
template InputSection<ELF64LE> *elf::createInterpSection();
template InputSection<ELF64BE> *elf::createInterpSection();

template MergeInputSection<ELF32LE> *elf::createCommentSection();
template MergeInputSection<ELF32BE> *elf::createCommentSection();
template MergeInputSection<ELF64LE> *elf::createCommentSection();
template MergeInputSection<ELF64BE> *elf::createCommentSection();

template class elf::MipsAbiFlagsSection<ELF32LE>;
template class elf::MipsAbiFlagsSection<ELF32BE>;
template class elf::MipsAbiFlagsSection<ELF64LE>;
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/SyntheticSections.h
Expand Up @@ -149,6 +149,7 @@ class GotPltSection final : public SyntheticSection<ELFT> {

template <class ELFT> InputSection<ELFT> *createCommonSection();
template <class ELFT> InputSection<ELFT> *createInterpSection();
template <class ELFT> MergeInputSection<ELFT> *createCommentSection();

// Linker generated sections which can be used as inputs.
template <class ELFT> struct In {
Expand Down
2 changes: 2 additions & 0 deletions lld/ELF/Writer.cpp
Expand Up @@ -268,6 +268,8 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
Out<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();

// Initialize linker generated sections
Symtab<ELFT>::X->Sections.push_back(createCommentSection<ELFT>());

if (Config->BuildId == BuildIdKind::Fast)
In<ELFT>::BuildId = make<BuildIdFastHash<ELFT>>();
else if (Config->BuildId == BuildIdKind::Md5)
Expand Down
2 changes: 1 addition & 1 deletion lld/test/ELF/aarch64-gnu-ifunc.s
Expand Up @@ -15,7 +15,7 @@
// CHECK-NEXT: Address: [[RELA:.*]]
// CHECK-NEXT: Offset: 0x158
// CHECK-NEXT: Size: 48
// CHECK-NEXT: Link: 5
// CHECK-NEXT: Link: 6
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 8
// CHECK-NEXT: EntrySize: 24
Expand Down
36 changes: 26 additions & 10 deletions lld/test/ELF/basic-aarch64.s
Expand Up @@ -26,15 +26,15 @@ _start:
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]]
# CHECK-NEXT: ProgramHeaderOffset: 0x40
# CHECK-NEXT: SectionHeaderOffset: 0x10088
# CHECK-NEXT: SectionHeaderOffset: 0x10098
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 64
# CHECK-NEXT: ProgramHeaderEntrySize: 56
# CHECK-NEXT: ProgramHeaderCount: 4
# CHECK-NEXT: SectionHeaderEntrySize: 64
# CHECK-NEXT: SectionHeaderCount: 5
# CHECK-NEXT: StringTableSectionIndex: 3
# CHECK-NEXT: SectionHeaderCount: 6
# CHECK-NEXT: StringTableSectionIndex: 4
# CHECK-NEXT: }
# CHECK-NEXT: Sections [
# CHECK-NEXT: Section {
Expand Down Expand Up @@ -69,40 +69,56 @@ _start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 2
# CHECK-NEXT: Name: .comment
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x30)
# CHECK-NEXT: SHF_MERGE (0x10)
# CHECK-NEXT: SHF_STRINGS (0x20)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x1000C
# CHECK-NEXT: Size: 8
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 1
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 3
# CHECK-NEXT: Name: .symtab
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x10010
# CHECK-NEXT: Offset: 0x10018
# CHECK-NEXT: Size: 72
# CHECK-NEXT: Link: 4
# CHECK-NEXT: Link: 5
# CHECK-NEXT: Info: 2
# CHECK-NEXT: AddressAlignment: 8
# CHECK-NEXT: EntrySize: 24
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 3
# CHECK-NEXT: Index: 4
# CHECK-NEXT: Name: .shstrtab
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x10058
# CHECK-NEXT: Size: 33
# CHECK-NEXT: Offset: 0x10060
# CHECK-NEXT: Size: 42
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 4
# CHECK-NEXT: Index: 5
# CHECK-NEXT: Name: .strtab
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x10079
# CHECK-NEXT: Offset: 0x1008A
# CHECK-NEXT: Size: 13
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
Expand Down
36 changes: 26 additions & 10 deletions lld/test/ELF/basic-mips.s
Expand Up @@ -27,7 +27,7 @@ __start:
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: 0x20000
# CHECK-NEXT: ProgramHeaderOffset: 0x34
# CHECK-NEXT: SectionHeaderOffset: 0x30088
# CHECK-NEXT: SectionHeaderOffset: 0x30098
# CHECK-NEXT: Flags [
# CHECK-NEXT: EF_MIPS_ABI_O32
# CHECK-NEXT: EF_MIPS_ARCH_32
Expand All @@ -37,8 +37,8 @@ __start:
# CHECK-NEXT: ProgramHeaderEntrySize: 32
# CHECK-NEXT: ProgramHeaderCount: 6
# CHECK-NEXT: SectionHeaderEntrySize: 40
# CHECK-NEXT: SectionHeaderCount: 10
# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT: SectionHeaderCount: 11
# CHECK-NEXT: StringTableSectionIndex: 9
# CHECK-NEXT: }
# CHECK-NEXT: Sections [
# CHECK-NEXT: Section {
Expand Down Expand Up @@ -152,40 +152,56 @@ __start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 7
# CHECK-NEXT: Name: .comment
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x30)
# CHECK-NEXT: SHF_MERGE (0x10)
# CHECK-NEXT: SHF_STRINGS (0x20)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Size: 8
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 1
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 8
# CHECK-NEXT: Name: .symtab
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Offset: 0x30008
# CHECK-NEXT: Size: 48
# CHECK-NEXT: Link: 9
# CHECK-NEXT: Link: 10
# CHECK-NEXT: Info: 1
# CHECK-NEXT: AddressAlignment: 4
# CHECK-NEXT: EntrySize: 16
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 8
# CHECK-NEXT: Index: 9
# CHECK-NEXT: Name: .shstrtab
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30030
# CHECK-NEXT: Size: 73
# CHECK-NEXT: Offset: 0x30038
# CHECK-NEXT: Size: 82
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 9
# CHECK-NEXT: Index: 10
# CHECK-NEXT: Name: .strtab
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30079
# CHECK-NEXT: Offset: 0x3008A
# CHECK-NEXT: Size: 13
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
Expand Down
44 changes: 32 additions & 12 deletions lld/test/ELF/basic-ppc.s
Expand Up @@ -28,15 +28,15 @@
// CHECK-NEXT: Version: 1
// CHECK-NEXT: Entry: 0x0
// CHECK-NEXT: ProgramHeaderOffset: 0x34
// CHECK-NEXT: SectionHeaderOffset: 0x209C
// CHECK-NEXT: SectionHeaderOffset: 0x20AC
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: HeaderSize: 52
// CHECK-NEXT: ProgramHeaderEntrySize: 32
// CHECK-NEXT: ProgramHeaderCount: 7
// CHECK-NEXT: SectionHeaderEntrySize: 40
// CHECK-NEXT: SectionHeaderCount: 9
// CHECK-NEXT: StringTableSectionIndex: 7
// CHECK-NEXT: SectionHeaderCount: 10
// CHECK-NEXT: StringTableSectionIndex: 8
// CHECK-NEXT: }
// CHECK-NEXT: Sections [
// CHECK-NEXT: Section {
Expand Down Expand Up @@ -151,14 +151,33 @@
// CHECK-NEXT: }
// CHECK-NEXT: Section {
// CHECK-NEXT: Index: 6
// CHECK-NEXT: Name: .comment
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
// CHECK-NEXT: Flags [ (0x30)
// CHECK-NEXT: SHF_MERGE (0x10)
// CHECK-NEXT: SHF_STRINGS (0x20)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x2030
// CHECK-NEXT: Size: 8
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
// CHECK-NEXT: EntrySize: 1
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
// CHECK-NEXT: )
// CHECK-NEXT: }
// CHECK-NEXT: Section {
// CHECK-NEXT: Index: 7
// CHECK-NEXT: Name: .symtab
// CHECK-NEXT: Type: SHT_SYMTAB (0x2)
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x2030
// CHECK-NEXT: Offset: 0x2038
// CHECK-NEXT: Size: 32
// CHECK-NEXT: Link: 8
// CHECK-NEXT: Link: 9
// CHECK-NEXT: Info: 1
// CHECK-NEXT: AddressAlignment: 4
// CHECK-NEXT: EntrySize: 16
Expand All @@ -168,33 +187,34 @@
// CHECK-NEXT: )
// CHECK-NEXT: }
// CHECK-NEXT: Section {
// CHECK-NEXT: Index: 7
// CHECK-NEXT: Index: 8
// CHECK-NEXT: Name: .shstrtab
// CHECK-NEXT: Type: SHT_STRTAB (0x3)
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x2050
// CHECK-NEXT: Size: 64
// CHECK-NEXT: Offset: 0x2058
// CHECK-NEXT: Size: 73
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
// CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..|
// CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy|
// CHECK-NEXT: 0020: 6E616D69 63002E73 796D7461 62002E73 |namic..symtab..s|
// CHECK-NEXT: 0030: 68737472 74616200 2E737472 74616200 |hstrtab..strtab.|
// CHECK-NEXT: 0020: 6E616D69 63002E63 6F6D6D65 6E74002E |namic..comment..|
// CHECK-NEXT: 0030: 73796D74 6162002E 73687374 72746162 |symtab..shstrtab|
// CHECK-NEXT: 0040: 002E7374 72746162 00 |..strtab.|
// CHECK-NEXT: )
// CHECK-NEXT: }
// CHECK-NEXT: Section {
// CHECK-NEXT: Index: 8
// CHECK-NEXT: Index: 9
// CHECK-NEXT: Name: .strtab
// CHECK-NEXT: Type: SHT_STRTAB (0x3)
// CHECK-NEXT: Flags [ (0x0)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x2090
// CHECK-NEXT: Offset: 0x20A1
// CHECK-NEXT: Size: 1
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
Expand Down

0 comments on commit 3da3f06

Please sign in to comment.