[lld] r323856 - [ELF] Make overlapping output sections an error

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 01:22:44 PST 2018


Author: arichardson
Date: Wed Jan 31 01:22:44 2018
New Revision: 323856

URL: http://llvm.org/viewvc/llvm-project?rev=323856&view=rev
Log:
[ELF] Make overlapping output sections an error

Summary:
While trying to make a linker script behave the same way with lld as it did
with bfd, I discovered that lld currently doesn't diagnose overlapping
output sections. I was getting very strange runtime failures which I
tracked down to overlapping sections in the resulting binary. When linking
with ld.bfd overlapping output sections are an error unless
--noinhibit-exec is passed and I believe lld should behave the same way
here to avoid surprising crashes at runtime.

The patch also uncovered an errors in the tests: arm-thumb-interwork-thunk
was creating a binary where .got.plt was placed at an address overlapping
with .got.

Reviewers: ruiu, grimar, rafael

Reviewed By: ruiu

Differential Revision: https://reviews.llvm.org/D41046

Added:
    lld/trunk/test/ELF/linkerscript/overlapping-sections.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/arm-thumb-interwork-thunk.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=323856&r1=323855&r2=323856&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Jan 31 01:22:44 2018
@@ -10,6 +10,7 @@
 #ifndef LLD_ELF_CONFIG_H
 #define LLD_ELF_CONFIG_H
 
+#include "lld/Common/ErrorHandler.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
@@ -240,6 +241,12 @@ struct Configuration {
 // The only instance of Configuration struct.
 extern Configuration *Config;
 
+static inline void errorOrWarn(const Twine &Msg) {
+  if (!Config->NoinhibitExec)
+    error(Msg);
+  else
+    warn(Msg);
+}
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=323856&r1=323855&r2=323856&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Jan 31 01:22:44 2018
@@ -534,13 +534,6 @@ template <class ELFT> static void addCop
   InX::RelaDyn->addReloc({Target->CopyRel, Sec, 0, false, &SS, 0});
 }
 
-static void errorOrWarn(const Twine &Msg) {
-  if (!Config->NoinhibitExec)
-    error(Msg);
-  else
-    warn(Msg);
-}
-
 // MIPS has an odd notion of "paired" relocations to calculate addends.
 // For example, if a relocation is of R_MIPS_HI16, there must be a
 // R_MIPS_LO16 relocation after that, and an addend is calculated using

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=323856&r1=323855&r2=323856&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jan 31 01:22:44 2018
@@ -62,6 +62,7 @@ private:
   void assignFileOffsets();
   void assignFileOffsetsBinary();
   void setPhdrs();
+  void checkNoOverlappingSections();
   void fixSectionAlignments();
   void openFile();
   void writeTrapInstr();
@@ -454,6 +455,8 @@ template <class ELFT> void Writer<ELFT>:
       Sec->Addr = 0;
   }
 
+  checkNoOverlappingSections();
+
   // It does not make sense try to open the file if we have error already.
   if (errorCount())
     return;
@@ -1903,6 +1906,103 @@ template <class ELFT> void Writer<ELFT>:
   }
 }
 
