ContentType ret = typeUnknown;
uint64_t flags = _section->sh_flags;
+ if (_section->sh_type == llvm::ELF::SHT_GROUP)
+ return typeGroupComdat;
+
if (!_symbol && _sectionName.startswith(".gnu.linkonce"))
return typeGnuLinkOnce;
static bool hasOutputSegment(Section<ELFT> *section);
// Adds an atom to the section
- ErrorOr<const lld::AtomLayout &> addAtom(const Atom *atom) override;
+ ErrorOr<const lld::AtomLayout *> addAtom(const Atom *atom) override;
/// \brief Find an output Section given a section name.
OutputSection<ELFT> *findOutputSection(StringRef name) {
}
template <class ELFT>
-ErrorOr<const lld::AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
+ErrorOr<const lld::AtomLayout *>
+DefaultLayout<ELFT>::addAtom(const Atom *atom) {
if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
// HACK: Ignore undefined atoms. We need to adjust the interface so that
// undefined atoms can still be included in the output symbol table for
// link
_absoluteAtoms.push_back(new (_allocator)
lld::AtomLayout(absoluteAtom, 0, absoluteAtom->value()));
- return *_absoluteAtoms.back();
+ return _absoluteAtoms.back();
} else {
llvm_unreachable("Only absolute / defined atoms can be added here");
}
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela_Iter Elf_Rela_Iter;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel_Iter Elf_Rel_Iter;
+ typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
// A Map is used to hold the atoms that have been divided up
// after reading the section that contains Merge String attributes
Atom *findAtom(const Elf_Sym *sourceSymbol, const Elf_Sym *targetSymbol) {
// All references to atoms inside a group are through undefined atoms.
Atom *targetAtom = _symbolToAtomMapping.lookup(targetSymbol);
+ StringRef targetSymbolName = targetAtom->name();
if (targetAtom->definition() != Atom::definitionRegular)
return targetAtom;
if ((llvm::dyn_cast<DefinedAtom>(targetAtom))->scope() ==
return targetAtom;
if (!redirectReferenceUsingUndefAtom(sourceSymbol, targetSymbol))
return targetAtom;
- auto undefForGroupchild = _undefAtomsForgroupChild.find(targetAtom->name());
+ auto undefForGroupchild = _undefAtomsForgroupChild.find(targetSymbolName);
if (undefForGroupchild != _undefAtomsForgroupChild.end())
return undefForGroupchild->getValue();
auto undefGroupChildAtom =
- new (_readerStorage) SimpleUndefinedAtom(*this, targetAtom->name());
+ new (_readerStorage) SimpleUndefinedAtom(*this, targetSymbolName);
_undefinedAtoms._atoms.push_back(undefGroupChildAtom);
- return (_undefAtomsForgroupChild[targetAtom->name()] = undefGroupChildAtom);
+ return (_undefAtomsForgroupChild[targetSymbolName] = undefGroupChildAtom);
}
protected:
llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
const Elf_Shdr *shdr);
+ // Handle Section groups/COMDAT scetions.
+ std::error_code handleSectionGroup(
+ StringRef signature, StringRef groupSectionName,
+ llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
+ llvm::DenseMap<const Elf_Shdr *, std::vector<StringRef>> &comdatSections,
+ const Elf_Shdr *shdr);
+
/// Process the Undefined symbol and create an atom for it.
ErrorOr<ELFUndefinedAtom<ELFT> *>
handleUndefinedSymbol(StringRef symName, const Elf_Sym *sym) {
return sectionName.startswith(".gnu.linkonce");
}
+ /// Returns true if the section is a COMDAT group section.
+ bool isGroupSection(const Elf_Shdr *shdr) const {
+ return (shdr->sh_type == llvm::ELF::SHT_GROUP);
+ }
+
+ /// Returns true if the section is a member of some group.
+ bool isSectionMemberOfGroup(const Elf_Shdr *shdr) const {
+ return (shdr->sh_flags & llvm::ELF::SHF_GROUP);
+ }
+
/// Returns correct st_value for the symbol depending on the architecture.
/// For most architectures it's just a regular st_value with no changes.
virtual uint64_t getSymbolValue(const Elf_Sym *symbol) const {
// Holds all the atoms that are part of the section. They are the targets of
// the kindGroupChild reference.
llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> atomsForSection;
- // group sections have a mapping of the section header to the signature.
- llvm::DenseMap<const Elf_Shdr *, StringRef> groupSections;
+ // group sections have a mapping of the section header to the
+ // signature/section.
+ llvm::DenseMap<const Elf_Shdr *, std::pair<StringRef, StringRef>>
+ groupSections;
+ // Contains a list of comdat sections for a group.
+ llvm::DenseMap<const Elf_Shdr *, std::vector<StringRef>> comdatSections;
for (auto &i : _sectionSymbols) {
const Elf_Shdr *section = i.first;
std::vector<Elf_Sym_Iter> &symbols = i.second;
bool addAtoms = true;
+ // A section of type SHT_GROUP defines a grouping of sections. The name of a
+ // symbol from one of the containing object's symbol tables provides a
+ // signature
+ // for the section group. The section header of the SHT_GROUP section
+ // specifies
+ // the identifying symbol entry, as described : the sh_link member contains
+ // the section header index of the symbol table section that contains the
+ // entry.
+ // The sh_info member contains the symbol table index of the identifying
+ // entry.
+ // The sh_flags member of the section header contains 0. The name of the
+ // section
+ // (sh_name) is not specified.
+ if (isGroupSection(section)) {
+ const Elf_Word *groupMembers =
+ reinterpret_cast<const Elf_Word *>(sectionContents->data());
+ const long count = (section->sh_size) / sizeof(Elf_Word);
+ for (int i = 1; i < count; i++) {
+ const Elf_Shdr *sHdr = _objFile->getSection(groupMembers[i]);
+ ErrorOr<StringRef> sectionName = _objFile->getSectionName(sHdr);
+ if (std::error_code ec = sectionName.getError())
+ return ec;
+ comdatSections[section].push_back(*sectionName);
+ }
+ const Elf_Sym *symbol = _objFile->getSymbol(section->sh_info);
+ const Elf_Shdr *symtab = _objFile->getSection(section->sh_link);
+ ErrorOr<StringRef> symbolName = _objFile->getSymbolName(symtab, symbol);
+ if (std::error_code ec = symbolName.getError())
+ return ec;
+ groupSections.insert(
+ std::make_pair(section, std::make_pair(*symbolName, *sectionName)));
+ continue;
+ }
+
if (isGnuLinkOnceSection(*sectionName)) {
- groupSections.insert(std::make_pair(section, *sectionName));
+ groupSections.insert(
+ std::make_pair(section, std::make_pair(*sectionName, *sectionName)));
addAtoms = false;
}
+ if (isSectionMemberOfGroup(section))
+ addAtoms = false;
+
if (handleSectionWithNoSymbols(section, symbols)) {
ELFDefinedAtom<ELFT> *newAtom =
createSectionAtom(section, *sectionName, *sectionContents);
// Iterate over all the group sections to create parent atoms pointing to
// group-child atoms.
for (auto § : groupSections) {
- StringRef signature = sect.second;
+ StringRef signature = sect.second.first;
+ StringRef groupSectionName = sect.second.second;
if (isGnuLinkOnceSection(signature))
handleGnuLinkOnceSection(signature, atomsForSection, sect.first);
+ else if (isGroupSection(sect.first))
+ handleSectionGroup(signature, groupSectionName, atomsForSection,
+ comdatSections, sect.first);
}
updateReferences();
return std::error_code();
}
+template <class ELFT>
+std::error_code ELFFile<ELFT>::handleSectionGroup(
+ StringRef signature, StringRef groupSectionName,
+ llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
+ llvm::DenseMap<const Elf_Shdr *, std::vector<StringRef>> &comdatSections,
+ const Elf_Shdr *shdr) {
+ unsigned int referenceStart = _references.size();
+ std::vector<ELFReference<ELFT> *> refs;
+ auto sectionNamesInGroup = comdatSections[shdr];
+ for (auto sectionName : sectionNamesInGroup) {
+ for (auto ha : atomsForSection[sectionName]) {
+ _groupChild[ha->symbol()] = std::make_pair(signature, shdr);
+ ELFReference<ELFT> *ref = new (_readerStorage)
+ ELFReference<ELFT>(lld::Reference::kindGroupChild);
+ ref->setTarget(ha);
+ refs.push_back(ref);
+ }
+ atomsForSection[sectionName].clear();
+ }
+ // Create a gnu linkonce atom.
+ auto sectionGroupAtom = handleDefinedSymbol(
+ signature, groupSectionName, nullptr, shdr, ArrayRef<uint8_t>(),
+ referenceStart, _references.size(), _references);
+ (*sectionGroupAtom)->setOrdinal(++_ordinal);
+ _definedAtoms._atoms.push_back(*sectionGroupAtom);
+ for (auto reference : refs)
+ (*sectionGroupAtom)->addReference(reference);
+ return std::error_code();
+}
+
template <class ELFT> std::error_code ELFFile<ELFT>::createAtomsFromContext() {
if (!_useWrap)
return std::error_code();
template <class ELFT>
bool ELFFile<ELFT>::redirectReferenceUsingUndefAtom(
const Elf_Sym *sourceSymbol, const Elf_Sym *targetSymbol) const {
- auto groupChild = _groupChild.find(targetSymbol);
+ auto groupChildTarget = _groupChild.find(targetSymbol);
// If the reference is not to a group child atom, there is no need to redirect
- // using a undefined atom.
- if (groupChild == _groupChild.end())
+ // using a undefined atom. Its also not needed if the source and target are
+ // from the same section.
+ if ((groupChildTarget == _groupChild.end()) ||
+ (sourceSymbol->st_shndx == targetSymbol->st_shndx))
return false;
- if (sourceSymbol->st_shndx != targetSymbol->st_shndx) {
+ auto groupChildSource = _groupChild.find(sourceSymbol);
+
+ // If the source symbol is not in a group, use a undefined symbol too.
+ if (groupChildSource == _groupChild.end())
return true;
- }
- return false;
+ // If the source and child are from the same group, we dont need the
+ // relocation to go through a undefined symbol.
+ if (groupChildSource->second.second == groupChildTarget->second.second)
+ return false;
+
+ return true;
}
} // end namespace elf
/// \brief Does this section have an output segment.
virtual bool hasOutputSegment() { return true; }
- const lld::AtomLayout &appendAtom(const Atom *atom) {
+ const lld::AtomLayout *appendAtom(const Atom *atom) {
const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
DefinedAtom::Alignment atomAlign = definedAtom->alignment();
uint64_t alignment = 1u << atomAlign.powerOf2;
// std::max doesn't support uint64_t
if (this->_alignment < alignment)
this->_alignment = alignment;
- return *(this->_atoms.back());
+ return (this->_atoms.back());
}
}; // SDataSection
/// \brief Append the Atom to the layout and create appropriate sections.
/// \returns A reference to the atom layout or an error. The atom layout will
/// be updated as linking progresses.
- virtual ErrorOr<const lld::AtomLayout &> addAtom(const Atom *atom) = 0;
+ virtual ErrorOr<const lld::AtomLayout *> addAtom(const Atom *atom) = 0;
/// find the Atom in the current layout
virtual const AtomLayout *findAtomLayoutByName(StringRef name) const = 0;
/// associates a section to a segment
return ia == _posMap.end() && ib != _posMap.end();
}
- const lld::AtomLayout &appendAtom(const Atom *atom) override {
+ const lld::AtomLayout *appendAtom(const Atom *atom) override {
const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
for (const auto &r : *da) {
return it != _pltLayoutMap.end() ? it->second : nullptr;
}
- const lld::AtomLayout &appendAtom(const Atom *atom) override {
- const auto &layout = AtomSection<ELFType>::appendAtom(atom);
+ const lld::AtomLayout *appendAtom(const Atom *atom) override {
+ const auto *layout = AtomSection<ELFType>::appendAtom(atom);
const DefinedAtom *da = cast<DefinedAtom>(atom);
continue;
assert(r->kindArch() == Reference::KindArch::Mips);
if (r->kindValue() == LLD_R_MIPS_STO_PLT) {
- _pltLayoutMap[r->target()] = &layout;
+ _pltLayoutMap[r->target()] = layout;
break;
}
}
void OutputELFWriter<ELFT>::buildChunks(const File &file) {
ScopedTask task(getDefaultDomain(), "buildChunks");
for (const DefinedAtom *definedAtom : file.defined()) {
+ DefinedAtom::ContentType contentType = definedAtom->contentType();
+ // Dont add COMDAT group atoms and GNU linkonce atoms, as they are used for
+ // symbol resolution.
+ // TODO: handle partial linking.
+ if (contentType == DefinedAtom::typeGroupComdat ||
+ contentType == DefinedAtom::typeGnuLinkOnce)
+ continue;
_layout.addAtom(definedAtom);
}
for (const AbsoluteAtom *absoluteAtom : file.absolute())
// \brief Append an atom to a Section. The atom gets pushed into a vector
// contains the atom, the atom file offset, the atom virtual address
// the atom file offset is aligned appropriately as set by the Reader
- virtual const lld::AtomLayout &appendAtom(const Atom *atom);
+ virtual const lld::AtomLayout *appendAtom(const Atom *atom);
/// \brief Set the virtual address of each Atom in the Section. This
/// routine gets called after the linker fixes up the virtual address
// contains the atom, the atom file offset, the atom virtual address
// the atom file offset is aligned appropriately as set by the Reader
template <class ELFT>
-const lld::AtomLayout &AtomSection<ELFT>::appendAtom(const Atom *atom) {
+const lld::AtomLayout *AtomSection<ELFT>::appendAtom(const Atom *atom) {
const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
DefinedAtom::Alignment atomAlign = definedAtom->alignment();
_atoms.push_back(new (_alloc) lld::AtomLayout(atom, mOffset, 0));
this->_msize = mOffset + definedAtom->size();
break;
- case DefinedAtom::typeGnuLinkOnce:
- // Discard gnu linkonce atoms as they are just used to identify signature.
- break;
default:
llvm::dbgs() << definedAtom->contentType() << "\n";
llvm_unreachable("Uexpected content type.");
if (this->_alignment < alignment)
this->_alignment = alignment;
- return *_atoms.back();
+ if (_atoms.size())
+ return _atoms.back();
+ return nullptr;
}
/// \brief convert the segment type to a String for diagnostics
--- /dev/null
+# Checks that the linker picks the first group in the output file when the file
+# have some members dont appear in the first group.
+# 1a.s
+# ------
+#
+# .section .text,"axG",%progbits,foo_group,comdat
+# .weak foo
+#foo:
+# .word 0
+# 1b.s
+# -----
+# .section .text,"axG",%progbits,foo_group,comdat
+# .global foo
+# .global bar
+#foo:
+# .word 0
+#bar:
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.group1a.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.group1b.o
+#RUN: lld -flavor gnu -target x86_64 %t.group1a.o %t.group1b.o \
+#RUN: --noinhibit-exec --output-filetype=yaml -o %t2.out.yaml
+#RUN: lld -flavor gnu -target x86_64 %t.group1a.o %t.group1b.o \
+#RUN: --noinhibit-exec -o %t2.out
+#RUN: FileCheck %s -check-prefix=CHECKGROUP < %t2.out.yaml
+#RUN: llvm-readobj -sections %t2.out | FileCheck %s -check-prefix=CHECKGROUPSECTIONS
+#RUN: llvm-readobj -symbols %t2.out | FileCheck %s -check-prefix=CHECKSYMBOLS
+#CHECKGROUP: - name: foo
+#CHECKGROUP: scope: global
+#CHECKGROUP: merge: as-weak
+#CHECKGROUP: section-name: .text
+#CHECKGROUP: - name: foo_group
+#CHECKGROUP: scope: global
+#CHECKGROUP: type: group-comdat
+#CHECKGROUP: section-choice: custom-required
+#CHECKGROUP: section-name: .group
+#CHECKGROUP: permissions: ---
+#CHECKGROUP: references:
+#CHECKGROUP: - kind: group-child
+#CHECKGROUP: offset: 0
+#CHECKGROUP: target: foo
+#CHECKGROUPSECTIONS: Section {
+#CHECKGROUPSECTIONS: Name: .text
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [ (0x6)
+#CHECKGROUPSECTIONS: SHF_ALLOC (0x2)
+#CHECKGROUPSECTIONS: SHF_EXECINSTR (0x4)
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 2
+#CHECKGROUPSECTIONS: AddressAlignment: 1
+#CHECKGROUPSECTIONS: }
+#CHECKSYMBOLS: Name: foo
+#CHECKSYMBOLS: Type: Function
+#CHECKSYMBOLS: Section: .text
+#CHECKSYMBOLS-NOT: Name: bar
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: foo_group
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .text
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0000'
+Symbols:
+ Local:
+ - Name: foo_group
+ Section: .group
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ Weak:
+ - Name: foo
+ Section: .text
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: foo_group
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .text
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0000'
+Symbols:
+ Local:
+ - Name: foo_group
+ Section: .group
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ Global:
+ - Name: bar
+ Section: .text
+ Value: 0x0000000000000002
+ - Name: foo
+ Section: .text
+...
--- /dev/null
+# Checks that the linker picks the first group in the output file when the file
+# have some members dont appear in the first group.
+# 1a.s
+# ------
+# .section .text,"axG",%progbits,foo_group,comdat
+# .weak foo
+#foo:
+# .word 0
+# 1b.s
+# -----
+# .section .text,"axG",%progbits,foo_group,comdat
+# .global bar
+#bar:
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.group1a.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.group1b.o
+#RUN: lld -flavor gnu -target x86_64 %t.group1a.o %t.group1b.o \
+#RUN: --noinhibit-exec --output-filetype=yaml -o %t2.out.yaml
+#RUN: lld -flavor gnu -target x86_64 %t.group1a.o %t.group1b.o \
+#RUN: --noinhibit-exec -o %t2.out
+#RUN: FileCheck %s -check-prefix=CHECKGROUP < %t2.out.yaml
+#RUN: llvm-readobj -sections %t2.out | FileCheck %s -check-prefix=CHECKGROUPSECTIONS
+#RUN: llvm-readobj -symbols %t2.out | FileCheck %s -check-prefix=CHECKSYMBOLS
+#CHECKGROUP: - name: foo
+#CHECKGROUP: scope: global
+#CHECKGROUP: merge: as-weak
+#CHECKGROUP: section-name: .text
+#CHECKGROUP: - name: foo_group
+#CHECKGROUP: scope: global
+#CHECKGROUP: type: group-comdat
+#CHECKGROUP: section-choice: custom-required
+#CHECKGROUP: section-name: .group
+#CHECKGROUP: permissions: ---
+#CHECKGROUP: references:
+#CHECKGROUP: - kind: group-child
+#CHECKGROUP: offset: 0
+#CHECKGROUP: target: foo
+#CHECKGROUPSECTIONS: Section {
+#CHECKGROUPSECTIONS: Name: .text
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [ (0x6)
+#CHECKGROUPSECTIONS: SHF_ALLOC (0x2)
+#CHECKGROUPSECTIONS: SHF_EXECINSTR (0x4)
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 2
+#CHECKGROUPSECTIONS: AddressAlignment: 1
+#CHECKGROUPSECTIONS: }
+#CHECKSYMBOLS: Name: foo
+#CHECKSYMBOLS: Type: Function
+#CHECKSYMBOLS: Section: .text
+
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: foo_group
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .text
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0000'
+Symbols:
+ Local:
+ - Name: foo_group
+ Section: .group
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ Weak:
+ - Name: foo
+ Section: .text
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: foo_group
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .text
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: ''
+Symbols:
+ Local:
+ - Name: foo_group
+ Section: .group
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ Global:
+ - Name: bar
+ Section: .text
+...
--- /dev/null
+# Tests that linker throws an error for an undefined symbol in the section
+# group, which is the same as the signature in the next input file.
+# comdat1.s
+# ------------
+# .section .foo,"axG",@progbits,g1,comdat
+# .word g1
+#comdat2.s
+#-----------
+# .global g1
+# .section .bar,"axG",@progbits,g1,comdat
+#g2:
+# nop
+# .section .car,"axG",@progbits,g1,comdat
+#g3:
+# nop
+#
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.group1a.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.group1b.o
+#RUN: lld -flavor gnu -target x86_64 %t.group1a.o %t.group1b.o \
+#RUN: --noinhibit-exec -o %t2.out 2>&1 | FileCheck %s
+#CHECK: Undefined symbol: {{.*}} g1
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - SectionOrType: .rela.foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0000'
+ - Name: .rela.foo
+ Type: SHT_RELA
+ Flags: [ SHF_GROUP ]
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .foo
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: g1
+ Type: R_X86_64_16
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ - Name: .group
+ Type: STT_SECTION
+ Section: .group
+ Global:
+ - Name: g1
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .bar
+ - SectionOrType: .car
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bar
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '90'
+ - Name: .car
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '90'
+Symbols:
+ Local:
+ - Name: g2
+ Section: .bar
+ - Name: g3
+ Section: .car
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .bar
+ Type: STT_SECTION
+ Section: .bar
+ - Name: .car
+ Type: STT_SECTION
+ Section: .car
+ - Name: .group
+ Type: STT_SECTION
+ Section: .group
+ Global:
+ - Name: g1
+ Section: .group
+...
--- /dev/null
+# Tests that linker throws an error for an undefined symbol in the section
+# group.
+#
+#comdata.s
+#------------
+# .section .foo,"axG",@progbits,g1,comdat
+# .word g1
+#
+#comdatb.s
+#------------
+# .global g1
+# .section .foo,"axG",@progbits,g1,comdat
+#g1:
+# nop
+#
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.group1a.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.group1b.o
+#RUN: lld -flavor gnu -target x86_64 %t.group1a.o %t.group1b.o \
+#RUN: --noinhibit-exec -o %t2.out 2>&1 | FileCheck %s
+#CHECK: Undefined symbol: {{.*}} g1
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - SectionOrType: .rela.foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0000'
+ - Name: .rela.foo
+ Type: SHT_RELA
+ Flags: [ SHF_GROUP ]
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .foo
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: g1
+ Type: R_X86_64_16
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ - Name: .group
+ Type: STT_SECTION
+ Section: .group
+ Global:
+ - Name: g1
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '90'
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ - Name: .group
+ Type: STT_SECTION
+ Section: .group
+ Global:
+ - Name: g1
+ Section: .foo
+...
--- /dev/null
+# This tests that comdat weak symbol can be overridden by a global symbol.
+# comdat1.s
+#------------------------
+# .weak g1
+# .section .foo,"axG",@progbits,g1,comdat
+#g1:
+# nop
+# .global g2
+#g2:
+# nop
+#!
+#
+#comdat2.s << \!
+#-----------------
+# .global g1
+# .section .foo,"axG",@progbits,g1,comdat
+#g1:
+# nop
+# .global g2
+#g2:
+# nop
+#
+#cat > g1.c << \!
+#int g1() {
+# return 0;
+#}
+#
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.comdat1.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.comdat2.o
+#RUN: yaml2obj -format=elf -docnum 3 %s -o %t.g1.o
+#RUN: lld -flavor gnu -target x86_64 %t.comdat1.o %t.comdat2.o \
+#RUN: %t.g1.o --noinhibit-exec --output-filetype=yaml -o %t2.out.yaml
+#RUN: lld -flavor gnu -target x86_64 %t.comdat1.o %t.comdat2.o \
+#RUN: %t.g1.o --noinhibit-exec -o %t2.out
+#RUN: FileCheck %s -check-prefix=CHECKGROUP < %t2.out.yaml
+#RUN: llvm-readobj -sections %t2.out | FileCheck %s -check-prefix=CHECKGROUPSECTIONS
+#RUN: llvm-readobj -symbols %t2.out | FileCheck %s -check-prefix=CHECKSYMBOLS
+#CHECKGROUP: - name: g2
+#CHECKGROUP: content: [ 90 ]
+#CHECKGROUP: section-choice: custom-required
+#CHECKGROUP: section-name: .foo
+#CHECKGROUP: - name: g1
+#CHECKGROUP: scope: global
+#CHECKGROUP: content: [ 55, 48, 89, E5, 31, C0, 5D, C3 ]
+#CHECKGROUP: alignment: 2^4
+#CHECKGROUP: section-name: .text
+#CHECKGROUPSECTIONS: Name: .text
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [
+#CHECKGROUPSECTIONS: SHF_ALLOC
+#CHECKGROUPSECTIONS: SHF_EXECINSTR
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 8
+#CHECKGROUPSECTIONS: Name: .foo
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [
+#CHECKGROUPSECTIONS: SHF_ALLOC
+#CHECKGROUPSECTIONS: SHF_EXECINSTR
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 2
+#CHECKSYMBOLS: Name: g2
+#CHECKSYMBOLS: Section: .foo
+#CHECKSYMBOLS: Name: g1
+#CHECKSYMBOLS: Section: .text
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '9090'
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ Global:
+ - Name: g2
+ Section: .foo
+ Value: 0x0000000000000001
+ Weak:
+ - Name: g1
+ Section: .foo
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '9090'
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ Global:
+ - Name: g1
+ Section: .foo
+ - Name: g2
+ Section: .foo
+ Value: 0x0000000000000001
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000010
+ Content: 554889E531C05DC3
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: 00636C616E672076657273696F6E20332E372E3020287472756E6B203232393535372920286C6C766D2F7472756E6B203232393536332900
+ - Name: .note.GNU-stack
+ Type: SHT_PROGBITS
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ AddressAlign: 0x0000000000000008
+ Content: 1400000000000000037A5200017810011B0C0708900100001C0000001C000000000000000800000000410E108602430D0600000000000000
+ - Name: .rela.eh_frame
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .eh_frame
+ Relocations:
+ - Offset: 0x0000000000000020
+ Symbol: .text
+ Type: R_X86_64_PC32
+Symbols:
+ Local:
+ - Name: g1.c
+ Type: STT_FILE
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: .note.GNU-stack
+ Type: STT_SECTION
+ Section: .note.GNU-stack
+ - Name: .eh_frame
+ Type: STT_SECTION
+ Section: .eh_frame
+ Global:
+ - Name: g1
+ Type: STT_FUNC
+ Section: .text
+ Size: 0x0000000000000008
+...
--- /dev/null
+# This tests that comdat undef symbol is overridden by a global symbol.
+# comdat1.s
+#------------------------
+# .global g1
+# .section .foo,"axG",@progbits,g1,comdat
+#g1:
+# .word 5
+#
+#comdat2.s << \!
+#-----------------
+# .global g1
+# .section .foo,"axG",@progbits,g1,comdat
+#g1:
+# nop
+#
+#g1.c
+#-----------
+#extern int g1;
+#int fn() { return g1;}
+#
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.comdat1.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.comdat2.o
+#RUN: yaml2obj -format=elf -docnum 3 %s -o %t.g1.o
+#RUN: lld -flavor gnu -target x86_64 %t.comdat1.o %t.comdat2.o \
+#RUN: %t.g1.o --noinhibit-exec --output-filetype=yaml -o %t2.out.yaml
+#RUN: lld -flavor gnu -target x86_64 %t.comdat1.o %t.comdat2.o \
+#RUN: %t.g1.o --noinhibit-exec -o %t2.out
+#RUN: FileCheck %s -check-prefix=CHECKGROUP < %t2.out.yaml
+#RUN: llvm-readobj -sections %t2.out | FileCheck %s -check-prefix=CHECKGROUPSECTIONS
+#RUN: llvm-readobj -symbols %t2.out | FileCheck %s -check-prefix=CHECKSYMBOLS
+#CHECKGROUP: - name: g1
+#CHECKGROUP: scope: global
+#CHECKGROUP: content: [ 05, 00 ]
+#CHECKGROUP: section-name: .foo
+#CHECKGROUPSECTIONS: Section {
+#CHECKGROUPSECTIONS: Name: .foo
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [
+#CHECKGROUPSECTIONS: SHF_ALLOC
+#CHECKGROUPSECTIONS: SHF_EXECINSTR
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 2
+#CHECKGROUPSECTIONS: }
+#CHECKSYMBOLS: Name: g1
+#CHECKSYMBOLS: Section: .foo
+#CHECKSYMBOLS: Name: fn
+#CHECKSYMBOLS: Section: .text
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0500'
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ Global:
+ - Name: g1
+ Section: .foo
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '90'
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ Global:
+ - Name: g1
+ Section: .foo
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000010
+ Content: 554889E58B0425000000005DC3
+ - Name: .rela.text
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .text
+ Relocations:
+ - Offset: 0x0000000000000007
+ Symbol: g1
+ Type: R_X86_64_32S
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: 00636C616E672076657273696F6E20332E372E3020287472756E6B203232393535372920286C6C766D2F7472756E6B203232393536332900
+ - Name: .note.GNU-stack
+ Type: SHT_PROGBITS
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ AddressAlign: 0x0000000000000008
+ Content: 1400000000000000037A5200017810011B0C0708900100001C0000001C000000000000000D00000000410E108602430D0600000000000000
+ - Name: .rela.eh_frame
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .eh_frame
+ Relocations:
+ - Offset: 0x0000000000000020
+ Symbol: .text
+ Type: R_X86_64_PC32
+Symbols:
+ Local:
+ - Name: global-g1.c
+ Type: STT_FILE
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: .note.GNU-stack
+ Type: STT_SECTION
+ Section: .note.GNU-stack
+ - Name: .eh_frame
+ Type: STT_SECTION
+ Section: .eh_frame
+ Global:
+ - Name: fn
+ Type: STT_FUNC
+ Section: .text
+ Size: 0x000000000000000D
+ - Name: g1
+...
--- /dev/null
+# This tests that comdat undef symbol is overridden by a global symbol.
+# comdat1.s
+#------------------------
+# .section .foo,"axG",@progbits,g1,comdat
+# word g1
+#
+#comdat2.s << \!
+#-----------------
+# .global g1
+# .section .foo,"axG",@progbits,g1,comdat
+#g1:
+# nop
+#
+#global-g1.c
+#-----------
+#int g1=10;
+#
+#RUN: yaml2obj -format=elf -docnum 1 %s -o %t.comdat1.o
+#RUN: yaml2obj -format=elf -docnum 2 %s -o %t.comdat2.o
+#RUN: yaml2obj -format=elf -docnum 3 %s -o %t.g1.o
+#RUN: lld -flavor gnu -target x86_64 %t.comdat1.o %t.comdat2.o \
+#RUN: %t.g1.o --noinhibit-exec --output-filetype=yaml -o %t2.out.yaml
+#RUN: lld -flavor gnu -target x86_64 %t.comdat1.o %t.comdat2.o \
+#RUN: %t.g1.o --noinhibit-exec -o %t2.out
+#RUN: FileCheck %s -check-prefix=CHECKGROUP < %t2.out.yaml
+#RUN: llvm-readobj -sections %t2.out | FileCheck %s -check-prefix=CHECKGROUPSECTIONS
+#RUN: llvm-readobj -symbols %t2.out | FileCheck %s -check-prefix=CHECKSYMBOLS
+#CHECKGROUP: - name: g1
+#CHECKGROUP: scope: global
+#CHECKGROUP: content: [ 0A, 00, 00, 00 ]
+#CHECKGROUP: section-name: .data
+#CHECKGROUPSECTIONS: Name: .foo
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [
+#CHECKGROUPSECTIONS: SHF_ALLOC
+#CHECKGROUPSECTIONS: SHF_EXECINSTR
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 2
+#CHECKGROUPSECTIONS: Name: .data
+#CHECKGROUPSECTIONS: Type: SHT_PROGBITS
+#CHECKGROUPSECTIONS: Flags [
+#CHECKGROUPSECTIONS: SHF_ALLOC
+#CHECKGROUPSECTIONS: SHF_WRITE
+#CHECKGROUPSECTIONS: ]
+#CHECKGROUPSECTIONS: Size: 4
+#CHECKSYMBOLS: Name: g1
+#CHECKSYMBOLS: Section: .data
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - SectionOrType: .rela.foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '0000'
+ - Name: .rela.foo
+ Type: SHT_RELA
+ Flags: [ SHF_GROUP ]
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .foo
+ Relocations:
+ - Offset: 0x0000000000000000
+ Symbol: g1
+ Type: R_X86_64_16
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ Global:
+ - Name: g1
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .group
+ Type: SHT_GROUP
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: g1
+ Members:
+ - SectionOrType: GRP_COMDAT
+ - SectionOrType: .foo
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .foo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+ AddressAlign: 0x0000000000000001
+ Content: '90'
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .foo
+ Type: STT_SECTION
+ Section: .foo
+ Global:
+ - Name: g1
+ Section: .foo
+...
+---
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: 0A000000
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: ''
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: 00636C616E672076657273696F6E20332E372E3020287472756E6B203232393535372920286C6C766D2F7472756E6B203232393536332900
+ - Name: .note.GNU-stack
+ Type: SHT_PROGBITS
+ AddressAlign: 0x0000000000000001
+ Content: ''
+Symbols:
+ Local:
+ - Name: global-g1.c
+ Type: STT_FILE
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: .note.GNU-stack
+ Type: STT_SECTION
+ Section: .note.GNU-stack
+ Global:
+ - Name: g1
+ Type: STT_OBJECT
+ Section: .data
+ Size: 0x0000000000000004
+...