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