+static std::string rangeToString(uint64_t Addr, uint64_t Len) {
+  if (Len == 0)
+    return "<emtpy range at 0x" + utohexstr(Addr) + ">";
+  return "[0x" + utohexstr(Addr) + " -> 0x" +
+         utohexstr(Addr + Len - 1) + "]";
+}
+
+// Check whether sections overlap for a specific address range (file offsets,
+// load and virtual adresses).
+//
+// This is a helper function called by Writer::checkNoOverlappingSections().
+template <typename Getter, typename Predicate>
+static void checkForSectionOverlap(ArrayRef<OutputSection *> AllSections,
+                                   StringRef Kind, Getter GetStart,
+                                   Predicate ShouldSkip) {
+  std::vector<OutputSection *> Sections;
+  // By removing all zero-size sections we can simplify the check for overlap to
+  // just checking whether the section range contains the other section's start
+  // address. Additionally, it also slightly speeds up the checking since we
+  // don't bother checking for overlap with sections that can never overlap.
+  for (OutputSection *Sec : AllSections)
+    if (Sec->Size > 0 && !ShouldSkip(Sec))
+      Sections.push_back(Sec);
+
+  // Instead of comparing every OutputSection with every other output section
+  // we sort the sections by address (file offset or load/virtual address). This
+  // way we find all overlapping sections but only need one comparision with the
+  // next section in the common non-overlapping case. The only time we end up
+  // doing more than one iteration of the following nested loop is if there are
+  // overlapping sections.
+  std::sort(Sections.begin(), Sections.end(),
+            [=](const OutputSection *A, const OutputSection *B) {
+              return GetStart(A) < GetStart(B);
+            });
+  for (size_t i = 0; i < Sections.size(); ++i) {
+    OutputSection *Sec = Sections[i];
+    uint64_t Start = GetStart(Sec);
+    for (auto *Other : ArrayRef<OutputSection *>(Sections).slice(i + 1)) {
+      // Since the sections are storted by start address we only need to check
+      // whether the other sections starts before the end of Sec. If this is
+      // not the case we can break out of this loop since all following sections
+      // will also start after the end of Sec.
+      if (Start + Sec->Size <= GetStart(Other))
+        break;
+      errorOrWarn("section " + Sec->Name + " " + Kind +
+                  " range overlaps with " + Other->Name + "\n>>> " + Sec->Name +
+                  " range is " + rangeToString(Start, Sec->Size) + "\n>>> " +
+                  Other->Name + " range is " +
+                  rangeToString(GetStart(Other), Other->Size));
+    }
+  }
+}
+
+// Check for overlapping sections
+//
+// In this function we check that none of the output sections have overlapping
+// file offsets. For SHF_ALLOC sections we also check that the load address
+// ranges and the virtual address ranges don't overlap
+template <class ELFT> void Writer<ELFT>::checkNoOverlappingSections() {
+  // First check for overlapping file offsets. In this case we need to skip
+  // Any section marked as SHT_NOBITS. These sections don't actually occupy
+  // space in the file so Sec->Offset + Sec->Size can overlap with others.
+  // If --oformat binary is specified only add SHF_ALLOC sections are added to
+  // the output file so we skip any non-allocated sections in that case.
+  checkForSectionOverlap(
+      OutputSections, "file", [](const OutputSection *Sec) { return Sec->Offset; },
+      [](const OutputSection *Sec) {
+        return Sec->Type == SHT_NOBITS ||
+               (Config->OFormatBinary && (Sec->Flags & SHF_ALLOC) == 0);
+      });
+
+  // When linking with -r there is no need to check for overlapping virtual/load
+  // addresses since those addresses will only be assigned when the final
+  // executable/shared object is created.
+  if (Config->Relocatable)
+    return;
+
+  // Checking for overlapping virtual and load addresses only needs to take
+  // into account SHF_ALLOC sections since since others will not be loaded.
+  // Furthermore, we also need to skip SHF_TLS sections since these will be
+  // mapped to other addresses at runtime and can therefore have overlapping
+  // ranges in the file.
+  auto SkipNonAllocSections = [](const OutputSection *Sec) {
+    return (Sec->Flags & SHF_ALLOC) == 0 || (Sec->Flags & SHF_TLS);
+  };
+  checkForSectionOverlap(OutputSections, "virtual address",
+                         [](const OutputSection *Sec) { return Sec->Addr; },
+                         SkipNonAllocSections);
+
+  // Finally, check that the load addresses don't overlap. This will usually be
+  // the same as the virtual addresses but can be different when using a linker
+  // script with AT().
+  checkForSectionOverlap(OutputSections, "load address",
+                         [](const OutputSection *Sec) { return Sec->getLMA(); },
+                         SkipNonAllocSections);
+}
+
 // The entry point address is chosen in the following ways.
 //
 // 1. the '-e' entry command-line option;

Modified: lld/trunk/test/ELF/arm-thumb-interwork-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-thunk.s?rev=323856&r1=323855&r2=323856&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-thunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-interwork-thunk.s Wed Jan 31 01:22:44 2018
@@ -8,7 +8,7 @@
 // RUN:       .thumb_caller : { *(.thumb_caller) } \
 // RUN:       .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \
 // RUN:       .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } \
-// RUN:       .got.plt 0x1894 : {  }  } " > %t.script
+// RUN:       .got.plt 0x18b4 : {  }  } " > %t.script
 // RUN: ld.lld --script %t.script %t -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-ABS-THUMB %s
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-ABS-ARM %s
@@ -368,11 +368,11 @@ _start:
 // CHECK-PI-ARM-PLT-NEXT: 183c:         00 f0 9c e5     ldr     pc, [r12]
 // CHECK-PI-ARM-PLT-NEXT: 1840:         7c 00 00 00
 
