tst-abi-interlink.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /* Copyright (C) 2014-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <sys/prctl.h>
  15. #include <dlfcn.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdbool.h>
  19. #include <errno.h>
  20. #if defined PR_GET_FP_MODE && defined PR_SET_FP_MODE
  21. # define HAVE_PRCTL_FP_MODE 1
  22. # define FR1_MODE (PR_FP_MODE_FR)
  23. # define FRE_MODE (PR_FP_MODE_FR | PR_FP_MODE_FRE)
  24. #else
  25. # define HAVE_PRCTL_FP_MODE 0
  26. # define FR1_MODE 0x1
  27. # define FRE_MODE 0x2
  28. #endif
  29. #define STR_VAL(VAL) #VAL
  30. #define N_STR(VAL) STR_VAL(VAL)
  31. #define START_STATE(NAME) \
  32. case s_ ## NAME: \
  33. { \
  34. switch (obj) \
  35. {
  36. #define END_STATE \
  37. default: \
  38. return false; \
  39. } \
  40. break; \
  41. }
  42. #define NEXT(OBJ, NEXT_STATE) \
  43. case o_ ## OBJ: \
  44. current_fp_state = s_ ## NEXT_STATE; \
  45. break;
  46. #define NEXT_REQ_FR1(OBJ, NEXT_STATE) \
  47. case o_ ## OBJ: \
  48. { \
  49. if (has_fr1) \
  50. current_fp_state = s_ ## NEXT_STATE; \
  51. else \
  52. return false; \
  53. } \
  54. break;
  55. #define NEXT_REQ_FR0(OBJ, NEXT_STATE) \
  56. case o_ ## OBJ: \
  57. { \
  58. if (!is_r6 \
  59. || (is_r6 && has_fr1 && has_fre)) \
  60. current_fp_state = s_ ## NEXT_STATE; \
  61. else \
  62. return false; \
  63. } \
  64. break;
  65. #define NEXT_REQ_FRE(OBJ, NEXT_STATE) \
  66. case o_ ## OBJ: \
  67. { \
  68. if (has_fr1 && has_fre) \
  69. current_fp_state = s_ ## NEXT_STATE; \
  70. else \
  71. return false; \
  72. } \
  73. break;
  74. #define NEXT_NO_MODE_CHANGE(OBJ, NEXT_STATE) \
  75. case o_ ## OBJ: \
  76. { \
  77. if (current_mode_valid_p (s_ ## NEXT_STATE)) \
  78. { \
  79. current_fp_state = s_ ## NEXT_STATE; \
  80. cant_change_mode = true; \
  81. } \
  82. else \
  83. return false; \
  84. } \
  85. break;
  86. static const char * const shared_lib_names[] =
  87. {
  88. "tst-abi-fpanymod.so", "tst-abi-fpsoftmod.so", "tst-abi-fpsinglemod.so",
  89. "tst-abi-fp32mod.so", "tst-abi-fp64mod.so", "tst-abi-fp64amod.so",
  90. "tst-abi-fpxxmod.so", "tst-abi-fpxxomod.so"
  91. };
  92. struct fp_mode_req
  93. {
  94. int mode1;
  95. int mode2;
  96. int mode3;
  97. };
  98. enum fp_obj
  99. {
  100. o_any,
  101. o_soft,
  102. o_single,
  103. o_fp32,
  104. o_fp64,
  105. o_fp64a,
  106. o_fpxx,
  107. o_fpxxo,
  108. o_max
  109. };
  110. enum fp_state
  111. {
  112. s_any,
  113. s_soft,
  114. s_single,
  115. s_fp32,
  116. s_fpxx,
  117. s_fpxxo,
  118. s_fp64a,
  119. s_fp64,
  120. s_fpxxo_fpxx,
  121. s_fp32_fpxx,
  122. s_fp32_fpxxo,
  123. s_fp32_fpxxo_fpxx,
  124. s_fp32_fp64a_fpxx,
  125. s_fp32_fp64a_fpxxo,
  126. s_fp32_fp64a_fpxxo_fpxx,
  127. s_fp64a_fp32,
  128. s_fp64a_fpxx,
  129. s_fp64a_fpxxo,
  130. s_fp64a_fp64,
  131. s_fp64a_fp64_fpxx,
  132. s_fp64a_fp64_fpxxo,
  133. s_fp64a_fpxx_fpxxo,
  134. s_fp64a_fp64_fpxxo_fpxx,
  135. s_fp64_fpxx,
  136. s_fp64_fpxxo,
  137. s_fp64_fpxx_fpxxo
  138. };
  139. static int current_fp_mode;
  140. static bool cant_change_mode = false;
  141. static bool has_fr1 = false;
  142. static bool has_fre = false;
  143. static bool is_r6 = false;
  144. static unsigned int fp_obj_count[o_max];
  145. void * shared_lib_ptrs[o_max];
  146. static enum fp_state current_fp_state = s_any;
  147. static enum fp_obj test_objects[FPABI_COUNT] = { FPABI_LIST };
  148. /* This function will return the valid FP modes for the specified state. */
  149. static struct fp_mode_req
  150. compute_fp_modes (enum fp_state state)
  151. {
  152. struct fp_mode_req requirements;
  153. requirements.mode1 = -1;
  154. requirements.mode2 = -1;
  155. requirements.mode3 = -1;
  156. switch (state)
  157. {
  158. case s_single:
  159. {
  160. if (is_r6)
  161. requirements.mode1 = FR1_MODE;
  162. else
  163. {
  164. requirements.mode1 = 0;
  165. requirements.mode2 = FR1_MODE;
  166. }
  167. break;
  168. }
  169. case s_fp32:
  170. case s_fp32_fpxx:
  171. case s_fp32_fpxxo:
  172. case s_fp32_fpxxo_fpxx:
  173. {
  174. if (is_r6)
  175. requirements.mode1 = FRE_MODE;
  176. else
  177. {
  178. requirements.mode1 = 0;
  179. requirements.mode2 = FRE_MODE;
  180. }
  181. break;
  182. }
  183. case s_fpxx:
  184. case s_fpxxo:
  185. case s_fpxxo_fpxx:
  186. case s_any:
  187. case s_soft:
  188. {
  189. if (is_r6)
  190. {
  191. requirements.mode1 = FR1_MODE;
  192. requirements.mode2 = FRE_MODE;
  193. }
  194. else
  195. {
  196. requirements.mode1 = 0;
  197. requirements.mode2 = FR1_MODE;
  198. requirements.mode3 = FRE_MODE;
  199. }
  200. break;
  201. }
  202. case s_fp64a:
  203. case s_fp64a_fpxx:
  204. case s_fp64a_fpxxo:
  205. case s_fp64a_fpxx_fpxxo:
  206. {
  207. requirements.mode1 = FR1_MODE;
  208. requirements.mode2 = FRE_MODE;
  209. break;
  210. }
  211. case s_fp64:
  212. case s_fp64_fpxx:
  213. case s_fp64_fpxxo:
  214. case s_fp64_fpxx_fpxxo:
  215. case s_fp64a_fp64:
  216. case s_fp64a_fp64_fpxx:
  217. case s_fp64a_fp64_fpxxo:
  218. case s_fp64a_fp64_fpxxo_fpxx:
  219. {
  220. requirements.mode1 = FR1_MODE;
  221. break;
  222. }
  223. case s_fp64a_fp32:
  224. case s_fp32_fp64a_fpxx:
  225. case s_fp32_fp64a_fpxxo:
  226. case s_fp32_fp64a_fpxxo_fpxx:
  227. {
  228. requirements.mode1 = FRE_MODE;
  229. break;
  230. }
  231. }
  232. return requirements;
  233. }
  234. /* Check the current mode is suitable for the specified state. */
  235. static bool
  236. current_mode_valid_p (enum fp_state s)
  237. {
  238. struct fp_mode_req req = compute_fp_modes (s);
  239. return (req.mode1 == current_fp_mode
  240. || req.mode2 == current_fp_mode
  241. || req.mode3 == current_fp_mode);
  242. }
  243. /* Run the state machine by adding a new object. */
  244. static bool
  245. set_next_fp_state (enum fp_obj obj)
  246. {
  247. cant_change_mode = false;
  248. switch (current_fp_state)
  249. {
  250. START_STATE(soft)
  251. NEXT(soft,soft)
  252. NEXT(any,soft)
  253. END_STATE
  254. START_STATE(single)
  255. NEXT(single,single)
  256. NEXT(any,single)
  257. END_STATE
  258. START_STATE(any)
  259. NEXT_REQ_FR0(fp32, fp32)
  260. NEXT(fpxx, fpxx)
  261. NEXT(fpxxo, fpxxo)
  262. NEXT_REQ_FR1(fp64a, fp64a)
  263. NEXT_REQ_FR1(fp64, fp64)
  264. NEXT(any,any)
  265. NEXT(soft,soft)
  266. NEXT(single,single)
  267. END_STATE
  268. START_STATE(fp32)
  269. NEXT_REQ_FR0(fp32,fp32)
  270. NEXT(fpxx, fp32_fpxx)
  271. NEXT(fpxxo, fp32_fpxxo)
  272. NEXT_REQ_FRE(fp64a, fp64a_fp32)
  273. NEXT(any,fp32)
  274. END_STATE
  275. START_STATE(fpxx)
  276. NEXT_REQ_FR0(fp32, fp32_fpxx)
  277. NEXT_REQ_FR1(fp64, fp64_fpxx)
  278. NEXT_REQ_FR1(fp64a, fp64a_fpxx)
  279. NEXT(fpxxo, fpxxo_fpxx)
  280. NEXT(fpxx,fpxx)
  281. NEXT(any,fpxx)
  282. END_STATE
  283. START_STATE(fpxxo)
  284. NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo)
  285. NEXT_NO_MODE_CHANGE(fp64, fp64_fpxxo)
  286. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxxo)
  287. NEXT_NO_MODE_CHANGE(fpxx, fpxxo_fpxx)
  288. NEXT_NO_MODE_CHANGE(fpxxo,fpxxo)
  289. NEXT_NO_MODE_CHANGE(any,fpxxo)
  290. END_STATE
  291. START_STATE(fp64a)
  292. NEXT_REQ_FRE(fp32, fp64a_fp32)
  293. NEXT_REQ_FR1(fp64, fp64a_fp64)
  294. NEXT(fpxxo, fp64a_fpxxo)
  295. NEXT(fpxx, fp64a_fpxx)
  296. NEXT_REQ_FR1(fp64a, fp64a)
  297. NEXT(any, fp64a)
  298. END_STATE
  299. START_STATE(fp64)
  300. NEXT_REQ_FR1(fp64a, fp64a_fp64)
  301. NEXT(fpxxo, fp64_fpxxo)
  302. NEXT(fpxx, fp64_fpxx)
  303. NEXT_REQ_FR1(fp64, fp64)
  304. NEXT(any, fp64)
  305. END_STATE
  306. START_STATE(fpxxo_fpxx)
  307. NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo_fpxx)
  308. NEXT_NO_MODE_CHANGE(fp64, fp64_fpxx_fpxxo)
  309. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxx_fpxxo)
  310. NEXT_NO_MODE_CHANGE(fpxx, fpxxo_fpxx)
  311. NEXT_NO_MODE_CHANGE(fpxxo, fpxxo_fpxx)
  312. NEXT_NO_MODE_CHANGE(any, fpxxo_fpxx)
  313. END_STATE
  314. START_STATE(fp32_fpxx)
  315. NEXT_REQ_FR0(fp32, fp32_fpxx)
  316. NEXT(fpxx, fp32_fpxx)
  317. NEXT(fpxxo, fp32_fpxxo_fpxx)
  318. NEXT_REQ_FRE(fp64a, fp32_fp64a_fpxx)
  319. NEXT(any, fp32_fpxx)
  320. END_STATE
  321. START_STATE(fp32_fpxxo)
  322. NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo)
  323. NEXT_NO_MODE_CHANGE(fpxxo, fp32_fpxxo)
  324. NEXT_NO_MODE_CHANGE(fpxx, fp32_fpxxo_fpxx)
  325. NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo)
  326. NEXT_NO_MODE_CHANGE(any, fp32_fpxxo)
  327. END_STATE
  328. START_STATE(fp32_fpxxo_fpxx)
  329. NEXT_NO_MODE_CHANGE(fp32, fp32_fpxxo_fpxx)
  330. NEXT_NO_MODE_CHANGE(fpxxo, fp32_fpxxo_fpxx)
  331. NEXT_NO_MODE_CHANGE(fpxx, fp32_fpxxo_fpxx)
  332. NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo_fpxx)
  333. NEXT_NO_MODE_CHANGE(any, fp32_fpxxo_fpxx)
  334. END_STATE
  335. START_STATE(fp64a_fp32)
  336. NEXT_REQ_FRE(fp32, fp64a_fp32)
  337. NEXT_REQ_FRE(fp64a, fp64a_fp32)
  338. NEXT(fpxxo, fp32_fp64a_fpxxo)
  339. NEXT(fpxx, fp32_fp64a_fpxx)
  340. NEXT(any, fp64a_fp32)
  341. END_STATE
  342. START_STATE(fp64a_fpxx)
  343. NEXT_REQ_FRE(fp32, fp32_fp64a_fpxx)
  344. NEXT_REQ_FR1(fp64a, fp64a_fpxx)
  345. NEXT(fpxx, fp64a_fpxx)
  346. NEXT(fpxxo, fp64a_fpxx_fpxxo)
  347. NEXT_REQ_FR1(fp64, fp64a_fp64_fpxx)
  348. NEXT(any, fp64a_fpxx)
  349. END_STATE
  350. START_STATE(fp64a_fpxxo)
  351. NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo)
  352. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxxo)
  353. NEXT_NO_MODE_CHANGE(fpxx, fp64a_fpxx_fpxxo)
  354. NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fpxxo)
  355. NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo)
  356. NEXT_NO_MODE_CHANGE(any, fp64a_fpxxo)
  357. END_STATE
  358. START_STATE(fp64a_fpxx_fpxxo)
  359. NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo_fpxx)
  360. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fpxx_fpxxo)
  361. NEXT_NO_MODE_CHANGE(fpxx, fp64a_fpxx_fpxxo)
  362. NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fpxx_fpxxo)
  363. NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo_fpxx)
  364. NEXT_NO_MODE_CHANGE(any, fp64a_fpxx_fpxxo)
  365. END_STATE
  366. START_STATE(fp64_fpxx)
  367. NEXT_REQ_FR1(fp64a, fp64a_fp64_fpxx)
  368. NEXT(fpxxo, fp64_fpxx_fpxxo)
  369. NEXT(fpxx, fp64_fpxx)
  370. NEXT_REQ_FR1(fp64, fp64_fpxx)
  371. NEXT(any, fp64_fpxx)
  372. END_STATE
  373. START_STATE(fp64_fpxxo)
  374. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo)
  375. NEXT_NO_MODE_CHANGE(fpxxo, fp64_fpxxo)
  376. NEXT_NO_MODE_CHANGE(fpxx, fp64_fpxx_fpxxo)
  377. NEXT_NO_MODE_CHANGE(fp64, fp64_fpxxo)
  378. NEXT_NO_MODE_CHANGE(any, fp64_fpxxo)
  379. END_STATE
  380. START_STATE(fp64_fpxx_fpxxo)
  381. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo_fpxx)
  382. NEXT_NO_MODE_CHANGE(fpxxo, fp64_fpxx_fpxxo)
  383. NEXT_NO_MODE_CHANGE(fpxx, fp64_fpxx_fpxxo)
  384. NEXT_NO_MODE_CHANGE(fp64, fp64_fpxx_fpxxo)
  385. NEXT_NO_MODE_CHANGE(any, fp64_fpxx_fpxxo)
  386. END_STATE
  387. START_STATE(fp64a_fp64)
  388. NEXT_REQ_FR1(fp64a, fp64a_fp64)
  389. NEXT(fpxxo, fp64a_fp64_fpxxo)
  390. NEXT(fpxx, fp64a_fp64_fpxx)
  391. NEXT_REQ_FR1(fp64, fp64a_fp64)
  392. NEXT(any, fp64a_fp64)
  393. END_STATE
  394. START_STATE(fp64a_fp64_fpxx)
  395. NEXT_REQ_FR1(fp64a, fp64a_fp64_fpxx)
  396. NEXT(fpxxo, fp64a_fp64_fpxxo_fpxx)
  397. NEXT(fpxx, fp64a_fp64_fpxx)
  398. NEXT_REQ_FR1(fp64, fp64a_fp64_fpxx)
  399. NEXT(any, fp64a_fp64_fpxx)
  400. END_STATE
  401. START_STATE(fp64a_fp64_fpxxo)
  402. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo)
  403. NEXT_NO_MODE_CHANGE(fpxx, fp64a_fp64_fpxxo_fpxx)
  404. NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fp64_fpxxo)
  405. NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo)
  406. NEXT_NO_MODE_CHANGE(any, fp64a_fp64_fpxxo)
  407. END_STATE
  408. START_STATE(fp64a_fp64_fpxxo_fpxx)
  409. NEXT_NO_MODE_CHANGE(fp64a, fp64a_fp64_fpxxo_fpxx)
  410. NEXT_NO_MODE_CHANGE(fpxx, fp64a_fp64_fpxxo_fpxx)
  411. NEXT_NO_MODE_CHANGE(fpxxo, fp64a_fp64_fpxxo_fpxx)
  412. NEXT_NO_MODE_CHANGE(fp64, fp64a_fp64_fpxxo_fpxx)
  413. NEXT_NO_MODE_CHANGE(any, fp64a_fp64_fpxxo_fpxx)
  414. END_STATE
  415. START_STATE(fp32_fp64a_fpxx)
  416. NEXT_REQ_FRE(fp32, fp32_fp64a_fpxx)
  417. NEXT_REQ_FRE(fp64a, fp32_fp64a_fpxx)
  418. NEXT(fpxxo, fp32_fp64a_fpxxo_fpxx)
  419. NEXT(fpxx, fp32_fp64a_fpxx)
  420. NEXT(any, fp32_fp64a_fpxx)
  421. END_STATE
  422. START_STATE(fp32_fp64a_fpxxo)
  423. NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo)
  424. NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo)
  425. NEXT_NO_MODE_CHANGE(fpxx, fp32_fp64a_fpxxo_fpxx)
  426. NEXT_NO_MODE_CHANGE(fpxxo, fp32_fp64a_fpxxo)
  427. NEXT_NO_MODE_CHANGE(any, fp32_fp64a_fpxxo)
  428. END_STATE
  429. START_STATE(fp32_fp64a_fpxxo_fpxx)
  430. NEXT_NO_MODE_CHANGE(fp32, fp32_fp64a_fpxxo_fpxx)
  431. NEXT_NO_MODE_CHANGE(fp64a, fp32_fp64a_fpxxo_fpxx)
  432. NEXT_NO_MODE_CHANGE(fpxx, fp32_fp64a_fpxxo_fpxx)
  433. NEXT_NO_MODE_CHANGE(fpxxo, fp32_fp64a_fpxxo_fpxx)
  434. NEXT_NO_MODE_CHANGE(any, fp32_fp64a_fpxxo_fpxx)
  435. END_STATE
  436. }
  437. if (obj != o_max)
  438. fp_obj_count[obj]++;
  439. return true;
  440. }
  441. /* Run the state machine by removing an object. */
  442. static bool
  443. remove_object (enum fp_obj obj)
  444. {
  445. if (obj == o_max)
  446. return false;
  447. fp_obj_count[obj]--;
  448. /* We can't change fp state until all the objects
  449. of a particular type have been unloaded. */
  450. if (fp_obj_count[obj] != 0)
  451. return false;
  452. switch (current_fp_state)
  453. {
  454. START_STATE(soft)
  455. NEXT(soft,any)
  456. END_STATE
  457. START_STATE(single)
  458. NEXT(single,any)
  459. END_STATE
  460. START_STATE(any)
  461. NEXT(any,any)
  462. END_STATE
  463. START_STATE(fp32)
  464. NEXT (fp32,any)
  465. END_STATE
  466. START_STATE(fpxx)
  467. NEXT (fpxx,any)
  468. END_STATE
  469. START_STATE(fpxxo)
  470. NEXT (fpxxo,any)
  471. END_STATE
  472. START_STATE(fp64a)
  473. NEXT(fp64a, any)
  474. END_STATE
  475. START_STATE(fp64)
  476. NEXT(fp64, any)
  477. END_STATE
  478. START_STATE(fpxxo_fpxx)
  479. NEXT(fpxx, fpxxo)
  480. NEXT(fpxxo, fpxx)
  481. END_STATE
  482. START_STATE(fp32_fpxx)
  483. NEXT(fp32, fpxx)
  484. NEXT(fpxx, fp32)
  485. END_STATE
  486. START_STATE(fp32_fpxxo)
  487. NEXT(fp32, fpxxo)
  488. NEXT(fpxxo, fp32)
  489. END_STATE
  490. START_STATE(fp32_fpxxo_fpxx)
  491. NEXT(fp32, fpxxo_fpxx)
  492. NEXT(fpxxo, fp32_fpxx)
  493. NEXT(fpxx, fp32_fpxxo)
  494. END_STATE
  495. START_STATE(fp64a_fp32)
  496. NEXT(fp32, fp64a)
  497. NEXT(fp64a, fp32)
  498. END_STATE
  499. START_STATE(fp64a_fpxx)
  500. NEXT(fp64a, fpxx)
  501. NEXT(fpxx, fp64a)
  502. END_STATE
  503. START_STATE(fp64a_fpxxo)
  504. NEXT(fp64a, fpxxo)
  505. NEXT(fpxxo, fp64a)
  506. END_STATE
  507. START_STATE(fp64a_fpxx_fpxxo)
  508. NEXT(fp64a, fpxxo_fpxx)
  509. NEXT(fpxx, fp64a_fpxxo)
  510. NEXT(fpxxo, fp64a_fpxx)
  511. END_STATE
  512. START_STATE(fp64_fpxx)
  513. NEXT(fpxx, fp64)
  514. NEXT(fp64, fpxx)
  515. END_STATE
  516. START_STATE(fp64_fpxxo)
  517. NEXT(fpxxo, fp64)
  518. NEXT(fp64, fpxxo)
  519. END_STATE
  520. START_STATE(fp64_fpxx_fpxxo)
  521. NEXT(fp64, fpxxo_fpxx)
  522. NEXT(fpxxo, fp64_fpxx)
  523. NEXT(fpxx, fp64_fpxxo)
  524. END_STATE
  525. START_STATE(fp64a_fp64)
  526. NEXT(fp64a, fp64)
  527. NEXT(fp64, fp64a)
  528. END_STATE
  529. START_STATE(fp64a_fp64_fpxx)
  530. NEXT(fp64a, fp64_fpxx)
  531. NEXT(fpxx, fp64a_fp64)
  532. NEXT(fp64, fp64a_fpxx)
  533. END_STATE
  534. START_STATE(fp64a_fp64_fpxxo)
  535. NEXT(fp64a, fp64_fpxxo)
  536. NEXT(fpxxo, fp64a_fp64)
  537. NEXT(fp64, fp64a_fpxxo)
  538. END_STATE
  539. START_STATE(fp64a_fp64_fpxxo_fpxx)
  540. NEXT(fp64a, fp64_fpxx_fpxxo)
  541. NEXT(fpxx, fp64a_fp64_fpxxo)
  542. NEXT(fpxxo, fp64a_fp64_fpxx)
  543. NEXT(fp64, fp64a_fpxx_fpxxo)
  544. END_STATE
  545. START_STATE(fp32_fp64a_fpxx)
  546. NEXT(fp32, fp64a_fpxx)
  547. NEXT(fp64a, fp32_fpxx)
  548. NEXT(fpxx, fp64a_fp32)
  549. END_STATE
  550. START_STATE(fp32_fp64a_fpxxo)
  551. NEXT(fp32, fp64a_fpxxo)
  552. NEXT(fp64a, fp32_fpxxo)
  553. NEXT(fpxxo, fp64a_fp32)
  554. END_STATE
  555. START_STATE(fp32_fp64a_fpxxo_fpxx)
  556. NEXT(fp32, fp64a_fpxx_fpxxo)
  557. NEXT(fp64a, fp32_fpxxo_fpxx)
  558. NEXT(fpxx, fp32_fp64a_fpxxo)
  559. NEXT(fpxxo, fp32_fp64a_fpxx)
  560. END_STATE
  561. }
  562. return true;
  563. }
  564. static int
  565. mode_transition_valid_p (void)
  566. {
  567. int prev_fp_mode;
  568. /* Get the current fp mode. */
  569. prev_fp_mode = current_fp_mode;
  570. #if HAVE_PRCTL_FP_MODE
  571. current_fp_mode = prctl (PR_GET_FP_MODE);
  572. /* If the prctl call fails assume the core only has FR0 mode support. */
  573. if (current_fp_mode == -1)
  574. current_fp_mode = 0;
  575. #endif
  576. if (!current_mode_valid_p (current_fp_state))
  577. return 0;
  578. /* Check if mode changes are not allowed but a mode change happened. */
  579. if (cant_change_mode
  580. && current_fp_mode != prev_fp_mode)
  581. return 0;
  582. return 1;
  583. }
  584. /* Load OBJ and check that it was/was not loaded correctly. */
  585. bool
  586. load_object (enum fp_obj obj)
  587. {
  588. bool should_load = set_next_fp_state (obj);
  589. shared_lib_ptrs[obj] = dlopen (shared_lib_names[obj], RTLD_LAZY);
  590. /* If we expected an error and the load was successful then fail. */
  591. if (!should_load && (shared_lib_ptrs[obj] != 0))
  592. return false;
  593. if (should_load && (shared_lib_ptrs[obj] == 0))
  594. return false;
  595. if (!mode_transition_valid_p ())
  596. return false;
  597. return true;
  598. }
  599. /* Remove an object and check the state remains valid. */
  600. bool
  601. unload_object (enum fp_obj obj)
  602. {
  603. if (!shared_lib_ptrs[obj])
  604. return true;
  605. remove_object (obj);
  606. if (dlclose (shared_lib_ptrs[obj]) != 0)
  607. return false;
  608. shared_lib_ptrs[obj] = 0;
  609. if (!mode_transition_valid_p ())
  610. return false;
  611. return true;
  612. }
  613. /* Load every permuation of OBJECTS. */
  614. static bool
  615. test_permutations (enum fp_obj objects[], int count)
  616. {
  617. int i;
  618. for (i = 0 ; i < count ; i++)
  619. {
  620. if (!load_object (objects[i]))
  621. return false;
  622. if (count > 1)
  623. {
  624. enum fp_obj new_objects[count - 1];
  625. int j;
  626. int k = 0;
  627. for (j = 0 ; j < count ; j++)
  628. {
  629. if (j != i)
  630. new_objects[k++] = objects[j];
  631. }
  632. if (!test_permutations (new_objects, count - 1))
  633. return false;
  634. }
  635. if (!unload_object (objects[i]))
  636. return false;
  637. }
  638. return true;
  639. }
  640. int
  641. do_test (void)
  642. {
  643. #if HAVE_PRCTL_FP_MODE
  644. /* Determine available hardware support and current mode. */
  645. current_fp_mode = prctl (PR_GET_FP_MODE);
  646. /* If the prctl call fails assume the core only has FR0 mode support. */
  647. if (current_fp_mode == -1)
  648. current_fp_mode = 0;
  649. else
  650. {
  651. if (prctl (PR_SET_FP_MODE, 0) != 0)
  652. {
  653. if (errno == ENOTSUP)
  654. is_r6 = true;
  655. else
  656. {
  657. printf ("unexpected error from PR_SET_FP_MODE, 0: %m\n");
  658. return 1;
  659. }
  660. }
  661. if (prctl (PR_SET_FP_MODE, PR_FP_MODE_FR) != 0)
  662. {
  663. if (errno != ENOTSUP)
  664. {
  665. printf ("unexpected error from PR_SET_FP_MODE, "
  666. "PR_FP_MODE_FR: %m\n");
  667. return 1;
  668. }
  669. }
  670. else
  671. has_fr1 = true;
  672. if (prctl (PR_SET_FP_MODE, PR_FP_MODE_FR | PR_FP_MODE_FRE) != 0)
  673. {
  674. if (errno != ENOTSUP)
  675. {
  676. printf ("unexpected error from PR_SET_FP_MODE, "
  677. "PR_FP_MODE_FR | PR_FP_MODE_FRE: %m\n");
  678. return 1;
  679. }
  680. }
  681. else
  682. has_fre = true;
  683. if (prctl (PR_SET_FP_MODE, current_fp_mode) != 0)
  684. {
  685. printf ("unable to restore initial FP mode: %m\n");
  686. return 1;
  687. }
  688. }
  689. if ((is_r6 && !(current_fp_mode & PR_FP_MODE_FR))
  690. || (!has_fr1 && (current_fp_mode & PR_FP_MODE_FR))
  691. || (!has_fre && (current_fp_mode & PR_FP_MODE_FRE)))
  692. {
  693. puts ("Inconsistency detected between initial FP mode "
  694. "and supported FP modes\n");
  695. return 1;
  696. }
  697. #else
  698. current_fp_mode = 0;
  699. #endif
  700. /* Set up the initial state from executable and LDSO. Assumptions:
  701. 1) All system libraries have the same ABI as ld.so.
  702. 2) Due to the fact that ld.so is tested by invoking it directly
  703. rather than via an interpreter, there is no point in varying
  704. the ABI of the test program. Instead the ABI only varies for
  705. the shared libraries which get loaded. */
  706. if (!set_next_fp_state (FPABI_NATIVE))
  707. {
  708. puts ("Unable to enter initial ABI state\n");
  709. return 1;
  710. }
  711. /* Compare the computed state with the hardware state. */
  712. if (!mode_transition_valid_p ())
  713. return 1;
  714. /* Run all possible test permutations. */
  715. if (!test_permutations (test_objects, FPABI_COUNT))
  716. {
  717. puts ("Mode checks failed\n");
  718. return 1;
  719. }
  720. return 0;
  721. }
  722. #define TEST_FUNCTION do_test ()
  723. #include "../../test-skeleton.c"