uint8_t* copyRoutinesLoadCommand(uint8_t* p) const;
uint8_t* copyUUIDLoadCommand(uint8_t* p) const;
uint8_t* copyVersionLoadCommand(uint8_t* p) const;
+ uint8_t* copyBuildVersionLoadCommand(uint8_t* p) const;
uint8_t* copySourceVersionLoadCommand(uint8_t* p) const;
uint8_t* copyThreadsLoadCommand(uint8_t* p) const;
uint8_t* copyEntryPointLoadCommand(uint8_t* p) const;
bool _hasRPathLoadCommands;
bool _hasSubFrameworkLoadCommand;
bool _hasVersionLoadCommand;
+ bool _hasBuildVersionLoadCommand;
bool _hasFunctionStartsLoadCommand;
bool _hasDataInCodeLoadCommand;
bool _hasSourceVersionLoadCommand;
bool _hasOptimizationHints;
+ Options::Platform _platform;
uint32_t _dylibLoadCommmandsCount;
uint32_t _allowableClientLoadCommmandsCount;
uint32_t _dyldEnvironExrasCount;
mutable uint32_t _linkeditCmdOffset;
mutable uint32_t _symboltableCmdOffset;
std::vector< std::vector<const char*> > _linkerOptions;
+ std::unordered_set<uint64_t>& _toolsVersions;
static ld::Section _s_section;
static ld::Section _s_preload_section;
ld::Atom::scopeTranslationUnit, ld::Atom::typeUnclassified,
ld::Atom::symbolTableNotIn, false, false, false,
(opts.outputKind() == Options::kPreload) ? ld::Atom::Alignment(0) : ld::Atom::Alignment(log2(opts.segmentAlignment())) ),
- _options(opts), _state(state), _writer(writer), _address(0), _uuidCmdInOutputBuffer(NULL), _linkeditCmdOffset(0), _symboltableCmdOffset(0)
+ _options(opts), _state(state), _writer(writer), _address(0), _uuidCmdInOutputBuffer(NULL), _linkeditCmdOffset(0), _symboltableCmdOffset(0),
+ _toolsVersions(state.toolsVersions)
{
bzero(_uuid, 16);
_hasDyldInfoLoadCommand = opts.makeCompressedDyldInfo();
}
_hasRPathLoadCommands = (_options.rpaths().size() != 0);
_hasSubFrameworkLoadCommand = (_options.umbrellaName() != NULL);
- _hasVersionLoadCommand = _options.addVersionLoadCommand() ||
- (!state.objectFileFoundWithNoVersion && (_options.outputKind() == Options::kObjectFile)
- && ((_options.platform() != Options::kPlatformUnknown) || (state.derivedPlatformLoadCommand != 0)) );
+ _platform = _options.platform();
+ if ( (_platform == Options::kPlatformUnknown) && (_state.derivedPlatform != 0) )
+ _platform = (Options::Platform)_state.derivedPlatform;
+ if ( _options.addVersionLoadCommand() ) {
+ _hasBuildVersionLoadCommand = _options.addBuildVersionLoadCommand();
+ _hasVersionLoadCommand = !_hasBuildVersionLoadCommand;
+ }
+ else if (((_options.outputKind() == Options::kObjectFile) && (_platform != Options::kPlatformUnknown) && !state.objectFileFoundWithNoVersion) ) {
+ _hasBuildVersionLoadCommand = (_platform == Options::kPlatform_bridgeOS);
+ _hasVersionLoadCommand = !_hasBuildVersionLoadCommand;
+ }
+ else {
+ _hasVersionLoadCommand = false;
+ _hasBuildVersionLoadCommand = false;
+ }
_hasFunctionStartsLoadCommand = _options.addFunctionStarts();
_hasDataInCodeLoadCommand = _options.addDataInCodeInfo();
_hasSourceVersionLoadCommand = _options.needsSourceVersionLoadCommand();
if ( _hasVersionLoadCommand )
sz += sizeof(macho_version_min_command<P>);
+ if ( _hasBuildVersionLoadCommand )
+ sz += alignedSize(sizeof(macho_build_version_command<P>) + sizeof(macho_build_tool_version<P>)*_toolsVersions.size());
+
if ( _hasSourceVersionLoadCommand )
sz += sizeof(macho_source_version_command<P>);
if ( _hasVersionLoadCommand )
++count;
+ if ( _hasBuildVersionLoadCommand )
+ ++count;
+
if ( _hasSourceVersionLoadCommand )
++count;
template <>
uint32_t HeaderAndLoadCommandsAtom<arm64>::cpuSubType() const
{
- return CPU_SUBTYPE_ARM64_ALL;
+ return _state.cpuSubType;
}
uint8_t* HeaderAndLoadCommandsAtom<A>::copyVersionLoadCommand(uint8_t* p) const
{
macho_version_min_command<P>* cmd = (macho_version_min_command<P>*)p;
- switch (_options.platform()) {
- case Options::kPlatformUnknown:
- assert(_state.derivedPlatformLoadCommand != 0 && "unknown platform");
- cmd->set_cmd(_state.derivedPlatformLoadCommand);
- cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
- cmd->set_version(_state.minOSVersion);
- cmd->set_sdk(0);
- break;
+ switch (_platform) {
case Options::kPlatformOSX:
cmd->set_cmd(LC_VERSION_MIN_MACOSX);
cmd->set_cmdsize(sizeof(macho_version_min_command<P>));
cmd->set_sdk(_options.sdkVersion());
break;
#endif
+ case Options::kPlatformUnknown:
+ assert(0 && "unknown platform");
+ break;
+ case Options::kPlatform_bridgeOS:
+ assert(0 && "bridgeOS uses LC_BUILD_VERSION");
+ break;
}
return p + sizeof(macho_version_min_command<P>);
}
+
+
+template <typename A>
+uint8_t* HeaderAndLoadCommandsAtom<A>::copyBuildVersionLoadCommand(uint8_t* p) const
+{
+ macho_build_version_command<P>* cmd = (macho_build_version_command<P>*)p;
+
+ cmd->set_cmd(LC_BUILD_VERSION);
+ cmd->set_cmdsize(alignedSize(sizeof(macho_build_version_command<P>) + sizeof(macho_build_tool_version<P>)*_toolsVersions.size()));
+ cmd->set_platform(_options.platform());
+ cmd->set_minos(_state.minOSVersion);
+ cmd->set_sdk(_options.sdkVersion());
+ cmd->set_ntools(_toolsVersions.size());
+ macho_build_tool_version<P>* tools = (macho_build_tool_version<P>*)(p + sizeof(macho_build_version_command<P>));
+ for (uint64_t tool : _toolsVersions) {
+ tools->set_tool((uint64_t)tool >> 32);
+ tools->set_version(tool & 0xFFFFFFFF);
+ ++tools;
+ }
+
+ return p + cmd->cmdsize();
+}
+
+
template <typename A>
uint8_t* HeaderAndLoadCommandsAtom<A>::copySourceVersionLoadCommand(uint8_t* p) const
{
if ( _hasVersionLoadCommand )
p = this->copyVersionLoadCommand(p);
+ if ( _hasBuildVersionLoadCommand )
+ p = this->copyBuildVersionLoadCommand(p);
+
if ( _hasSourceVersionLoadCommand )
p = this->copySourceVersionLoadCommand(p);