diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-06 20:14:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-06 20:14:02 +0000 |
commit | c09ce7fd2d62d85dcdf370f4bef732380fca4f1b (patch) | |
tree | dd5cf05b9ae703e6fb816b9663d4a0c903e0c2c6 | |
parent | 5d4d137132d719d0d20d119375b205d6a2c721ee (diff) | |
download | src-test2-c09ce7fd2d62d85dcdf370f4bef732380fca4f1b.tar.gz src-test2-c09ce7fd2d62d85dcdf370f4bef732380fca4f1b.zip |
Notes
38 files changed, 271 insertions, 336 deletions
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp index dc3a00ba55ed..4dabd9ebcc6d 100644 --- a/COFF/Driver.cpp +++ b/COFF/Driver.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/TarWriter.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -98,9 +99,9 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) { MemoryBufferRef MBRef = *MB; OwningMBs.push_back(std::move(MB)); - if (Driver->Cpio) - Driver->Cpio->append(relativeToRoot(MBRef.getBufferIdentifier()), - MBRef.getBuffer()); + if (Driver->Tar) + Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()), + MBRef.getBuffer()); return MBRef; } @@ -368,7 +369,7 @@ static std::string createResponseFile(const opt::InputArgList &Args, case OPT_libpath: break; default: - OS << stringize(Arg) << "\n"; + OS << toString(Arg) << "\n"; } } @@ -458,13 +459,17 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { if (auto *Arg = Args.getLastArg(OPT_linkrepro)) { SmallString<64> Path = StringRef(Arg->getValue()); - sys::path::append(Path, "repro"); - ErrorOr<CpioFile *> F = CpioFile::create(Path); - if (F) - Cpio.reset(*F); - else - errs() << "/linkrepro: failed to open " << Path - << ".cpio: " << F.getError().message() << '\n'; + sys::path::append(Path, "repro.tar"); + + Expected<std::unique_ptr<TarWriter>> ErrOrWriter = + TarWriter::create(Path, "repro"); + + if (ErrOrWriter) { + Tar = std::move(*ErrOrWriter); + } else { + errs() << "/linkrepro: failed to open " << Path << ": " + << toString(ErrOrWriter.takeError()) << '\n'; + } } if (Args.filtered_begin(OPT_INPUT) == Args.filtered_end()) @@ -683,10 +688,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { if (!Resources.empty()) addBuffer(convertResToCOFF(Resources)); - if (Cpio) - Cpio->append("response.txt", - createResponseFile(Args, FilePaths, - ArrayRef<StringRef>(SearchPaths).slice(1))); + if (Tar) + Tar->append("response.txt", + createResponseFile(Args, FilePaths, + ArrayRef<StringRef>(SearchPaths).slice(1))); // Handle /largeaddressaware if (Config->is64() || Args.hasArg(OPT_largeaddressaware)) diff --git a/COFF/Driver.h b/COFF/Driver.h index e8114640edec..44894269fcbe 100644 --- a/COFF/Driver.h +++ b/COFF/Driver.h @@ -20,6 +20,7 @@ #include "llvm/Object/COFF.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/TarWriter.h" #include <memory> #include <set> #include <vector> @@ -74,7 +75,7 @@ private: ArgParser Parser; SymbolTable Symtab; - std::unique_ptr<CpioFile> Cpio; // for /linkrepro + std::unique_ptr<llvm::TarWriter> Tar; // for /linkrepro // Opens a file. Path has to be resolved already. MemoryBufferRef openFile(StringRef Path); diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp index 0a97c2185f89..cde355cd3f34 100644 --- a/COFF/InputFiles.cpp +++ b/COFF/InputFiles.cpp @@ -372,6 +372,8 @@ MachineTypes BitcodeFile::getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; } } +} // namespace coff +} // namespace lld // Returns the last element of a path, which is supposed to be a filename. static StringRef getBasename(StringRef Path) { @@ -382,7 +384,7 @@ static StringRef getBasename(StringRef Path) { } // Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)". -std::string toString(InputFile *File) { +std::string lld::toString(coff::InputFile *File) { if (!File) return "(internal)"; if (File->ParentName.empty()) @@ -393,6 +395,3 @@ std::string toString(InputFile *File) { .str(); return StringRef(Res).lower(); } - -} // namespace coff -} // namespace lld diff --git a/COFF/InputFiles.h b/COFF/InputFiles.h index 498a1743e985..1b5d42939cca 100644 --- a/COFF/InputFiles.h +++ b/COFF/InputFiles.h @@ -202,10 +202,9 @@ private: llvm::BumpPtrAllocator Alloc; std::unique_ptr<LTOModule> M; }; - -std::string toString(InputFile *File); - } // namespace coff + +std::string toString(coff::InputFile *File); } // namespace lld #endif diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp index 6de85d581f49..c44537d37135 100644 --- a/COFF/Symbols.cpp +++ b/COFF/Symbols.cpp @@ -19,6 +19,13 @@ using namespace llvm; using namespace llvm::object; +// Returns a symbol name for an error message. +std::string lld::toString(coff::SymbolBody &B) { + if (Optional<std::string> S = coff::demangle(B.getName())) + return ("\"" + *S + "\" (" + B.getName() + ")").str(); + return B.getName(); +} + namespace lld { namespace coff { @@ -73,13 +80,5 @@ Defined *Undefined::getWeakAlias() { return D; return nullptr; } - -// Returns a symbol name for an error message. -std::string toString(SymbolBody &B) { - if (Optional<std::string> S = demangle(B.getName())) - return ("\"" + *S + "\" (" + B.getName() + ")").str(); - return B.getName(); -} - } // namespace coff } // namespace lld diff --git a/COFF/Symbols.h b/COFF/Symbols.h index bc9ad4aa8aff..1ca7366364d7 100644 --- a/COFF/Symbols.h +++ b/COFF/Symbols.h @@ -428,10 +428,9 @@ inline Symbol *SymbolBody::symbol() { return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) - offsetof(Symbol, Body)); } - -std::string toString(SymbolBody &B); - } // namespace coff + +std::string toString(coff::SymbolBody &B); } // namespace lld #endif diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp index a11dbc7cc47f..6afbe62e5ec7 100644 --- a/ELF/Driver.cpp +++ b/ELF/Driver.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include <cstdlib> @@ -182,8 +183,8 @@ Optional<MemoryBufferRef> LinkerDriver::readFile(StringRef Path) { MemoryBufferRef MBRef = MB->getMemBufferRef(); make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership - if (Cpio) - Cpio->append(relativeToRoot(Path), MBRef.getBuffer()); + if (Tar) + Tar->append(relativeToRoot(Path), MBRef.getBuffer()); return MBRef; } @@ -309,14 +310,16 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { if (const char *Path = getReproduceOption(Args)) { // Note that --reproduce is a debug option so you can ignore it // if you are trying to understand the whole picture of the code. - ErrorOr<CpioFile *> F = CpioFile::create(Path); - if (F) { - Cpio.reset(*F); - Cpio->append("response.txt", createResponseFile(Args)); - Cpio->append("version.txt", getLLDVersion() + "\n"); - } else - error(F.getError(), - Twine("--reproduce: failed to open ") + Path + ".cpio"); + Expected<std::unique_ptr<TarWriter>> ErrOrWriter = + TarWriter::create(Path, path::stem(Path)); + if (ErrOrWriter) { + Tar = std::move(*ErrOrWriter); + Tar->append("response.txt", createResponseFile(Args)); + Tar->append("version.txt", getLLDVersion() + "\n"); + } else { + error(Twine("--reproduce: failed to open ") + Path + ": " + + toString(ErrOrWriter.takeError())); + } } readConfigs(Args); @@ -423,7 +426,7 @@ static uint64_t parseSectionAddress(StringRef S, opt::Arg *Arg) { if (S.startswith("0x")) S = S.drop_front(2); if (S.getAsInteger(16, VA)) - error("invalid argument: " + stringize(Arg)); + error("invalid argument: " + toString(Arg)); return VA; } diff --git a/ELF/Driver.h b/ELF/Driver.h index cba1eb164fdd..dadee5eef355 100644 --- a/ELF/Driver.h +++ b/ELF/Driver.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/TarWriter.h" #include "llvm/Support/raw_ostream.h" namespace lld { @@ -29,7 +30,7 @@ public: void main(ArrayRef<const char *> Args, bool CanExitEarly); void addFile(StringRef Path); void addLibrary(StringRef Name); - std::unique_ptr<CpioFile> Cpio; // for reproduce + std::unique_ptr<llvm::TarWriter> Tar; // for reproduce private: std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB); diff --git a/ELF/DriverUtils.cpp b/ELF/DriverUtils.cpp index a81b133f674b..3a20cd76efe2 100644 --- a/ELF/DriverUtils.cpp +++ b/ELF/DriverUtils.cpp @@ -146,7 +146,7 @@ std::string elf::createResponseFile(const opt::InputArgList &Args) { << "\n"; break; default: - OS << stringize(Arg) << "\n"; + OS << toString(Arg) << "\n"; } } return Data.str(); diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp index f4128c5096cb..bd9f25873c87 100644 --- a/ELF/InputFiles.cpp +++ b/ELF/InputFiles.cpp @@ -92,12 +92,11 @@ std::string elf::ObjectFile<ELFT>::getLineInfo(InputSectionBase<ELFT> *S, DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info); if (Info.Line == 0) return ""; - return convertToUnixPathSeparator(Info.FileName) + ":" + - std::to_string(Info.Line); + return Info.FileName + ":" + std::to_string(Info.Line); } // Returns "(internal)", "foo.a(bar.o)" or "baz.o". -std::string elf::toString(const InputFile *F) { +std::string lld::toString(const InputFile *F) { if (!F) return "(internal)"; if (!F->ArchiveName.empty()) @@ -525,9 +524,9 @@ ArchiveFile::getMember(const Archive::Symbol *Sym) { "could not get the buffer for the member defining symbol " + Sym->getName()); - if (C.getParent()->isThin() && Driver->Cpio) - Driver->Cpio->append(relativeToRoot(check(C.getFullName())), - Ret.getBuffer()); + if (C.getParent()->isThin() && Driver->Tar) + Driver->Tar->append(relativeToRoot(check(C.getFullName())), + Ret.getBuffer()); if (C.getParent()->isThin()) return {Ret, 0}; return {Ret, C.getChildOffset()}; diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h index aba1d71379b0..8b188348199f 100644 --- a/ELF/InputFiles.h +++ b/ELF/InputFiles.h @@ -36,10 +36,16 @@ class InputFile; namespace lld { namespace elf { +class InputFile; +} + +// Returns "(internal)", "foo.a(bar.o)" or "baz.o". +std::string toString(const elf::InputFile *F); + +namespace elf { using llvm::object::Archive; -class InputFile; class Lazy; class SymbolBody; @@ -84,9 +90,6 @@ private: const Kind FileKind; }; -// Returns "(internal)", "foo.a(bar.o)" or "baz.o". -std::string toString(const InputFile *F); - template <typename ELFT> class ELFFileBase : public InputFile { public: typedef typename ELFT::Shdr Elf_Shdr; diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp index 805e51dab507..e87d92aa207c 100644 --- a/ELF/InputSection.cpp +++ b/ELF/InputSection.cpp @@ -34,7 +34,7 @@ using namespace lld::elf; // Returns a string to construct an error message. template <class ELFT> -std::string elf::toString(const InputSectionBase<ELFT> *Sec) { +std::string lld::toString(const InputSectionBase<ELFT> *Sec) { return (Sec->getFile()->getName() + ":(" + Sec->Name + ")").str(); } @@ -844,7 +844,7 @@ template class elf::MergeInputSection<ELF32BE>; template class elf::MergeInputSection<ELF64LE>; template class elf::MergeInputSection<ELF64BE>; -template std::string elf::toString(const InputSectionBase<ELF32LE> *); -template std::string elf::toString(const InputSectionBase<ELF32BE> *); -template std::string elf::toString(const InputSectionBase<ELF64LE> *); -template std::string elf::toString(const InputSectionBase<ELF64BE> *); +template std::string lld::toString(const InputSectionBase<ELF32LE> *); +template std::string lld::toString(const InputSectionBase<ELF32BE> *); +template std::string lld::toString(const InputSectionBase<ELF64LE> *); +template std::string lld::toString(const InputSectionBase<ELF64BE> *); diff --git a/ELF/InputSection.h b/ELF/InputSection.h index adbc1e1e3829..fc7a7fb60973 100644 --- a/ELF/InputSection.h +++ b/ELF/InputSection.h @@ -318,10 +318,9 @@ private: }; template <class ELFT> InputSection<ELFT> InputSection<ELFT>::Discarded; - -template <class ELFT> std::string toString(const InputSectionBase<ELFT> *); - } // namespace elf + +template <class ELFT> std::string toString(const elf::InputSectionBase<ELFT> *); } // namespace lld #endif diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp index 5057b57a4a54..ccc1059949db 100644 --- a/ELF/LinkerScript.cpp +++ b/ELF/LinkerScript.cpp @@ -264,42 +264,12 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { } template <class ELFT> -static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, - StringRef OutsecName) { - // When using linker script the merge rules are different. - // Unfortunately, linker scripts are name based. This means that expressions - // like *(.foo*) can refer to multiple input sections that would normally be - // placed in different output sections. We cannot put them in different - // output sections or we would produce wrong results for - // start = .; *(.foo.*) end = .; *(.bar) - // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to - // another. The problem is that there is no way to layout those output - // sections such that the .foo sections are the only thing between the - // start and end symbols. - - // An extra annoyance is that we cannot simply disable merging of the contents - // of SHF_MERGE sections, but our implementation requires one output section - // per "kind" (string or not, which size/aligment). - // Fortunately, creating symbols in the middle of a merge section is not - // supported by bfd or gold, so we can just create multiple section in that - // case. - typedef typename ELFT::uint uintX_t; - uintX_t Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); - - uintX_t Alignment = 0; - if (isa<MergeInputSection<ELFT>>(C)) - Alignment = std::max<uintX_t>(C->Alignment, C->Entsize); - - return SectionKey<ELFT::Is64Bits>{OutsecName, /*Type*/ 0, Flags, Alignment}; -} - -template <class ELFT> void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, InputSectionBase<ELFT> *Sec, StringRef Name) { OutputSectionBase *OutSec; bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); + std::tie(OutSec, IsNew) = Factory.create(Sec, Name); if (IsNew) OutputSections->push_back(OutSec); OutSec->addSection(Sec); diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp index bf7f9c29a29a..a9d951dcc745 100644 --- a/ELF/OutputSections.cpp +++ b/ELF/OutputSections.cpp @@ -534,41 +534,111 @@ static typename ELFT::uint getOutFlags(InputSectionBase<ELFT> *S) { return S->Flags & ~SHF_GROUP & ~SHF_COMPRESSED; } +namespace llvm { +template <> struct DenseMapInfo<lld::elf::SectionKey> { + static lld::elf::SectionKey getEmptyKey(); + static lld::elf::SectionKey getTombstoneKey(); + static unsigned getHashValue(const lld::elf::SectionKey &Val); + static bool isEqual(const lld::elf::SectionKey &LHS, + const lld::elf::SectionKey &RHS); +}; +} + template <class ELFT> -static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, - StringRef OutsecName) { +static SectionKey createKey(InputSectionBase<ELFT> *C, StringRef OutsecName) { + // The ELF spec just says + // ---------------------------------------------------------------- + // In the first phase, input sections that match in name, type and + // attribute flags should be concatenated into single sections. + // ---------------------------------------------------------------- + // + // However, it is clear that at least some flags have to be ignored for + // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be + // ignored. We should not have two output .text sections just because one was + // in a group and another was not for example. + // + // It also seems that that wording was a late addition and didn't get the + // necessary scrutiny. + // + // Merging sections with different flags is expected by some users. One + // reason is that if one file has + // + // int *const bar __attribute__((section(".foo"))) = (int *)0; + // + // gcc with -fPIC will produce a read only .foo section. But if another + // file has + // + // int zed; + // int *const bar __attribute__((section(".foo"))) = (int *)&zed; + // + // gcc with -fPIC will produce a read write section. + // + // Last but not least, when using linker script the merge rules are forced by + // the script. Unfortunately, linker scripts are name based. This means that + // expressions like *(.foo*) can refer to multiple input sections with + // different flags. We cannot put them in different output sections or we + // would produce wrong results for + // + // start = .; *(.foo.*) end = .; *(.bar) + // + // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to + // another. The problem is that there is no way to layout those output + // sections such that the .foo sections are the only thing between the start + // and end symbols. + // + // Given the above issues, we instead merge sections by name and error on + // incompatible types and flags. + // + // The exception being SHF_MERGE, where we create different output sections + // for each alignment. This makes each output section simple. In case of + // relocatable object generation we do not try to perform merging and treat + // SHF_MERGE sections as regular ones, but also create different output + // sections for them to allow merging at final linking stage. + // + // Fortunately, creating symbols in the middle of a merge section is not + // supported by bfd or gold, so the SHF_MERGE exception should not cause + // problems with most linker scripts. + typedef typename ELFT::uint uintX_t; - uintX_t Flags = getOutFlags(C); + uintX_t Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); - // For SHF_MERGE we create different output sections for each alignment. - // This makes each output section simple and keeps a single level mapping from - // input to output. - // In case of relocatable object generation we do not try to perform merging - // and treat SHF_MERGE sections as regular ones, but also create different - // output sections for them to allow merging at final linking stage. uintX_t Alignment = 0; if (isa<MergeInputSection<ELFT>>(C) || (Config->Relocatable && (C->Flags & SHF_MERGE))) Alignment = std::max<uintX_t>(C->Alignment, C->Entsize); - return SectionKey<ELFT::Is64Bits>{OutsecName, C->Type, Flags, Alignment}; + return SectionKey{OutsecName, Flags, Alignment}; } +template <class ELFT> OutputSectionFactory<ELFT>::OutputSectionFactory() {} + +template <class ELFT> OutputSectionFactory<ELFT>::~OutputSectionFactory() {} + template <class ELFT> std::pair<OutputSectionBase *, bool> OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, StringRef OutsecName) { - SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName); + SectionKey Key = createKey(C, OutsecName); return create(Key, C); } +static uint64_t getIncompatibleFlags(uint64_t Flags) { + return Flags & (SHF_ALLOC | SHF_TLS); +} + template <class ELFT> std::pair<OutputSectionBase *, bool> -OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key, +OutputSectionFactory<ELFT>::create(const SectionKey &Key, InputSectionBase<ELFT> *C) { uintX_t Flags = getOutFlags(C); OutputSectionBase *&Sec = Map[Key]; if (Sec) { + if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags)) + error("Section has flags incompatible with others with the same name " + + toString(C)); + if (Sec->Type != C->Type) + error("Section has different type from others with the same name " + + toString(C)); Sec->Flags |= Flags; return {Sec, false}; } @@ -588,36 +658,22 @@ OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key, return {Sec, true}; } -template <bool Is64Bits> -typename lld::elf::SectionKey<Is64Bits> -DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getEmptyKey() { - return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0, 0}; +SectionKey DenseMapInfo<SectionKey>::getEmptyKey() { + return SectionKey{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0}; } -template <bool Is64Bits> -typename lld::elf::SectionKey<Is64Bits> -DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getTombstoneKey() { - return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 0, - 0}; +SectionKey DenseMapInfo<SectionKey>::getTombstoneKey() { + return SectionKey{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 0}; } -template <bool Is64Bits> -unsigned -DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getHashValue(const Key &Val) { - return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment); +unsigned DenseMapInfo<SectionKey>::getHashValue(const SectionKey &Val) { + return hash_combine(Val.Name, Val.Flags, Val.Alignment); } -template <bool Is64Bits> -bool DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::isEqual(const Key &LHS, - const Key &RHS) { +bool DenseMapInfo<SectionKey>::isEqual(const SectionKey &LHS, + const SectionKey &RHS) { return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) && - LHS.Type == RHS.Type && LHS.Flags == RHS.Flags && - LHS.Alignment == RHS.Alignment; -} - -namespace llvm { -template struct DenseMapInfo<SectionKey<true>>; -template struct DenseMapInfo<SectionKey<false>>; + LHS.Flags == RHS.Flags && LHS.Alignment == RHS.Alignment; } namespace lld { diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h index 978b1f8191ef..45e1a232e2a9 100644 --- a/ELF/OutputSections.h +++ b/ELF/OutputSections.h @@ -217,12 +217,10 @@ template <class ELFT> struct Out { static OutputSectionBase *FiniArray; }; -template <bool Is64Bits> struct SectionKey { - typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t; +struct SectionKey { StringRef Name; - uint32_t Type; - uintX_t Flags; - uintX_t Alignment; + uint64_t Flags; + uint64_t Alignment; }; // This class knows how to create an output section for a given @@ -232,16 +230,17 @@ template <bool Is64Bits> struct SectionKey { template <class ELFT> class OutputSectionFactory { typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::uint uintX_t; - typedef typename elf::SectionKey<ELFT::Is64Bits> Key; public: + OutputSectionFactory(); + ~OutputSectionFactory(); std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C, StringRef OutsecName); - std::pair<OutputSectionBase *, bool> - create(const SectionKey<ELFT::Is64Bits> &Key, InputSectionBase<ELFT> *C); + std::pair<OutputSectionBase *, bool> create(const SectionKey &Key, + InputSectionBase<ELFT> *C); private: - llvm::SmallDenseMap<Key, OutputSectionBase *> Map; + llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map; }; template <class ELFT> uint64_t getHeaderSize() { @@ -265,15 +264,5 @@ template <class ELFT> OutputSectionBase *Out<ELFT>::FiniArray; } // namespace elf } // namespace lld -namespace llvm { -template <bool Is64Bits> struct DenseMapInfo<lld::elf::SectionKey<Is64Bits>> { - typedef typename lld::elf::SectionKey<Is64Bits> Key; - - static Key getEmptyKey(); - static Key getTombstoneKey(); - static unsigned getHashValue(const Key &Val); - static bool isEqual(const Key &LHS, const Key &RHS); -}; -} #endif diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp index f168d37bdf0a..72bcff4e0f4d 100644 --- a/ELF/Symbols.cpp +++ b/ELF/Symbols.cpp @@ -305,7 +305,7 @@ void elf::printTraceSymbol(Symbol *Sym) { } // Returns a symbol for an error message. -std::string elf::toString(const SymbolBody &B) { +std::string lld::toString(const SymbolBody &B) { if (Config->Demangle) if (Optional<std::string> S = demangle(B.getName())) return *S; diff --git a/ELF/Symbols.h b/ELF/Symbols.h index cbf8fa81a138..38889571679c 100644 --- a/ELF/Symbols.h +++ b/ELF/Symbols.h @@ -453,10 +453,9 @@ inline Symbol *SymbolBody::symbol() { return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) - offsetof(Symbol, Body)); } - -std::string toString(const SymbolBody &B); - } // namespace elf + +std::string toString(const elf::SymbolBody &B); } // namespace lld #endif diff --git a/ELF/Target.cpp b/ELF/Target.cpp index d82e654b9c4c..cb2b178fa849 100644 --- a/ELF/Target.cpp +++ b/ELF/Target.cpp @@ -44,6 +44,10 @@ using namespace llvm::object; using namespace llvm::support::endian; using namespace llvm::ELF; +std::string lld::toString(uint32_t Type) { + return getELFRelocationTypeName(elf::Config->EMachine, Type); +} + namespace lld { namespace elf { @@ -52,10 +56,6 @@ TargetInfo *Target; static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); } static void or32be(uint8_t *P, int32_t V) { write32be(P, read32be(P) | V); } -std::string toString(uint32_t Type) { - return getELFRelocationTypeName(Config->EMachine, Type); -} - template <class ELFT> static std::string getErrorLoc(uint8_t *Loc) { for (InputSectionData *D : Symtab<ELFT>::X->Sections) { auto *IS = dyn_cast_or_null<InputSection<ELFT>>(D); diff --git a/ELF/Target.h b/ELF/Target.h index 156a2c023230..752f9cd5ee4e 100644 --- a/ELF/Target.h +++ b/ELF/Target.h @@ -104,13 +104,14 @@ public: virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; }; -std::string toString(uint32_t RelType); uint64_t getPPC64TocBase(); uint64_t getAArch64Page(uint64_t Expr); extern TargetInfo *Target; TargetInfo *createTarget(); } + +std::string toString(uint32_t RelType); } #endif diff --git a/include/lld/Core/Reproduce.h b/include/lld/Core/Reproduce.h index cf2747493834..1b65f763acee 100644 --- a/include/lld/Core/Reproduce.h +++ b/include/lld/Core/Reproduce.h @@ -11,46 +11,15 @@ #define LLD_CORE_REPRODUCE_H #include "lld/Core/LLVM.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" namespace llvm { - -class raw_fd_ostream; - namespace opt { class Arg; } - } namespace lld { -// This class creates a .cpio file for --reproduce (ELF) or /linkrepro (COFF). -// -// If "--reproduce foo" is given, we create a file "foo.cpio" and -// copy all input files to the archive, along with a response file -// to re-run the same command with the same inputs. -// It is useful for reporting issues to LLD developers. -// -// Cpio as a file format is a deliberate choice. It's standardized in -// POSIX and very easy to create. cpio command is available virtually -// on all Unix systems. See -// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_07 -// for the format details. -class CpioFile { -public: - static ErrorOr<CpioFile *> create(StringRef OutputPath); - void append(StringRef Path, StringRef Data); - -private: - CpioFile(std::unique_ptr<llvm::raw_fd_ostream> OS, StringRef Basename); - - std::unique_ptr<llvm::raw_fd_ostream> OS; - llvm::StringSet<> Seen; - std::string Basename; -}; - // Makes a given pathname an absolute path first, and then remove // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", // assuming that the current directory is "/home/john/bar". @@ -64,7 +33,7 @@ std::string quote(StringRef S); std::string rewritePath(StringRef S); // Returns the string form of the given argument. -std::string stringize(llvm::opt::Arg *Arg); +std::string toString(llvm::opt::Arg *Arg); // Replaces backslashes with slashes if Windows. std::string convertToUnixPathSeparator(StringRef S); diff --git a/lib/Core/Reproduce.cpp b/lib/Core/Reproduce.cpp index 39b0e41c44e5..ab7261fa0e75 100644 --- a/lib/Core/Reproduce.cpp +++ b/lib/Core/Reproduce.cpp @@ -8,66 +8,14 @@ //===----------------------------------------------------------------------===// #include "lld/Core/Reproduce.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Twine.h" #include "llvm/Option/Arg.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/Format.h" #include "llvm/Support/Path.h" using namespace lld; using namespace llvm; -using namespace sys; - -CpioFile::CpioFile(std::unique_ptr<raw_fd_ostream> OS, StringRef S) - : OS(std::move(OS)), Basename(S) {} - -ErrorOr<CpioFile *> CpioFile::create(StringRef OutputPath) { - std::string Path = (OutputPath + ".cpio").str(); - std::error_code EC; - auto OS = llvm::make_unique<raw_fd_ostream>(Path, EC, sys::fs::F_None); - if (EC) - return EC; - return new CpioFile(std::move(OS), path::filename(OutputPath)); -} - -static void writeMember(raw_fd_ostream &OS, StringRef Path, StringRef Data) { - // The c_dev/c_ino pair should be unique according to the spec, - // but no one seems to care. - OS << "070707"; // c_magic - OS << "000000"; // c_dev - OS << "000000"; // c_ino - OS << "100664"; // c_mode: C_ISREG | rw-rw-r-- - OS << "000000"; // c_uid - OS << "000000"; // c_gid - OS << "000001"; // c_nlink - OS << "000000"; // c_rdev - OS << "00000000000"; // c_mtime - OS << format("%06o", Path.size() + 1); // c_namesize - OS << format("%011o", Data.size()); // c_filesize - OS << Path << '\0'; // c_name - OS << Data; // c_filedata -} - -void CpioFile::append(StringRef Path, StringRef Data) { - if (!Seen.insert(Path).second) - return; - - // Construct an in-archive filename so that /home/foo/bar is stored - // as baz/home/foo/bar where baz is the basename of the output file. - // (i.e. in that case we are creating baz.cpio.) - SmallString<128> Fullpath; - path::append(Fullpath, Basename, Path); - - writeMember(*OS, convertToUnixPathSeparator(Fullpath), Data); - - // Print the trailer and seek back. - // This way we have a valid archive if we crash. - uint64_t Pos = OS->tell(); - writeMember(*OS, "TRAILER!!!", ""); - OS->seek(Pos); -} +using namespace llvm::sys; // Makes a given pathname an absolute path first, and then remove // beginning /. For example, "../foo.o" is converted to "home/john/foo.o", @@ -76,7 +24,7 @@ void CpioFile::append(StringRef Path, StringRef Data) { // a mess with backslash-as-escape and backslash-as-path-separator. std::string lld::relativeToRoot(StringRef Path) { SmallString<128> Abs = Path; - if (sys::fs::make_absolute(Abs)) + if (fs::make_absolute(Abs)) return Path; path::remove_dots(Abs, /*remove_dot_dot=*/true); @@ -107,7 +55,7 @@ std::string lld::rewritePath(StringRef S) { return S; } -std::string lld::stringize(opt::Arg *Arg) { +std::string lld::toString(opt::Arg *Arg) { std::string K = Arg->getSpelling(); if (Arg->getNumValues() == 0) return K; diff --git a/test/COFF/linkrepro.test b/test/COFF/linkrepro.test index b3c13764d81d..a1d85a159a72 100644 --- a/test/COFF/linkrepro.test +++ b/test/COFF/linkrepro.test @@ -1,6 +1,3 @@ -# cpio fails on windows with "Function not implemented". -# REQUIRES: shell - # RUN: rm -rf %t.dir # RUN: mkdir -p %t.dir/build1 %t.dir/build2 %t.dir/build3 # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj @@ -8,7 +5,7 @@ # RUN: cd %t.dir/build1 # RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \ # RUN: /entry:main@0 /linkrepro:. /out:%t.exe -# RUN: cpio -id < repro.cpio +# RUN: tar xf repro.tar # RUN: diff %t.obj repro/%:t.obj # RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib # RUN: FileCheck %s --check-prefix=RSP < repro/response.txt @@ -16,7 +13,7 @@ # RUN: cd %t.dir/build2 # RUN: lld-link %t.obj /libpath:%p/Inputs /defaultlib:std32 /subsystem:console \ # RUN: /entry:main@0 /linkrepro:. /out:%t.exe -# RUN: cpio -id < repro.cpio +# RUN: tar xf repro.tar # RUN: diff %t.obj repro/%:t.obj # RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib # RUN: FileCheck %s --check-prefix=RSP < repro/response.txt @@ -24,7 +21,7 @@ # RUN: cd %t.dir/build3 # RUN: env LIB=%p/Inputs lld-link %t.obj /defaultlib:std32 /subsystem:console \ # RUN: /entry:main@0 /linkrepro:. /out:%t.exe -# RUN: cpio -id < repro.cpio +# RUN: tar xf repro.tar # RUN: diff %t.obj repro/%:t.obj # RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib # RUN: FileCheck %s --check-prefix=RSP < repro/response.txt diff --git a/test/ELF/incompatible-section-flags.s b/test/ELF/incompatible-section-flags.s new file mode 100644 index 000000000000..efca31bb9a80 --- /dev/null +++ b/test/ELF/incompatible-section-flags.s @@ -0,0 +1,18 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s + +// CHECK: error: Section has flags incompatible with others with the same name {{.*}}incompatible-section-flags.s.tmp.o:(.foo) +// CHECK: error: Section has flags incompatible with others with the same name {{.*}}incompatible-section-flags.s.tmp.o:(.bar) + +.section .foo, "awT", @progbits, unique, 1 +.quad 0 + +.section .foo, "aw", @progbits, unique, 2 +.quad 0 + + +.section .bar, "aw", @progbits, unique, 3 +.quad 0 + +.section .bar, "awT", @progbits, unique, 4 +.quad 0 diff --git a/test/ELF/incompatible-section-types.s b/test/ELF/incompatible-section-types.s new file mode 100644 index 000000000000..0d075aca068b --- /dev/null +++ b/test/ELF/incompatible-section-types.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s + +// CHECK: error: Section has different type from others with the same name {{.*}}incompatible-section-types.s.tmp.o:(.foo) + +.section .foo, "aw", @progbits, unique, 1 +.quad 0 + +.section .foo, "aw", @nobits, unique, 2 +.quad 0 diff --git a/test/ELF/linkerscript/phdrs.s b/test/ELF/linkerscript/phdrs.s index a7476e802341..025ced95b30a 100644 --- a/test/ELF/linkerscript/phdrs.s +++ b/test/ELF/linkerscript/phdrs.s @@ -93,7 +93,7 @@ ## Check the numetic values for PHDRS. # RUN: echo "PHDRS {text PT_LOAD FILEHDR PHDRS; foo 0x11223344; } \ -# RUN: SECTIONS { . = SIZEOF_HEADERS; .foo : { *(.*) } : text : foo}" > %t1.script +# RUN: SECTIONS { . = SIZEOF_HEADERS; .foo : { *(.foo* .text*) } : text : foo}" > %t1.script # RUN: ld.lld -o %t2 --script %t1.script %t # RUN: llvm-readobj -program-headers %t2 | FileCheck --check-prefix=INT-PHDRS %s diff --git a/test/ELF/linkerscript/sections.s b/test/ELF/linkerscript/sections.s index 416e77346a59..2cb9395e6692 100644 --- a/test/ELF/linkerscript/sections.s +++ b/test/ELF/linkerscript/sections.s @@ -20,11 +20,10 @@ # SEC-DEFAULT: 2 .data 00000020 {{[0-9a-f]*}} DATA # SEC-DEFAULT: 3 other 00000003 {{[0-9a-f]*}} DATA # SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS -# SEC-DEFAULT: 5 .shstrtab 00000002 {{[0-9a-f]*}} -# SEC-DEFAULT: 6 .comment 00000008 {{[0-9a-f]*}} -# SEC-DEFAULT: 7 .symtab 00000030 {{[0-9a-f]*}} -# SEC-DEFAULT: 8 .shstrtab 0000003b {{[0-9a-f]*}} -# SEC-DEFAULT: 9 .strtab 00000008 {{[0-9a-f]*}} +# SEC-DEFAULT: 5 .comment 00000008 {{[0-9a-f]*}} +# SEC-DEFAULT: 6 .symtab 00000030 {{[0-9a-f]*}} +# SEC-DEFAULT: 7 .shstrtab 0000003b {{[0-9a-f]*}} +# SEC-DEFAULT: 8 .strtab 00000008 {{[0-9a-f]*}} # Sections are put in order specified in linker script, other than alloc # sections going first. @@ -43,12 +42,11 @@ # Idx Name Size # SEC-ORDER: 1 .bss 00000002 {{[0-9a-f]*}} BSS # SEC-ORDER: 2 other 00000003 {{[0-9a-f]*}} DATA -# SEC-ORDER: 3 .shstrtab 00000002 {{[0-9a-f]*}} -# SEC-ORDER: 4 .shstrtab 0000003b {{[0-9a-f]*}} -# SEC-ORDER: 5 .symtab 00000030 {{[0-9a-f]*}} -# SEC-ORDER: 6 .strtab 00000008 {{[0-9a-f]*}} -# SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA -# SEC-ORDER: 8 .text 0000000e {{[0-9a-f]*}} TEXT DATA +# SEC-ORDER: 3 .shstrtab 0000003b {{[0-9a-f]*}} +# SEC-ORDER: 4 .symtab 00000030 {{[0-9a-f]*}} +# SEC-ORDER: 5 .strtab 00000008 {{[0-9a-f]*}} +# SEC-ORDER: 6 .data 00000020 {{[0-9a-f]*}} DATA +# SEC-ORDER: 7 .text 0000000e {{[0-9a-f]*}} TEXT DATA # .text and .data have swapped names but proper sizes and types. # RUN: echo "SECTIONS { \ @@ -63,11 +61,10 @@ # SEC-SWAP-NAMES: 2 .text 00000020 {{[0-9a-f]*}} DATA # SEC-SWAP-NAMES: 3 other 00000003 {{[0-9a-f]*}} DATA # SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS -# SEC-SWAP-NAMES: 5 .shstrtab 00000002 {{[0-9a-f]*}} -# SEC-SWAP-NAMES: 6 .comment 00000008 {{[0-9a-f]*}} -# SEC-SWAP-NAMES: 7 .symtab 00000030 {{[0-9a-f]*}} -# SEC-SWAP-NAMES: 8 .shstrtab 0000003b {{[0-9a-f]*}} -# SEC-SWAP-NAMES: 9 .strtab 00000008 {{[0-9a-f]*}} +# SEC-SWAP-NAMES: 5 .comment 00000008 {{[0-9a-f]*}} +# SEC-SWAP-NAMES: 6 .symtab 00000030 {{[0-9a-f]*}} +# SEC-SWAP-NAMES: 7 .shstrtab 0000003b {{[0-9a-f]*}} +# SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}} # .shstrtab from the input object file is discarded. # RUN: echo "SECTIONS { \ @@ -102,11 +99,10 @@ # SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA # SEC-MULTI: 2 .data 00000023 {{[0-9a-f]*}} DATA # SEC-MULTI: 3 .bss 00000002 {{[0-9a-f]*}} BSS -# SEC-MULTI: 4 .shstrtab 00000002 {{[0-9a-f]*}} -# SEC-MULTI: 5 .comment 00000008 {{[0-9a-f]*}} -# SEC-MULTI: 6 .symtab 00000030 {{[0-9a-f]*}} -# SEC-MULTI: 7 .shstrtab 00000035 {{[0-9a-f]*}} -# SEC-MULTI: 8 .strtab 00000008 {{[0-9a-f]*}} +# SEC-MULTI: 4 .comment 00000008 {{[0-9a-f]*}} +# SEC-MULTI: 5 .symtab 00000030 {{[0-9a-f]*}} +# SEC-MULTI: 6 .shstrtab 00000035 {{[0-9a-f]*}} +# SEC-MULTI: 7 .strtab 00000008 {{[0-9a-f]*}} .globl _start _start: @@ -118,7 +114,5 @@ _start: .section other,"aw" .short 10 .byte 20 -.section .shstrtab,"" -.short 20 .section .bss,"",@nobits .short 0 diff --git a/test/ELF/reproduce-backslash.s b/test/ELF/reproduce-backslash.s index 849c8f8fb3dd..53feb5ff3223 100644 --- a/test/ELF/reproduce-backslash.s +++ b/test/ELF/reproduce-backslash.s @@ -1,9 +1,9 @@ -# REQUIRES: x86, cpio, shell +# REQUIRES: x86, shell # Test that we don't erroneously replace \ with / on UNIX, as it's # legal for a filename to contain backslashes. # RUN: llvm-mc %s -o foo\\.o -filetype=obj -triple=x86_64-pc-linux -# RUN: ld.lld foo\\.o --reproduce repro -# RUN: cpio -it < repro.cpio | FileCheck %s +# RUN: ld.lld foo\\.o --reproduce repro.tar +# RUN: tar tf repro.tar | FileCheck %s -# CHECK: repro/{{.*}}/foo\.o +# CHECK: repro/{{.*}}/foo\\.o diff --git a/test/ELF/reproduce-error.s b/test/ELF/reproduce-error.s index c66132c4bd01..e2de8a4feeba 100644 --- a/test/ELF/reproduce-error.s +++ b/test/ELF/reproduce-error.s @@ -1,15 +1,14 @@ -# Extracting the cpio archive can get over the path limit on windows. +# Extracting the tar archive can get over the path limit on windows. # REQUIRES: shell # RUN: rm -rf %t.dir # RUN: mkdir -p %t.dir # RUN: cd %t.dir -# RUN: not ld.lld --reproduce repro abc -o t 2>&1 | FileCheck %s +# RUN: not ld.lld --reproduce repro.tar abc -o t 2>&1 | FileCheck %s # CHECK: cannot open abc: {{N|n}}o such file or directory -# RUN: grep TRAILER repro.cpio -# RUN: cpio -id < repro.cpio +# RUN: tar xf repro.tar # RUN: FileCheck --check-prefix=RSP %s < repro/response.txt # RSP: abc # RSP: -o t diff --git a/test/ELF/reproduce-linkerscript.s b/test/ELF/reproduce-linkerscript.s index a020fcc9a4f1..1938e2b6cf94 100644 --- a/test/ELF/reproduce-linkerscript.s +++ b/test/ELF/reproduce-linkerscript.s @@ -5,8 +5,8 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build/foo.o # RUN: echo "INPUT(\"%t.dir/build/foo.o\")" > %t.dir/build/foo.script # RUN: cd %t.dir -# RUN: ld.lld build/foo.script -o bar --reproduce repro -# RUN: cpio -id < repro.cpio +# RUN: ld.lld build/foo.script -o bar --reproduce repro.tar +# RUN: tar xf repro.tar # RUN: diff build/foo.script repro/%:t.dir/build/foo.script # RUN: diff build/foo.o repro/%:t.dir/build/foo.o diff --git a/test/ELF/reproduce-thin-archive.s b/test/ELF/reproduce-thin-archive.s index 0797b6c67e9c..2de88d77f51b 100644 --- a/test/ELF/reproduce-thin-archive.s +++ b/test/ELF/reproduce-thin-archive.s @@ -5,8 +5,8 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.dir/foo.o # RUN: cd %t.dir # RUN: llvm-ar --format=gnu rcT foo.a foo.o -# RUN: ld.lld -m elf_x86_64 foo.a -o bar --reproduce repro -# RUN: cpio -id < repro.cpio +# RUN: ld.lld -m elf_x86_64 foo.a -o bar --reproduce repro.tar +# RUN: tar xf repro.tar # RUN: diff foo.a repro/%:t.dir/foo.a # RUN: diff foo.o repro/%:t.dir/foo.o diff --git a/test/ELF/reproduce-windows.s b/test/ELF/reproduce-windows.s index 4825a8a95e78..6dd1fe2eeadb 100644 --- a/test/ELF/reproduce-windows.s +++ b/test/ELF/reproduce-windows.s @@ -1,12 +1,12 @@ -# REQUIRES: x86, cpio +# REQUIRES: x86 # Test that a repro archive always uses / instead of \. # RUN: rm -rf %t.dir # RUN: mkdir -p %t.dir/build # RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux # RUN: cd %t.dir -# RUN: ld.lld build/foo.o --reproduce repro -# RUN: cpio -it < repro.cpio | FileCheck %s +# RUN: ld.lld build/foo.o --reproduce repro.tar +# RUN: tar tf repro.tar | FileCheck %s # CHECK: repro/response.txt # CHECK: repro/{{.*}}/build/foo.o diff --git a/test/ELF/reproduce-windows2.s b/test/ELF/reproduce-windows2.s index d428288a3640..38e00247eaf1 100644 --- a/test/ELF/reproduce-windows2.s +++ b/test/ELF/reproduce-windows2.s @@ -1,11 +1,10 @@ -# REQUIRES: system-windows, x86, cpio +# REQUIRES: system-windows, x86 # Test that a response.txt file always uses / instead of \. # RUN: rm -rf %t.dir # RUN: mkdir -p %t.dir/build # RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux # RUN: cd %t.dir -# RUN: ld.lld build/foo.o --reproduce repro -# RUN: echo "*response.txt" > list.txt -# RUN: cpio -i --to-stdout --pattern-file=list.txt < repro.cpio | FileCheck %s +# RUN: ld.lld build/foo.o --reproduce repro.tar +# RUN: tar -O -x -f repro.tar repro/response.txt | FileCheck %s # CHECK: {{.*}}/build/foo.o diff --git a/test/ELF/reproduce.s b/test/ELF/reproduce.s index 471a0f82da44..c7955e02a822 100644 --- a/test/ELF/reproduce.s +++ b/test/ELF/reproduce.s @@ -1,14 +1,14 @@ -# REQUIRES: x86, cpio +# REQUIRES: x86 -# Extracting the cpio archive can get over the path limit on windows. +# Extracting the tar archive can get over the path limit on windows. # REQUIRES: shell # RUN: rm -rf %t.dir # RUN: mkdir -p %t.dir/build1 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build1/foo.o # RUN: cd %t.dir -# RUN: ld.lld --hash-style=gnu build1/foo.o -o bar -shared --as-needed --reproduce repro -# RUN: cpio -id < repro.cpio +# RUN: ld.lld --hash-style=gnu build1/foo.o -o bar -shared --as-needed --reproduce repro.tar +# RUN: tar xf repro.tar # RUN: diff build1/foo.o repro/%:t.dir/build1/foo.o # RUN: FileCheck %s --check-prefix=RSP < repro/response.txt @@ -25,8 +25,8 @@ # RUN: mkdir -p %t.dir/build2/a/b/c # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build2/foo.o # RUN: cd %t.dir/build2/a/b/c -# RUN: env LLD_REPRODUCE=repro ld.lld ./../../../foo.o -o bar -shared --as-needed -# RUN: cpio -id < repro.cpio +# RUN: env LLD_REPRODUCE=repro.tar ld.lld ./../../../foo.o -o bar -shared --as-needed +# RUN: tar xf repro.tar # RUN: diff %t.dir/build2/foo.o repro/%:t.dir/build2/foo.o # RUN: echo "{ local: *; };" > ver @@ -34,10 +34,10 @@ # RUN: echo > file # RUN: echo > file2 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar' -# RUN: ld.lld --reproduce repro2 'foo bar' -L"foo bar" -Lfile -Tfile2 \ +# RUN: ld.lld --reproduce repro2.tar 'foo bar' -L"foo bar" -Lfile -Tfile2 \ # RUN: --dynamic-list dyn -rpath file --script=file --version-script ver \ # RUN: --dynamic-linker "some unusual/path" -soname 'foo bar' -soname='foo bar' -# RUN: cpio -id < repro2.cpio +# RUN: tar xf repro2.tar # RUN: FileCheck %s --check-prefix=RSP2 < repro2/response.txt # RSP2: "{{.*}}foo bar" # RSP2-NEXT: -L "{{.*}}foo bar" @@ -51,7 +51,7 @@ # RSP2-NEXT: -soname="foo bar" # RSP2-NEXT: -soname="foo bar" -# RUN: cpio -it < repro2.cpio | FileCheck %s +# RUN: tar tf repro2.tar | FileCheck %s # CHECK: repro2/response.txt # CHECK-NEXT: repro2/version.txt # CHECK-NEXT: repro2/{{.*}}/dyn diff --git a/test/ELF/section-name.s b/test/ELF/section-name.s index 53f0e536f3d6..06d741b2ea77 100644 --- a/test/ELF/section-name.s +++ b/test/ELF/section-name.s @@ -19,9 +19,9 @@ _start: .byte 0 .section .data,"aw" .byte 0 -.section .bss.a,"",@nobits +.section .bss.a,"aw",@nobits .byte 0 -.section .bss,"",@nobits +.section .bss,"aw",@nobits .byte 0 .section .foo.a,"aw" .byte 0 @@ -51,9 +51,8 @@ _start: // CHECK: 7 .data 00000002 // CHECK: 8 .foo.a 00000001 // CHECK: 9 .foo 00000001 -// CHECK: 10 .bss 00000001 -// CHECK: 11 .bss 00000001 -// CHECK: 12 .comment 00000008 -// CHECK: 13 .symtab 00000060 -// CHECK: 14 .shstrtab 00000075 -// CHECK: 15 .strtab 0000001d +// CHECK: 10 .bss 00000002 +// CHECK: 11 .comment 00000008 +// CHECK: 12 .symtab 00000060 +// CHECK: 13 .shstrtab 00000075 +// CHECK: 14 .strtab 0000001d diff --git a/test/ELF/string-table.s b/test/ELF/string-table.s index 92b8345976d8..490c4d574cf1 100644 --- a/test/ELF/string-table.s +++ b/test/ELF/string-table.s @@ -6,10 +6,7 @@ .global _start _start: -.section foobar,"",@progbits,unique,1 -.section foobar,"T",@progbits,unique,2 -.section foobar,"",@nobits,unique,3 -.section foobar,"",@nobits,unique,4 +.section foobar,"",@progbits .section bar, "a" @@ -27,17 +24,4 @@ _start: // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK: Name: foobar -// CHECK-NEXT: Type: SHT_PROGBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_TLS -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x0 - -// CHECK: Name: foobar -// CHECK-NEXT: Type: SHT_NOBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x0 - // CHECK-NOT: Name: foobar diff --git a/test/ELF/undef.s b/test/ELF/undef.s index 5fcd75f948b0..d0f95a3b6381 100644 --- a/test/ELF/undef.s +++ b/test/ELF/undef.s @@ -9,9 +9,9 @@ # CHECK: error: undef.s:(.text+0x6): undefined symbol 'bar' # CHECK: error: undef.s:(.text+0x10): undefined symbol 'foo(int)' # CHECK: error: {{.*}}2.a({{.*}}.o):(.text+0x0): undefined symbol 'zed2' -# CHECK: error: dir/undef-debug.s:3: undefined symbol 'zed3' -# CHECK: error: dir/undef-debug.s:7: undefined symbol 'zed4' -# CHECK: error: dir/undef-debug.s:11: undefined symbol 'zed5' +# CHECK: error: dir{{/|\\}}undef-debug.s:3: undefined symbol 'zed3' +# CHECK: error: dir{{/|\\}}undef-debug.s:7: undefined symbol 'zed4' +# CHECK: error: dir{{/|\\}}undef-debug.s:11: undefined symbol 'zed5' # RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \ # RUN: FileCheck -check-prefix=NO-DEMANGLE %s diff --git a/test/lit.cfg b/test/lit.cfg index a4105b34e122..0db879312413 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -258,7 +258,3 @@ cvtres = lit.util.which('cvtres', config.environment['PATH']) rc = lit.util.which('rc', config.environment['PATH']) if cvtres and rc: config.available_features.add('winres') - -# Check if "cpio" command exists. -if lit.util.which('cpio', config.environment['PATH']): - config.available_features.add('cpio') |