[core] support .gnu.linkonce sections
.gnu.linkonce sections are similar to section groups. They were supported before section groups existed and provided a way to resolve COMDAT sections using a different design. There are few implementations that use .gnu.linkonce sections to store simple floating point constants which doesnot require complex section group support but need a way to store only one copy of the floating point constant in a binary. .gnu.linkonce based symbol resolution achieves that. Review : http://llvm-reviews.chandlerc.com/D3242 llvm-svn: 205280
This commit is contained in:
parent
d09ba23faf
commit
9316c40a1b
|
@ -147,6 +147,7 @@ public:
|
|||
typeRWNote, // Identifies readwrite note sections [ELF]
|
||||
typeNoAlloc, // Identifies non allocatable sections [ELF]
|
||||
typeGroupComdat, // Identifies a section group [ELF, COFF]
|
||||
typeGnuLinkOnce, // Identifies a gnu.linkonce section [ELF]
|
||||
};
|
||||
|
||||
// Permission bits for atoms and segments. The order of these values are
|
||||
|
@ -330,6 +331,14 @@ public:
|
|||
atomContentType == DefinedAtom::typeThreadZeroFill);
|
||||
}
|
||||
|
||||
/// Utility function to check if the atom belongs to a group section
|
||||
/// that represents section groups or .gnu.linkonce sections.
|
||||
bool isGroupParent() const {
|
||||
ContentType atomContentType = contentType();
|
||||
return (atomContentType == DefinedAtom::typeGroupComdat ||
|
||||
atomContentType == DefinedAtom::typeGnuLinkOnce);
|
||||
}
|
||||
|
||||
protected:
|
||||
// DefinedAtom is an abstract base class. Only subclasses can access
|
||||
// constructor.
|
||||
|
|
|
@ -67,8 +67,8 @@ public:
|
|||
private:
|
||||
typedef std::function<void(StringRef, bool)> UndefCallback;
|
||||
|
||||
/// \brief Add section group if it does not exist previously.
|
||||
void maybeAddSectionGroup(const DefinedAtom &atom);
|
||||
/// \brief Add section group/.gnu.linkonce if it does not exist previously.
|
||||
bool maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom);
|
||||
|
||||
/// \brief The main function that iterates over the files to resolve
|
||||
bool resolveUndefines();
|
||||
|
|
|
@ -72,6 +72,7 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
|
|||
return permRW_L;
|
||||
|
||||
case typeGroupComdat:
|
||||
case typeGnuLinkOnce:
|
||||
case typeUnknown:
|
||||
case typeTempLTO:
|
||||
return permUnknown;
|
||||
|
|
|
@ -184,11 +184,24 @@ void Resolver::doUndefinedAtom(const UndefinedAtom &atom) {
|
|||
}
|
||||
|
||||
/// \brief Add the section group and the group-child reference members.
|
||||
void Resolver::maybeAddSectionGroup(const DefinedAtom &atom) {
|
||||
bool Resolver::maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom) {
|
||||
// First time adding a group ?
|
||||
bool isFirstTime = _symbolTable.addGroup(atom);
|
||||
if (!isFirstTime)
|
||||
return;
|
||||
|
||||
if (!isFirstTime) {
|
||||
// If duplicate symbols are allowed, select the first group.
|
||||
if (_context.getAllowDuplicates())
|
||||
return true;
|
||||
const DefinedAtom *prevGroup =
|
||||
llvm::dyn_cast<DefinedAtom>(_symbolTable.findGroup(atom.name()));
|
||||
assert(prevGroup &&
|
||||
"Internal Error: The group atom could only be a defined atom");
|
||||
// The atoms should be of the same content type, reject invalid group
|
||||
// resolution behaviors.
|
||||
if (atom.contentType() != prevGroup->contentType())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const Reference *r : atom) {
|
||||
if ((r->kindNamespace() == lld::Reference::KindNamespace::all) &&
|
||||
|
@ -200,6 +213,7 @@ void Resolver::maybeAddSectionGroup(const DefinedAtom &atom) {
|
|||
_symbolTable.add(*target);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// called on each atom when a file is added
|
||||
|
@ -229,10 +243,16 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) {
|
|||
// add to list of known atoms
|
||||
_atoms.push_back(&atom);
|
||||
|
||||
if (atom.contentType() == DefinedAtom::typeGroupComdat)
|
||||
maybeAddSectionGroup(atom);
|
||||
else
|
||||
if (atom.isGroupParent()) {
|
||||
// Raise error if there exists a similar gnu linkonce section.
|
||||
if (!maybeAddSectionGroupOrGnuLinkOnce(atom)) {
|
||||
llvm::errs() << "SymbolTable: error while merging " << atom.name()
|
||||
<< "\n";
|
||||
llvm::report_fatal_error("duplicate symbol error");
|
||||
}
|
||||
} else {
|
||||
_symbolTable.add(atom);
|
||||
}
|
||||
|
||||
if (_context.deadStrip()) {
|
||||
// add to set of dead-strip-roots, all symbols that
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
// We are trying to process all atoms, but the defined() iterator does not
|
||||
// return group children. So, when a group parent is found, we need to
|
||||
// handle each child atom.
|
||||
if (defAtom->contentType() == DefinedAtom::typeGroupComdat) {
|
||||
if (defAtom->isGroupParent()) {
|
||||
for (const Reference *r : *defAtom) {
|
||||
if (r->kindNamespace() != lld::Reference::KindNamespace::all)
|
||||
continue;
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
if (!atom->name().empty())
|
||||
buildDuplicateNameMap(*atom);
|
||||
|
||||
if (atom->contentType() == DefinedAtom::typeGroupComdat) {
|
||||
if (atom->isGroupParent()) {
|
||||
for (const lld::Reference *ref : *atom) {
|
||||
if (ref->kindNamespace() != lld::Reference::KindNamespace::all)
|
||||
continue;
|
||||
|
@ -229,7 +229,7 @@ private:
|
|||
}
|
||||
|
||||
if (const lld::DefinedAtom *da = dyn_cast<DefinedAtom>(atom)) {
|
||||
if (da->contentType() == DefinedAtom::typeGroupComdat) {
|
||||
if (da->isGroupParent()) {
|
||||
if (_groupMap.count(name)) {
|
||||
_io.setError(Twine("duplicate group name: ") + name);
|
||||
} else {
|
||||
|
@ -477,6 +477,7 @@ template <> struct ScalarEnumerationTraits<lld::DefinedAtom::ContentType> {
|
|||
io.enumCase(value, "rw-note", DefinedAtom::typeRWNote);
|
||||
io.enumCase(value, "no-alloc", DefinedAtom::typeNoAlloc);
|
||||
io.enumCase(value, "group-comdat", DefinedAtom::typeGroupComdat);
|
||||
io.enumCase(value, "gnu-linkonce", DefinedAtom::typeGnuLinkOnce);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
# RUN: lld -core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that gnu linkonce sections are parsed and the first section selected for symbol
|
||||
# resolution
|
||||
#
|
||||
|
||||
---
|
||||
defined-atoms:
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
---
|
||||
defined-atoms:
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
...
|
||||
|
||||
# CHECK: defined-atoms:
|
||||
# CHECK: - name: g1
|
||||
# CHECK: ref-name: [[PARENT:[a-zA-Z\.0-9_]+]]
|
||||
# CHECK: type: gnu-linkonce
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: group-child
|
||||
# CHECK: target: f1
|
||||
# CHECK: - kind: group-child
|
||||
# CHECK: target: f2
|
||||
# CHECK: - kind: group-child
|
||||
# CHECK: target: [[CHILD:[a-zA-Z\.0-9_]+]]
|
||||
# CHECK: - kind: group-child
|
||||
# CHECK: target: d1
|
||||
# CHECK: - name: f1
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: group-parent
|
||||
# CHECK: target: [[PARENT]]
|
||||
# CHECK: - name: f2
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: group-parent
|
||||
# CHECK: target: [[PARENT]]
|
||||
# CHECK: - name: g1
|
||||
# CHECK: ref-name: [[CHILD]]
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: group-parent
|
||||
# CHECK: target: [[PARENT]]
|
||||
# CHECK: - name: d1
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: group-parent
|
||||
# CHECK: target: [[PARENT]]
|
|
@ -0,0 +1,113 @@
|
|||
# RUN: lld -core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that gnu linkonce sections are parsed and the first section selected for
|
||||
# symbol resolution. The second file which has the same gnu linkonce section has
|
||||
# a unresolved undefined symbol. lets make sure that the symbol is kept around
|
||||
# in the final link and remains undefined.
|
||||
#
|
||||
|
||||
---
|
||||
defined-atoms:
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
---
|
||||
defined-atoms:
|
||||
- name: anotherfunction
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: layout-before
|
||||
target: f3
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f3
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: f3
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
undefined-atoms:
|
||||
- name: f3
|
||||
can-be-null: never
|
||||
...
|
||||
|
||||
#CHECK: - name: anotherfunction
|
||||
#CHECK: scope: global
|
||||
#CHECK: type: data
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: layout-before
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: f3
|
||||
#CHECK: undefined-atoms:
|
||||
#CHECK: - name: f3
|
|
@ -0,0 +1,133 @@
|
|||
# RUN: lld -core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that gnu linkonce sections are parsed and the first section selected for symbol
|
||||
# resolution
|
||||
#
|
||||
|
||||
---
|
||||
defined-atoms:
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
---
|
||||
defined-atoms:
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
...
|
||||
|
||||
#CHECK: defined-atoms:
|
||||
#CHECK: - name: g1
|
||||
#CHECK: ref-name: [[PARENT:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: type: gnu-linkonce
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDONE:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDTWO:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDTHREE:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDFOUR:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - name: f1
|
||||
#CHECK: ref-name: [[GCHILDONE]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: f2
|
||||
#CHECK: ref-name: [[GCHILDTWO]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: g1
|
||||
#CHECK: ref-name: [[GCHILDTHREE]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: d1
|
||||
#CHECK: ref-name: [[GCHILDFOUR]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: type: data
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: ...
|
|
@ -0,0 +1,112 @@
|
|||
# RUN: lld -core %s | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that gnu linkonce sections are parsed properly when there is a reference to a
|
||||
# atom from outside the gnu linkonce section.
|
||||
#
|
||||
|
||||
---
|
||||
defined-atoms:
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: d1
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- name: anotherfunction
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: layout-before
|
||||
target: f1
|
||||
|
||||
undefined-atoms:
|
||||
- name: f1
|
||||
can-be-null: never
|
||||
...
|
||||
|
||||
#CHECK: defined-atoms:
|
||||
#CHECK: - name: g1
|
||||
#CHECK: ref-name: [[PARENT:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: type: gnu-linkonce
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDONE:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDTWO:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDTHREE:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - kind: group-child
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDFOUR:[a-zA-Z\.0-9_]+]]
|
||||
#CHECK: - name: f1
|
||||
#CHECK: ref-name: [[GCHILDONE]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: f2
|
||||
#CHECK: ref-name: [[GCHILDTWO]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: d1
|
||||
#CHECK: ref-name: [[GCHILDTHREE]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: type: data
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: g1
|
||||
#CHECK: ref-name: [[GCHILDFOUR]]
|
||||
#CHECK: scope: global
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: group-parent
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[PARENT]]
|
||||
#CHECK: - name: anotherfunction
|
||||
#CHECK: scope: global
|
||||
#CHECK: type: data
|
||||
#CHECK: references:
|
||||
#CHECK: - kind: layout-before
|
||||
#CHECK: offset: 0
|
||||
#CHECK: target: [[GCHILDONE]]
|
||||
#CHECK: ...
|
|
@ -0,0 +1,88 @@
|
|||
# RUN: not lld -core %s 2>&1 | FileCheck %s
|
||||
|
||||
#
|
||||
# Test that section groups/gnu linkonce sections are parsed and a merge error
|
||||
# is displayed at the time of symbol resolution.
|
||||
#
|
||||
|
||||
---
|
||||
defined-atoms:
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: group-comdat
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
---
|
||||
defined-atoms:
|
||||
- name: f1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: f2
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: code
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: d1
|
||||
scope: global
|
||||
type: data
|
||||
references:
|
||||
- kind: group-parent
|
||||
target: g1
|
||||
- name: g1
|
||||
scope: global
|
||||
type: gnu-linkonce
|
||||
references:
|
||||
- kind: group-child
|
||||
target: f1
|
||||
- kind: group-child
|
||||
target: f2
|
||||
- kind: group-child
|
||||
target: g1
|
||||
- kind: group-child
|
||||
target: d1
|
||||
...
|
||||
|
||||
#CHECK: SymbolTable: error while merging g1
|
||||
#CHECK: LLVM ERROR: duplicate symbol error
|
||||
|
Loading…
Reference in New Issue