-// CHECK-DSO-REL:      0x18A0 R_ARM_JUMP_SLOT arm_caller
-// CHECK-DSO-REL-NEXT: 0x18A4 R_ARM_JUMP_SLOT thumb_caller
-// CHECK-DSO-REL-NEXT: 0x18A8 R_ARM_JUMP_SLOT thumb_callee1
-// CHECK-DSO-REL-NEXT: 0x18AC R_ARM_JUMP_SLOT thumb_callee2
-// CHECK-DSO-REL-NEXT: 0x18B0 R_ARM_JUMP_SLOT thumb_callee3
-// CHECK-DSO-REL-NEXT: 0x18B4 R_ARM_JUMP_SLOT arm_callee1
-// CHECK-DSO-REL-NEXT: 0x18B8 R_ARM_JUMP_SLOT arm_callee2
-// CHECK-DSO-REL-NEXT: 0x18BC R_ARM_JUMP_SLOT arm_callee3
+// CHECK-DSO-REL:      0x18C0 R_ARM_JUMP_SLOT arm_caller
+// CHECK-DSO-REL-NEXT: 0x18C4 R_ARM_JUMP_SLOT thumb_caller
+// CHECK-DSO-REL-NEXT: 0x18C8 R_ARM_JUMP_SLOT thumb_callee1
+// CHECK-DSO-REL-NEXT: 0x18CC R_ARM_JUMP_SLOT thumb_callee2
+// CHECK-DSO-REL-NEXT: 0x18D0 R_ARM_JUMP_SLOT thumb_callee3
+// CHECK-DSO-REL-NEXT: 0x18D4 R_ARM_JUMP_SLOT arm_callee1
+// CHECK-DSO-REL-NEXT: 0x18D8 R_ARM_JUMP_SLOT arm_callee2
+// CHECK-DSO-REL-NEXT: 0x18DC R_ARM_JUMP_SLOT arm_callee3

