| 193 | |
| 194 | |
| 195 | MachoView::MachoView(const string& typeName, BinaryView* data, bool parseOnly): BinaryView(typeName, data->GetFile(), data), |
| 196 | m_universalImageOffset(0), m_parseOnly(parseOnly) |
| 197 | { |
| 198 | CreateLogger("BinaryView"); |
| 199 | m_logger = CreateLogger("BinaryView.MachoView"); |
| 200 | |
| 201 | m_backedByDatabase = data->GetFile()->IsBackedByDatabase(typeName); |
| 202 | |
| 203 | Ref<BinaryViewType> universalViewType = BinaryViewType::GetByName("Universal"); |
| 204 | bool isUniversal = (universalViewType && universalViewType->IsTypeValidForData(data)); |
| 205 | |
| 206 | Ref<Settings> viewSettings = Settings::Instance(); |
| 207 | m_extractMangledTypes = viewSettings->Get<bool>("analysis.extractTypesFromMangledNames", data); |
| 208 | m_simplifyTemplates = viewSettings->Get<bool>("analysis.types.templateSimplifier", data); |
| 209 | |
| 210 | Ref<Settings> settings = data->GetLoadSettings(typeName); |
| 211 | if (settings && settings->Contains("loader.macho.universalImageOffset")) |
| 212 | { |
| 213 | settings->SetResourceId(typeName); |
| 214 | m_universalImageOffset = settings->Get<uint64_t>("loader.macho.universalImageOffset", data); |
| 215 | } |
| 216 | else if (isUniversal) |
| 217 | { |
| 218 | Ref<Settings> loadSettings = universalViewType->GetLoadSettingsForData(data); |
| 219 | if (loadSettings && loadSettings->Contains("loader.universal.architectures")) |
| 220 | { |
| 221 | string json = loadSettings->Get<string>("loader.universal.architectures"); |
| 222 | rapidjson::Document jsonArchitectures; |
| 223 | jsonArchitectures.Parse(json.data(), json.size()); |
| 224 | if (!json.size() || jsonArchitectures.HasParseError()) |
| 225 | throw MachoFormatException("Mach-O view could not be created! Json parse error."); |
| 226 | if (!jsonArchitectures.IsArray() || jsonArchitectures.Empty()) |
| 227 | throw MachoFormatException("Mach-O view could not be created! Json data error."); |
| 228 | |
| 229 | // Select the object file based on architecture preference. |
| 230 | // Note: This code is duplicated in options.cpp |
| 231 | vector<string> architectures; |
| 232 | for (const auto& entry : jsonArchitectures.GetArray()) |
| 233 | architectures.push_back(entry["architecture"].GetString()); |
| 234 | auto archPref = Settings::Instance()->Get<vector<string>>("files.universal.architecturePreference"); |
| 235 | int archIndex = 0; |
| 236 | if (auto result = find_first_of(archPref.begin(), archPref.end(), architectures.begin(), architectures.end()); result != archPref.end()) |
| 237 | archIndex = std::find(architectures.begin(), architectures.end(), *result) - architectures.begin(); |
| 238 | |
| 239 | const auto& archEntry = jsonArchitectures[archIndex]; |
| 240 | loadSettings = Settings::Instance(GetUniqueIdentifierString()); |
| 241 | loadSettings->SetResourceId(typeName); |
| 242 | loadSettings->DeserializeSchema(archEntry["loadSchema"].GetString()); |
| 243 | data->SetLoadSettings(typeName, loadSettings); |
| 244 | if (!m_file->IsBackedByDatabase(typeName)) |
| 245 | { |
| 246 | auto defaultSettings = loadSettings->SerializeSettings(Ref<BinaryView>(), SettingsDefaultScope); |
| 247 | loadSettings->DeserializeSettings(defaultSettings, data, SettingsResourceScope); |
| 248 | } |
| 249 | |
| 250 | m_universalImageOffset = loadSettings->Get<uint64_t>("loader.macho.universalImageOffset", data); |
| 251 | |
| 252 | // NOTE: this silences the 'Updated load schema detected' warning. There is some chicken/egg stuff here. |
nothing calls this directly
no test coverage detected