[lld] r214268 - [mach-o] Add support for -sectalign option

Nick Kledzik kledzik at apple.com
Tue Jul 29 17:58:06 PDT 2014


Author: kledzik
Date: Tue Jul 29 19:58:06 2014
New Revision: 214268

URL: http://llvm.org/viewvc/llvm-project?rev=214268&view=rev
Log:
[mach-o] Add support for -sectalign option

The -sectalign option is used to increase the alignment required for a section.
It required some reworking of how the __TEXT segment is laid out because that
segment also contains the mach_header and load commands. And the size of load
commands depend on the number of segments, sections, and dependent dylibs used.

Using this option will simplify some future test cases because the final
address of code can be pinned down, making tests of its content easier.

Added:
    lld/trunk/test/mach-o/sectalign.yaml
Modified:
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/DarwinLdOptions.td
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=214268&r1=214267&r2=214268&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Tue Jul 29 19:58:06 2014
@@ -166,6 +166,12 @@ public:
     _existingPaths.insert(path);
   }
 
+  /// Add section alignment constraint on final layout.
+  void addSectionAlignment(StringRef seg, StringRef sect, uint8_t align2);
+
+  /// Returns true if specified section had alignment constraints.
+  bool sectionAligned(StringRef seg, StringRef sect, uint8_t &align2) const;
+
   StringRef dyldPath() const { return "/usr/lib/dyld"; }
 
   /// Stub creation Pass should be run.
@@ -201,6 +207,12 @@ private:
     uint32_t                  cpusubtype;
   };
 
+  struct SectionAlign {
+    StringRef segmentName;
+    StringRef sectionName;
+    uint8_t   align2;
+  };
+
   static ArchInfo _s_archInfos[];
 
   std::set<StringRef> _existingPaths; // For testing only.
@@ -222,6 +234,7 @@ private:
   StringRef _bundleLoader;
   mutable std::unique_ptr<mach_o::ArchHandler> _archHandler;
   mutable std::unique_ptr<Writer> _writer;
+  std::vector<SectionAlign> _sectAligns;
 };
 
 } // end namespace lld

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=214268&r1=214267&r2=214268&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Tue Jul 29 19:58:06 2014
@@ -23,6 +23,7 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MachO.h"
 #include "llvm/Support/ManagedStatic.h"
@@ -254,6 +255,30 @@ bool DarwinLdDriver::parse(int argc, con
     }
   }
 
+  // Handle -sectalign segname sectname align
+  for (auto &alignArg : parsedArgs->filtered(OPT_sectalign)) {
+    const char* segName   = alignArg->getValue(0);
+    const char* sectName  = alignArg->getValue(1);
+    const char* alignStr  = alignArg->getValue(2);
+    if ((alignStr[0] == '0') && (alignStr[1] == 'x'))
+      alignStr += 2;
+    unsigned long long alignValue;
+    if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) {
+      diagnostics << "error: -sectalign alignment value '"
+                  << alignStr << "' not a valid number\n";
+      return false;
+    }
+    uint8_t align2 = llvm::countTrailingZeros(alignValue);
+    if ( (unsigned long)(1 << align2) != alignValue ) {
+      diagnostics << "warning: alignment for '-sectalign "
+                  << segName << " " << sectName
+                  << llvm::format(" 0x%llX", alignValue)
+                  << "' is not a power of two, using "
+                  << llvm::format("0x%08X", (1 << align2)) << "\n";
+    }
+    ctx.addSectionAlignment(segName, sectName, align2);
+  }
+
   // Handle -mllvm
   for (auto &llvmArg : parsedArgs->filtered(OPT_mllvm)) {
     ctx.appendLLVMOption(llvmArg->getValue());

Modified: lld/trunk/lib/Driver/DarwinLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdOptions.td?rev=214268&r1=214267&r2=214268&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdOptions.td (original)
+++ lld/trunk/lib/Driver/DarwinLdOptions.td Tue Jul 29 19:58:06 2014
@@ -92,6 +92,9 @@ def path_exists : Separate<["-"], "path_
 // general options
 def output : Separate<["-"], "o">, HelpText<"Output file path">;
 def arch : Separate<["-"], "arch">, HelpText<"Architecture to link">;
+def sectalign : MultiArg<["-"], "sectalign", 3>,
+                HelpText<"alignment for segment/section">;
+
 
 // extras
 def help : Flag<["-"], "help">;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=214268&r1=214267&r2=214268&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Tue Jul 29 19:58:06 2014
@@ -422,4 +422,24 @@ ArchHandler &MachOLinkingContext::archHa
 }
 
 
