2017-11-02 05:16:06 +08:00
|
|
|
//===- llvm-objcopy.cpp ---------------------------------------------------===//
|
2017-08-01 08:33:58 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-08-01 08:33:58 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2017-11-02 05:16:06 +08:00
|
|
|
|
2018-10-16 13:40:18 +08:00
|
|
|
#include "Buffer.h"
|
2020-01-30 09:30:57 +08:00
|
|
|
#include "COFF/COFFObjcopy.h"
|
2018-10-12 06:33:50 +08:00
|
|
|
#include "CopyConfig.h"
|
2018-10-30 05:22:58 +08:00
|
|
|
#include "ELF/ELFObjcopy.h"
|
2019-02-02 08:38:07 +08:00
|
|
|
#include "MachO/MachOObjcopy.h"
|
2020-01-30 09:30:57 +08:00
|
|
|
#include "wasm/WasmObjcopy.h"
|
2018-10-12 06:33:50 +08:00
|
|
|
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2018-08-02 00:23:22 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
#include "llvm/ADT/Twine.h"
|
2018-07-07 01:51:03 +08:00
|
|
|
#include "llvm/Object/Archive.h"
|
|
|
|
#include "llvm/Object/ArchiveWriter.h"
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/Object/Binary.h"
|
2018-12-19 15:24:38 +08:00
|
|
|
#include "llvm/Object/COFF.h"
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/Object/ELFObjectFile.h"
|
|
|
|
#include "llvm/Object/ELFTypes.h"
|
|
|
|
#include "llvm/Object/Error.h"
|
2019-02-02 08:38:07 +08:00
|
|
|
#include "llvm/Object/MachO.h"
|
2020-01-30 09:30:57 +08:00
|
|
|
#include "llvm/Object/Wasm.h"
|
2018-04-24 13:43:32 +08:00
|
|
|
#include "llvm/Option/Arg.h"
|
|
|
|
#include "llvm/Option/ArgList.h"
|
|
|
|
#include "llvm/Option/Option.h"
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/Support/Casting.h"
|
2019-09-14 09:14:43 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/Support/Error.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/ErrorOr.h"
|
2020-03-12 06:39:28 +08:00
|
|
|
#include "llvm/Support/Host.h"
|
2018-04-14 02:26:06 +08:00
|
|
|
#include "llvm/Support/InitLLVM.h"
|
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
2018-08-18 02:51:11 +08:00
|
|
|
#include "llvm/Support/Memory.h"
|
2018-05-08 03:32:09 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2018-08-17 02:29:40 +08:00
|
|
|
#include "llvm/Support/Process.h"
|
2019-09-14 09:14:43 +08:00
|
|
|
#include "llvm/Support/StringSaver.h"
|
2018-08-10 06:52:03 +08:00
|
|
|
#include "llvm/Support/WithColor.h"
|
2017-11-02 05:16:06 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdlib>
|
2017-08-01 08:33:58 +08:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
#include <system_error>
|
2017-11-02 05:16:06 +08:00
|
|
|
#include <utility>
|
2017-08-01 08:33:58 +08:00
|
|
|
|
2018-07-18 08:10:51 +08:00
|
|
|
namespace llvm {
|
|
|
|
namespace objcopy {
|
|
|
|
|
|
|
|
// The name this program was invoked as.
|
|
|
|
StringRef ToolName;
|
|
|
|
|
2019-06-18 08:39:10 +08:00
|
|
|
ErrorSuccess reportWarning(Error E) {
|
|
|
|
assert(E);
|
2019-08-20 23:00:07 +08:00
|
|
|
WithColor::warning(errs(), ToolName) << toString(std::move(E)) << '\n';
|
2019-06-18 08:39:10 +08:00
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2018-07-18 08:10:51 +08:00
|
|
|
} // end namespace objcopy
|
2018-10-25 06:49:06 +08:00
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace llvm::object;
|
|
|
|
using namespace llvm::objcopy;
|
|
|
|
|
2018-07-07 01:51:03 +08:00
|
|
|
// For regular archives this function simply calls llvm::writeArchive,
|
|
|
|
// For thin archives it writes the archive file itself as well as its members.
|
2018-07-17 06:17:05 +08:00
|
|
|
static Error deepWriteArchive(StringRef ArcName,
|
|
|
|
ArrayRef<NewArchiveMember> NewMembers,
|
|
|
|
bool WriteSymtab, object::Archive::Kind Kind,
|
|
|
|
bool Deterministic, bool Thin) {
|
2019-02-02 01:08:07 +08:00
|
|
|
if (Error E = writeArchive(ArcName, NewMembers, WriteSymtab, Kind,
|
|
|
|
Deterministic, Thin))
|
|
|
|
return createFileError(ArcName, std::move(E));
|
|
|
|
|
|
|
|
if (!Thin)
|
|
|
|
return Error::success();
|
|
|
|
|
2018-07-07 01:51:03 +08:00
|
|
|
for (const NewArchiveMember &Member : NewMembers) {
|
|
|
|
// Internally, FileBuffer will use the buffer created by
|
|
|
|
// FileOutputBuffer::create, for regular files (that is the case for
|
|
|
|
// deepWriteArchive) FileOutputBuffer::create will return OnDiskBuffer.
|
|
|
|
// OnDiskBuffer uses a temporary file and then renames it. So in reality
|
|
|
|
// there is no inefficiency / duplicated in-memory buffers in this case. For
|
|
|
|
// now in-memory buffers can not be completely avoided since
|
|
|
|
// NewArchiveMember still requires them even though writeArchive does not
|
|
|
|
// write them on disk.
|
|
|
|
FileBuffer FB(Member.MemberName);
|
[llvm-objcopy] Return Error from Buffer::allocate(), [ELF]Writer::finalize(), and [ELF]Writer::commit()
Summary:
This patch changes a few methods to return Error instead of manually calling error/reportError to abort. This will make it easier to extract into a library.
Note that error() takes just a string (this patch also adds an overload that takes an Error), while reportError() takes string + [error/code]. To help unify things, use FileError to associate a given filename with an error. Note that this takes some special care (for now), e.g. calling reportError(FileName, <something that could be FileError>) will duplicate the filename. The goal is to eventually remove reportError() and have every error associated with a file to be a FileError, and just one error handling block at the tool level.
This change was suggested in D56806. I took it a little further than suggested, but completely fixing llvm-objcopy will take a couple more patches. If this approach looks good, I'll commit this and apply similar patche(s) for the rest.
This change is NFC in terms of non-error related code, although the error message changes in one context.
Reviewers: alexshap, jhenderson, jakehehrlich, mstorsjo, espindola
Reviewed By: alexshap, jhenderson
Subscribers: llvm-commits, emaste, arichardson
Differential Revision: https://reviews.llvm.org/D56930
llvm-svn: 351896
2019-01-23 07:49:16 +08:00
|
|
|
if (Error E = FB.allocate(Member.Buf->getBufferSize()))
|
|
|
|
return E;
|
2018-07-07 01:51:03 +08:00
|
|
|
std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(),
|
|
|
|
FB.getBufferStart());
|
[llvm-objcopy] Return Error from Buffer::allocate(), [ELF]Writer::finalize(), and [ELF]Writer::commit()
Summary:
This patch changes a few methods to return Error instead of manually calling error/reportError to abort. This will make it easier to extract into a library.
Note that error() takes just a string (this patch also adds an overload that takes an Error), while reportError() takes string + [error/code]. To help unify things, use FileError to associate a given filename with an error. Note that this takes some special care (for now), e.g. calling reportError(FileName, <something that could be FileError>) will duplicate the filename. The goal is to eventually remove reportError() and have every error associated with a file to be a FileError, and just one error handling block at the tool level.
This change was suggested in D56806. I took it a little further than suggested, but completely fixing llvm-objcopy will take a couple more patches. If this approach looks good, I'll commit this and apply similar patche(s) for the rest.
This change is NFC in terms of non-error related code, although the error message changes in one context.
Reviewers: alexshap, jhenderson, jakehehrlich, mstorsjo, espindola
Reviewed By: alexshap, jhenderson
Subscribers: llvm-commits, emaste, arichardson
Differential Revision: https://reviews.llvm.org/D56930
llvm-svn: 351896
2019-01-23 07:49:16 +08:00
|
|
|
if (Error E = FB.commit())
|
2018-07-07 01:51:03 +08:00
|
|
|
return E;
|
|
|
|
}
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2019-06-13 17:56:14 +08:00
|
|
|
/// The function executeObjcopyOnIHex does the dispatch based on the format
|
|
|
|
/// of the output specified by the command line options.
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
static Error executeObjcopyOnIHex(CopyConfig &Config, MemoryBuffer &In,
|
2019-06-13 17:56:14 +08:00
|
|
|
Buffer &Out) {
|
|
|
|
// TODO: support output formats other than ELF.
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
if (Error E = Config.parseELFConfig())
|
|
|
|
return E;
|
2019-06-13 17:56:14 +08:00
|
|
|
return elf::executeObjcopyOnIHex(Config, In, Out);
|
|
|
|
}
|
|
|
|
|
2018-10-25 06:49:06 +08:00
|
|
|
/// The function executeObjcopyOnRawBinary does the dispatch based on the format
|
|
|
|
/// of the output specified by the command line options.
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
static Error executeObjcopyOnRawBinary(CopyConfig &Config, MemoryBuffer &In,
|
|
|
|
Buffer &Out) {
|
2019-07-05 13:28:38 +08:00
|
|
|
switch (Config.OutputFormat) {
|
|
|
|
case FileFormat::ELF:
|
|
|
|
// FIXME: Currently, we call elf::executeObjcopyOnRawBinary even if the
|
|
|
|
// output format is binary/ihex or it's not given. This behavior differs from
|
|
|
|
// GNU objcopy. See https://bugs.llvm.org/show_bug.cgi?id=42171 for details.
|
|
|
|
case FileFormat::Binary:
|
|
|
|
case FileFormat::IHex:
|
|
|
|
case FileFormat::Unspecified:
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
if (Error E = Config.parseELFConfig())
|
|
|
|
return E;
|
2019-07-05 13:28:38 +08:00
|
|
|
return elf::executeObjcopyOnRawBinary(Config, In, Out);
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("unsupported output format");
|
2018-10-25 06:49:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// The function executeObjcopyOnBinary does the dispatch based on the format
|
|
|
|
/// of the input binary (ELF, MachO or COFF).
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
static Error executeObjcopyOnBinary(CopyConfig &Config, object::Binary &In,
|
|
|
|
Buffer &Out) {
|
|
|
|
if (auto *ELFBinary = dyn_cast<object::ELFObjectFileBase>(&In)) {
|
|
|
|
if (Error E = Config.parseELFConfig())
|
|
|
|
return E;
|
2018-10-25 06:49:06 +08:00
|
|
|
return elf::executeObjcopyOnBinary(Config, *ELFBinary, Out);
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
} else if (auto *COFFBinary = dyn_cast<object::COFFObjectFile>(&In))
|
2018-12-19 15:24:38 +08:00
|
|
|
return coff::executeObjcopyOnBinary(Config, *COFFBinary, Out);
|
2019-02-02 08:38:07 +08:00
|
|
|
else if (auto *MachOBinary = dyn_cast<object::MachOObjectFile>(&In))
|
|
|
|
return macho::executeObjcopyOnBinary(Config, *MachOBinary, Out);
|
2020-01-30 09:30:57 +08:00
|
|
|
else if (auto *WasmBinary = dyn_cast<object::WasmObjectFile>(&In))
|
|
|
|
return objcopy::wasm::executeObjcopyOnBinary(Config, *WasmBinary, Out);
|
2018-10-25 06:49:06 +08:00
|
|
|
else
|
2019-01-30 22:36:53 +08:00
|
|
|
return createStringError(object_error::invalid_file_type,
|
2019-06-14 10:04:02 +08:00
|
|
|
"unsupported object file format");
|
2018-10-25 06:49:06 +08:00
|
|
|
}
|
|
|
|
|
2020-10-06 17:29:24 +08:00
|
|
|
static Error executeObjcopyOnArchive(CopyConfig &Config, const Archive &Ar) {
|
2018-07-07 01:51:03 +08:00
|
|
|
std::vector<NewArchiveMember> NewArchiveMembers;
|
|
|
|
Error Err = Error::success();
|
|
|
|
for (const Archive::Child &Child : Ar.children(Err)) {
|
|
|
|
Expected<StringRef> ChildNameOrErr = Child.getName();
|
|
|
|
if (!ChildNameOrErr)
|
2019-02-02 01:08:07 +08:00
|
|
|
return createFileError(Ar.getFileName(), ChildNameOrErr.takeError());
|
2018-07-07 01:51:03 +08:00
|
|
|
|
2019-05-08 21:28:58 +08:00
|
|
|
Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
|
|
|
|
if (!ChildOrErr)
|
|
|
|
return createFileError(Ar.getFileName() + "(" + *ChildNameOrErr + ")",
|
|
|
|
ChildOrErr.takeError());
|
|
|
|
|
2018-07-07 01:51:03 +08:00
|
|
|
MemBuffer MB(ChildNameOrErr.get());
|
2019-05-08 21:28:58 +08:00
|
|
|
if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MB))
|
2020-10-06 17:29:24 +08:00
|
|
|
return E;
|
2018-07-07 01:51:03 +08:00
|
|
|
|
|
|
|
Expected<NewArchiveMember> Member =
|
2018-11-02 01:36:37 +08:00
|
|
|
NewArchiveMember::getOldMember(Child, Config.DeterministicArchives);
|
2018-07-07 01:51:03 +08:00
|
|
|
if (!Member)
|
2019-02-02 01:08:07 +08:00
|
|
|
return createFileError(Ar.getFileName(), Member.takeError());
|
2018-07-07 01:51:03 +08:00
|
|
|
Member->Buf = MB.releaseMemoryBuffer();
|
|
|
|
Member->MemberName = Member->Buf->getBufferIdentifier();
|
|
|
|
NewArchiveMembers.push_back(std::move(*Member));
|
|
|
|
}
|
|
|
|
if (Err)
|
2019-02-02 01:08:07 +08:00
|
|
|
return createFileError(Config.InputFilename, std::move(Err));
|
|
|
|
|
2020-10-06 17:29:24 +08:00
|
|
|
return deepWriteArchive(Config.OutputFilename, NewArchiveMembers,
|
2019-02-02 01:08:07 +08:00
|
|
|
Ar.hasSymbolTable(), Ar.kind(),
|
|
|
|
Config.DeterministicArchives, Ar.isThin());
|
2018-07-07 01:51:03 +08:00
|
|
|
}
|
|
|
|
|
[llvm-objcopy] Change handling of output file permissions
Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay
Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62718
llvm-svn: 365162
2019-07-05 06:45:27 +08:00
|
|
|
static Error restoreStatOnFile(StringRef Filename,
|
|
|
|
const sys::fs::file_status &Stat,
|
|
|
|
bool PreserveDates) {
|
2018-08-17 02:29:40 +08:00
|
|
|
int FD;
|
|
|
|
|
[llvm-objcopy] Change handling of output file permissions
Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay
Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62718
llvm-svn: 365162
2019-07-05 06:45:27 +08:00
|
|
|
// Writing to stdout should not be treated as an error here, just
|
|
|
|
// do not set access/modification times or permissions.
|
|
|
|
if (Filename == "-")
|
|
|
|
return Error::success();
|
|
|
|
|
2018-08-30 07:21:56 +08:00
|
|
|
if (auto EC =
|
|
|
|
sys::fs::openFileForWrite(Filename, FD, sys::fs::CD_OpenExisting))
|
2019-02-22 01:05:19 +08:00
|
|
|
return createFileError(Filename, EC);
|
2018-08-17 02:29:40 +08:00
|
|
|
|
[llvm-objcopy] Change handling of output file permissions
Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay
Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62718
llvm-svn: 365162
2019-07-05 06:45:27 +08:00
|
|
|
if (PreserveDates)
|
|
|
|
if (auto EC = sys::fs::setLastAccessAndModificationTime(
|
|
|
|
FD, Stat.getLastAccessedTime(), Stat.getLastModificationTime()))
|
|
|
|
return createFileError(Filename, EC);
|
|
|
|
|
2019-07-11 18:17:59 +08:00
|
|
|
sys::fs::file_status OStat;
|
|
|
|
if (std::error_code EC = sys::fs::status(FD, OStat))
|
2019-02-22 01:05:19 +08:00
|
|
|
return createFileError(Filename, EC);
|
2019-07-11 18:17:59 +08:00
|
|
|
if (OStat.type() == sys::fs::file_type::regular_file)
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (auto EC = sys::fs::setPermissions(
|
|
|
|
Filename, static_cast<sys::fs::perms>(Stat.permissions() &
|
|
|
|
~sys::fs::getUmask())))
|
|
|
|
#else
|
|
|
|
if (auto EC = sys::fs::setPermissions(
|
|
|
|
FD, static_cast<sys::fs::perms>(Stat.permissions() &
|
|
|
|
~sys::fs::getUmask())))
|
|
|
|
#endif
|
|
|
|
return createFileError(Filename, EC);
|
2018-08-17 02:29:40 +08:00
|
|
|
|
|
|
|
if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
|
2019-02-22 01:05:19 +08:00
|
|
|
return createFileError(Filename, EC);
|
|
|
|
|
|
|
|
return Error::success();
|
2018-08-17 02:29:40 +08:00
|
|
|
}
|
|
|
|
|
2018-10-25 06:49:06 +08:00
|
|
|
/// The function executeObjcopy does the higher level dispatch based on the type
|
|
|
|
/// of input (raw binary, archive or single object file) and takes care of the
|
|
|
|
/// format-agnostic modifications, i.e. preserving dates.
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
static Error executeObjcopy(CopyConfig &Config) {
|
2018-08-17 02:29:40 +08:00
|
|
|
sys::fs::file_status Stat;
|
[llvm-objcopy] Change handling of output file permissions
Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay
Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62718
llvm-svn: 365162
2019-07-05 06:45:27 +08:00
|
|
|
if (Config.InputFilename != "-") {
|
2018-08-17 02:29:40 +08:00
|
|
|
if (auto EC = sys::fs::status(Config.InputFilename, Stat))
|
2019-02-22 01:05:19 +08:00
|
|
|
return createFileError(Config.InputFilename, EC);
|
[llvm-objcopy] Change handling of output file permissions
Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay
Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62718
llvm-svn: 365162
2019-07-05 06:45:27 +08:00
|
|
|
} else {
|
|
|
|
Stat.permissions(static_cast<sys::fs::perms>(0777));
|
|
|
|
}
|
2018-08-17 02:29:40 +08:00
|
|
|
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
using ProcessRawFn = Error (*)(CopyConfig &, MemoryBuffer &, Buffer &);
|
2019-07-05 13:28:38 +08:00
|
|
|
ProcessRawFn ProcessRaw;
|
|
|
|
switch (Config.InputFormat) {
|
|
|
|
case FileFormat::Binary:
|
|
|
|
ProcessRaw = executeObjcopyOnRawBinary;
|
|
|
|
break;
|
|
|
|
case FileFormat::IHex:
|
|
|
|
ProcessRaw = executeObjcopyOnIHex;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ProcessRaw = nullptr;
|
|
|
|
}
|
2019-06-13 17:56:14 +08:00
|
|
|
|
|
|
|
if (ProcessRaw) {
|
|
|
|
auto BufOrErr = MemoryBuffer::getFileOrSTDIN(Config.InputFilename);
|
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
2018-08-18 02:51:11 +08:00
|
|
|
if (!BufOrErr)
|
2019-02-22 01:05:19 +08:00
|
|
|
return createFileError(Config.InputFilename, BufOrErr.getError());
|
2018-08-17 02:29:40 +08:00
|
|
|
FileBuffer FB(Config.OutputFilename);
|
2019-06-13 17:56:14 +08:00
|
|
|
if (Error E = ProcessRaw(Config, *BufOrErr->get(), FB))
|
2019-02-22 01:05:19 +08:00
|
|
|
return E;
|
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
2018-08-18 02:51:11 +08:00
|
|
|
} else {
|
|
|
|
Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
|
|
|
|
createBinary(Config.InputFilename);
|
|
|
|
if (!BinaryOrErr)
|
2019-02-22 01:05:19 +08:00
|
|
|
return createFileError(Config.InputFilename, BinaryOrErr.takeError());
|
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
2018-08-18 02:51:11 +08:00
|
|
|
|
|
|
|
if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) {
|
2019-01-30 22:36:53 +08:00
|
|
|
if (Error E = executeObjcopyOnArchive(Config, *Ar))
|
2019-02-22 01:05:19 +08:00
|
|
|
return E;
|
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
2018-08-18 02:51:11 +08:00
|
|
|
} else {
|
|
|
|
FileBuffer FB(Config.OutputFilename);
|
2019-01-30 22:36:53 +08:00
|
|
|
if (Error E = executeObjcopyOnBinary(Config,
|
|
|
|
*BinaryOrErr.get().getBinary(), FB))
|
2019-02-22 01:05:19 +08:00
|
|
|
return E;
|
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
2018-08-18 02:51:11 +08:00
|
|
|
}
|
2018-08-17 02:29:40 +08:00
|
|
|
}
|
2018-07-07 01:51:03 +08:00
|
|
|
|
[llvm-objcopy] Change handling of output file permissions
Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay
Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62718
llvm-svn: 365162
2019-07-05 06:45:27 +08:00
|
|
|
if (Error E =
|
|
|
|
restoreStatOnFile(Config.OutputFilename, Stat, Config.PreserveDates))
|
|
|
|
return E;
|
|
|
|
|
|
|
|
if (!Config.SplitDWO.empty()) {
|
|
|
|
Stat.permissions(static_cast<sys::fs::perms>(0666));
|
|
|
|
if (Error E =
|
|
|
|
restoreStatOnFile(Config.SplitDWO, Stat, Config.PreserveDates))
|
2019-02-22 01:05:19 +08:00
|
|
|
return E;
|
2018-08-17 02:29:40 +08:00
|
|
|
}
|
2019-02-22 01:05:19 +08:00
|
|
|
|
|
|
|
return Error::success();
|
2018-07-07 01:51:03 +08:00
|
|
|
}
|
|
|
|
|
2019-11-20 15:30:52 +08:00
|
|
|
namespace {
|
|
|
|
|
2020-09-19 09:11:22 +08:00
|
|
|
enum class ToolType { Objcopy, Strip, InstallNameTool, BitcodeStrip };
|
2019-11-20 15:30:52 +08:00
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
2017-08-01 08:33:58 +08:00
|
|
|
int main(int argc, char **argv) {
|
2018-04-14 02:26:06 +08:00
|
|
|
InitLLVM X(argc, argv);
|
2017-08-01 08:33:58 +08:00
|
|
|
ToolName = argv[0];
|
2020-03-22 14:39:01 +08:00
|
|
|
|
|
|
|
StringRef Stem = sys::path::stem(ToolName);
|
|
|
|
auto Is = [=](StringRef Tool) {
|
|
|
|
// We need to recognize the following filenames:
|
|
|
|
//
|
|
|
|
// llvm-objcopy -> objcopy
|
|
|
|
// strip-10.exe -> strip
|
|
|
|
// powerpc64-unknown-freebsd13-objcopy -> objcopy
|
|
|
|
// llvm-install-name-tool -> install-name-tool
|
|
|
|
auto I = Stem.rfind_lower(Tool);
|
|
|
|
return I != StringRef::npos &&
|
|
|
|
(I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
|
|
|
|
};
|
|
|
|
ToolType Tool = ToolType::Objcopy;
|
2020-09-19 09:11:22 +08:00
|
|
|
if (Is("bitcode-strip") || Is("bitcode_strip"))
|
|
|
|
Tool = ToolType::BitcodeStrip;
|
|
|
|
else if (Is("strip"))
|
2020-03-22 14:39:01 +08:00
|
|
|
Tool = ToolType::Strip;
|
|
|
|
else if (Is("install-name-tool") || Is("install_name_tool"))
|
|
|
|
Tool = ToolType::InstallNameTool;
|
|
|
|
|
2019-09-14 09:14:43 +08:00
|
|
|
// Expand response files.
|
|
|
|
// TODO: Move these lines, which are copied from lib/Support/CommandLine.cpp,
|
|
|
|
// into a separate function in the CommandLine library and call that function
|
|
|
|
// here. This is duplicated code.
|
|
|
|
SmallVector<const char *, 20> NewArgv(argv, argv + argc);
|
|
|
|
BumpPtrAllocator A;
|
|
|
|
StringSaver Saver(A);
|
|
|
|
cl::ExpandResponseFiles(Saver,
|
|
|
|
Triple(sys::getProcessTriple()).isOSWindows()
|
|
|
|
? cl::TokenizeWindowsCommandLine
|
|
|
|
: cl::TokenizeGNUCommandLine,
|
|
|
|
NewArgv);
|
|
|
|
|
|
|
|
auto Args = makeArrayRef(NewArgv).drop_front();
|
2019-02-22 01:05:19 +08:00
|
|
|
Expected<DriverConfig> DriverConfig =
|
2020-09-19 09:11:22 +08:00
|
|
|
(Tool == ToolType::Strip)
|
|
|
|
? parseStripOptions(Args, reportWarning)
|
|
|
|
: ((Tool == ToolType::InstallNameTool)
|
|
|
|
? parseInstallNameToolOptions(Args)
|
|
|
|
: ((Tool == ToolType::BitcodeStrip)
|
|
|
|
? parseBitcodeStripOptions(Args)
|
|
|
|
: parseObjcopyOptions(Args, reportWarning)));
|
2019-02-22 01:05:19 +08:00
|
|
|
if (!DriverConfig) {
|
|
|
|
logAllUnhandledErrors(DriverConfig.takeError(),
|
|
|
|
WithColor::error(errs(), ToolName));
|
|
|
|
return 1;
|
|
|
|
}
|
[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
2019-09-24 17:38:23 +08:00
|
|
|
for (CopyConfig &CopyConfig : DriverConfig->CopyConfigs) {
|
2019-02-22 01:05:19 +08:00
|
|
|
if (Error E = executeObjcopy(CopyConfig)) {
|
|
|
|
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolName));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2017-08-01 08:33:58 +08:00
|
|
|
}
|