mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-01 13:20:25 +00:00
Add linker-script-included files to reproduce tar files.
Previously, files added using INCLUDE directive weren't added to reproduce archives. In this patch, I defined a function to open a file and use that from Driver and LinkerScript. llvm-svn: 291413
This commit is contained in:
parent
7950d82ab5
commit
ec1c75e059
@ -26,6 +26,7 @@
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/TarWriter.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdlib>
|
||||
@ -51,6 +52,7 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
|
||||
ErrorCount = 0;
|
||||
ErrorOS = &Error;
|
||||
Argv0 = Args[0];
|
||||
Tar = nullptr;
|
||||
|
||||
Config = make<Configuration>();
|
||||
Driver = make<LinkerDriver>();
|
||||
@ -170,25 +172,6 @@ void LinkerDriver::addFile(StringRef Path) {
|
||||
}
|
||||
}
|
||||
|
||||
Optional<MemoryBufferRef> LinkerDriver::readFile(StringRef Path) {
|
||||
if (Config->Verbose)
|
||||
outs() << Path << "\n";
|
||||
|
||||
auto MBOrErr = MemoryBuffer::getFile(Path);
|
||||
if (auto EC = MBOrErr.getError()) {
|
||||
error(EC, "cannot open " + Path);
|
||||
return None;
|
||||
}
|
||||
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
|
||||
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
||||
make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
|
||||
|
||||
if (Tar)
|
||||
Tar->append(relativeToRoot(Path), MBRef.getBuffer());
|
||||
|
||||
return MBRef;
|
||||
}
|
||||
|
||||
// Add a given library by searching it from input search paths.
|
||||
void LinkerDriver::addLibrary(StringRef Name) {
|
||||
if (Optional<std::string> Path = searchLibrary(Name))
|
||||
@ -313,9 +296,10 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
|
||||
Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
|
||||
TarWriter::create(Path, path::stem(Path));
|
||||
if (ErrOrWriter) {
|
||||
Tar = std::move(*ErrOrWriter);
|
||||
Tar = ErrOrWriter->get();
|
||||
Tar->append("response.txt", createResponseFile(Args));
|
||||
Tar->append("version.txt", getLLDVersion() + "\n");
|
||||
make<std::unique_ptr<TarWriter>>(std::move(*ErrOrWriter));
|
||||
} else {
|
||||
error(Twine("--reproduce: failed to open ") + Path + ": " +
|
||||
toString(ErrOrWriter.takeError()));
|
||||
|
@ -17,7 +17,6 @@
|
||||
#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 {
|
||||
@ -30,11 +29,9 @@ public:
|
||||
void main(ArrayRef<const char *> Args, bool CanExitEarly);
|
||||
void addFile(StringRef Path);
|
||||
void addLibrary(StringRef Name);
|
||||
std::unique_ptr<llvm::TarWriter> Tar; // for reproduce
|
||||
|
||||
private:
|
||||
std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB);
|
||||
llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
|
||||
void readConfigs(llvm::opt::InputArgList &Args);
|
||||
void createFiles(llvm::opt::InputArgList &Args);
|
||||
void inferMachineType();
|
||||
|
@ -8,7 +8,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "InputFiles.h"
|
||||
#include "Driver.h"
|
||||
#include "Error.h"
|
||||
#include "InputSection.h"
|
||||
#include "LinkerScript.h"
|
||||
@ -26,6 +25,7 @@
|
||||
#include "llvm/MC/StringTableBuilder.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/TarWriter.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -36,6 +36,8 @@ using namespace llvm::sys::fs;
|
||||
using namespace lld;
|
||||
using namespace lld::elf;
|
||||
|
||||
TarWriter *elf::Tar;
|
||||
|
||||
namespace {
|
||||
// In ELF object file all section addresses are zero. If we have multiple
|
||||
// .text sections (when using -ffunction-section or comdat group) then
|
||||
@ -53,6 +55,24 @@ public:
|
||||
};
|
||||
}
|
||||
|
||||
Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
|
||||
if (Config->Verbose)
|
||||
outs() << Path << "\n";
|
||||
|
||||
auto MBOrErr = MemoryBuffer::getFile(Path);
|
||||
if (auto EC = MBOrErr.getError()) {
|
||||
error(EC, "cannot open " + Path);
|
||||
return None;
|
||||
}
|
||||
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
|
||||
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
||||
make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
|
||||
|
||||
if (Tar)
|
||||
Tar->append(relativeToRoot(Path), MBRef.getBuffer());
|
||||
return MBRef;
|
||||
}
|
||||
|
||||
template <class ELFT> void elf::ObjectFile<ELFT>::initializeDwarfLine() {
|
||||
std::unique_ptr<object::ObjectFile> Obj =
|
||||
check(object::ObjectFile::createObjectFile(this->MB),
|
||||
@ -524,9 +544,8 @@ ArchiveFile::getMember(const Archive::Symbol *Sym) {
|
||||
"could not get the buffer for the member defining symbol " +
|
||||
Sym->getName());
|
||||
|
||||
if (C.getParent()->isThin() && Driver->Tar)
|
||||
Driver->Tar->append(relativeToRoot(check(C.getFullName())),
|
||||
Ret.getBuffer());
|
||||
if (C.getParent()->isThin() && Tar)
|
||||
Tar->append(relativeToRoot(check(C.getFullName())), Ret.getBuffer());
|
||||
if (C.getParent()->isThin())
|
||||
return {Ret, 0};
|
||||
return {Ret, C.getChildOffset()};
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class DWARFDebugLine;
|
||||
class TarWriter;
|
||||
namespace lto {
|
||||
class InputFile;
|
||||
}
|
||||
@ -49,6 +50,13 @@ using llvm::object::Archive;
|
||||
class Lazy;
|
||||
class SymbolBody;
|
||||
|
||||
// If -reproduce option is given, all input files are written
|
||||
// to this tar archive.
|
||||
extern llvm::TarWriter *Tar;
|
||||
|
||||
// Opens a given file.
|
||||
llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
|
||||
|
||||
// The root class of input files.
|
||||
class InputFile {
|
||||
public:
|
||||
|
@ -1143,20 +1143,21 @@ void ScriptParser::readGroup() {
|
||||
|
||||
void ScriptParser::readInclude() {
|
||||
StringRef Tok = unquote(next());
|
||||
|
||||
// https://sourceware.org/binutils/docs/ld/File-Commands.html:
|
||||
// The file will be searched for in the current directory, and in any
|
||||
// directory specified with the -L option.
|
||||
auto MBOrErr = MemoryBuffer::getFile(Tok);
|
||||
if (!MBOrErr)
|
||||
if (Optional<std::string> Path = findFromSearchPaths(Tok))
|
||||
MBOrErr = MemoryBuffer::getFile(*Path);
|
||||
if (!MBOrErr) {
|
||||
setError("cannot open " + Tok);
|
||||
if (sys::fs::exists(Tok)) {
|
||||
if (Optional<MemoryBufferRef> MB = readFile(Tok))
|
||||
tokenize(*MB);
|
||||
return;
|
||||
}
|
||||
MemoryBufferRef MBRef = (*MBOrErr)->getMemBufferRef();
|
||||
make<std::unique_ptr<MemoryBuffer>>(std::move(*MBOrErr)); // take MB ownership
|
||||
tokenize(MBRef);
|
||||
if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
|
||||
if (Optional<MemoryBufferRef> MB = readFile(*Path))
|
||||
tokenize(*MB);
|
||||
return;
|
||||
}
|
||||
setError("cannot open " + Tok);
|
||||
}
|
||||
|
||||
void ScriptParser::readOutput() {
|
||||
|
@ -4,10 +4,13 @@
|
||||
# RUN: mkdir -p %t.dir/build
|
||||
# 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: echo "INCLUDE \"%t.dir/build/bar.script\"" >> %t.dir/build/foo.script
|
||||
# RUN: echo "/* empty */" > %t.dir/build/bar.script
|
||||
# RUN: cd %t.dir
|
||||
# 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/bar.script repro/%:t.dir/build/bar.script
|
||||
# RUN: diff build/foo.o repro/%:t.dir/build/foo.o
|
||||
|
||||
.globl _start
|
||||
|
Loading…
Reference in New Issue
Block a user