[mach-o] parse literal sections into atoms
authorNick Kledzik <kledzik@apple.com>
Thu, 22 May 2014 01:42:06 +0000 (01:42 +0000)
committerNick Kledzik <kledzik@apple.com>
Thu, 22 May 2014 01:42:06 +0000 (01:42 +0000)
llvm-svn: 209379

lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/test/mach-o/parse-literals.yaml [new file with mode: 0644]

index b5b5718..072f40d 100644 (file)
@@ -179,6 +179,15 @@ SectionInfo *Util::makeSection(DefinedAtom::ContentType type) {
   case DefinedAtom::typeZeroFill:
      return new (_allocator) SectionInfo("__DATA", "__bss",
                             S_ZEROFILL);
+  case DefinedAtom::typeLiteral4:
+     return new (_allocator) SectionInfo("__TEXT", "__literal4",
+                            S_4BYTE_LITERALS);
+  case DefinedAtom::typeLiteral8:
+     return new (_allocator) SectionInfo("__TEXT", "__literal8",
+                            S_8BYTE_LITERALS);
+  case DefinedAtom::typeLiteral16:
+     return new (_allocator) SectionInfo("__TEXT", "__literal16",
+                            S_16BYTE_LITERALS);
   default:
     llvm_unreachable("TO DO: add support for more sections");
     break;
index ab29f85..d40321b 100644 (file)
@@ -107,23 +107,80 @@ static void processUndefindeSymbol(MachOFile &file, const Symbol &sym,
   }
 }
 
+static void processSection(MachOFile &file, const Section &section,
+                           bool copyRefs) {
+  unsigned offset = 0;
+  switch (section.type) {
+  case llvm::MachO::S_REGULAR:
+  case llvm::MachO::S_COALESCED:
+  case llvm::MachO::S_ZEROFILL:
+    // These sections are broken in to atoms based on symbols.
+    break;
+  case llvm::MachO::S_CSTRING_LITERALS:
+    for (size_t i = 0, e = section.content.size(); i != e; ++i) {
+      if (section.content[i] == 0) {
+        unsigned size = i - offset + 1;
+        ArrayRef<uint8_t> strContent = section.content.slice(offset, size);
+        file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,
+                            DefinedAtom::typeCString, strContent, copyRefs);
+        offset = i + 1;
+      }
+    }
+    break;
+  case llvm::MachO::S_4BYTE_LITERALS:
+    assert((section.content.size() % 4) == 0);
+    for (size_t i = 0, e = section.content.size(); i != e; i += 4) {
+      ArrayRef<uint8_t> byteContent = section.content.slice(offset, 4);
+      file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,
+                          DefinedAtom::typeLiteral4, byteContent, copyRefs);
+      offset += 4;
+    }
+    break;
+  case llvm::MachO::S_8BYTE_LITERALS:
+    assert((section.content.size() % 8) == 0);
+    for (size_t i = 0, e = section.content.size(); i != e; i += 8) {
+      ArrayRef<uint8_t> byteContent = section.content.slice(offset, 8);
+      file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,
+                          DefinedAtom::typeLiteral8, byteContent, copyRefs);
+      offset += 8;
+    }
+    break;
+  case llvm::MachO::S_16BYTE_LITERALS:
+    assert((section.content.size() % 16) == 0);
+    for (size_t i = 0, e = section.content.size(); i != e; i += 16) {
+      ArrayRef<uint8_t> byteContent = section.content.slice(offset, 16);
+      file.addDefinedAtom(StringRef(), DefinedAtom::scopeLinkageUnit,
+                          DefinedAtom::typeLiteral16, byteContent, copyRefs);
+      offset += 16;
+    }
+    break;
+  default:
+    llvm_unreachable("mach-o section type not supported");
+    break;
+  }
+}
 
 static ErrorOr<std::unique_ptr<lld::File>>
 normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path,
                         bool copyRefs) {
   std::unique_ptr<MachOFile> file(new MachOFile(path));
-
+  
+  // Create atoms from global symbols.
   for (const Symbol &sym : normalizedFile.globalSymbols) {
     processSymbol(normalizedFile, *file, sym, copyRefs);
   }
-
+  // Create atoms from local symbols.
   for (const Symbol &sym : normalizedFile.localSymbols) {
     processSymbol(normalizedFile, *file, sym, copyRefs);
   }
-
+  // Create atoms from undefinded symbols.
   for (auto &sym : normalizedFile.undefinedSymbols) {
     processUndefindeSymbol(*file, sym, copyRefs);
   }
+  // Create atoms from sections that don't have symbols.
+  for (auto &sect : normalizedFile.sections) {
+    processSection(*file, sect, copyRefs);
+  }
 
   return std::unique_ptr<File>(std::move(file));
 }
diff --git a/lld/test/mach-o/parse-literals.yaml b/lld/test/mach-o/parse-literals.yaml
new file mode 100644 (file)
index 0000000..9169ca2
--- /dev/null
@@ -0,0 +1,78 @@
+# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t  | FileCheck %s
+#
+# Test parsing of literal sections.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __cstring
+    type:            S_CSTRING_LITERALS
+    attributes:      [  ]
+    alignment:       0
+    address:         0x0000000000000100
+    content:         [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x00, 0x74, 0x68, 
+                       0x65, 0x72, 0x65, 0x00, 0x77, 0x6F, 0x72, 0x6C, 
+                       0x64, 0x00 ]
+  - segment:         __TEXT
+    section:         __literal4
+    type:            S_4BYTE_LITERALS
+    attributes:      [  ]
+    alignment:       0
+    address:         0x0000000000000114
+    content:         [ 0x01, 0x02, 0x03, 0x04, 0x11, 0x12, 0x13, 0x14,
+                       0x28, 0x29, 0x2A, 0x2B ]
+  - segment:         __TEXT
+    section:         __literal8
+    type:            S_8BYTE_LITERALS
+    attributes:      [  ]
+    alignment:       0
+    address:         0x0000000000000120
+    content:         [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+                       0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F ]
+  - segment:         __TEXT
+    section:         __literal16
+    type:            S_16BYTE_LITERALS
+    attributes:      [  ]
+    alignment:       0
+    address:         0x0000000000000130
+    content:         [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+                       0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00 ]
+...
+
+
+# CHECK:defined-atoms:   
+# CHECK:  - scope:           hidden
+# CHECK:    type:            c-string
+# CHECK:    content:         [ 68, 65, 6C, 6C, 6F, 00 ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            c-string
+# CHECK:    content:         [ 74, 68, 65, 72, 65, 00 ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            c-string
+# CHECK:    content:         [ 77, 6F, 72, 6C, 64, 00 ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            const-4-byte
+# CHECK:    content:         [ 01, 02, 03, 04 ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            const-4-byte
+# CHECK:    content:         [ 11, 12, 13, 14 ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            const-4-byte
+# CHECK:    content:         [ 28, 29, 2A, 2B ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            const-8-byte
+# CHECK:    content:         [ 01, 02, 03, 04, 05, 06, 07, 08 ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            const-8-byte
+# CHECK:    content:         [ 28, 29, 2A, 2B, 2C, 2D, 2E, 2F ]
+# CHECK:  - scope:           hidden
+# CHECK:    type:            const-16-byte
+# CHECK:    content:         [ 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 
+# CHECK:                       0D, 0E, 0F, 00 ]
+