common.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <stdio.h>
  3. #include "common.h"
  4. #include "../util/env.h"
  5. #include "../util/util.h"
  6. #include "../util/debug.h"
  7. const char *const arm_triplets[] = {
  8. "arm-eabi-",
  9. "arm-linux-androideabi-",
  10. "arm-unknown-linux-",
  11. "arm-unknown-linux-gnu-",
  12. "arm-unknown-linux-gnueabi-",
  13. "arm-linux-gnu-",
  14. "arm-linux-gnueabihf-",
  15. "arm-none-eabi-",
  16. NULL
  17. };
  18. const char *const arm64_triplets[] = {
  19. "aarch64-linux-android-",
  20. "aarch64-linux-gnu-",
  21. NULL
  22. };
  23. const char *const powerpc_triplets[] = {
  24. "powerpc-unknown-linux-gnu-",
  25. "powerpc-linux-gnu-",
  26. "powerpc64-unknown-linux-gnu-",
  27. "powerpc64-linux-gnu-",
  28. "powerpc64le-linux-gnu-",
  29. NULL
  30. };
  31. const char *const s390_triplets[] = {
  32. "s390-ibm-linux-",
  33. "s390x-linux-gnu-",
  34. NULL
  35. };
  36. const char *const sh_triplets[] = {
  37. "sh-unknown-linux-gnu-",
  38. "sh64-unknown-linux-gnu-",
  39. "sh-linux-gnu-",
  40. "sh64-linux-gnu-",
  41. NULL
  42. };
  43. const char *const sparc_triplets[] = {
  44. "sparc-unknown-linux-gnu-",
  45. "sparc64-unknown-linux-gnu-",
  46. "sparc64-linux-gnu-",
  47. NULL
  48. };
  49. const char *const x86_triplets[] = {
  50. "x86_64-pc-linux-gnu-",
  51. "x86_64-unknown-linux-gnu-",
  52. "i686-pc-linux-gnu-",
  53. "i586-pc-linux-gnu-",
  54. "i486-pc-linux-gnu-",
  55. "i386-pc-linux-gnu-",
  56. "i686-linux-android-",
  57. "i686-android-linux-",
  58. "x86_64-linux-gnu-",
  59. "i586-linux-gnu-",
  60. NULL
  61. };
  62. const char *const mips_triplets[] = {
  63. "mips-unknown-linux-gnu-",
  64. "mipsel-linux-android-",
  65. "mips-linux-gnu-",
  66. "mips64-linux-gnu-",
  67. "mips64el-linux-gnuabi64-",
  68. "mips64-linux-gnuabi64-",
  69. "mipsel-linux-gnu-",
  70. NULL
  71. };
  72. static bool lookup_path(char *name)
  73. {
  74. bool found = false;
  75. char *path, *tmp = NULL;
  76. char buf[PATH_MAX];
  77. char *env = getenv("PATH");
  78. if (!env)
  79. return false;
  80. env = strdup(env);
  81. if (!env)
  82. return false;
  83. path = strtok_r(env, ":", &tmp);
  84. while (path) {
  85. scnprintf(buf, sizeof(buf), "%s/%s", path, name);
  86. if (access(buf, F_OK) == 0) {
  87. found = true;
  88. break;
  89. }
  90. path = strtok_r(NULL, ":", &tmp);
  91. }
  92. free(env);
  93. return found;
  94. }
  95. static int lookup_triplets(const char *const *triplets, const char *name)
  96. {
  97. int i;
  98. char buf[PATH_MAX];
  99. for (i = 0; triplets[i] != NULL; i++) {
  100. scnprintf(buf, sizeof(buf), "%s%s", triplets[i], name);
  101. if (lookup_path(buf))
  102. return i;
  103. }
  104. return -1;
  105. }
  106. static int perf_env__lookup_binutils_path(struct perf_env *env,
  107. const char *name, const char **path)
  108. {
  109. int idx;
  110. const char *arch = perf_env__arch(env), *cross_env;
  111. const char *const *path_list;
  112. char *buf = NULL;
  113. /*
  114. * We don't need to try to find objdump path for native system.
  115. * Just use default binutils path (e.g.: "objdump").
  116. */
  117. if (!strcmp(perf_env__arch(NULL), arch))
  118. goto out;
  119. cross_env = getenv("CROSS_COMPILE");
  120. if (cross_env) {
  121. if (asprintf(&buf, "%s%s", cross_env, name) < 0)
  122. goto out_error;
  123. if (buf[0] == '/') {
  124. if (access(buf, F_OK) == 0)
  125. goto out;
  126. goto out_error;
  127. }
  128. if (lookup_path(buf))
  129. goto out;
  130. zfree(&buf);
  131. }
  132. if (!strcmp(arch, "arm"))
  133. path_list = arm_triplets;
  134. else if (!strcmp(arch, "arm64"))
  135. path_list = arm64_triplets;
  136. else if (!strcmp(arch, "powerpc"))
  137. path_list = powerpc_triplets;
  138. else if (!strcmp(arch, "sh"))
  139. path_list = sh_triplets;
  140. else if (!strcmp(arch, "s390"))
  141. path_list = s390_triplets;
  142. else if (!strcmp(arch, "sparc"))
  143. path_list = sparc_triplets;
  144. else if (!strcmp(arch, "x86"))
  145. path_list = x86_triplets;
  146. else if (!strcmp(arch, "mips"))
  147. path_list = mips_triplets;
  148. else {
  149. ui__error("binutils for %s not supported.\n", arch);
  150. goto out_error;
  151. }
  152. idx = lookup_triplets(path_list, name);
  153. if (idx < 0) {
  154. ui__error("Please install %s for %s.\n"
  155. "You can add it to PATH, set CROSS_COMPILE or "
  156. "override the default using --%s.\n",
  157. name, arch, name);
  158. goto out_error;
  159. }
  160. if (asprintf(&buf, "%s%s", path_list[idx], name) < 0)
  161. goto out_error;
  162. out:
  163. *path = buf;
  164. return 0;
  165. out_error:
  166. free(buf);
  167. *path = NULL;
  168. return -1;
  169. }
  170. int perf_env__lookup_objdump(struct perf_env *env, const char **path)
  171. {
  172. /*
  173. * For live mode, env->arch will be NULL and we can use
  174. * the native objdump tool.
  175. */
  176. if (env->arch == NULL)
  177. return 0;
  178. return perf_env__lookup_binutils_path(env, "objdump", path);
  179. }
  180. /*
  181. * Some architectures have a single address space for kernel and user addresses,
  182. * which makes it possible to determine if an address is in kernel space or user
  183. * space.
  184. */
  185. bool perf_env__single_address_space(struct perf_env *env)
  186. {
  187. return strcmp(perf_env__arch(env), "sparc");
  188. }