@@ -140,6 +140,9 @@ using namespace lldb;
140
140
using namespace lldb_private ;
141
141
using namespace llvm ::MachO;
142
142
143
+ static constexpr llvm::StringLiteral g_loader_path = " @loader_path" ;
144
+ static constexpr llvm::StringLiteral g_executable_path = " @executable_path" ;
145
+
143
146
LLDB_PLUGIN_DEFINE (ObjectFileMachO)
144
147
145
148
static void PrintRegisterValue(RegisterContext *reg_ctx, const char *name,
@@ -5145,123 +5148,121 @@ UUID ObjectFileMachO::GetUUID() {
5145
5148
}
5146
5149
5147
5150
uint32_t ObjectFileMachO::GetDependentModules (FileSpecList &files) {
5151
+ ModuleSP module_sp = GetModule ();
5152
+ if (!module_sp)
5153
+ return 0 ;
5154
+
5148
5155
uint32_t count = 0 ;
5149
- ModuleSP module_sp (GetModule ());
5150
- if (module_sp) {
5151
- std::lock_guard<std::recursive_mutex> guard (module_sp->GetMutex ());
5152
- llvm::MachO::load_command load_cmd;
5153
- lldb::offset_t offset = MachHeaderSizeFromMagic (m_header.magic );
5154
- std::vector<std::string> rpath_paths;
5155
- std::vector<std::string> rpath_relative_paths;
5156
- std::vector<std::string> at_exec_relative_paths;
5157
- uint32_t i;
5158
- for (i = 0 ; i < m_header.ncmds ; ++i) {
5159
- const uint32_t cmd_offset = offset;
5160
- if (m_data.GetU32 (&offset, &load_cmd, 2 ) == nullptr )
5161
- break ;
5156
+ std::lock_guard<std::recursive_mutex> guard (module_sp->GetMutex ());
5157
+ llvm::MachO::load_command load_cmd;
5158
+ lldb::offset_t offset = MachHeaderSizeFromMagic (m_header.magic );
5159
+ std::vector<std::string> rpath_paths;
5160
+ std::vector<std::string> rpath_relative_paths;
5161
+ std::vector<std::string> at_exec_relative_paths;
5162
+ uint32_t i;
5163
+ for (i = 0 ; i < m_header.ncmds ; ++i) {
5164
+ const uint32_t cmd_offset = offset;
5165
+ if (m_data.GetU32 (&offset, &load_cmd, 2 ) == nullptr )
5166
+ break ;
5162
5167
5163
- switch (load_cmd.cmd ) {
5164
- case LC_RPATH:
5165
- case LC_LOAD_DYLIB:
5166
- case LC_LOAD_WEAK_DYLIB:
5167
- case LC_REEXPORT_DYLIB:
5168
- case LC_LOAD_DYLINKER:
5169
- case LC_LOADFVMLIB:
5170
- case LC_LOAD_UPWARD_DYLIB: {
5171
- uint32_t name_offset = cmd_offset + m_data.GetU32 (&offset);
5172
- // For LC_LOAD_DYLIB there is an alternate encoding
5173
- // which adds a uint32_t `flags` field for `DYLD_USE_*`
5174
- // flags. This can be detected by a timestamp field with
5175
- // the `DYLIB_USE_MARKER` constant value.
5176
- bool is_delayed_init = false ;
5177
- uint32_t use_command_marker = m_data.GetU32 (&offset);
5178
- if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */ ) {
5179
- offset += 4 ; /* uint32_t current_version */
5180
- offset += 4 ; /* uint32_t compat_version */
5181
- uint32_t flags = m_data.GetU32 (&offset);
5182
- // If this LC_LOAD_DYLIB is marked delay-init,
5183
- // don't report it as a dependent library -- it
5184
- // may be loaded in the process at some point,
5185
- // but will most likely not be load at launch.
5186
- if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */ )
5187
- is_delayed_init = true ;
5188
- }
5189
- const char *path = m_data.PeekCStr (name_offset);
5190
- if (path && !is_delayed_init) {
5191
- if (load_cmd.cmd == LC_RPATH)
5192
- rpath_paths.push_back (path);
5193
- else {
5194
- if (path[0 ] == ' @' ) {
5195
- if (strncmp (path, " @rpath" , strlen (" @rpath" )) == 0 )
5196
- rpath_relative_paths.push_back (path + strlen (" @rpath" ));
5197
- else if (strncmp (path, " @executable_path" ,
5198
- strlen (" @executable_path" )) == 0 )
5199
- at_exec_relative_paths.push_back (path +
5200
- strlen (" @executable_path" ));
5201
- } else {
5202
- FileSpec file_spec (path);
5203
- if (files.AppendIfUnique (file_spec))
5204
- count++;
5205
- }
5168
+ switch (load_cmd.cmd ) {
5169
+ case LC_RPATH:
5170
+ case LC_LOAD_DYLIB:
5171
+ case LC_LOAD_WEAK_DYLIB:
5172
+ case LC_REEXPORT_DYLIB:
5173
+ case LC_LOAD_DYLINKER:
5174
+ case LC_LOADFVMLIB:
5175
+ case LC_LOAD_UPWARD_DYLIB: {
5176
+ uint32_t name_offset = cmd_offset + m_data.GetU32 (&offset);
5177
+ // For LC_LOAD_DYLIB there is an alternate encoding
5178
+ // which adds a uint32_t `flags` field for `DYLD_USE_*`
5179
+ // flags. This can be detected by a timestamp field with
5180
+ // the `DYLIB_USE_MARKER` constant value.
5181
+ bool is_delayed_init = false ;
5182
+ uint32_t use_command_marker = m_data.GetU32 (&offset);
5183
+ if (use_command_marker == 0x1a741800 /* DYLIB_USE_MARKER */ ) {
5184
+ offset += 4 ; /* uint32_t current_version */
5185
+ offset += 4 ; /* uint32_t compat_version */
5186
+ uint32_t flags = m_data.GetU32 (&offset);
5187
+ // If this LC_LOAD_DYLIB is marked delay-init,
5188
+ // don't report it as a dependent library -- it
5189
+ // may be loaded in the process at some point,
5190
+ // but will most likely not be load at launch.
5191
+ if (flags & 0x08 /* DYLIB_USE_DELAYED_INIT */ )
5192
+ is_delayed_init = true ;
5193
+ }
5194
+ const char *path = m_data.PeekCStr (name_offset);
5195
+ if (path && !is_delayed_init) {
5196
+ if (load_cmd.cmd == LC_RPATH)
5197
+ rpath_paths.push_back (path);
5198
+ else {
5199
+ if (path[0 ] == ' @' ) {
5200
+ if (strncmp (path, " @rpath" , strlen (" @rpath" )) == 0 )
5201
+ rpath_relative_paths.push_back (path + strlen (" @rpath" ));
5202
+ else if (strncmp (path, " @executable_path" ,
5203
+ strlen (" @executable_path" )) == 0 )
5204
+ at_exec_relative_paths.push_back (path +
5205
+ strlen (" @executable_path" ));
5206
+ } else {
5207
+ FileSpec file_spec (path);
5208
+ if (files.AppendIfUnique (file_spec))
5209
+ count++;
5206
5210
}
5207
5211
}
5208
- } break ;
5209
-
5210
- default :
5211
- break ;
5212
5212
}
5213
- offset = cmd_offset + load_cmd.cmdsize ;
5214
- }
5213
+ } break ;
5215
5214
5216
- FileSpec this_file_spec (m_file);
5217
- FileSystem::Instance ().Resolve (this_file_spec);
5218
-
5219
- if (!rpath_paths.empty ()) {
5220
- // Fixup all LC_RPATH values to be absolute paths
5221
- std::string loader_path (" @loader_path" );
5222
- std::string executable_path (" @executable_path" );
5223
- for (auto &rpath : rpath_paths) {
5224
- if (llvm::StringRef (rpath).starts_with (loader_path)) {
5225
- rpath.erase (0 , loader_path.size ());
5226
- rpath.insert (0 , this_file_spec.GetDirectory ().GetCString ());
5227
- } else if (llvm::StringRef (rpath).starts_with (executable_path)) {
5228
- rpath.erase (0 , executable_path.size ());
5229
- rpath.insert (0 , this_file_spec.GetDirectory ().GetCString ());
5230
- }
5231
- }
5215
+ default :
5216
+ break ;
5217
+ }
5218
+ offset = cmd_offset + load_cmd.cmdsize ;
5219
+ }
5232
5220
5233
- for (const auto &rpath_relative_path : rpath_relative_paths) {
5234
- for (const auto &rpath : rpath_paths) {
5235
- std::string path = rpath;
5236
- path += rpath_relative_path;
5237
- // It is OK to resolve this path because we must find a file on disk
5238
- // for us to accept it anyway if it is rpath relative.
5239
- FileSpec file_spec (path);
5240
- FileSystem::Instance ().Resolve (file_spec);
5241
- if (FileSystem::Instance ().Exists (file_spec) &&
5242
- files.AppendIfUnique (file_spec)) {
5243
- count++;
5244
- break ;
5245
- }
5246
- }
5247
- }
5221
+ FileSpec this_file_spec (m_file);
5222
+ FileSystem::Instance ().Resolve (this_file_spec);
5223
+
5224
+ if (!rpath_paths.empty ()) {
5225
+ // Fixup all LC_RPATH values to be absolute paths.
5226
+ const std::string this_directory =
5227
+ this_file_spec.GetDirectory ().GetString ();
5228
+ for (auto &rpath : rpath_paths) {
5229
+ if (llvm::StringRef (rpath).starts_with (g_loader_path))
5230
+ rpath = this_directory + rpath.substr (g_loader_path.size ());
5231
+ else if (llvm::StringRef (rpath).starts_with (g_executable_path))
5232
+ rpath = this_directory + rpath.substr (g_executable_path.size ());
5248
5233
}
5249
5234
5250
- // We may have @executable_paths but no RPATHS. Figure those out here.
5251
- // Only do this if this object file is the executable. We have no way to
5252
- // get back to the actual executable otherwise, so we won't get the right
5253
- // path.
5254
- if (!at_exec_relative_paths.empty () && CalculateType () == eTypeExecutable) {
5255
- FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent ();
5256
- for (const auto &at_exec_relative_path : at_exec_relative_paths) {
5257
- FileSpec file_spec =
5258
- exec_dir.CopyByAppendingPathComponent (at_exec_relative_path);
5235
+ for (const auto &rpath_relative_path : rpath_relative_paths) {
5236
+ for (const auto &rpath : rpath_paths) {
5237
+ std::string path = rpath;
5238
+ path += rpath_relative_path;
5239
+ // It is OK to resolve this path because we must find a file on disk
5240
+ // for us to accept it anyway if it is rpath relative.
5241
+ FileSpec file_spec (path);
5242
+ FileSystem::Instance ().Resolve (file_spec);
5259
5243
if (FileSystem::Instance ().Exists (file_spec) &&
5260
- files.AppendIfUnique (file_spec))
5244
+ files.AppendIfUnique (file_spec)) {
5261
5245
count++;
5246
+ break ;
5247
+ }
5262
5248
}
5263
5249
}
5264
5250
}
5251
+
5252
+ // We may have @executable_paths but no RPATHS. Figure those out here.
5253
+ // Only do this if this object file is the executable. We have no way to
5254
+ // get back to the actual executable otherwise, so we won't get the right
5255
+ // path.
5256
+ if (!at_exec_relative_paths.empty () && CalculateType () == eTypeExecutable) {
5257
+ FileSpec exec_dir = this_file_spec.CopyByRemovingLastPathComponent ();
5258
+ for (const auto &at_exec_relative_path : at_exec_relative_paths) {
5259
+ FileSpec file_spec =
5260
+ exec_dir.CopyByAppendingPathComponent (at_exec_relative_path);
5261
+ if (FileSystem::Instance ().Exists (file_spec) &&
5262
+ files.AppendIfUnique (file_spec))
5263
+ count++;
5264
+ }
5265
+ }
5265
5266
return count;
5266
5267
}
5267
5268
0 commit comments