mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-21 12:35:47 -04:00
Introduce llvm-install-name-tool
This diff adds a new "driver" for llvm-objcopy which is supposed to emulate the behavior of install-name-tool. Differential revision: https://reviews.llvm.org/D69146 Test plan: make check-all
This commit is contained in:
parent
2293b3f169
commit
b5913e6d2f
88
llvm/test/tools/llvm-objcopy/MachO/Inputs/i386.yaml
Normal file
88
llvm/test/tools/llvm-objcopy/MachO/Inputs/i386.yaml
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
--- !mach-o
|
||||||
|
FileHeader:
|
||||||
|
magic: 0xFEEDFACE
|
||||||
|
cputype: 0x00000007
|
||||||
|
cpusubtype: 0x00000003
|
||||||
|
filetype: 0x00000001
|
||||||
|
ncmds: 4
|
||||||
|
sizeofcmds: 312
|
||||||
|
flags: 0x00002000
|
||||||
|
LoadCommands:
|
||||||
|
- cmd: LC_SEGMENT
|
||||||
|
cmdsize: 192
|
||||||
|
segname: ''
|
||||||
|
vmaddr: 0
|
||||||
|
vmsize: 72
|
||||||
|
fileoff: 340
|
||||||
|
filesize: 72
|
||||||
|
maxprot: 7
|
||||||
|
initprot: 7
|
||||||
|
nsects: 2
|
||||||
|
flags: 0
|
||||||
|
Sections:
|
||||||
|
- sectname: __text
|
||||||
|
segname: __TEXT
|
||||||
|
addr: 0x0000000000000000
|
||||||
|
size: 18
|
||||||
|
offset: 0x00000154
|
||||||
|
align: 4
|
||||||
|
reloff: 0x00000000
|
||||||
|
nreloc: 0
|
||||||
|
flags: 0x80000400
|
||||||
|
reserved1: 0x00000000
|
||||||
|
reserved2: 0x00000000
|
||||||
|
reserved3: 0x00000000
|
||||||
|
- sectname: __eh_frame
|
||||||
|
segname: __TEXT
|
||||||
|
addr: 0x0000000000000014
|
||||||
|
size: 52
|
||||||
|
offset: 0x00000168
|
||||||
|
align: 2
|
||||||
|
reloff: 0x00000000
|
||||||
|
nreloc: 0
|
||||||
|
flags: 0x6800000B
|
||||||
|
reserved1: 0x00000000
|
||||||
|
reserved2: 0x00000000
|
||||||
|
reserved3: 0x00000000
|
||||||
|
- cmd: LC_VERSION_MIN_MACOSX
|
||||||
|
cmdsize: 16
|
||||||
|
version: 656384
|
||||||
|
sdk: 0
|
||||||
|
- cmd: LC_SYMTAB
|
||||||
|
cmdsize: 24
|
||||||
|
symoff: 412
|
||||||
|
nsyms: 1
|
||||||
|
stroff: 424
|
||||||
|
strsize: 8
|
||||||
|
- cmd: LC_DYSYMTAB
|
||||||
|
cmdsize: 80
|
||||||
|
ilocalsym: 0
|
||||||
|
nlocalsym: 0
|
||||||
|
iextdefsym: 0
|
||||||
|
nextdefsym: 1
|
||||||
|
iundefsym: 1
|
||||||
|
nundefsym: 0
|
||||||
|
tocoff: 0
|
||||||
|
ntoc: 0
|
||||||
|
modtaboff: 0
|
||||||
|
nmodtab: 0
|
||||||
|
extrefsymoff: 0
|
||||||
|
nextrefsyms: 0
|
||||||
|
indirectsymoff: 0
|
||||||
|
nindirectsyms: 0
|
||||||
|
extreloff: 0
|
||||||
|
nextrel: 0
|
||||||
|
locreloff: 0
|
||||||
|
nlocrel: 0
|
||||||
|
LinkEditData:
|
||||||
|
NameList:
|
||||||
|
- n_strx: 1
|
||||||
|
n_type: 0x0F
|
||||||
|
n_sect: 1
|
||||||
|
n_desc: 0
|
||||||
|
n_value: 0
|
||||||
|
StringTable:
|
||||||
|
- ''
|
||||||
|
- _main
|
||||||
|
- ''
|
||||||
|
...
|
89
llvm/test/tools/llvm-objcopy/MachO/Inputs/x86_64.yaml
Normal file
89
llvm/test/tools/llvm-objcopy/MachO/Inputs/x86_64.yaml
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
--- !mach-o
|
||||||
|
FileHeader:
|
||||||
|
magic: 0xFEEDFACF
|
||||||
|
cputype: 0x01000007
|
||||||
|
cpusubtype: 0x00000003
|
||||||
|
filetype: 0x00000001
|
||||||
|
ncmds: 4
|
||||||
|
sizeofcmds: 352
|
||||||
|
flags: 0x00002000
|
||||||
|
reserved: 0x00000000
|
||||||
|
LoadCommands:
|
||||||
|
- cmd: LC_SEGMENT_64
|
||||||
|
cmdsize: 232
|
||||||
|
segname: ''
|
||||||
|
vmaddr: 0
|
||||||
|
vmsize: 80
|
||||||
|
fileoff: 384
|
||||||
|
filesize: 80
|
||||||
|
maxprot: 7
|
||||||
|
initprot: 7
|
||||||
|
nsects: 2
|
||||||
|
flags: 0
|
||||||
|
Sections:
|
||||||
|
- sectname: __text
|
||||||
|
segname: __TEXT
|
||||||
|
addr: 0x0000000000000000
|
||||||
|
size: 15
|
||||||
|
offset: 0x00000180
|
||||||
|
align: 4
|
||||||
|
reloff: 0x00000000
|
||||||
|
nreloc: 0
|
||||||
|
flags: 0x80000400
|
||||||
|
reserved1: 0x00000000
|
||||||
|
reserved2: 0x00000000
|
||||||
|
reserved3: 0x00000000
|
||||||
|
- sectname: __eh_frame
|
||||||
|
segname: __TEXT
|
||||||
|
addr: 0x0000000000000010
|
||||||
|
size: 64
|
||||||
|
offset: 0x00000190
|
||||||
|
align: 3
|
||||||
|
reloff: 0x00000000
|
||||||
|
nreloc: 0
|
||||||
|
flags: 0x6800000B
|
||||||
|
reserved1: 0x00000000
|
||||||
|
reserved2: 0x00000000
|
||||||
|
reserved3: 0x00000000
|
||||||
|
- cmd: LC_VERSION_MIN_MACOSX
|
||||||
|
cmdsize: 16
|
||||||
|
version: 656384
|
||||||
|
sdk: 0
|
||||||
|
- cmd: LC_SYMTAB
|
||||||
|
cmdsize: 24
|
||||||
|
symoff: 464
|
||||||
|
nsyms: 1
|
||||||
|
stroff: 480
|
||||||
|
strsize: 8
|
||||||
|
- cmd: LC_DYSYMTAB
|
||||||
|
cmdsize: 80
|
||||||
|
ilocalsym: 0
|
||||||
|
nlocalsym: 0
|
||||||
|
iextdefsym: 0
|
||||||
|
nextdefsym: 1
|
||||||
|
iundefsym: 1
|
||||||
|
nundefsym: 0
|
||||||
|
tocoff: 0
|
||||||
|
ntoc: 0
|
||||||
|
modtaboff: 0
|
||||||
|
nmodtab: 0
|
||||||
|
extrefsymoff: 0
|
||||||
|
nextrefsyms: 0
|
||||||
|
indirectsymoff: 0
|
||||||
|
nindirectsyms: 0
|
||||||
|
extreloff: 0
|
||||||
|
nextrel: 0
|
||||||
|
locreloff: 0
|
||||||
|
nlocrel: 0
|
||||||
|
LinkEditData:
|
||||||
|
NameList:
|
||||||
|
- n_strx: 1
|
||||||
|
n_type: 0x0F
|
||||||
|
n_sect: 1
|
||||||
|
n_desc: 0
|
||||||
|
n_value: 0
|
||||||
|
StringTable:
|
||||||
|
- ''
|
||||||
|
- _main
|
||||||
|
- ''
|
||||||
|
...
|
@ -0,0 +1,23 @@
|
|||||||
|
## This test checks adding a new LC_RPATH load command to a MachO binary.
|
||||||
|
|
||||||
|
# RUN: yaml2obj %p/Inputs/i386.yaml > %t.i386
|
||||||
|
# RUN: llvm-install-name-tool -add_rpath @executable_path/. %t.i386
|
||||||
|
# RUN: llvm-objdump -p %t.i386 | FileCheck --check-prefix=NEW-RPATH %s
|
||||||
|
|
||||||
|
# RUN: yaml2obj %p/Inputs/x86_64.yaml > %t.x86_64
|
||||||
|
# RUN: llvm-install-name-tool -add_rpath @executable_path/. %t.x86_64
|
||||||
|
# RUN: llvm-objdump -p %t.x86_64 | FileCheck --check-prefix=NEW-RPATH %s
|
||||||
|
|
||||||
|
# NEW-RPATH: cmd LC_RPATH
|
||||||
|
# NEW-RPATH-NEXT: cmdsize
|
||||||
|
# NEW-RPATH-NEXT: @executable_path/.
|
||||||
|
|
||||||
|
# RUN: not llvm-install-name-tool -add_rpath @executable_path/. %t.i386 2>&1 \
|
||||||
|
# RUN: | FileCheck --check-prefix=DUPLICATE-RPATH %s
|
||||||
|
|
||||||
|
# DUPLICATE-RPATH: duplicate load command
|
||||||
|
|
||||||
|
# RUN: not llvm-install-name-tool -add_rpath @executable_path/. 2>&1 \
|
||||||
|
# RUN: | FileCheck --check-prefix=NO-INPUT %s
|
||||||
|
|
||||||
|
# NO-INPUT: no input file specified
|
@ -0,0 +1,10 @@
|
|||||||
|
# RUN: llvm-install-name-tool -h | FileCheck --check-prefix=INSTALL-NAME-TOOL-USAGE %s
|
||||||
|
# RUN: llvm-install-name-tool --help | FileCheck --check-prefix=INSTALL-NAME-TOOL-USAGE %s
|
||||||
|
# RUN: not llvm-install-name-tool 2>&1 | FileCheck --check-prefix=INSTALL-NAME-TOOL-USAGE %s
|
||||||
|
# RUN: not llvm-install-name-tool -abcabc 2>&1 | FileCheck --check-prefix=UNKNOWN-ARG %s
|
||||||
|
# RUN: not llvm-install-name-tool --abcabc 2>&1 | FileCheck --check-prefix=UNKNOWN-ARG %s
|
||||||
|
|
||||||
|
# INSTALL-NAME-TOOL-USAGE: USAGE: llvm-install-name-tool
|
||||||
|
# INSTALL-NAME-TOOL-USAGE: @FILE
|
||||||
|
|
||||||
|
# UNKNOWN-ARG: unknown argument '{{-+}}abcabc'
|
@ -0,0 +1,2 @@
|
|||||||
|
# RUN: llvm-install-name-tool --version | FileCheck %s
|
||||||
|
# CHECK: {{ version }}
|
@ -9,6 +9,10 @@ set(LLVM_TARGET_DEFINITIONS ObjcopyOpts.td)
|
|||||||
tablegen(LLVM ObjcopyOpts.inc -gen-opt-parser-defs)
|
tablegen(LLVM ObjcopyOpts.inc -gen-opt-parser-defs)
|
||||||
add_public_tablegen_target(ObjcopyOptsTableGen)
|
add_public_tablegen_target(ObjcopyOptsTableGen)
|
||||||
|
|
||||||
|
set(LLVM_TARGET_DEFINITIONS InstallNameToolOpts.td)
|
||||||
|
tablegen(LLVM InstallNameToolOpts.inc -gen-opt-parser-defs)
|
||||||
|
add_public_tablegen_target(InstallNameToolOptsTableGen)
|
||||||
|
|
||||||
set(LLVM_TARGET_DEFINITIONS StripOpts.td)
|
set(LLVM_TARGET_DEFINITIONS StripOpts.td)
|
||||||
tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
|
tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
|
||||||
add_public_tablegen_target(StripOptsTableGen)
|
add_public_tablegen_target(StripOptsTableGen)
|
||||||
@ -31,9 +35,11 @@ add_llvm_tool(llvm-objcopy
|
|||||||
MachO/Object.cpp
|
MachO/Object.cpp
|
||||||
DEPENDS
|
DEPENDS
|
||||||
ObjcopyOptsTableGen
|
ObjcopyOptsTableGen
|
||||||
|
InstallNameToolOptsTableGen
|
||||||
StripOptsTableGen
|
StripOptsTableGen
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_llvm_tool_symlink(llvm-install-name-tool llvm-objcopy)
|
||||||
add_llvm_tool_symlink(llvm-strip llvm-objcopy)
|
add_llvm_tool_symlink(llvm-strip llvm-objcopy)
|
||||||
|
|
||||||
if(LLVM_INSTALL_BINUTILS_SYMLINKS)
|
if(LLVM_INSTALL_BINUTILS_SYMLINKS)
|
||||||
|
@ -63,6 +63,44 @@ public:
|
|||||||
ObjcopyOptTable() : OptTable(ObjcopyInfoTable) {}
|
ObjcopyOptTable() : OptTable(ObjcopyInfoTable) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum InstallNameToolID {
|
||||||
|
INSTALL_NAME_TOOL_INVALID = 0, // This is not an option ID.
|
||||||
|
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||||
|
HELPTEXT, METAVAR, VALUES) \
|
||||||
|
INSTALL_NAME_TOOL_##ID,
|
||||||
|
#include "InstallNameToolOpts.inc"
|
||||||
|
#undef OPTION
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PREFIX(NAME, VALUE) \
|
||||||
|
const char *const INSTALL_NAME_TOOL_##NAME[] = VALUE;
|
||||||
|
#include "InstallNameToolOpts.inc"
|
||||||
|
#undef PREFIX
|
||||||
|
|
||||||
|
static const opt::OptTable::Info InstallNameToolInfoTable[] = {
|
||||||
|
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||||
|
HELPTEXT, METAVAR, VALUES) \
|
||||||
|
{INSTALL_NAME_TOOL_##PREFIX, \
|
||||||
|
NAME, \
|
||||||
|
HELPTEXT, \
|
||||||
|
METAVAR, \
|
||||||
|
INSTALL_NAME_TOOL_##ID, \
|
||||||
|
opt::Option::KIND##Class, \
|
||||||
|
PARAM, \
|
||||||
|
FLAGS, \
|
||||||
|
INSTALL_NAME_TOOL_##GROUP, \
|
||||||
|
INSTALL_NAME_TOOL_##ALIAS, \
|
||||||
|
ALIASARGS, \
|
||||||
|
VALUES},
|
||||||
|
#include "InstallNameToolOpts.inc"
|
||||||
|
#undef OPTION
|
||||||
|
};
|
||||||
|
|
||||||
|
class InstallNameToolOptTable : public opt::OptTable {
|
||||||
|
public:
|
||||||
|
InstallNameToolOptTable() : OptTable(InstallNameToolInfoTable) {}
|
||||||
|
};
|
||||||
|
|
||||||
enum StripID {
|
enum StripID {
|
||||||
STRIP_INVALID = 0, // This is not an option ID.
|
STRIP_INVALID = 0, // This is not an option ID.
|
||||||
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
|
||||||
@ -752,6 +790,57 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
|
|||||||
return std::move(DC);
|
return std::move(DC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseInstallNameToolOptions returns the config and sets the input arguments.
|
||||||
|
// If a help flag is set then ParseInstallNameToolOptions will print the help
|
||||||
|
// messege and exit.
|
||||||
|
Expected<DriverConfig>
|
||||||
|
parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
|
||||||
|
DriverConfig DC;
|
||||||
|
CopyConfig Config;
|
||||||
|
InstallNameToolOptTable T;
|
||||||
|
unsigned MissingArgumentIndex, MissingArgumentCount;
|
||||||
|
llvm::opt::InputArgList InputArgs =
|
||||||
|
T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
|
||||||
|
|
||||||
|
if (InputArgs.size() == 0) {
|
||||||
|
printHelp(T, errs(), "llvm-install-name-tool");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputArgs.hasArg(INSTALL_NAME_TOOL_help)) {
|
||||||
|
printHelp(T, outs(), "llvm-install-name-tool");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputArgs.hasArg(INSTALL_NAME_TOOL_version)) {
|
||||||
|
outs() << "llvm-install-name-tool, compatible with cctools "
|
||||||
|
"install_name_tool\n";
|
||||||
|
cl::PrintVersionMessage();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_add_rpath))
|
||||||
|
Config.RPathToAdd.push_back(Arg->getValue());
|
||||||
|
|
||||||
|
SmallVector<StringRef, 2> Positional;
|
||||||
|
for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_UNKNOWN))
|
||||||
|
return createStringError(errc::invalid_argument, "unknown argument '%s'",
|
||||||
|
Arg->getAsString(InputArgs).c_str());
|
||||||
|
for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT))
|
||||||
|
Positional.push_back(Arg->getValue());
|
||||||
|
if (Positional.empty())
|
||||||
|
return createStringError(errc::invalid_argument, "no input file specified");
|
||||||
|
if (Positional.size() > 1)
|
||||||
|
return createStringError(
|
||||||
|
errc::invalid_argument,
|
||||||
|
"llvm-install-name-tool expects a single input file");
|
||||||
|
Config.InputFilename = Positional[0];
|
||||||
|
Config.OutputFilename = Positional[0];
|
||||||
|
|
||||||
|
DC.CopyConfigs.push_back(std::move(Config));
|
||||||
|
return std::move(DC);
|
||||||
|
}
|
||||||
|
|
||||||
// ParseStripOptions returns the config and sets the input arguments. If a
|
// ParseStripOptions returns the config and sets the input arguments. If a
|
||||||
// help flag is set then ParseStripOptions will print the help messege and
|
// help flag is set then ParseStripOptions will print the help messege and
|
||||||
// exit.
|
// exit.
|
||||||
|
@ -175,6 +175,7 @@ struct CopyConfig {
|
|||||||
std::vector<StringRef> AddSection;
|
std::vector<StringRef> AddSection;
|
||||||
std::vector<StringRef> DumpSection;
|
std::vector<StringRef> DumpSection;
|
||||||
std::vector<StringRef> SymbolsToAdd;
|
std::vector<StringRef> SymbolsToAdd;
|
||||||
|
std::vector<StringRef> RPathToAdd;
|
||||||
|
|
||||||
// Section matchers
|
// Section matchers
|
||||||
NameMatcher KeepSection;
|
NameMatcher KeepSection;
|
||||||
@ -251,6 +252,12 @@ Expected<DriverConfig>
|
|||||||
parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
|
parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
|
||||||
llvm::function_ref<Error(Error)> ErrorCallback);
|
llvm::function_ref<Error(Error)> ErrorCallback);
|
||||||
|
|
||||||
|
// ParseInstallNameToolOptions returns the config and sets the input arguments.
|
||||||
|
// If a help flag is set then ParseInstallNameToolOptions will print the help
|
||||||
|
// messege and exit.
|
||||||
|
Expected<DriverConfig>
|
||||||
|
parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
|
||||||
|
|
||||||
// ParseStripOptions returns the config and sets the input arguments. If a
|
// ParseStripOptions returns the config and sets the input arguments. If a
|
||||||
// help flag is set then ParseStripOptions will print the help messege and
|
// help flag is set then ParseStripOptions will print the help messege and
|
||||||
// exit. ErrorCallback is used to handle recoverable errors. An Error returned
|
// exit. ErrorCallback is used to handle recoverable errors. An Error returned
|
||||||
@ -258,7 +265,6 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
|
|||||||
Expected<DriverConfig>
|
Expected<DriverConfig>
|
||||||
parseStripOptions(ArrayRef<const char *> ArgsArr,
|
parseStripOptions(ArrayRef<const char *> ArgsArr,
|
||||||
llvm::function_ref<Error(Error)> ErrorCallback);
|
llvm::function_ref<Error(Error)> ErrorCallback);
|
||||||
|
|
||||||
} // namespace objcopy
|
} // namespace objcopy
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
|
22
llvm/tools/llvm-objcopy/InstallNameToolOpts.td
Normal file
22
llvm/tools/llvm-objcopy/InstallNameToolOpts.td
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//===-- InstallNameToolOpts.td - llvm-install-name-tool options --------*-===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file describes the command line options of llvm-install-name.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
include "llvm/Option/OptParser.td"
|
||||||
|
|
||||||
|
def help : Flag<["--"], "help">;
|
||||||
|
def h : Flag<["-"], "h">, Alias<help>;
|
||||||
|
|
||||||
|
def add_rpath : Option<["-", "--"], "add_rpath", KIND_SEPARATE>,
|
||||||
|
HelpText<"Add new rpath">;
|
||||||
|
|
||||||
|
def version : Flag<["--"], "version">,
|
||||||
|
HelpText<"Print the version and exit.">;
|
@ -59,6 +59,18 @@ static void removeSymbols(const CopyConfig &Config, Object &Obj) {
|
|||||||
Obj.SymTable.removeSymbols(RemovePred);
|
Obj.SymTable.removeSymbols(RemovePred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LoadCommand buildRPathLoadCommand(StringRef Path) {
|
||||||
|
LoadCommand LC;
|
||||||
|
MachO::rpath_command RPathLC;
|
||||||
|
RPathLC.cmd = MachO::LC_RPATH;
|
||||||
|
RPathLC.path = sizeof(MachO::rpath_command);
|
||||||
|
RPathLC.cmdsize = alignTo(sizeof(MachO::rpath_command) + Path.size(), 8);
|
||||||
|
LC.MachOLoadCommand.rpath_command_data = RPathLC;
|
||||||
|
LC.Payload.assign(RPathLC.cmdsize - sizeof(MachO::rpath_command), 0);
|
||||||
|
std::copy(Path.begin(), Path.end(), LC.Payload.begin());
|
||||||
|
return LC;
|
||||||
|
}
|
||||||
|
|
||||||
static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
||||||
if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
|
if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
|
||||||
Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
|
Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
|
||||||
@ -81,7 +93,6 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
|||||||
return createStringError(llvm::errc::invalid_argument,
|
return createStringError(llvm::errc::invalid_argument,
|
||||||
"option not supported by llvm-objcopy for MachO");
|
"option not supported by llvm-objcopy for MachO");
|
||||||
}
|
}
|
||||||
|
|
||||||
removeSections(Config, Obj);
|
removeSections(Config, Obj);
|
||||||
|
|
||||||
// Mark symbols to determine which symbols are still needed.
|
// Mark symbols to determine which symbols are still needed.
|
||||||
@ -95,6 +106,19 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
|
|||||||
for (Section &Sec : LC.Sections)
|
for (Section &Sec : LC.Sections)
|
||||||
Sec.Relocations.clear();
|
Sec.Relocations.clear();
|
||||||
|
|
||||||
|
for (StringRef RPath : Config.RPathToAdd) {
|
||||||
|
for (LoadCommand &LC : Obj.LoadCommands) {
|
||||||
|
if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH &&
|
||||||
|
RPath == StringRef(reinterpret_cast<char *>(LC.Payload.data()),
|
||||||
|
LC.Payload.size())
|
||||||
|
.trim(0)) {
|
||||||
|
return createStringError(errc::invalid_argument,
|
||||||
|
"rpath " + RPath +
|
||||||
|
" would create a duplicate load command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Obj.addLoadCommand(buildRPathLoadCommand(RPath));
|
||||||
|
}
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
|
|||||||
std::end(LC.Sections));
|
std::end(LC.Sections));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Object::addLoadCommand(LoadCommand LC) {
|
||||||
|
LoadCommands.push_back(std::move(LC));
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace macho
|
} // end namespace macho
|
||||||
} // end namespace objcopy
|
} // end namespace objcopy
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@ -74,7 +74,7 @@ struct LoadCommand {
|
|||||||
// The raw content of the payload of the load command (located right after the
|
// The raw content of the payload of the load command (located right after the
|
||||||
// corresponding struct). In some cases it is either empty or can be
|
// corresponding struct). In some cases it is either empty or can be
|
||||||
// copied-over without digging into its structure.
|
// copied-over without digging into its structure.
|
||||||
ArrayRef<uint8_t> Payload;
|
std::vector<uint8_t> Payload;
|
||||||
|
|
||||||
// Some load commands can contain (inside the payload) an array of sections,
|
// Some load commands can contain (inside the payload) an array of sections,
|
||||||
// though the contents of the sections are stored separately. The struct
|
// though the contents of the sections are stored separately. The struct
|
||||||
@ -270,6 +270,7 @@ struct Object {
|
|||||||
Optional<size_t> FunctionStartsCommandIndex;
|
Optional<size_t> FunctionStartsCommandIndex;
|
||||||
|
|
||||||
void removeSections(function_ref<bool(const Section &)> ToRemove);
|
void removeSections(function_ref<bool(const Section &)> ToRemove);
|
||||||
|
void addLoadCommand(LoadCommand LC);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace macho
|
} // end namespace macho
|
||||||
|
@ -313,11 +313,20 @@ static Error executeObjcopy(CopyConfig &Config) {
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
enum class ToolType { Objcopy, Strip, InstallNameTool };
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
InitLLVM X(argc, argv);
|
InitLLVM X(argc, argv);
|
||||||
ToolName = argv[0];
|
ToolName = argv[0];
|
||||||
bool IsStrip = sys::path::stem(ToolName).contains("strip");
|
ToolType Tool = StringSwitch<ToolType>(sys::path::stem(ToolName))
|
||||||
|
.EndsWith("strip", ToolType::Strip)
|
||||||
|
.EndsWith("install-name-tool", ToolType::InstallNameTool)
|
||||||
|
.EndsWith("install_name_tool", ToolType::InstallNameTool)
|
||||||
|
.Default(ToolType::Objcopy);
|
||||||
// Expand response files.
|
// Expand response files.
|
||||||
// TODO: Move these lines, which are copied from lib/Support/CommandLine.cpp,
|
// TODO: Move these lines, which are copied from lib/Support/CommandLine.cpp,
|
||||||
// into a separate function in the CommandLine library and call that function
|
// into a separate function in the CommandLine library and call that function
|
||||||
@ -332,10 +341,11 @@ int main(int argc, char **argv) {
|
|||||||
NewArgv);
|
NewArgv);
|
||||||
|
|
||||||
auto Args = makeArrayRef(NewArgv).drop_front();
|
auto Args = makeArrayRef(NewArgv).drop_front();
|
||||||
|
|
||||||
Expected<DriverConfig> DriverConfig =
|
Expected<DriverConfig> DriverConfig =
|
||||||
IsStrip ? parseStripOptions(Args, reportWarning)
|
(Tool == ToolType::Strip) ? parseStripOptions(Args, reportWarning)
|
||||||
: parseObjcopyOptions(Args, reportWarning);
|
: ((Tool == ToolType::InstallNameTool)
|
||||||
|
? parseInstallNameToolOptions(Args)
|
||||||
|
: parseObjcopyOptions(Args, reportWarning));
|
||||||
if (!DriverConfig) {
|
if (!DriverConfig) {
|
||||||
logAllUnhandledErrors(DriverConfig.takeError(),
|
logAllUnhandledErrors(DriverConfig.takeError(),
|
||||||
WithColor::error(errs(), ToolName));
|
WithColor::error(errs(), ToolName));
|
||||||
|
Loading…
Reference in New Issue
Block a user