1/* 2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include <architecture_private.h> 8 9#include <stdio.h> 10#include <string.h> 11#include <sys/stat.h> 12 13#include <OS.h> 14 15#include <directories.h> 16#include <find_directory_private.h> 17#include <runtime_loader.h> 18 19 20static const char* const kArchitecture = B_HAIKU_ABI_NAME; 21static const char* const kPrimaryArchitecture = __HAIKU_PRIMARY_PACKAGING_ARCH; 22 23#ifdef __HAIKU_ARCH_X86 24 static const char* const kSiblingArchitectures[] = {"x86_gcc2", "x86"}; 25#else 26 static const char* const kSiblingArchitectures[] = {}; 27#endif 28 29static const size_t kSiblingArchitectureCount 30 = sizeof(kSiblingArchitectures) / sizeof(const char*); 31 32 33static bool 34has_secondary_architecture(const char* architecture) 35{ 36 if (strcmp(architecture, kPrimaryArchitecture) == 0) 37 return false; 38 39 char path[B_PATH_NAME_LENGTH]; 40 snprintf(path, sizeof(path), kSystemLibDirectory "/%s/libroot.so", 41 architecture); 42 43 struct stat st; 44 return lstat(path, &st) == 0; 45} 46 47 48// #pragma mark - 49 50 51const char* 52__get_architecture() 53{ 54 return kArchitecture; 55} 56 57 58const char* 59__get_primary_architecture() 60{ 61 return kPrimaryArchitecture; 62} 63 64 65size_t 66__get_secondary_architectures(const char** architectures, size_t count) 67{ 68 size_t index = 0; 69 70 // If this is an architecture that could be a primary or secondary 71 // architecture, check for which architectures a libroot.so is present. 72 if (kSiblingArchitectureCount > 0) { 73 for (size_t i = 0; i < kSiblingArchitectureCount; i++) { 74 const char* architecture = kSiblingArchitectures[i]; 75 if (!has_secondary_architecture(architecture)) 76 continue; 77 78 if (index < count) 79 architectures[index] = architecture; 80 index++; 81 } 82 } 83 84 return index; 85} 86 87 88size_t 89__get_architectures(const char** architectures, size_t count) 90{ 91 if (count == 0) 92 return __get_secondary_architectures(NULL, 0) + 1; 93 94 architectures[0] = __get_primary_architecture(); 95 return __get_secondary_architectures(architectures + 1, count -1) + 1; 96} 97 98 99const char* 100__guess_architecture_for_path(const char* path) 101{ 102 if (kSiblingArchitectureCount == 0) 103 return kPrimaryArchitecture; 104 105 // ask the runtime loader 106 const char* architecture; 107 if (__gRuntimeLoader->get_executable_architecture(path, &architecture) 108 == B_OK) { 109 // verify that it is one of the sibling architectures 110 for (size_t i = 0; i < kSiblingArchitectureCount; i++) { 111 if (strcmp(architecture, kSiblingArchitectures[i]) == 0) 112 return kSiblingArchitectures[i]; 113 } 114 } 115 116 // guess from the given path 117 architecture = __guess_secondary_architecture_from_path(path, 118 kSiblingArchitectures, kSiblingArchitectureCount); 119 120 return architecture != NULL && has_secondary_architecture(architecture) 121 ? architecture : kPrimaryArchitecture; 122} 123 124 125B_DEFINE_WEAK_ALIAS(__get_architecture, get_architecture); 126B_DEFINE_WEAK_ALIAS(__get_primary_architecture, get_primary_architecture); 127B_DEFINE_WEAK_ALIAS(__get_secondary_architectures, get_secondary_architectures); 128B_DEFINE_WEAK_ALIAS(__get_architectures, get_architectures); 129B_DEFINE_WEAK_ALIAS(__guess_architecture_for_path, guess_architecture_for_path); 130