+void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
+                                                               uint8_t align2) {
+  SectionAlign entry;
+  entry.segmentName = seg;
+  entry.sectionName = sect;
+  entry.align2 = align2;
+  _sectAligns.push_back(entry);
+}
+
+bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
+                                                        uint8_t &align2) const {
+  for (const SectionAlign &entry : _sectAligns) {
+    if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
+      align2 = entry.align2;
+      return true;
+    }
+  }
+  return false;
+}
+
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp?rev=214268&r1=214267&r2=214268&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp Tue Jul 29 19:58:06 2014
@@ -58,6 +58,9 @@ public:
   /// Returns the final file size as computed in the constructor.
   size_t      size() const;
 
+  // Returns size of the mach_header and load commands.
+  size_t      headerAndLoadCommandsSize() const;
+
   /// Writes the normalized file as a binary mach-o file to the specified
   /// path.  This does not have a stream interface because the generated
   /// file may need the 'x' bit set.
@@ -200,7 +203,7 @@ private:
 
 size_t headerAndLoadCommandsSize(const NormalizedFile &file) {
   MachOFileLayout layout(file);
-  return layout.size();
+  return layout.headerAndLoadCommandsSize();
 }
 
 StringRef MachOFileLayout::dyldPath() {
@@ -212,6 +215,9 @@ uint32_t MachOFileLayout::pointerAlign(u
 }
 
 
+size_t MachOFileLayout::headerAndLoadCommandsSize() const {
+  return _endOfLoadCommands;
+}
 
 
 MachOFileLayout::MachOFileLayout(const NormalizedFile &file)

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=214268&r1=214267&r2=214268&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Tue Jul 29 19:58:06 2014
@@ -51,7 +51,8 @@ struct AtomInfo {
 };
 
 struct SectionInfo {
-  SectionInfo(StringRef seg, StringRef sect, SectionType type, uint32_t attr=0);
+  SectionInfo(StringRef seg, StringRef sect, SectionType type,
+              const MachOLinkingContext &ctxt, uint32_t attr=0);
 
   StringRef                 segmentName;
   StringRef                 sectionName;
@@ -65,10 +66,15 @@ struct SectionInfo {
   uint32_t                  finalSectionIndex;
 };
 
-SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t, uint32_t a)
- : segmentName(sg), sectionName(sct), type(t), attributes(a),
+SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
+                         const MachOLinkingContext &ctxt, uint32_t attrs)
+ : segmentName(sg), sectionName(sct), type(t), attributes(attrs),
                  address(0), size(0), alignment(0),
                  normalizedSectionIndex(0), finalSectionIndex(0) {
+  uint8_t align;
+  if (ctxt.sectionAligned(segmentName, sectionName, align)) {
+    alignment = align;
+  }
 }
 
 struct SegmentInfo {
@@ -79,10 +85,11 @@ struct SegmentInfo {
   uint64_t                   size;
   uint32_t                   access;
   std::vector<SectionInfo*>  sections;
+  uint32_t                   normalizedSegmentIndex;
 };
 
 SegmentInfo::SegmentInfo(StringRef n)
- : name(n), address(0), size(0), access(0) {
+ : name(n), address(0), size(0), access(0), normalizedSegmentIndex(0) {
 }
 
 
@@ -93,10 +100,11 @@ public:
 
   void      assignAtomsToSections(const lld::File &atomFile);
   void      organizeSections();
-  void      assignAddressesToSections();
+  void      assignAddressesToSections(const NormalizedFile &file);
   uint32_t  fileFlags();
   void      copySegmentInfo(NormalizedFile &file);
-  void      copySections(NormalizedFile &file);
+  void      copySectionInfo(NormalizedFile &file);
+  void      updateSectionInfo(NormalizedFile &file);
   void      buildAtomToAddressMap();
   void      addSymbols(const lld::File &atomFile, NormalizedFile &file);
   void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
@@ -105,6 +113,7 @@ public:
   void      buildDataInCodeArray(const lld::File &, NormalizedFile &file);
   void      addDependentDylibs(const lld::File &, NormalizedFile &file);
   void      copyEntryPointAddress(NormalizedFile &file);
+  void      copySectionContent(NormalizedFile &file);
 
 private:
   typedef std::map<DefinedAtom::ContentType, SectionInfo*> TypeToSection;
@@ -119,7 +128,7 @@ private:
   void         appendAtom(SectionInfo *sect, const DefinedAtom *atom);
   SegmentInfo *segmentForName(StringRef segName);
   void         layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
-  void         layoutSectionsInTextSegment(SegmentInfo *seg, uint64_t &addr);
+  void         layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
   void         copySectionContent(SectionInfo *si, ContentBytes &content);
   uint8_t      scopeBits(const DefinedAtom* atom);
   uint16_t     descBits(const DefinedAtom* atom);
@@ -180,7 +189,8 @@ SectionInfo *Util::getRelocatableSection
   }
   // Otherwise allocate new SectionInfo object.
   SectionInfo *sect = new (_allocator) SectionInfo(segmentName, sectionName, 
-                                                   sectionType, sectionAttrs);
+                                                   sectionType, _context,
+                                                   sectionAttrs);
   _sectionInfos.push_back(sect);
   _sectionMap[type] = sect;
   return sect;
