[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/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; }