common.c 4.5 KB

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