forked from OSchip/llvm-project
Add support for the source_version cmdline option.
This is of the form A.B.C.D.E and to match ld64's behaviour, is always output to files, even when the version is 0. rdar://problem/24472630 llvm-svn: 259746
This commit is contained in:
parent
0e05d6eb9c
commit
40576fa0e9
|
@ -169,6 +169,9 @@ public:
|
|||
uint32_t sdkVersion() const { return _sdkVersion; }
|
||||
void setSdkVersion(uint64_t v) { _sdkVersion = v; }
|
||||
|
||||
uint64_t sourceVersion() const { return _sourceVersion; }
|
||||
void setSourceVersion(uint64_t v) { _sourceVersion = v; }
|
||||
|
||||
uint32_t swiftVersion() const { return _swiftVersion; }
|
||||
|
||||
/// \brief Checks whether a given path on the filesystem exists.
|
||||
|
@ -371,6 +374,10 @@ public:
|
|||
/// bits are xxxx.yy.zz. Largest number is 65535.255.255
|
||||
static bool parsePackedVersion(StringRef str, uint32_t &result);
|
||||
|
||||
/// Construct 64-bit value from string "A.B.C.D.E" where
|
||||
/// bits are aaaa.bb.cc.dd.ee. Largest number is 16777215.1023.1023.1023.1023
|
||||
static bool parsePackedVersion(StringRef str, uint64_t &result);
|
||||
|
||||
void finalizeInputFiles() override;
|
||||
|
||||
std::error_code handleLoadedFile(File &file) override;
|
||||
|
@ -424,6 +431,7 @@ private:
|
|||
OS _os;
|
||||
uint32_t _osMinVersion;
|
||||
uint32_t _sdkVersion = 0;
|
||||
uint64_t _sourceVersion = 0;
|
||||
uint64_t _pageZeroSize;
|
||||
uint64_t _pageSize;
|
||||
uint64_t _baseAddress;
|
||||
|
|
|
@ -812,6 +812,17 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
|
|||
ctx.setSdkVersion(ctx.osMinVersion());
|
||||
}
|
||||
|
||||
// Handle source_version
|
||||
if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_source_version)) {
|
||||
uint64_t version = 0;
|
||||
if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
|
||||
version)) {
|
||||
diagnostics << "error: malformed source_version value\n";
|
||||
return false;
|
||||
}
|
||||
ctx.setSourceVersion(version);
|
||||
}
|
||||
|
||||
// Handle stack_size
|
||||
if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) {
|
||||
uint64_t stackSizeVal;
|
||||
|
|
|
@ -36,6 +36,9 @@ def ios_simulator_version_min : Separate<["-"], "ios_simulator_version_min">,
|
|||
def sdk_version : Separate<["-"], "sdk_version">,
|
||||
MetaVarName<"<version>">,
|
||||
HelpText<"SDK version">, Group<grp_opts>;
|
||||
def source_version : Separate<["-"], "source_version">,
|
||||
MetaVarName<"<version>">,
|
||||
HelpText<"Source version">, Group<grp_opts>;
|
||||
def version_load_command : Flag<["-"], "version_load_command">,
|
||||
HelpText<"Force generation of a version load command">, Group<grp_opts>;
|
||||
def no_version_load_command : Flag<["-"], "no_version_load_command">,
|
||||
|
|
|
@ -76,6 +76,35 @@ bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
|
||||
result = 0;
|
||||
|
||||
if (str.empty())
|
||||
return false;
|
||||
|
||||
SmallVector<StringRef, 5> parts;
|
||||
llvm::SplitString(str, parts, ".");
|
||||
|
||||
uint64_t num;
|
||||
if (llvm::getAsUnsignedInteger(parts[0], 10, num))
|
||||
return true;
|
||||
if (num > 0xFFFFFF)
|
||||
return true;
|
||||
result = num << 40;
|
||||
|
||||
unsigned Shift = 30;
|
||||
for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
|
||||
if (llvm::getAsUnsignedInteger(str, 10, num))
|
||||
return true;
|
||||
if (num > 0x3FF)
|
||||
return true;
|
||||
result |= (num << Shift);
|
||||
Shift -= 10;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
|
||||
{ "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
|
||||
{ "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
|
||||
|
|
|
@ -467,6 +467,10 @@ uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
|
|||
++count;
|
||||
}
|
||||
|
||||
// Add LC_SOURCE_VERSION
|
||||
size += sizeof(source_version_command);
|
||||
++count;
|
||||
|
||||
// If main executable add LC_MAIN
|
||||
if (_file.fileType == llvm::MachO::MH_EXECUTE) {
|
||||
size += sizeof(entry_point_command);
|
||||
|
@ -915,6 +919,17 @@ std::error_code MachOFileLayout::writeLoadCommands() {
|
|||
// LC_VERSION_MIN_TVOS
|
||||
writeVersionMinLoadCommand(_file, _swap, lc);
|
||||
|
||||
// Add LC_SOURCE_VERSION
|
||||
{
|
||||
source_version_command* sv = reinterpret_cast<source_version_command*>(lc);
|
||||
sv->cmd = LC_SOURCE_VERSION;
|
||||
sv->cmdsize = sizeof(source_version_command);
|
||||
sv->version = _file.sourceVersion;
|
||||
if (_swap)
|
||||
swapStruct(*sv);
|
||||
lc += sizeof(source_version_command);
|
||||
}
|
||||
|
||||
// If main executable, add LC_MAIN.
|
||||
if (_file.fileType == llvm::MachO::MH_EXECUTE) {
|
||||
// Build LC_MAIN load command.
|
||||
|
|
|
@ -1285,6 +1285,7 @@ normalizedFromAtoms(const lld::File &atomFile,
|
|||
normFile.minOSVersionKind = util.minVersionCommandType();
|
||||
|
||||
normFile.sdkVersion = context.sdkVersion();
|
||||
normFile.sourceVersion = context.sourceVersion();
|
||||
|
||||
if (context.generateVersionLoadCommand() &&
|
||||
context.os() != MachOLinkingContext::OS::unknown)
|
||||
|
|
Loading…
Reference in New Issue