@@ -912,22 +912,34 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
912
912
// create a JSONGenerator object
913
913
// with all the details we want to send to lldb.
914
914
JSONGenerator::ObjectSP MachProcess::FormatDynamicLibrariesIntoJSON (
915
- const std::vector<struct binary_image_information > &image_infos) {
915
+ const std::vector<struct binary_image_information > &image_infos,
916
+ bool report_load_commands) {
916
917
917
918
JSONGenerator::ArraySP image_infos_array_sp (new JSONGenerator::Array ());
918
919
919
920
const size_t image_count = image_infos.size ();
920
921
921
922
for (size_t i = 0 ; i < image_count; i++) {
922
- if (!image_infos[i].is_valid_mach_header )
923
+ // If we should report the Mach-O header and load commands,
924
+ // and those were unreadable, don't report anything about this
925
+ // binary.
926
+ if (report_load_commands && !image_infos[i].is_valid_mach_header )
923
927
continue ;
924
928
JSONGenerator::DictionarySP image_info_dict_sp (
925
929
new JSONGenerator::Dictionary ());
926
930
image_info_dict_sp->AddIntegerItem (" load_address" ,
927
931
image_infos[i].load_address );
928
- image_info_dict_sp->AddIntegerItem (" mod_date" , image_infos[i].mod_date );
932
+ // TODO: lldb currently rejects a response without this, but it
933
+ // is always zero from dyld. It can be removed once we've had time
934
+ // for lldb's that require it to be present are obsolete.
935
+ image_info_dict_sp->AddIntegerItem (" mod_date" , 0 );
929
936
image_info_dict_sp->AddStringItem (" pathname" , image_infos[i].filename );
930
937
938
+ if (!report_load_commands) {
939
+ image_infos_array_sp->AddItem (image_info_dict_sp);
940
+ continue ;
941
+ }
942
+
931
943
uuid_string_t uuidstr;
932
944
uuid_unparse_upper (image_infos[i].macho_info .uuid , uuidstr);
933
945
image_info_dict_sp->AddStringItem (" uuid" , uuidstr);
@@ -1000,109 +1012,6 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
1000
1012
return reply_sp;
1001
1013
}
1002
1014
1003
- // Get the shared library information using the old (pre-macOS 10.12, pre-iOS
1004
- // 10, pre-tvOS 10, pre-watchOS 3)
1005
- // code path. We'll be given the address of an array of structures in the form
1006
- // {void* load_addr, void* mod_date, void* pathname}
1007
- //
1008
- // In macOS 10.12 etc and newer, we'll use SPI calls into dyld to gather this
1009
- // information.
1010
- JSONGenerator::ObjectSP MachProcess::GetLoadedDynamicLibrariesInfos (
1011
- nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count) {
1012
-
1013
- JSONGenerator::ObjectSP empty_reply_sp (new JSONGenerator::Dictionary ());
1014
- int pointer_size = GetInferiorAddrSize (pid);
1015
-
1016
- std::vector<struct binary_image_information > image_infos;
1017
- size_t image_infos_size = image_count * 3 * pointer_size;
1018
-
1019
- uint8_t *image_info_buf = (uint8_t *)malloc (image_infos_size);
1020
- if (image_info_buf == NULL ) {
1021
- return empty_reply_sp;
1022
- }
1023
- if (ReadMemory (image_list_address, image_infos_size, image_info_buf) !=
1024
- image_infos_size) {
1025
- return empty_reply_sp;
1026
- }
1027
-
1028
- // / First the image_infos array with (load addr, pathname, mod date)
1029
- // / tuples
1030
-
1031
- for (size_t i = 0 ; i < image_count; i++) {
1032
- struct binary_image_information info;
1033
- nub_addr_t pathname_address;
1034
- if (pointer_size == 4 ) {
1035
- uint32_t load_address_32;
1036
- uint32_t pathname_address_32;
1037
- uint32_t mod_date_32;
1038
- ::memcpy (&load_address_32, image_info_buf + (i * 3 * pointer_size), 4);
1039
- ::memcpy (&pathname_address_32,
1040
- image_info_buf + (i * 3 * pointer_size) + pointer_size, 4);
1041
- ::memcpy (&mod_date_32,
1042
- image_info_buf + (i * 3 * pointer_size) + pointer_size +
1043
- pointer_size,
1044
- 4);
1045
- info.load_address = load_address_32;
1046
- info.mod_date = mod_date_32;
1047
- pathname_address = pathname_address_32;
1048
- } else {
1049
- uint64_t load_address_64;
1050
- uint64_t pathname_address_64;
1051
- uint64_t mod_date_64;
1052
- ::memcpy (&load_address_64, image_info_buf + (i * 3 * pointer_size), 8);
1053
- ::memcpy (&pathname_address_64,
1054
- image_info_buf + (i * 3 * pointer_size) + pointer_size, 8);
1055
- ::memcpy (&mod_date_64,
1056
- image_info_buf + (i * 3 * pointer_size) + pointer_size +
1057
- pointer_size,
1058
- 8);
1059
- info.load_address = load_address_64;
1060
- info.mod_date = mod_date_64;
1061
- pathname_address = pathname_address_64;
1062
- }
1063
- char strbuf[17 ];
1064
- info.filename = " " ;
1065
- uint64_t pathname_ptr = pathname_address;
1066
- bool still_reading = true ;
1067
- while (still_reading && ReadMemory (pathname_ptr, sizeof (strbuf) - 1 ,
1068
- strbuf) == sizeof (strbuf) - 1 ) {
1069
- strbuf[sizeof (strbuf) - 1 ] = ' \0 ' ;
1070
- info.filename += strbuf;
1071
- pathname_ptr += sizeof (strbuf) - 1 ;
1072
- // Stop if we found nul byte indicating the end of the string
1073
- for (size_t i = 0 ; i < sizeof (strbuf) - 1 ; i++) {
1074
- if (strbuf[i] == ' \0 ' ) {
1075
- still_reading = false ;
1076
- break ;
1077
- }
1078
- }
1079
- }
1080
- uuid_clear (info.macho_info .uuid );
1081
- image_infos.push_back (info);
1082
- }
1083
- if (image_infos.size () == 0 ) {
1084
- return empty_reply_sp;
1085
- }
1086
-
1087
- free (image_info_buf);
1088
-
1089
- // / Second, read the mach header / load commands for all the dylibs
1090
-
1091
- for (size_t i = 0 ; i < image_count; i++) {
1092
- // The SPI to provide platform is not available on older systems.
1093
- uint32_t platform = 0 ;
1094
- if (GetMachOInformationFromMemory (platform, image_infos[i].load_address ,
1095
- pointer_size,
1096
- image_infos[i].macho_info )) {
1097
- image_infos[i].is_valid_mach_header = true ;
1098
- }
1099
- }
1100
-
1101
- // / Third, format all of the above in the JSONGenerator object.
1102
-
1103
- return FormatDynamicLibrariesIntoJSON (image_infos);
1104
- }
1105
-
1106
1015
// / From dyld SPI header dyld_process_info.h
1107
1016
typedef void *dyld_process_info;
1108
1017
struct dyld_process_cache_info {
@@ -1162,21 +1071,24 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
1162
1071
// in
1163
1072
// macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.
1164
1073
JSONGenerator::ObjectSP
1165
- MachProcess::GetAllLoadedLibrariesInfos (nub_process_t pid) {
1074
+ MachProcess::GetAllLoadedLibrariesInfos (nub_process_t pid,
1075
+ bool report_load_commands) {
1166
1076
1167
1077
int pointer_size = GetInferiorAddrSize (pid);
1168
1078
std::vector<struct binary_image_information > image_infos;
1169
1079
GetAllLoadedBinariesViaDYLDSPI (image_infos);
1170
- uint32_t platform = GetPlatform ();
1171
- const size_t image_count = image_infos.size ();
1172
- for (size_t i = 0 ; i < image_count; i++) {
1173
- if (GetMachOInformationFromMemory (platform, image_infos[i].load_address ,
1174
- pointer_size,
1175
- image_infos[i].macho_info )) {
1176
- image_infos[i].is_valid_mach_header = true ;
1080
+ if (report_load_commands) {
1081
+ uint32_t platform = GetPlatform ();
1082
+ const size_t image_count = image_infos.size ();
1083
+ for (size_t i = 0 ; i < image_count; i++) {
1084
+ if (GetMachOInformationFromMemory (platform, image_infos[i].load_address ,
1085
+ pointer_size,
1086
+ image_infos[i].macho_info )) {
1087
+ image_infos[i].is_valid_mach_header = true ;
1088
+ }
1177
1089
}
1178
1090
}
1179
- return FormatDynamicLibrariesIntoJSON (image_infos);
1091
+ return FormatDynamicLibrariesIntoJSON (image_infos, report_load_commands );
1180
1092
}
1181
1093
1182
1094
// Fetch information about the shared libraries at the given load addresses
@@ -1226,7 +1138,8 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
1226
1138
image_infos[i].is_valid_mach_header = true ;
1227
1139
}
1228
1140
}
1229
- return FormatDynamicLibrariesIntoJSON (image_infos);
1141
+ return FormatDynamicLibrariesIntoJSON (image_infos,
1142
+ /* report_load_commands = */ true );
1230
1143
}
1231
1144
1232
1145
// From dyld's internal podyld_process_info.h:
0 commit comments