Added: lld/trunk/test/ELF/linkerscript/overlapping-sections.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/overlapping-sections.s?rev=323856&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/overlapping-sections.s (added)
+++ lld/trunk/test/ELF/linkerscript/overlapping-sections.s Wed Jan 31 01:22:44 2018
@@ -0,0 +1,169 @@
+# TODO: maybe this should be converted to an x86 test to get more buildbot coverage
+# REQUIRES: mips
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
+
+# RUN: echo "SECTIONS { \
+# RUN:   .sec1 0x8000 : { sec1_start = .; *(.first_sec) sec1_end = .;} \
+# RUN:   .sec2 0x8800 : { sec2_start = .; *(.second_sec) sec2_end = .;} \
+# RUN: }" > %t.script
+# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
+# RUN: llvm-readobj -sections -program-headers %t.so | FileCheck %s -check-prefix GOOD
+
+# GOOD:        Name: .sec1
+# GOOD-NEXT:   Type: SHT_PROGBITS (0x1)
+# GOOD-NEXT:   Flags [ (0x3)
+# GOOD-NEXT:     SHF_ALLOC (0x2)
+# GOOD-NEXT:     SHF_WRITE (0x1)
+# GOOD-NEXT:   ]
+# GOOD-NEXT:   Address: 0x8000
+# GOOD-NEXT:   Offset: 0x18000
+# GOOD-NEXT:   Size: 256
+
+# GOOD:        Name: .sec2
+# GOOD-NEXT:   Type: SHT_PROGBITS (0x1)
+# GOOD-NEXT:   Flags [ (0x3)
+# GOOD-NEXT:     SHF_ALLOC (0x2)
+# GOOD-NEXT:     SHF_WRITE (0x1)
+# GOOD-NEXT:   ]
+# GOOD-NEXT:   Address: 0x8800
+# GOOD-NEXT:   Offset: 0x18800
+# GOOD-NEXT:   Size: 256
+
+# GOOD:      ProgramHeaders [
+# GOOD-NEXT:  ProgramHeader {
+# GOOD-NEXT:    Type: PT_LOAD (0x1)
+# GOOD-NEXT:    Offset: 0x10000
+# GOOD-NEXT:    VirtualAddress: 0x0
+# GOOD-NEXT:    PhysicalAddress: 0x0
+# GOOD-NEXT:    FileSize: 481
+# GOOD-NEXT:    MemSize: 481
+# GOOD-NEXT:    Flags [ (0x5)
+# GOOD-NEXT:      PF_R (0x4)
+# GOOD-NEXT:      PF_X (0x1)
+# GOOD-NEXT:    ]
+# GOOD-NEXT:    Alignment: 65536
+# GOOD-NEXT:  }
+# GOOD-NEXT:  ProgramHeader {
+# GOOD-NEXT:    Type: PT_LOAD (0x1)
+# GOOD-NEXT:    Offset: 0x18000
+# GOOD-NEXT:    VirtualAddress: 0x8000
+# GOOD-NEXT:    PhysicalAddress: 0x8000
+# GOOD-NEXT:    FileSize: 2320
+# GOOD-NEXT:    MemSize: 2320
+# GOOD-NEXT:    Flags [ (0x6)
+# GOOD-NEXT:      PF_R (0x4)
+# GOOD-NEXT:      PF_W (0x2)
+# GOOD-NEXT:    ]
+# GOOD-NEXT:    Alignment: 65536
+# GOOD-NEXT:  }
+
+# RUN: echo "SECTIONS { \
+# RUN:   .sec1 0x8000 : AT(0x8000) { sec1_start = .; *(.first_sec) sec1_end = .;} \
+# RUN:   .sec2 0x8800 : AT(0x8080) { sec2_start = .; *(.second_sec) sec2_end = .;} \
+# RUN: }" > %t-lma.script
+# RUN: not ld.lld -o %t.so --script %t-lma.script %t.o -shared 2>&1 | FileCheck %s -check-prefix LMA-OVERLAP-ERR
+# LMA-OVERLAP-ERR:      error: section .sec1 load address range overlaps with .sec2
+# LMA-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000 -> 0x80FF]
+# LMA-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8080 -> 0x817F]
+
+# check that we create the expected binary with --noinhibit-exec:
+# RUN: ld.lld -o %t.so --script %t-lma.script %t.o -shared --noinhibit-exec
+
+# Verify that the .sec2 was indeed placed in a PT_LOAD where the PhysAddr
+# overlaps with where .sec1 is loaded:
+# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-LMA
+# BAD-LMA-LABEL: Section Headers:
+# BAD-LMA: .sec1             PROGBITS        0000000000008000 018000 000100 00  WA  0   0  1
+# BAD-LMA: .sec2             PROGBITS        0000000000008800 018800 000100 00  WA  0   0  1
+# BAD-LMA-LABEL: Program Headers:
+# BAD-LMA-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+# BAD-LMA-NEXT:  LOAD           0x010000 0x0000000000000000 0x0000000000000000 0x0001e1 0x0001e1 R E 0x10000
+# BAD-LMA-NEXT:  LOAD           0x018000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW  0x10000
+# BAD-LMA-NEXT:  LOAD           0x018800 0x0000000000008800 0x0000000000008080 0x000110 0x000110 RW  0x10000
+# BAD-LMA-LABEL: Section to Segment mapping:
+# BAD-LMA:  01     .sec1
+# BAD-LMA:  02     .sec2 .data .got
+
+
+# Now try a script where the virtual memory addresses overlap but ensure that the
+# load addresses don't:
+# RUN: echo "SECTIONS { \
+# RUN:   .sec1 0x8000 : AT(0x8000) { sec1_start = .; *(.first_sec) sec1_end = .;} \
+# RUN:   .sec2 0x8020 : AT(0x8800) { sec2_start = .; *(.second_sec) sec2_end = .;} \
+# RUN: }" > %t-vaddr.script
+# RUN: not ld.lld -o %t.so --script %t-vaddr.script %t.o -shared 2>&1 | FileCheck %s -check-prefix VADDR-OVERLAP-ERR
+# VADDR-OVERLAP-ERR:      error: section .sec1 virtual address range overlaps with .sec2
+# VADDR-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000 -> 0x80FF]
+# VADDR-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8020 -> 0x811F]
+
+# Check that the expected binary was created with --noinhibit-exec:
+# RUN: ld.lld -o %t.so --script %t-vaddr.script %t.o -shared --noinhibit-exec
+# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-VADDR
+# BAD-VADDR-LABEL: Section Headers:
+# BAD-VADDR: .sec1             PROGBITS        0000000000008000 018000 000100 00  WA  0   0  1
+# BAD-VADDR: .sec2             PROGBITS        0000000000008020 028020 000100 00  WA  0   0  1
+# BAD-VADDR-LABEL: Program Headers:
+# BAD-VADDR-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+# BAD-VADDR-NEXT:  LOAD           0x010000 0x0000000000000000 0x0000000000000000 0x0001e1 0x0001e1 R E 0x10000
+# BAD-VADDR-NEXT:  LOAD           0x018000 0x0000000000008000 0x0000000000008000 0x000100 0x000100 RW  0x10000
+# BAD-VADDR-NEXT:  LOAD           0x028020 0x0000000000008020 0x0000000000008800 0x000110 0x000110 RW  0x10000
+# BAD-VADDR-LABEL: Section to Segment mapping:
+# BAD-VADDR:  01     .sec1
+# BAD-VADDR:  02     .sec2 .data .got
+
+# Finally check the case where both LMA and vaddr overlap
+
+# RUN: echo "SECTIONS { \
+# RUN:   .sec1 0x8000 : { sec1_start = .; *(.first_sec) sec1_end = .;} \
+# RUN:   .sec2 0x8040 : { sec2_start = .; *(.second_sec) sec2_end = .;} \
+# RUN: }" > %t-both-overlap.script
+
+# RUN: not ld.lld -o %t.so --script %t-both-overlap.script %t.o -shared 2>&1 | FileCheck %s -check-prefix BOTH-OVERLAP-ERR
+
+# BOTH-OVERLAP-ERR:      error: section .sec1 file range overlaps with .sec2
+# BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x18000 -> 0x180FF]
+# BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x18040 -> 0x1813F]
+# BOTH-OVERLAP-ERR:      error: section .sec1 virtual address range overlaps with .sec2
+# BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000 -> 0x80FF]
+# BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8040 -> 0x813F]
+# BOTH-OVERLAP-ERR:      error: section .sec1 load address range overlaps with .sec2
+# BOTH-OVERLAP-ERR-NEXT: >>> .sec1 range is [0x8000 -> 0x80FF]
+# BOTH-OVERLAP-ERR-NEXT: >>> .sec2 range is [0x8040 -> 0x813F]
+
+# RUN: ld.lld -o %t.so --script %t-both-overlap.script %t.o -shared --noinhibit-exec
+# Note: I case everything overlaps we create a binary with overlapping file
+# offsets. ld.bfd seems to place .sec1 to file offset 18000 and .sec2
+# at 18100 so that only virtual addr and LMA overlap
+# However, in order to create such a broken binary the user has to ignore a
+# fatal error by passing --noinhibit-exec, so this behaviour is fine.
+
+# RUN: llvm-objdump -s %t.so | FileCheck %s -check-prefix BROKEN-OUTPUT-FILE
+# BROKEN-OUTPUT-FILE-LABEL: Contents of section .sec1:
+# BROKEN-OUTPUT-FILE-NEXT: 8000 01010101 01010101 01010101 01010101  ................
+# BROKEN-OUTPUT-FILE-NEXT: 8010 01010101 01010101 01010101 01010101  ................
+# BROKEN-OUTPUT-FILE-NEXT: 8020 01010101 01010101 01010101 01010101  ................
+# BROKEN-OUTPUT-FILE-NEXT: 8030 01010101 01010101 01010101 01010101  ................
+# Starting here the contents of .sec2 overwrites .sec1:
+# BROKEN-OUTPUT-FILE-NEXT: 8040 02020202 02020202 02020202 02020202  ................
+
+# RUN: llvm-readobj -sections -program-headers -elf-output-style=GNU %t.so | FileCheck %s -check-prefix BAD-BOTH
+# BAD-BOTH-LABEL: Section Headers:
+# BAD-BOTH: .sec1             PROGBITS        0000000000008000 018000 000100 00  WA  0   0  1
+# BAD-BOTH: .sec2             PROGBITS        0000000000008040 018040 000100 00  WA  0   0  1
+# BAD-BOTH-LABEL: Program Headers:
+# BAD-BOTH-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+# BAD-BOTH-NEXT:  LOAD           0x010000 0x0000000000000000 0x0000000000000000 0x0001e1 0x0001e1 R E 0x10000
+# BAD-BOTH-NEXT:  LOAD           0x018000 0x0000000000008000 0x0000000000008000 0x000150 0x000150 RW  0x10000
+# BAD-BOTH-LABEL: Section to Segment mapping:
+# BAD-BOTH:   01     .sec1 .sec2 .data .got
+
+
+.section        .first_sec,"aw", at progbits
+.rept 0x100
+.byte 1
+.endr
+
+.section        .second_sec,"aw", at progbits
+.rept 0x100
+.byte 2
+.endr




More information about the llvm-commits mailing list