@@ -255,6 +265,7 @@ SectionInfo *Util::getFinalSection(Defin
     SectionInfo *sect = new (_allocator) SectionInfo(p.segmentName,
                                                      p.sectionName,
                                                      p.sectionType,
+                                                     _context,
                                                      sectionAttrs);
     _sectionInfos.push_back(sect);
     _sectionMap[atomType] = sect;
@@ -290,7 +301,7 @@ SectionInfo *Util::sectionForAtom(const
     StringRef segName = customName.slice(0, seperatorIndex);
     StringRef sectName = customName.drop_front(seperatorIndex + 1);
     SectionInfo *sect = new (_allocator) SectionInfo(segName, sectName,
-                                                     S_REGULAR);
+                                                    S_REGULAR, _context);
     _customSections.push_back(sect);
     _sectionInfos.push_back(sect);
     return sect;
@@ -402,11 +413,13 @@ void Util::organizeSections() {
     }
 
     // Record final section indexes.
+    uint32_t segmentIndex = 0;
     uint32_t sectionIndex = 1;
     for (SegmentInfo *seg : _segmentInfos) {
-        for (SectionInfo *sect : seg->sections) {
-          sect->finalSectionIndex = sectionIndex++;
-        }
+      seg->normalizedSegmentIndex = segmentIndex++;
+      for (SectionInfo *sect : seg->sections) {
+        sect->finalSectionIndex = sectionIndex++;
+      }
     }
   }
 
