diff --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h --- a/llvm/include/llvm/BinaryFormat/XCOFF.h +++ b/llvm/include/llvm/BinaryFormat/XCOFF.h @@ -27,6 +27,7 @@ constexpr size_t NameSize = 8; constexpr size_t SymbolTableEntrySize = 18; constexpr size_t RelocationSerializationSize32 = 10; +constexpr uint16_t RelocOverflow = 65535; enum ReservedSectionNum : int16_t { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 }; diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -740,8 +740,16 @@ if (Group->empty()) continue; - for (auto &Csect : *Group) - Section->RelocationCount += Csect.Relocations.size(); + for (auto &Csect : *Group) { + const size_t CsectRelocCount = Csect.Relocations.size(); + if (CsectRelocCount >= XCOFF::RelocOverflow || + Section->RelocationCount >= XCOFF::RelocOverflow - CsectRelocCount) + report_fatal_error( + "relocation entries overflowed; overflow section is " + "not implemented yet"); + + Section->RelocationCount += CsectRelocCount; + } } } diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -20,7 +20,6 @@ static const uint8_t FunctionSym = 0x20; static const uint8_t SymTypeMask = 0x07; -static const uint16_t RelocOverflow = 65535; static const uint16_t NoRelMask = 0x0001; // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer @@ -632,7 +631,7 @@ uint16_t SectionIndex = &Sec - sectionHeaderTable32() + 1; - if (Sec.NumberOfRelocations < RelocOverflow) + if (Sec.NumberOfRelocations < XCOFF::RelocOverflow) return Sec.NumberOfRelocations; for (const auto &Sec : sections32()) { if (Sec.Flags == XCOFF::STYP_OVRFLO && diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-huge-relocs.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-huge-relocs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-huge-relocs.ll @@ -0,0 +1,46 @@ +;; This test generates 65535 relocation entries in a single section, +;; which would trigger an overflow section to be generated in 32-bit mode. +;; Since overflow section is not supported yet, we will emit an error instead of +;; generating an invalid binary for now. +; RUN: grep -v RUN: %s | \ +; RUN: sed >%t.overflow.ll 's/SIZE/65535/;s/MACRO/#/;s/#/################/g;s/#/################/g;s/#/################/g;s/#/################/g;s/#/#_/g;s/_#_\([^#]\)/\1/;s/_/, /g;s/#/i8* @c/g;' +; RUN: not --crash llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -mcpu=pwr4 -mattr=-altivec -filetype=obj -o %t.o %t.overflow.ll 2>&1 | \ +; RUN: FileCheck --check-prefix=OVERFLOW %s +; OVERFLOW: LLVM ERROR: relocation entries overflowed; overflow section is not implemented yet + +;; This test generates 65534 relocation entries, an overflow section should +;; not be generated. +; RUN: grep -v RUN: %s | \ +; RUN: sed >%t.ll 's/SIZE/65534/;s/MACRO/#/;s/#/################/g;s/#/################/g;s/#/################/g;s/#/################/g;s/#/#_/g;s/_#_#_\([^#]\)/\1/;s/_/, /g;s/#/i8* @c/g;' +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -mcpu=pwr4 -mattr=-altivec -filetype=obj -o %t.o %t.ll +; RUN: llvm-readobj --section-headers %t.o | FileCheck --check-prefix=XCOFF32 %s + +; RUN: not --crash llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -mcpu=pwr4 -mattr=-altivec -filetype=obj -o %t.o %t.overflow.ll 2>&1 | \ +; RUN: FileCheck --check-prefix=XCOFF64 %s +; RUN: not --crash llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -mcpu=pwr4 -mattr=-altivec -filetype=obj -o %t.o %t.ll 2>&1 | \ +; RUN: FileCheck --check-prefix=XCOFF64 %s +; XCOFF64: LLVM ERROR: 64-bit XCOFF object files are not supported yet. + +@c = external global i8, align 1 +@arr = global [SIZE x i8*] [MACRO], align 8 + +; XCOFF32-NOT: Name: .ovrflo +; XCOFF32-NOT: Type: STYP_OVRFLO +; XCOFF32: Section { +; XCOFF32: Name: .data +; XCOFF32-NEXT: PhysicalAddress: 0x0 +; XCOFF32-NEXT: VirtualAddress: 0x0 +; XCOFF32-NEXT: Size: 0x3FFF8 +; XCOFF32-NEXT: RawDataOffset: 0x64 +; XCOFF32-NEXT: RelocationPointer: 0x4005C +; XCOFF32-NEXT: LineNumberPointer: 0x0 +; XCOFF32-NEXT: NumberOfRelocations: 65534 +; XCOFF32-NEXT: NumberOfLineNumbers: 0 +; XCOFF32-NEXT: Type: STYP_DATA (0x40) +; XCOFF32-NEXT: } +; XCOFF32-NOT: Name: .ovrflo +; XCOFF32-NOT: Type: STYP_OVRFLO