[lld] handle typeZeroFill atoms in ELF/Native/YAML
BSS atoms dont take any file space in the Input file. They are associated
with a contentType(typeZeroFill). Similiar zero fill types also exist which
have the same meaning in terms of occupying file space in the Input.
These atoms have to be handled seperately when writing to the
lld's intermediate file or the lld test infrastructure.
Also adds a test.
llvm-svn: 189136
diff --git a/lld/include/lld/Core/DefinedAtom.h b/lld/include/lld/Core/DefinedAtom.h
index b4b2f87..35ed0b2 100644
--- a/lld/include/lld/Core/DefinedAtom.h
+++ b/lld/include/lld/Core/DefinedAtom.h
@@ -306,6 +306,14 @@
/// Utility for deriving permissions from content type
static ContentPermissions permissions(ContentType type);
+ /// Utility function to check if the atom occupies file space
+ virtual bool occupiesDiskSpace() const {
+ ContentType atomContentType = contentType();
+ return !(atomContentType == DefinedAtom::typeZeroFill ||
+ atomContentType == DefinedAtom::typeZeroFillFast ||
+ atomContentType == DefinedAtom::typeTLVInitialZeroFill);
+ }
+
protected:
// DefinedAtom is an abstract base class. Only subclasses can access
// constructor.
diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h
index 08afdb4..bac88c9 100644
--- a/lld/lib/ReaderWriter/ELF/File.h
+++ b/lld/lib/ReaderWriter/ELF/File.h
@@ -344,8 +344,11 @@
if (!sectionName)
return error_code(sectionName);
- auto sectionContents = section ? _objFile->getSectionContents(section)
- : ArrayRef<uint8_t>();
+ auto sectionContents =
+ (section && section->sh_type != llvm::ELF::SHT_NOBITS)
+ ? _objFile->getSectionContents(section)
+ : ArrayRef<uint8_t>();
+
if (!sectionContents)
return error_code(sectionContents);
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
index 36546f9..4a0be32 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
@@ -46,7 +46,9 @@
return DefinedAtom::typeZeroFillFast;
default:
- if (section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
+ if (section->sh_type == llvm::ELF::SHT_NOBITS)
+ return DefinedAtom::typeZeroFillFast;
+ else if (section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
return DefinedAtom::typeDataFast;
else
llvm_unreachable("unknown symbol type");
diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h
index d5d4606..2af3282 100644
--- a/lld/lib/ReaderWriter/ELF/SectionChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h
@@ -359,8 +359,7 @@
llvm::dbgs() << "Writing atom: " << ai->_atom->name()
<< " | " << ai->_fileOffset << "\n");
const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
- if ((definedAtom->contentType() == DefinedAtom::typeZeroFill) ||
- (definedAtom->contentType() == DefinedAtom::typeZeroFillFast))
+ if (!definedAtom->occupiesDiskSpace())
return;
// Copy raw content of atom to file buffer.
llvm::ArrayRef<uint8_t> content = definedAtom->rawContent();
diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
index b11f680..ddb6234 100644
--- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp
+++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
@@ -816,12 +816,11 @@
}
inline ArrayRef<uint8_t> NativeDefinedAtomV1::rawContent() const {
- if (( this->contentType() == DefinedAtom::typeZeroFill ) ||
- ( this->contentType() == DefinedAtom::typeZeroFillFast))
+ if (!occupiesDiskSpace())
return ArrayRef<uint8_t>();
const uint8_t* p = _file->content(_ivarData->contentOffset,
_ivarData->contentSize);
- return ArrayRef<uint8_t>(p, _ivarData->contentSize);
+ return ArrayRef<uint8_t>(p, _ivarData->contentSize);
}
inline StringRef NativeDefinedAtomV1::customSectionName() const {
diff --git a/lld/lib/ReaderWriter/Native/WriterNative.cpp b/lld/lib/ReaderWriter/Native/WriterNative.cpp
index 0e6f283..bd2f8e0 100644
--- a/lld/lib/ReaderWriter/Native/WriterNative.cpp
+++ b/lld/lib/ReaderWriter/Native/WriterNative.cpp
@@ -370,8 +370,7 @@
// append atom cotent to content pool and return offset
uint32_t getContentOffset(const DefinedAtom& atom) {
- if ((atom.contentType() == DefinedAtom::typeZeroFill ) ||
- (atom.contentType() == DefinedAtom::typeZeroFillFast))
+ if (!atom.occupiesDiskSpace())
return 0;
uint32_t result = _contentPool.size();
ArrayRef<uint8_t> cont = atom.rawContent();
diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index e245788..d9424fa 100644
--- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -887,6 +887,8 @@
_sectionName(atom->customSectionName()) {
for ( const lld::Reference *r : *atom )
_references.push_back(r);
+ if (!atom->occupiesDiskSpace())
+ return;
ArrayRef<uint8_t> cont = atom->rawContent();
_content.reserve(cont.size());
for (uint8_t x : cont)
@@ -933,8 +935,10 @@
virtual ContentPermissions permissions() const { return _permissions; }
virtual bool isAlias() const { return false; }
ArrayRef<uint8_t> rawContent() const {
+ if (!occupiesDiskSpace())
+ return ArrayRef<uint8_t>();
return ArrayRef<uint8_t>(
- reinterpret_cast<const uint8_t *>(_content.data()), _content.size());
+ reinterpret_cast<const uint8_t *>(_content.data()), _content.size());
}
virtual uint64_t ordinal() const { return _ordinal; }
diff --git a/lld/test/elf/X86_64/Inputs/largebss.c b/lld/test/elf/X86_64/Inputs/largebss.c
new file mode 100644
index 0000000..157d017
--- /dev/null
+++ b/lld/test/elf/X86_64/Inputs/largebss.c
@@ -0,0 +1,3 @@
+int largebss[1000] = { 0 };
+int largecommon[1000];
+__thread int largetbss[1000] = { 0 };
diff --git a/lld/test/elf/X86_64/Inputs/largebss.o b/lld/test/elf/X86_64/Inputs/largebss.o
new file mode 100644
index 0000000..377370e
--- /dev/null
+++ b/lld/test/elf/X86_64/Inputs/largebss.o
Binary files differ
diff --git a/lld/test/elf/X86_64/largebss.test b/lld/test/elf/X86_64/largebss.test
new file mode 100644
index 0000000..bd425ef
--- /dev/null
+++ b/lld/test/elf/X86_64/largebss.test
@@ -0,0 +1,24 @@
+# This tests the functionality of handling BSS symbols
+# BSS symbols dont occupy file content and are associated with typeZeroFill
+# Any typeZeroFill content wouldnot have space reserved in the file to store
+# its content
+
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/largebss.o -emit-yaml | FileCheck %s
+
+
+CHECK: - name: largecommon
+CHECK: scope: global
+CHECK: type: zero-fill
+CHECK: size: 4000
+CHECK: merge: as-tentative
+CHECK: section-name: .bss
+CHECK: - name: largebss
+CHECK: scope: global
+CHECK: type: zero-fill
+CHECK: size: 4000
+CHECK: section-name: .bss
+CHECK: - name: largetbss
+CHECK: scope: global
+CHECK: type: tlv-zero-fill
+CHECK: size: 4000
+CHECK: section-name: .tbss
diff --git a/lld/test/elf/quickdata.test b/lld/test/elf/quickdata.test
index 8f7b30d..5c670f5 100644
--- a/lld/test/elf/quickdata.test
+++ b/lld/test/elf/quickdata.test
@@ -11,4 +11,4 @@
hexagon: type: quick-data
hexagon: - name: bss1
hexagon: scope: global
-hexagon: type: quick-data
+hexagon: type: zero-fill-quick