@@ -428,7 +441,8 @@ void Util::layoutSectionsInSegment(Segme
 
 
 // __TEXT segment lays out backwards so padding is at front after load commands.
-void Util::layoutSectionsInTextSegment(SegmentInfo *seg, uint64_t &addr) {
+void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
+                                                               uint64_t &addr) {
   seg->address = addr;
   // Walks sections starting at end to calculate padding for start.
   int64_t taddr = 0;
@@ -437,11 +451,11 @@ void Util::layoutSectionsInTextSegment(S
     taddr -= sect->size;
     taddr = taddr & (0 - (1 << sect->alignment));
   }
-  int64_t padding = taddr;
+  int64_t padding = taddr - hlcSize;
   while (padding < 0)
     padding += _context.pageSize();
   // Start assigning section address starting at padded offset.
-  addr += padding;
+  addr += (padding + hlcSize);
   for (SectionInfo *sect : seg->sections) {
     sect->address = alignTo(addr, sect->alignment);
     addr = sect->address + sect->size;
@@ -450,7 +464,8 @@ void Util::layoutSectionsInTextSegment(S
 }
 
 
-void Util::assignAddressesToSections() {
+void Util::assignAddressesToSections(const NormalizedFile &file) {
+  size_t hlcSize = headerAndLoadCommandsSize(file);
   uint64_t address = 0;  // FIXME
   if (_context.outputMachOType() != llvm::MachO::MH_OBJECT) {
     for (SegmentInfo *seg : _segmentInfos) {
@@ -459,7 +474,7 @@ void Util::assignAddressesToSections() {
         address += seg->size;
       }
       else if (seg->name.equals("__TEXT"))
-        layoutSectionsInTextSegment(seg, address);
+        layoutSectionsInTextSegment(hlcSize, seg, address);
       else
         layoutSectionsInSegment(seg, address);
 
@@ -510,16 +525,7 @@ void Util::copySegmentInfo(NormalizedFil
 }
 
 void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
-  const bool rMode = (_context.outputMachOType() == llvm::MachO::MH_OBJECT);
-
-  // Utility function for ArchHandler to find address of atom in output file.
-  auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
-    auto pos = _atomToAddress.find(&atom);
-    assert(pos != _atomToAddress.end());
-    return pos->second;
-  };
-
-  // Add new empty section to end of file.sections.
+   // Add new empty section to end of file.sections.
   Section temp;
   file.sections.push_back(std::move(temp));
   Section* normSect = &file.sections.back();
@@ -532,19 +538,35 @@ void Util::appendSection(SectionInfo *si
   normSect->alignment     = si->alignment;
   // Record where normalized section is.
   si->normalizedSectionIndex = file.sections.size()-1;
-  // Copy content from atoms to content buffer for section.
-  if (si->type == llvm::MachO::S_ZEROFILL)
-    return;
-  uint8_t *sectionContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
-  normSect->content = llvm::makeArrayRef(sectionContent, si->size);
-  for (AtomInfo &ai : si->atomsAndOffsets) {
-    uint8_t *atomContent = reinterpret_cast<uint8_t*>
+}
+
+void Util::copySectionContent(NormalizedFile &file) {
+  const bool r = (_context.outputMachOType() == llvm::MachO::MH_OBJECT);
+
+  // Utility function for ArchHandler to find address of atom in output file.
+  auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
+    auto pos = _atomToAddress.find(&atom);
+    assert(pos != _atomToAddress.end());
+    return pos->second;
+  };
+
+  for (SectionInfo *si : _sectionInfos) {
+    if (si->type == llvm::MachO::S_ZEROFILL)
+      continue;
+    // Copy content from atoms to content buffer for section.
+    uint8_t *sectionContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
+    Section *normSect = &file.sections[si->normalizedSectionIndex];
+    normSect->content = llvm::makeArrayRef(sectionContent, si->size);
+    for (AtomInfo &ai : si->atomsAndOffsets) {
+      uint8_t *atomContent = reinterpret_cast<uint8_t*>
                                           (&sectionContent[ai.offsetInSection]);
-    _archHandler.generateAtomContent(*ai.atom, rMode, addrForAtom, atomContent);
+      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom, atomContent);
+    }
   }
 }
 
-void Util::copySections(NormalizedFile &file) {
+
+void Util::copySectionInfo(NormalizedFile &file) {
   file.sections.reserve(_sectionInfos.size());
   // For final linked images, write sections grouped by segment.
   if (_context.outputMachOType() != llvm::MachO::MH_OBJECT) {
@@ -561,6 +583,28 @@ void Util::copySections(NormalizedFile &
   }
 }
 
+void Util::updateSectionInfo(NormalizedFile &file) {
+  file.sections.reserve(_sectionInfos.size());
+  if (_context.outputMachOType() != llvm::MachO::MH_OBJECT) {
+    // For final linked images, sections grouped by segment.
+    for (SegmentInfo *sgi : _segmentInfos) {
+      Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
+      normSeg->address = sgi->address;
+      normSeg->size = sgi->size;
+      for (SectionInfo *si : sgi->sections) {
+        Section *normSect = &file.sections[si->normalizedSectionIndex];
+        normSect->address = si->address;
+      }
+    }
+  } else {
+    // Object files write sections in default order.
+    for (SectionInfo *si : _sectionInfos) {
+      Section *normSect = &file.sections[si->normalizedSectionIndex];
+      normSect->address = si->address;
+    }
+  }
+}
+
 void Util::copyEntryPointAddress(NormalizedFile &nFile) {
   if (_context.outputTypeHasEntry()) {
     if (_archHandler.isThumbFunction(*_entryAtom))
@@ -1020,18 +1064,20 @@ normalizedFromAtoms(const lld::File &ato
   Util util(context);
   util.assignAtomsToSections(atomFile);
   util.organizeSections();
-  util.assignAddressesToSections();
-  util.buildAtomToAddressMap();
 
   std::unique_ptr<NormalizedFile> f(new NormalizedFile());
   NormalizedFile &normFile = *f.get();
-  f->arch = context.arch();
-  f->fileType = context.outputMachOType();
-  f->flags = util.fileFlags();
-  f->installName = context.installName();
-  util.copySegmentInfo(normFile);
-  util.copySections(normFile);
+  normFile.arch = context.arch();
+  normFile.fileType = context.outputMachOType();
+  normFile.flags = util.fileFlags();
+  normFile.installName = context.installName();
   util.addDependentDylibs(atomFile, normFile);
+  util.copySegmentInfo(normFile);
+  util.copySectionInfo(normFile);
+  util.assignAddressesToSections(normFile);
+  util.buildAtomToAddressMap();
+  util.updateSectionInfo(normFile);
+  util.copySectionContent(normFile);
   util.addSymbols(atomFile, normFile);
   util.addIndirectSymbols(atomFile, normFile);
   util.addRebaseAndBindingInfo(atomFile, normFile);

Added: lld/trunk/test/mach-o/sectalign.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/sectalign.yaml?rev=214268&view=auto
==============================================================================
--- lld/trunk/test/mach-o/sectalign.yaml (added)
+++ lld/trunk/test/mach-o/sectalign.yaml Tue Jul 29 19:58:06 2014
@@ -0,0 +1,79 @@
+# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -dylib \
+# RUN:   -sectalign __DATA __custom 0x800 -sectalign __TEXT __text 0x400 -o %t \
+# RUN: && llvm-readobj -sections %t | FileCheck %s
+#
+# Test -sectalign option on __text and a custom section.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x8B, 0x05, 0x00, 0x00, 
+                       0x00, 0x00, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 
+                       0x5D, 0xC3 ]
+    relocations:
+      - offset:          0x0000000C
+        type:            X86_64_RELOC_SIGNED
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          1
+      - offset:          0x00000006
+        type:            X86_64_RELOC_SIGNED
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          2
+  - segment:         __DATA
+    section:         __data
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x0000000000000014
+    content:         [ 0x0A, 0x00, 0x00, 0x00 ]
+  - segment:         __DATA
+    section:         __custom
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       2
+    address:         0x0000000000000018
+    content:         [ 0x0A, 0x00, 0x00, 0x00 ]
+global-symbols:
+  - name:            _a
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x0000000000000014
+  - name:            _b
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            3
+    value:           0x0000000000000018
+  - name:            _get
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+
+...
+
+
+# CHECK:  Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
+# CHECK:  Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
+# CHECK:  Address: 0xC00
+
+# CHECK:  Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+# CHECK:  Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+# CHECK:  Address: 0x1000
+
+# CHECK:  Name: __custom (5F 5F 63 75 73 74 6F 6D 00 00 00 00 00 00 00 00)
+# CHECK:  Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+# CHECK:  Address: 0x1800
+





More information about the llvm-commits mailing list