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 20 static const char* const kArchitecture = B_HAIKU_ABI_NAME; 21 static 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 29 static const size_t kSiblingArchitectureCount 30 = sizeof(kSiblingArchitectures) / sizeof(const char*); 31 32 33 static bool 34 has_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 51 const char* 52 __get_architecture() 53 { 54 return kArchitecture; 55 } 56 57 58 const char* 59 __get_primary_architecture() 60 { 61 return kPrimaryArchitecture; 62 } 63 64 65 size_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 88 size_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 99 const 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 125 B_DEFINE_WEAK_ALIAS(__get_architecture, get_architecture); 126 B_DEFINE_WEAK_ALIAS(__get_primary_architecture, get_primary_architecture); 127 B_DEFINE_WEAK_ALIAS(__get_secondary_architectures, get_secondary_architectures); 128 B_DEFINE_WEAK_ALIAS(__get_architectures, get_architectures); 129 B_DEFINE_WEAK_ALIAS(__guess_architecture_for_path, guess_architecture_for_path); 130