ppc-dis.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. /* ppc-dis.c -- Disassemble PowerPC instructions
  2. Copyright (C) 1994-2022 Free Software Foundation, Inc.
  3. Written by Ian Lance Taylor, Cygnus Support
  4. This file is part of the GNU opcodes library.
  5. This library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. It is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this file; see the file COPYING. If not, write to the
  15. Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. #include "sysdep.h"
  18. #include <stdio.h>
  19. #include "disassemble.h"
  20. #include "elf-bfd.h"
  21. #include "elf/ppc.h"
  22. #include "opintl.h"
  23. #include "opcode/ppc.h"
  24. #include "libiberty.h"
  25. /* This file provides several disassembler functions, all of which use
  26. the disassembler interface defined in dis-asm.h. Several functions
  27. are provided because this file handles disassembly for the PowerPC
  28. in both big and little endian mode and also for the POWER (RS/6000)
  29. chip. */
  30. static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int,
  31. ppc_cpu_t);
  32. struct dis_private
  33. {
  34. /* Stash the result of parsing disassembler_options here. */
  35. ppc_cpu_t dialect;
  36. /* .got and .plt sections. NAME is set to NULL if not present. */
  37. struct sec_buf {
  38. asection *sec;
  39. bfd_byte *buf;
  40. const char *name;
  41. } special[2];
  42. };
  43. static inline struct dis_private *
  44. private_data (struct disassemble_info *info)
  45. {
  46. return (struct dis_private *) info->private_data;
  47. }
  48. struct ppc_mopt {
  49. /* Option string, without -m or -M prefix. */
  50. const char *opt;
  51. /* CPU option flags. */
  52. ppc_cpu_t cpu;
  53. /* Flags that should stay on, even when combined with another cpu
  54. option. This should only be used for generic options like
  55. "-many" or "-maltivec" where it is reasonable to add some
  56. capability to another cpu selection. The added flags are sticky
  57. so that, for example, "-many -me500" and "-me500 -many" result in
  58. the same assembler or disassembler behaviour. Do not use
  59. "sticky" for specific cpus, as this will prevent that cpu's flags
  60. from overriding the defaults set in powerpc_init_dialect or a
  61. prior -m option. */
  62. ppc_cpu_t sticky;
  63. };
  64. struct ppc_mopt ppc_opts[] = {
  65. { "403", PPC_OPCODE_PPC | PPC_OPCODE_403,
  66. 0 },
  67. { "405", PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405,
  68. 0 },
  69. { "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
  70. | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
  71. 0 },
  72. { "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
  73. | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
  74. 0 },
  75. { "476", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_476
  76. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
  77. 0 },
  78. { "601", PPC_OPCODE_PPC | PPC_OPCODE_601,
  79. 0 },
  80. { "603", PPC_OPCODE_PPC,
  81. 0 },
  82. { "604", PPC_OPCODE_PPC,
  83. 0 },
  84. { "620", PPC_OPCODE_PPC | PPC_OPCODE_64,
  85. 0 },
  86. { "7400", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
  87. 0 },
  88. { "7410", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
  89. 0 },
  90. { "7450", PPC_OPCODE_PPC | PPC_OPCODE_7450 | PPC_OPCODE_ALTIVEC,
  91. 0 },
  92. { "7455", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
  93. 0 },
  94. { "750cl", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
  95. , 0 },
  96. { "gekko", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
  97. , 0 },
  98. { "broadway", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
  99. , 0 },
  100. { "821", PPC_OPCODE_PPC | PPC_OPCODE_860,
  101. 0 },
  102. { "850", PPC_OPCODE_PPC | PPC_OPCODE_860,
  103. 0 },
  104. { "860", PPC_OPCODE_PPC | PPC_OPCODE_860,
  105. 0 },
  106. { "a2", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
  107. | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
  108. | PPC_OPCODE_A2),
  109. 0 },
  110. { "altivec", PPC_OPCODE_PPC,
  111. PPC_OPCODE_ALTIVEC },
  112. { "any", PPC_OPCODE_PPC,
  113. PPC_OPCODE_ANY },
  114. { "booke", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
  115. 0 },
  116. { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
  117. 0 },
  118. { "cell", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  119. | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
  120. 0 },
  121. { "com", PPC_OPCODE_COMMON,
  122. 0 },
  123. { "e200z4", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
  124. | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
  125. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  126. | PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4
  127. | PPC_OPCODE_EFS2 | PPC_OPCODE_LSP),
  128. 0 },
  129. { "e300", PPC_OPCODE_PPC | PPC_OPCODE_E300,
  130. 0 },
  131. { "e500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
  132. | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
  133. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  134. | PPC_OPCODE_E500),
  135. 0 },
  136. { "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
  137. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  138. | PPC_OPCODE_E500MC),
  139. 0 },
  140. { "e500mc64", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
  141. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  142. | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
  143. | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
  144. 0 },
  145. { "e5500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
  146. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  147. | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  148. | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
  149. 0 },
  150. { "e6500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
  151. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  152. | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
  153. | PPC_OPCODE_E6500 | PPC_OPCODE_TMR | PPC_OPCODE_POWER4
  154. | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
  155. 0 },
  156. { "e500x2", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
  157. | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
  158. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  159. | PPC_OPCODE_E500),
  160. 0 },
  161. { "efs", PPC_OPCODE_PPC | PPC_OPCODE_EFS,
  162. 0 },
  163. { "efs2", PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2,
  164. 0 },
  165. { "power4", PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
  166. 0 },
  167. { "power5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  168. | PPC_OPCODE_POWER5),
  169. 0 },
  170. { "power6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  171. | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
  172. 0 },
  173. { "power7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  174. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  175. | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  176. 0 },
  177. { "power8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  178. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  179. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
  180. | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  181. 0 },
  182. { "power9", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  183. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  184. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
  185. | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  186. 0 },
  187. { "power10", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  188. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  189. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
  190. | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  191. 0 },
  192. { "future", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  193. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  194. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
  195. | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  196. 0 },
  197. { "ppc", PPC_OPCODE_PPC,
  198. 0 },
  199. { "ppc32", PPC_OPCODE_PPC,
  200. 0 },
  201. { "32", PPC_OPCODE_PPC,
  202. 0 },
  203. { "ppc64", PPC_OPCODE_PPC | PPC_OPCODE_64,
  204. 0 },
  205. { "64", PPC_OPCODE_PPC | PPC_OPCODE_64,
  206. 0 },
  207. { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE,
  208. 0 },
  209. { "ppcps", PPC_OPCODE_PPC | PPC_OPCODE_PPCPS,
  210. 0 },
  211. { "pwr", PPC_OPCODE_POWER,
  212. 0 },
  213. { "pwr2", PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
  214. 0 },
  215. { "pwr4", PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
  216. 0 },
  217. { "pwr5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  218. | PPC_OPCODE_POWER5),
  219. 0 },
  220. { "pwr5x", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  221. | PPC_OPCODE_POWER5),
  222. 0 },
  223. { "pwr6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
  224. | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
  225. 0 },
  226. { "pwr7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  227. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  228. | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  229. 0 },
  230. { "pwr8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  231. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  232. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
  233. | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  234. 0 },
  235. { "pwr9", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  236. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  237. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
  238. | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  239. 0 },
  240. { "pwr10", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
  241. | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
  242. | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
  243. | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
  244. 0 },
  245. { "pwrx", PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
  246. 0 },
  247. { "raw", PPC_OPCODE_PPC,
  248. PPC_OPCODE_RAW },
  249. { "spe", PPC_OPCODE_PPC | PPC_OPCODE_EFS,
  250. PPC_OPCODE_SPE },
  251. { "spe2", PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE,
  252. PPC_OPCODE_SPE2 },
  253. { "titan", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
  254. | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
  255. 0 },
  256. { "vle", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
  257. | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
  258. | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
  259. | PPC_OPCODE_LSP | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE2),
  260. PPC_OPCODE_VLE },
  261. { "vsx", PPC_OPCODE_PPC,
  262. PPC_OPCODE_VSX },
  263. };
  264. /* Switch between Booke and VLE dialects for interlinked dumps. */
  265. static ppc_cpu_t
  266. get_powerpc_dialect (struct disassemble_info *info)
  267. {
  268. ppc_cpu_t dialect = 0;
  269. if (info->private_data)
  270. dialect = private_data (info)->dialect;
  271. /* Disassemble according to the section headers flags for VLE-mode. */
  272. if (dialect & PPC_OPCODE_VLE
  273. && info->section != NULL && info->section->owner != NULL
  274. && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
  275. && elf_object_id (info->section->owner) == PPC32_ELF_DATA
  276. && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
  277. return dialect;
  278. else
  279. return dialect & ~ PPC_OPCODE_VLE;
  280. }
  281. /* Handle -m and -M options that set cpu type, and .machine arg. */
  282. ppc_cpu_t
  283. ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
  284. {
  285. unsigned int i;
  286. for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
  287. if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0)
  288. {
  289. if (ppc_opts[i].sticky)
  290. {
  291. *sticky |= ppc_opts[i].sticky;
  292. if ((ppc_cpu & ~*sticky) != 0)
  293. break;
  294. }
  295. ppc_cpu = ppc_opts[i].cpu;
  296. break;
  297. }
  298. if (i >= ARRAY_SIZE (ppc_opts))
  299. return 0;
  300. ppc_cpu |= *sticky;
  301. return ppc_cpu;
  302. }
  303. /* Determine which set of machines to disassemble for. */
  304. static void
  305. powerpc_init_dialect (struct disassemble_info *info)
  306. {
  307. ppc_cpu_t dialect = 0;
  308. ppc_cpu_t sticky = 0;
  309. struct dis_private *priv = calloc (sizeof (*priv), 1);
  310. if (priv == NULL)
  311. return;
  312. switch (info->mach)
  313. {
  314. case bfd_mach_ppc_403:
  315. case bfd_mach_ppc_403gc:
  316. dialect = ppc_parse_cpu (dialect, &sticky, "403");
  317. break;
  318. case bfd_mach_ppc_405:
  319. dialect = ppc_parse_cpu (dialect, &sticky, "405");
  320. break;
  321. case bfd_mach_ppc_601:
  322. dialect = ppc_parse_cpu (dialect, &sticky, "601");
  323. break;
  324. case bfd_mach_ppc_750:
  325. dialect = ppc_parse_cpu (dialect, &sticky, "750cl");
  326. break;
  327. case bfd_mach_ppc_a35:
  328. case bfd_mach_ppc_rs64ii:
  329. case bfd_mach_ppc_rs64iii:
  330. dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64;
  331. break;
  332. case bfd_mach_ppc_e500:
  333. dialect = ppc_parse_cpu (dialect, &sticky, "e500");
  334. break;
  335. case bfd_mach_ppc_e500mc:
  336. dialect = ppc_parse_cpu (dialect, &sticky, "e500mc");
  337. break;
  338. case bfd_mach_ppc_e500mc64:
  339. dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64");
  340. break;
  341. case bfd_mach_ppc_e5500:
  342. dialect = ppc_parse_cpu (dialect, &sticky, "e5500");
  343. break;
  344. case bfd_mach_ppc_e6500:
  345. dialect = ppc_parse_cpu (dialect, &sticky, "e6500");
  346. break;
  347. case bfd_mach_ppc_titan:
  348. dialect = ppc_parse_cpu (dialect, &sticky, "titan");
  349. break;
  350. case bfd_mach_ppc_vle:
  351. dialect = ppc_parse_cpu (dialect, &sticky, "vle");
  352. break;
  353. default:
  354. if (info->arch == bfd_arch_powerpc)
  355. dialect = ppc_parse_cpu (dialect, &sticky, "power10") | PPC_OPCODE_ANY;
  356. else
  357. dialect = ppc_parse_cpu (dialect, &sticky, "pwr");
  358. break;
  359. }
  360. const char *opt;
  361. FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options)
  362. {
  363. ppc_cpu_t new_cpu = 0;
  364. if (disassembler_options_cmp (opt, "32") == 0)
  365. dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
  366. else if (disassembler_options_cmp (opt, "64") == 0)
  367. dialect |= PPC_OPCODE_64;
  368. else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
  369. dialect = new_cpu;
  370. else
  371. /* xgettext: c-format */
  372. opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
  373. }
  374. info->private_data = priv;
  375. private_data (info)->dialect = dialect;
  376. }
  377. #define PPC_OPCD_SEGS (1 + PPC_OP (-1))
  378. static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1];
  379. #define PREFIX_OPCD_SEGS (1 + PPC_PREFIX_SEG (-1))
  380. static unsigned short prefix_opcd_indices[PREFIX_OPCD_SEGS + 1];
  381. #define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff)))
  382. static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1];
  383. #define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1)))
  384. static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1];
  385. static bool
  386. ppc_symbol_is_valid (asymbol *sym,
  387. struct disassemble_info *info ATTRIBUTE_UNUSED)
  388. {
  389. elf_symbol_type * est;
  390. if (sym == NULL)
  391. return false;
  392. est = elf_symbol_from (sym);
  393. /* Ignore ELF hidden, local, no-type symbols.
  394. These are generated by annobin. */
  395. if (est != NULL
  396. && ELF_ST_VISIBILITY (est->internal_elf_sym.st_other) == STV_HIDDEN
  397. && ELF_ST_BIND (est->internal_elf_sym.st_info) == STB_LOCAL
  398. && ELF_ST_TYPE (est->internal_elf_sym.st_info) == STT_NOTYPE)
  399. return false;
  400. return true;
  401. }
  402. /* Calculate opcode table indices to speed up disassembly,
  403. and init dialect. */
  404. void
  405. disassemble_init_powerpc (struct disassemble_info *info)
  406. {
  407. info->symbol_is_valid = ppc_symbol_is_valid;
  408. if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
  409. {
  410. unsigned seg, idx, op;
  411. /* PPC opcodes */
  412. for (seg = 0, idx = 0; seg <= PPC_OPCD_SEGS; seg++)
  413. {
  414. powerpc_opcd_indices[seg] = idx;
  415. for (; idx < powerpc_num_opcodes; idx++)
  416. if (seg < PPC_OP (powerpc_opcodes[idx].opcode))
  417. break;
  418. }
  419. /* 64-bit prefix opcodes */
  420. for (seg = 0, idx = 0; seg <= PREFIX_OPCD_SEGS; seg++)
  421. {
  422. prefix_opcd_indices[seg] = idx;
  423. for (; idx < prefix_num_opcodes; idx++)
  424. if (seg < PPC_PREFIX_SEG (prefix_opcodes[idx].opcode))
  425. break;
  426. }
  427. /* VLE opcodes */
  428. for (seg = 0, idx = 0; seg <= VLE_OPCD_SEGS; seg++)
  429. {
  430. vle_opcd_indices[seg] = idx;
  431. for (; idx < vle_num_opcodes; idx++)
  432. {
  433. op = VLE_OP (vle_opcodes[idx].opcode, vle_opcodes[idx].mask);
  434. if (seg < VLE_OP_TO_SEG (op))
  435. break;
  436. }
  437. }
  438. /* SPE2 opcodes */
  439. for (seg = 0, idx = 0; seg <= SPE2_OPCD_SEGS; seg++)
  440. {
  441. spe2_opcd_indices[seg] = idx;
  442. for (; idx < spe2_num_opcodes; idx++)
  443. {
  444. op = SPE2_XOP (spe2_opcodes[idx].opcode);
  445. if (seg < SPE2_XOP_TO_SEG (op))
  446. break;
  447. }
  448. }
  449. }
  450. powerpc_init_dialect (info);
  451. if (info->private_data != NULL)
  452. {
  453. private_data (info)->special[0].name = ".got";
  454. private_data (info)->special[1].name = ".plt";
  455. }
  456. }
  457. /* Print a big endian PowerPC instruction. */
  458. int
  459. print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
  460. {
  461. return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
  462. }
  463. /* Print a little endian PowerPC instruction. */
  464. int
  465. print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
  466. {
  467. return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
  468. }
  469. /* Extract the operand value from the PowerPC or POWER instruction. */
  470. static int64_t
  471. operand_value_powerpc (const struct powerpc_operand *operand,
  472. uint64_t insn, ppc_cpu_t dialect)
  473. {
  474. int64_t value;
  475. int invalid = 0;
  476. /* Extract the value from the instruction. */
  477. if (operand->extract)
  478. value = (*operand->extract) (insn, dialect, &invalid);
  479. else
  480. {
  481. if (operand->shift >= 0)
  482. value = (insn >> operand->shift) & operand->bitm;
  483. else
  484. value = (insn << -operand->shift) & operand->bitm;
  485. if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
  486. {
  487. /* BITM is always some number of zeros followed by some
  488. number of ones, followed by some number of zeros. */
  489. uint64_t top = operand->bitm;
  490. /* top & -top gives the rightmost 1 bit, so this
  491. fills in any trailing zeros. */
  492. top |= (top & -top) - 1;
  493. top &= ~(top >> 1);
  494. value = (value ^ top) - top;
  495. }
  496. }
  497. return value;
  498. }
  499. /* Determine whether the optional operand(s) should be printed. */
  500. static bool
  501. skip_optional_operands (const unsigned char *opindex,
  502. uint64_t insn, ppc_cpu_t dialect, bool *is_pcrel)
  503. {
  504. const struct powerpc_operand *operand;
  505. int num_optional;
  506. for (num_optional = 0; *opindex != 0; opindex++)
  507. {
  508. operand = &powerpc_operands[*opindex];
  509. if ((operand->flags & PPC_OPERAND_NEXT) != 0)
  510. return false;
  511. if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
  512. {
  513. int64_t value = operand_value_powerpc (operand, insn, dialect);
  514. if (operand->shift == 52)
  515. *is_pcrel = value != 0;
  516. /* Negative count is used as a flag to extract function. */
  517. --num_optional;
  518. if (value != ppc_optional_operand_value (operand, insn, dialect,
  519. num_optional))
  520. return false;
  521. }
  522. }
  523. return true;
  524. }
  525. /* Find a match for INSN in the opcode table, given machine DIALECT. */
  526. static const struct powerpc_opcode *
  527. lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
  528. {
  529. const struct powerpc_opcode *opcode, *opcode_end;
  530. unsigned long op;
  531. /* Get the major opcode of the instruction. */
  532. op = PPC_OP (insn);
  533. /* Find the first match in the opcode table for this major opcode. */
  534. opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
  535. for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
  536. opcode < opcode_end;
  537. ++opcode)
  538. {
  539. const unsigned char *opindex;
  540. const struct powerpc_operand *operand;
  541. int invalid;
  542. if ((insn & opcode->mask) != opcode->opcode
  543. || ((dialect & PPC_OPCODE_ANY) == 0
  544. && ((opcode->flags & dialect) == 0
  545. || (opcode->deprecated & dialect) != 0))
  546. || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0)
  547. continue;
  548. /* Check validity of operands. */
  549. invalid = 0;
  550. for (opindex = opcode->operands; *opindex != 0; opindex++)
  551. {
  552. operand = powerpc_operands + *opindex;
  553. if (operand->extract)
  554. (*operand->extract) (insn, dialect, &invalid);
  555. }
  556. if (invalid)
  557. continue;
  558. return opcode;
  559. }
  560. return NULL;
  561. }
  562. /* Find a match for INSN in the PREFIX opcode table. */
  563. static const struct powerpc_opcode *
  564. lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
  565. {
  566. const struct powerpc_opcode *opcode, *opcode_end;
  567. unsigned long seg;
  568. /* Get the opcode segment of the instruction. */
  569. seg = PPC_PREFIX_SEG (insn);
  570. /* Find the first match in the opcode table for this major opcode. */
  571. opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
  572. for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
  573. opcode < opcode_end;
  574. ++opcode)
  575. {
  576. const unsigned char *opindex;
  577. const struct powerpc_operand *operand;
  578. int invalid;
  579. if ((insn & opcode->mask) != opcode->opcode
  580. || ((dialect & PPC_OPCODE_ANY) == 0
  581. && (opcode->flags & dialect) == 0)
  582. || (opcode->deprecated & dialect) != 0)
  583. continue;
  584. /* Check validity of operands. */
  585. invalid = 0;
  586. for (opindex = opcode->operands; *opindex != 0; opindex++)
  587. {
  588. operand = powerpc_operands + *opindex;
  589. if (operand->extract)
  590. (*operand->extract) (insn, dialect, &invalid);
  591. }
  592. if (invalid)
  593. continue;
  594. return opcode;
  595. }
  596. return NULL;
  597. }
  598. /* Find a match for INSN in the VLE opcode table. */
  599. static const struct powerpc_opcode *
  600. lookup_vle (uint64_t insn, ppc_cpu_t dialect)
  601. {
  602. const struct powerpc_opcode *opcode;
  603. const struct powerpc_opcode *opcode_end;
  604. unsigned op, seg;
  605. op = PPC_OP (insn);
  606. if (op >= 0x20 && op <= 0x37)
  607. {
  608. /* This insn has a 4-bit opcode. */
  609. op &= 0x3c;
  610. }
  611. seg = VLE_OP_TO_SEG (op);
  612. /* Find the first match in the opcode table for this major opcode. */
  613. opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
  614. for (opcode = vle_opcodes + vle_opcd_indices[seg];
  615. opcode < opcode_end;
  616. ++opcode)
  617. {
  618. uint64_t table_opcd = opcode->opcode;
  619. uint64_t table_mask = opcode->mask;
  620. bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
  621. uint64_t insn2;
  622. const unsigned char *opindex;
  623. const struct powerpc_operand *operand;
  624. int invalid;
  625. insn2 = insn;
  626. if (table_op_is_short)
  627. insn2 >>= 16;
  628. if ((insn2 & table_mask) != table_opcd
  629. || (opcode->deprecated & dialect) != 0)
  630. continue;
  631. /* Check validity of operands. */
  632. invalid = 0;
  633. for (opindex = opcode->operands; *opindex != 0; ++opindex)
  634. {
  635. operand = powerpc_operands + *opindex;
  636. if (operand->extract)
  637. (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
  638. }
  639. if (invalid)
  640. continue;
  641. return opcode;
  642. }
  643. return NULL;
  644. }
  645. /* Find a match for INSN in the SPE2 opcode table. */
  646. static const struct powerpc_opcode *
  647. lookup_spe2 (uint64_t insn, ppc_cpu_t dialect)
  648. {
  649. const struct powerpc_opcode *opcode, *opcode_end;
  650. unsigned op, xop, seg;
  651. op = PPC_OP (insn);
  652. if (op != 0x4)
  653. {
  654. /* This is not SPE2 insn.
  655. * All SPE2 instructions have OP=4 and differs by XOP */
  656. return NULL;
  657. }
  658. xop = SPE2_XOP (insn);
  659. seg = SPE2_XOP_TO_SEG (xop);
  660. /* Find the first match in the opcode table for this major opcode. */
  661. opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
  662. for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
  663. opcode < opcode_end;
  664. ++opcode)
  665. {
  666. uint64_t table_opcd = opcode->opcode;
  667. uint64_t table_mask = opcode->mask;
  668. uint64_t insn2;
  669. const unsigned char *opindex;
  670. const struct powerpc_operand *operand;
  671. int invalid;
  672. insn2 = insn;
  673. if ((insn2 & table_mask) != table_opcd
  674. || (opcode->deprecated & dialect) != 0)
  675. continue;
  676. /* Check validity of operands. */
  677. invalid = 0;
  678. for (opindex = opcode->operands; *opindex != 0; ++opindex)
  679. {
  680. operand = powerpc_operands + *opindex;
  681. if (operand->extract)
  682. (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
  683. }
  684. if (invalid)
  685. continue;
  686. return opcode;
  687. }
  688. return NULL;
  689. }
  690. static arelent *
  691. bsearch_reloc (arelent **lo, arelent **hi, bfd_vma vma)
  692. {
  693. while (lo < hi)
  694. {
  695. arelent **mid = lo + (hi - lo) / 2;
  696. arelent *rel = *mid;
  697. if (vma < rel->address)
  698. hi = mid;
  699. else if (vma > rel->address)
  700. lo = mid + 1;
  701. else
  702. return rel;
  703. }
  704. return NULL;
  705. }
  706. static bool
  707. print_got_plt (struct sec_buf *sb, uint64_t vma, struct disassemble_info *info)
  708. {
  709. if (sb->name != NULL)
  710. {
  711. asection *s = sb->sec;
  712. if (s == NULL)
  713. {
  714. s = bfd_get_section_by_name (info->section->owner, sb->name);
  715. sb->sec = s;
  716. if (s == NULL)
  717. sb->name = NULL;
  718. }
  719. if (s != NULL
  720. && vma >= s->vma
  721. && vma < s->vma + s->size)
  722. {
  723. asymbol *sym = NULL;
  724. uint64_t ent = 0;
  725. if (info->dynrelcount > 0)
  726. {
  727. arelent **lo = info->dynrelbuf;
  728. arelent **hi = lo + info->dynrelcount;
  729. arelent *rel = bsearch_reloc (lo, hi, vma);
  730. if (rel != NULL && rel->sym_ptr_ptr != NULL)
  731. sym = *rel->sym_ptr_ptr;
  732. }
  733. if (sym == NULL && (s->flags & SEC_HAS_CONTENTS) != 0)
  734. {
  735. if (sb->buf == NULL
  736. && !bfd_malloc_and_get_section (s->owner, s, &sb->buf))
  737. sb->name = NULL;
  738. if (sb->buf != NULL)
  739. {
  740. ent = bfd_get_64 (s->owner, sb->buf + (vma - s->vma));
  741. if (ent != 0)
  742. sym = (*info->symbol_at_address_func) (ent, info);
  743. }
  744. }
  745. if (sym != NULL)
  746. (*info->fprintf_func) (info->stream, " [%s@%s]",
  747. bfd_asymbol_name (sym), sb->name + 1);
  748. else
  749. (*info->fprintf_func) (info->stream, " [%" PRIx64 "@%s]",
  750. ent, sb->name + 1);
  751. return true;
  752. }
  753. }
  754. return false;
  755. }
  756. /* Print a PowerPC or POWER instruction. */
  757. static int
  758. print_insn_powerpc (bfd_vma memaddr,
  759. struct disassemble_info *info,
  760. int bigendian,
  761. ppc_cpu_t dialect)
  762. {
  763. bfd_byte buffer[4];
  764. int status;
  765. uint64_t insn;
  766. const struct powerpc_opcode *opcode;
  767. int insn_length = 4; /* Assume we have a normal 4-byte instruction. */
  768. status = (*info->read_memory_func) (memaddr, buffer, 4, info);
  769. /* The final instruction may be a 2-byte VLE insn. */
  770. if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
  771. {
  772. /* Clear buffer so unused bytes will not have garbage in them. */
  773. buffer[2] = buffer[3] = 0;
  774. status = (*info->read_memory_func) (memaddr, buffer, 2, info);
  775. insn_length = 2;
  776. }
  777. if (status != 0)
  778. {
  779. (*info->memory_error_func) (status, memaddr, info);
  780. return -1;
  781. }
  782. if (bigendian)
  783. insn = bfd_getb32 (buffer);
  784. else
  785. insn = bfd_getl32 (buffer);
  786. /* Get the major opcode of the insn. */
  787. opcode = NULL;
  788. if ((dialect & PPC_OPCODE_POWER10) != 0
  789. && PPC_OP (insn) == 0x1)
  790. {
  791. uint64_t temp_insn, suffix;
  792. status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
  793. if (status == 0)
  794. {
  795. if (bigendian)
  796. suffix = bfd_getb32 (buffer);
  797. else
  798. suffix = bfd_getl32 (buffer);
  799. temp_insn = (insn << 32) | suffix;
  800. opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
  801. if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
  802. opcode = lookup_prefix (temp_insn, dialect);
  803. if (opcode != NULL)
  804. {
  805. insn = temp_insn;
  806. insn_length = 8;
  807. if ((info->flags & WIDE_OUTPUT) != 0)
  808. info->bytes_per_line = 8;
  809. }
  810. }
  811. }
  812. if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
  813. {
  814. opcode = lookup_vle (insn, dialect);
  815. if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
  816. {
  817. /* The operands will be fetched out of the 16-bit instruction. */
  818. insn >>= 16;
  819. insn_length = 2;
  820. }
  821. }
  822. if (opcode == NULL && insn_length == 4)
  823. {
  824. if ((dialect & PPC_OPCODE_SPE2) != 0)
  825. opcode = lookup_spe2 (insn, dialect);
  826. if (opcode == NULL)
  827. opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
  828. if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
  829. opcode = lookup_powerpc (insn, dialect);
  830. }
  831. if (opcode != NULL)
  832. {
  833. const unsigned char *opindex;
  834. const struct powerpc_operand *operand;
  835. enum {
  836. need_comma = 0,
  837. need_1space = 1,
  838. need_2spaces = 2,
  839. need_3spaces = 3,
  840. need_4spaces = 4,
  841. need_5spaces = 5,
  842. need_6spaces = 6,
  843. need_7spaces = 7,
  844. need_paren
  845. } op_separator;
  846. bool skip_optional;
  847. bool is_pcrel;
  848. uint64_t d34;
  849. int blanks;
  850. (*info->fprintf_func) (info->stream, "%s", opcode->name);
  851. /* gdb fprintf_func doesn't return count printed. */
  852. blanks = 8 - strlen (opcode->name);
  853. if (blanks <= 0)
  854. blanks = 1;
  855. /* Now extract and print the operands. */
  856. op_separator = blanks;
  857. skip_optional = false;
  858. is_pcrel = false;
  859. d34 = 0;
  860. for (opindex = opcode->operands; *opindex != 0; opindex++)
  861. {
  862. int64_t value;
  863. operand = powerpc_operands + *opindex;
  864. /* If all of the optional operands past this one have their
  865. default value, then don't print any of them. Except in
  866. raw mode, print them all. */
  867. if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
  868. && (dialect & PPC_OPCODE_RAW) == 0)
  869. {
  870. if (!skip_optional)
  871. skip_optional = skip_optional_operands (opindex, insn,
  872. dialect, &is_pcrel);
  873. if (skip_optional)
  874. continue;
  875. }
  876. value = operand_value_powerpc (operand, insn, dialect);
  877. if (op_separator == need_comma)
  878. (*info->fprintf_func) (info->stream, ",");
  879. else if (op_separator == need_paren)
  880. (*info->fprintf_func) (info->stream, "(");
  881. else
  882. (*info->fprintf_func) (info->stream, "%*s", op_separator, " ");
  883. /* Print the operand as directed by the flags. */
  884. if ((operand->flags & PPC_OPERAND_GPR) != 0
  885. || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
  886. (*info->fprintf_func) (info->stream, "r%" PRId64, value);
  887. else if ((operand->flags & PPC_OPERAND_FPR) != 0)
  888. (*info->fprintf_func) (info->stream, "f%" PRId64, value);
  889. else if ((operand->flags & PPC_OPERAND_VR) != 0)
  890. (*info->fprintf_func) (info->stream, "v%" PRId64, value);
  891. else if ((operand->flags & PPC_OPERAND_VSR) != 0)
  892. (*info->fprintf_func) (info->stream, "vs%" PRId64, value);
  893. else if ((operand->flags & PPC_OPERAND_ACC) != 0)
  894. (*info->fprintf_func) (info->stream, "a%" PRId64, value);
  895. else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
  896. (*info->print_address_func) (memaddr + value, info);
  897. else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
  898. (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
  899. else if ((operand->flags & PPC_OPERAND_FSL) != 0)
  900. (*info->fprintf_func) (info->stream, "fsl%" PRId64, value);
  901. else if ((operand->flags & PPC_OPERAND_FCR) != 0)
  902. (*info->fprintf_func) (info->stream, "fcr%" PRId64, value);
  903. else if ((operand->flags & PPC_OPERAND_UDI) != 0)
  904. (*info->fprintf_func) (info->stream, "%" PRId64, value);
  905. else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
  906. && (operand->flags & PPC_OPERAND_CR_BIT) == 0
  907. && (((dialect & PPC_OPCODE_PPC) != 0)
  908. || ((dialect & PPC_OPCODE_VLE) != 0)))
  909. (*info->fprintf_func) (info->stream, "cr%" PRId64, value);
  910. else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
  911. && (operand->flags & PPC_OPERAND_CR_REG) == 0
  912. && (((dialect & PPC_OPCODE_PPC) != 0)
  913. || ((dialect & PPC_OPCODE_VLE) != 0)))
  914. {
  915. static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
  916. int cr;
  917. int cc;
  918. cr = value >> 2;
  919. if (cr != 0)
  920. (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
  921. cc = value & 3;
  922. (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
  923. }
  924. else
  925. (*info->fprintf_func) (info->stream, "%" PRId64, value);
  926. if (operand->shift == 52)
  927. is_pcrel = value != 0;
  928. else if (operand->bitm == UINT64_C (0x3ffffffff))
  929. d34 = value;
  930. if (op_separator == need_paren)
  931. (*info->fprintf_func) (info->stream, ")");
  932. op_separator = need_comma;
  933. if ((operand->flags & PPC_OPERAND_PARENS) != 0)
  934. op_separator = need_paren;
  935. }
  936. if (is_pcrel)
  937. {
  938. d34 += memaddr;
  939. (*info->fprintf_func) (info->stream, "\t# %" PRIx64, d34);
  940. asymbol *sym = (*info->symbol_at_address_func) (d34, info);
  941. if (sym)
  942. (*info->fprintf_func) (info->stream, " <%s>",
  943. bfd_asymbol_name (sym));
  944. if (info->private_data != NULL
  945. && info->section != NULL
  946. && info->section->owner != NULL
  947. && (bfd_get_file_flags (info->section->owner)
  948. & (EXEC_P | DYNAMIC)) != 0
  949. && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
  950. == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
  951. {
  952. for (int i = 0; i < 2; i++)
  953. if (print_got_plt (private_data (info)->special + i, d34, info))
  954. break;
  955. }
  956. }
  957. /* We have found and printed an instruction. */
  958. return insn_length;
  959. }
  960. /* We could not find a match. */
  961. if (insn_length == 4)
  962. (*info->fprintf_func) (info->stream, ".long 0x%x",
  963. (unsigned int) insn);
  964. else
  965. (*info->fprintf_func) (info->stream, ".word 0x%x",
  966. (unsigned int) insn >> 16);
  967. return insn_length;
  968. }
  969. const disasm_options_and_args_t *
  970. disassembler_options_powerpc (void)
  971. {
  972. static disasm_options_and_args_t *opts_and_args;
  973. if (opts_and_args == NULL)
  974. {
  975. size_t i, num_options = ARRAY_SIZE (ppc_opts);
  976. disasm_options_t *opts;
  977. opts_and_args = XNEW (disasm_options_and_args_t);
  978. opts_and_args->args = NULL;
  979. opts = &opts_and_args->options;
  980. opts->name = XNEWVEC (const char *, num_options + 1);
  981. opts->description = NULL;
  982. opts->arg = NULL;
  983. for (i = 0; i < num_options; i++)
  984. opts->name[i] = ppc_opts[i].opt;
  985. /* The array we return must be NULL terminated. */
  986. opts->name[i] = NULL;
  987. }
  988. return opts_and_args;
  989. }
  990. void
  991. print_ppc_disassembler_options (FILE *stream)
  992. {
  993. unsigned int i, col;
  994. fprintf (stream, _("\n\
  995. The following PPC specific disassembler options are supported for use with\n\
  996. the -M switch:\n"));
  997. for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
  998. {
  999. col += fprintf (stream, " %s,", ppc_opts[i].opt);
  1000. if (col > 66)
  1001. {
  1002. fprintf (stream, "\n");
  1003. col = 0;
  1004. }
  1005. }
  1006. fprintf (stream, "\n");
  1007. }