Index: llvm/trunk/lib/Object/ArchiveWriter.cpp =================================================================== --- llvm/trunk/lib/Object/ArchiveWriter.cpp +++ llvm/trunk/lib/Object/ArchiveWriter.cpp @@ -35,6 +35,15 @@ using namespace llvm; +// The SYM64 format is used when an archive's member offsets are larger than +// 32-bits can hold. The need for this shift in format is detected by +// writeArchive. To test this we need to generate a file with a member that has +// an offset larger than 32-bits but this demands a very slow test. To speed +// the test up we use this flag to pretend like the cutoff happens before +// 32-bits and instead happens at some much smaller value. +static cl::opt Sym64Threshold("sym64-threshold", cl::Hidden, + cl::init(32)); + NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef) : Buf(MemoryBuffer::getMemBuffer(BufRef, false)), MemberName(BufRef.getBufferIdentifier()) {} @@ -484,7 +493,7 @@ // If LastOffset isn't going to fit in a 32-bit varible we need to switch // to 64-bit. Note that the file can be larger than 4GB as long as the last // member starts before the 4GB offset. - if (LastOffset >> 32 != 0) + if (LastOffset >= (1ULL << Sym64Threshold)) Kind = object::Archive::K_GNU64; } Index: llvm/trunk/test/Object/archive-GNU64-write.test =================================================================== --- llvm/trunk/test/Object/archive-GNU64-write.test +++ llvm/trunk/test/Object/archive-GNU64-write.test @@ -0,0 +1,39 @@ +# REQUIRES: llvm-64-bits +# REQUIRES: system-linux + +# RUN: yaml2obj %s > %t +# RUN: dd if=%t of=%t bs=1 count=0 seek=1M +# RUN: rm -f %t.lib +# RUN: cp %t %t2 +# RUN: llvm-ar -sym64-threshold=19 cr %t.lib %t %t2 %p/Inputs/trivial-object-test.elf-x86-64 +# RUN: llvm-nm --print-armap %t.lib | FileCheck %s +# RUN: grep SYM64 %t.lib + +# Delete temp files. They are too large. +# RUN: rm -f %t %t2 %t.lib + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: "00" + Size: 32 + +# CHECK: Archive map +# CHECK-NEXT: main in trivial-object-test.elf-x86-64 + +# CHECK: archive-GNU64-write.test.tmp: + +# CHECK: archive-GNU64-write.test.tmp2: + +# CHECK: trivial-object-test.elf-x86-64: +# CHECK-NEXT: U SomeOtherFunction +# CHECK-NEXT: 0000000000000000 T main +# CHECK-NEXT: U puts Index: llvm/trunk/test/Object/archive-SYM64-write.test =================================================================== --- llvm/trunk/test/Object/archive-SYM64-write.test +++ llvm/trunk/test/Object/archive-SYM64-write.test @@ -1,38 +0,0 @@ -# REQUIRES: llvm-64-bits -# REQUIRES: system-linux - -# RUN: yaml2obj %s > %t -# RUN: dd if=%t of=%t bs=1 count=0 seek=2200M -# RUN: rm -f %t.lib -# RUN: cp %t %t2 -# RUN: llvm-ar cr %t.lib %t %t2 %p/Inputs/trivial-object-test.elf-x86-64 -# RUN: llvm-nm --print-armap %t.lib | FileCheck %s - -# Delete temp files. They are too large. -# RUN: rm -f %t %t2 %t.lib - -!ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_X86_64 -Sections: - - Name: .data - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC ] - AddressAlign: 0x0000000000000001 - Content: "00" - Size: 32 - -# CHECK: Archive map -# CHECK-NEXT: main in trivial-object-test.elf-x86-64 - -# CHECK: archive-SYM64-write.test.tmp: - -# CHECK: archive-SYM64-write.test.tmp2: - -# CHECK: trivial-object-test.elf-x86-64: -# CHECK-NEXT: U SomeOtherFunction -# CHECK-NEXT: 0000000000000000 T main -# CHECK-NEXT: U puts