elfxx-riscv.c 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504
  1. /* RISC-V-specific support for ELF.
  2. Copyright (C) 2011-2022 Free Software Foundation, Inc.
  3. Contributed by Andrew Waterman (andrew@sifive.com).
  4. Based on TILE-Gx and MIPS targets.
  5. This file is part of BFD, the Binary File Descriptor library.
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING3. If not,
  16. see <http://www.gnu.org/licenses/>. */
  17. #include "sysdep.h"
  18. #include "bfd.h"
  19. #include "libbfd.h"
  20. #include "elf-bfd.h"
  21. #include "elf/riscv.h"
  22. #include "opcode/riscv.h"
  23. #include "libiberty.h"
  24. #include "elfxx-riscv.h"
  25. #include "safe-ctype.h"
  26. #define MINUS_ONE ((bfd_vma)0 - 1)
  27. /* Special handler for ADD/SUB relocations that allows them to be filled out
  28. both in the pre-linked and post-linked file. This is necessary to make
  29. pre-linked debug info work, as due to linker relaxations we need to emit
  30. relocations for the debug info. */
  31. static bfd_reloc_status_type riscv_elf_add_sub_reloc
  32. (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  33. /* The relocation table used for SHT_RELA sections. */
  34. static reloc_howto_type howto_table[] =
  35. {
  36. /* No relocation. */
  37. HOWTO (R_RISCV_NONE, /* type */
  38. 0, /* rightshift */
  39. 3, /* size */
  40. 0, /* bitsize */
  41. false, /* pc_relative */
  42. 0, /* bitpos */
  43. complain_overflow_dont, /* complain_on_overflow */
  44. bfd_elf_generic_reloc, /* special_function */
  45. "R_RISCV_NONE", /* name */
  46. false, /* partial_inplace */
  47. 0, /* src_mask */
  48. 0, /* dst_mask */
  49. false), /* pcrel_offset */
  50. /* 32 bit relocation. */
  51. HOWTO (R_RISCV_32, /* type */
  52. 0, /* rightshift */
  53. 2, /* size */
  54. 32, /* bitsize */
  55. false, /* pc_relative */
  56. 0, /* bitpos */
  57. complain_overflow_dont, /* complain_on_overflow */
  58. bfd_elf_generic_reloc, /* special_function */
  59. "R_RISCV_32", /* name */
  60. false, /* partial_inplace */
  61. 0, /* src_mask */
  62. 0xffffffff, /* dst_mask */
  63. false), /* pcrel_offset */
  64. /* 64 bit relocation. */
  65. HOWTO (R_RISCV_64, /* type */
  66. 0, /* rightshift */
  67. 4, /* size */
  68. 64, /* bitsize */
  69. false, /* pc_relative */
  70. 0, /* bitpos */
  71. complain_overflow_dont, /* complain_on_overflow */
  72. bfd_elf_generic_reloc, /* special_function */
  73. "R_RISCV_64", /* name */
  74. false, /* partial_inplace */
  75. 0, /* src_mask */
  76. MINUS_ONE, /* dst_mask */
  77. false), /* pcrel_offset */
  78. /* Relocation against a local symbol in a shared object. */
  79. HOWTO (R_RISCV_RELATIVE, /* type */
  80. 0, /* rightshift */
  81. 2, /* size */
  82. 32, /* bitsize */
  83. false, /* pc_relative */
  84. 0, /* bitpos */
  85. complain_overflow_dont, /* complain_on_overflow */
  86. bfd_elf_generic_reloc, /* special_function */
  87. "R_RISCV_RELATIVE", /* name */
  88. false, /* partial_inplace */
  89. 0, /* src_mask */
  90. 0xffffffff, /* dst_mask */
  91. false), /* pcrel_offset */
  92. HOWTO (R_RISCV_COPY, /* type */
  93. 0, /* rightshift */
  94. 0, /* this one is variable size */
  95. 0, /* bitsize */
  96. false, /* pc_relative */
  97. 0, /* bitpos */
  98. complain_overflow_bitfield, /* complain_on_overflow */
  99. bfd_elf_generic_reloc, /* special_function */
  100. "R_RISCV_COPY", /* name */
  101. false, /* partial_inplace */
  102. 0, /* src_mask */
  103. 0, /* dst_mask */
  104. false), /* pcrel_offset */
  105. HOWTO (R_RISCV_JUMP_SLOT, /* type */
  106. 0, /* rightshift */
  107. 4, /* size */
  108. 64, /* bitsize */
  109. false, /* pc_relative */
  110. 0, /* bitpos */
  111. complain_overflow_bitfield, /* complain_on_overflow */
  112. bfd_elf_generic_reloc, /* special_function */
  113. "R_RISCV_JUMP_SLOT", /* name */
  114. false, /* partial_inplace */
  115. 0, /* src_mask */
  116. 0, /* dst_mask */
  117. false), /* pcrel_offset */
  118. /* Dynamic TLS relocations. */
  119. HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
  120. 0, /* rightshift */
  121. 2, /* size */
  122. 32, /* bitsize */
  123. false, /* pc_relative */
  124. 0, /* bitpos */
  125. complain_overflow_dont, /* complain_on_overflow */
  126. bfd_elf_generic_reloc, /* special_function */
  127. "R_RISCV_TLS_DTPMOD32", /* name */
  128. false, /* partial_inplace */
  129. 0, /* src_mask */
  130. 0xffffffff, /* dst_mask */
  131. false), /* pcrel_offset */
  132. HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
  133. 0, /* rightshift */
  134. 4, /* size */
  135. 64, /* bitsize */
  136. false, /* pc_relative */
  137. 0, /* bitpos */
  138. complain_overflow_dont, /* complain_on_overflow */
  139. bfd_elf_generic_reloc, /* special_function */
  140. "R_RISCV_TLS_DTPMOD64", /* name */
  141. false, /* partial_inplace */
  142. 0, /* src_mask */
  143. MINUS_ONE, /* dst_mask */
  144. false), /* pcrel_offset */
  145. HOWTO (R_RISCV_TLS_DTPREL32, /* type */
  146. 0, /* rightshift */
  147. 2, /* size */
  148. 32, /* bitsize */
  149. false, /* pc_relative */
  150. 0, /* bitpos */
  151. complain_overflow_dont, /* complain_on_overflow */
  152. bfd_elf_generic_reloc, /* special_function */
  153. "R_RISCV_TLS_DTPREL32", /* name */
  154. true, /* partial_inplace */
  155. 0, /* src_mask */
  156. 0xffffffff, /* dst_mask */
  157. false), /* pcrel_offset */
  158. HOWTO (R_RISCV_TLS_DTPREL64, /* type */
  159. 0, /* rightshift */
  160. 4, /* size */
  161. 64, /* bitsize */
  162. false, /* pc_relative */
  163. 0, /* bitpos */
  164. complain_overflow_dont, /* complain_on_overflow */
  165. bfd_elf_generic_reloc, /* special_function */
  166. "R_RISCV_TLS_DTPREL64", /* name */
  167. true, /* partial_inplace */
  168. 0, /* src_mask */
  169. MINUS_ONE, /* dst_mask */
  170. false), /* pcrel_offset */
  171. HOWTO (R_RISCV_TLS_TPREL32, /* type */
  172. 0, /* rightshift */
  173. 2, /* size */
  174. 32, /* bitsize */
  175. false, /* pc_relative */
  176. 0, /* bitpos */
  177. complain_overflow_dont, /* complain_on_overflow */
  178. bfd_elf_generic_reloc, /* special_function */
  179. "R_RISCV_TLS_TPREL32", /* name */
  180. false, /* partial_inplace */
  181. 0, /* src_mask */
  182. 0xffffffff, /* dst_mask */
  183. false), /* pcrel_offset */
  184. HOWTO (R_RISCV_TLS_TPREL64, /* type */
  185. 0, /* rightshift */
  186. 4, /* size */
  187. 64, /* bitsize */
  188. false, /* pc_relative */
  189. 0, /* bitpos */
  190. complain_overflow_dont, /* complain_on_overflow */
  191. bfd_elf_generic_reloc, /* special_function */
  192. "R_RISCV_TLS_TPREL64", /* name */
  193. false, /* partial_inplace */
  194. 0, /* src_mask */
  195. MINUS_ONE, /* dst_mask */
  196. false), /* pcrel_offset */
  197. /* Reserved for future relocs that the dynamic linker must understand. */
  198. EMPTY_HOWTO (12),
  199. EMPTY_HOWTO (13),
  200. EMPTY_HOWTO (14),
  201. EMPTY_HOWTO (15),
  202. /* 12-bit PC-relative branch offset. */
  203. HOWTO (R_RISCV_BRANCH, /* type */
  204. 0, /* rightshift */
  205. 2, /* size */
  206. 32, /* bitsize */
  207. true, /* pc_relative */
  208. 0, /* bitpos */
  209. complain_overflow_signed, /* complain_on_overflow */
  210. bfd_elf_generic_reloc, /* special_function */
  211. "R_RISCV_BRANCH", /* name */
  212. false, /* partial_inplace */
  213. 0, /* src_mask */
  214. ENCODE_BTYPE_IMM (-1U), /* dst_mask */
  215. true), /* pcrel_offset */
  216. /* 20-bit PC-relative jump offset. */
  217. HOWTO (R_RISCV_JAL, /* type */
  218. 0, /* rightshift */
  219. 2, /* size */
  220. 32, /* bitsize */
  221. true, /* pc_relative */
  222. 0, /* bitpos */
  223. complain_overflow_dont, /* complain_on_overflow */
  224. bfd_elf_generic_reloc, /* special_function */
  225. "R_RISCV_JAL", /* name */
  226. false, /* partial_inplace */
  227. 0, /* src_mask */
  228. ENCODE_JTYPE_IMM (-1U), /* dst_mask */
  229. true), /* pcrel_offset */
  230. /* 32-bit PC-relative function call (AUIPC/JALR). */
  231. HOWTO (R_RISCV_CALL, /* type */
  232. 0, /* rightshift */
  233. 4, /* size */
  234. 64, /* bitsize */
  235. true, /* pc_relative */
  236. 0, /* bitpos */
  237. complain_overflow_dont, /* complain_on_overflow */
  238. bfd_elf_generic_reloc, /* special_function */
  239. "R_RISCV_CALL", /* name */
  240. false, /* partial_inplace */
  241. 0, /* src_mask */
  242. ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
  243. /* dst_mask */
  244. true), /* pcrel_offset */
  245. /* Like R_RISCV_CALL, but not locally binding. */
  246. HOWTO (R_RISCV_CALL_PLT, /* type */
  247. 0, /* rightshift */
  248. 4, /* size */
  249. 64, /* bitsize */
  250. true, /* pc_relative */
  251. 0, /* bitpos */
  252. complain_overflow_dont, /* complain_on_overflow */
  253. bfd_elf_generic_reloc, /* special_function */
  254. "R_RISCV_CALL_PLT", /* name */
  255. false, /* partial_inplace */
  256. 0, /* src_mask */
  257. ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
  258. /* dst_mask */
  259. true), /* pcrel_offset */
  260. /* High 20 bits of 32-bit PC-relative GOT access. */
  261. HOWTO (R_RISCV_GOT_HI20, /* type */
  262. 0, /* rightshift */
  263. 2, /* size */
  264. 32, /* bitsize */
  265. true, /* pc_relative */
  266. 0, /* bitpos */
  267. complain_overflow_dont, /* complain_on_overflow */
  268. bfd_elf_generic_reloc, /* special_function */
  269. "R_RISCV_GOT_HI20", /* name */
  270. false, /* partial_inplace */
  271. 0, /* src_mask */
  272. ENCODE_UTYPE_IMM (-1U), /* dst_mask */
  273. false), /* pcrel_offset */
  274. /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
  275. HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
  276. 0, /* rightshift */
  277. 2, /* size */
  278. 32, /* bitsize */
  279. true, /* pc_relative */
  280. 0, /* bitpos */
  281. complain_overflow_dont, /* complain_on_overflow */
  282. bfd_elf_generic_reloc, /* special_function */
  283. "R_RISCV_TLS_GOT_HI20", /* name */
  284. false, /* partial_inplace */
  285. 0, /* src_mask */
  286. ENCODE_UTYPE_IMM (-1U), /* dst_mask */
  287. false), /* pcrel_offset */
  288. /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
  289. HOWTO (R_RISCV_TLS_GD_HI20, /* type */
  290. 0, /* rightshift */
  291. 2, /* size */
  292. 32, /* bitsize */
  293. true, /* pc_relative */
  294. 0, /* bitpos */
  295. complain_overflow_dont, /* complain_on_overflow */
  296. bfd_elf_generic_reloc, /* special_function */
  297. "R_RISCV_TLS_GD_HI20", /* name */
  298. false, /* partial_inplace */
  299. 0, /* src_mask */
  300. ENCODE_UTYPE_IMM (-1U), /* dst_mask */
  301. false), /* pcrel_offset */
  302. /* High 20 bits of 32-bit PC-relative reference. */
  303. HOWTO (R_RISCV_PCREL_HI20, /* type */
  304. 0, /* rightshift */
  305. 2, /* size */
  306. 32, /* bitsize */
  307. true, /* pc_relative */
  308. 0, /* bitpos */
  309. complain_overflow_dont, /* complain_on_overflow */
  310. bfd_elf_generic_reloc, /* special_function */
  311. "R_RISCV_PCREL_HI20", /* name */
  312. false, /* partial_inplace */
  313. 0, /* src_mask */
  314. ENCODE_UTYPE_IMM (-1U), /* dst_mask */
  315. true), /* pcrel_offset */
  316. /* Low 12 bits of a 32-bit PC-relative load or add. */
  317. HOWTO (R_RISCV_PCREL_LO12_I, /* type */
  318. 0, /* rightshift */
  319. 2, /* size */
  320. 32, /* bitsize */
  321. false, /* pc_relative */
  322. 0, /* bitpos */
  323. complain_overflow_dont, /* complain_on_overflow */
  324. bfd_elf_generic_reloc, /* special_function */
  325. "R_RISCV_PCREL_LO12_I", /* name */
  326. false, /* partial_inplace */
  327. 0, /* src_mask */
  328. ENCODE_ITYPE_IMM (-1U), /* dst_mask */
  329. false), /* pcrel_offset */
  330. /* Low 12 bits of a 32-bit PC-relative store. */
  331. HOWTO (R_RISCV_PCREL_LO12_S, /* type */
  332. 0, /* rightshift */
  333. 2, /* size */
  334. 32, /* bitsize */
  335. false, /* pc_relative */
  336. 0, /* bitpos */
  337. complain_overflow_dont, /* complain_on_overflow */
  338. bfd_elf_generic_reloc, /* special_function */
  339. "R_RISCV_PCREL_LO12_S", /* name */
  340. false, /* partial_inplace */
  341. 0, /* src_mask */
  342. ENCODE_STYPE_IMM (-1U), /* dst_mask */
  343. false), /* pcrel_offset */
  344. /* High 20 bits of 32-bit absolute address. */
  345. HOWTO (R_RISCV_HI20, /* type */
  346. 0, /* rightshift */
  347. 2, /* size */
  348. 32, /* bitsize */
  349. false, /* pc_relative */
  350. 0, /* bitpos */
  351. complain_overflow_dont, /* complain_on_overflow */
  352. bfd_elf_generic_reloc, /* special_function */
  353. "R_RISCV_HI20", /* name */
  354. false, /* partial_inplace */
  355. 0, /* src_mask */
  356. ENCODE_UTYPE_IMM (-1U), /* dst_mask */
  357. false), /* pcrel_offset */
  358. /* High 12 bits of 32-bit load or add. */
  359. HOWTO (R_RISCV_LO12_I, /* type */
  360. 0, /* rightshift */
  361. 2, /* size */
  362. 32, /* bitsize */
  363. false, /* pc_relative */
  364. 0, /* bitpos */
  365. complain_overflow_dont, /* complain_on_overflow */
  366. bfd_elf_generic_reloc, /* special_function */
  367. "R_RISCV_LO12_I", /* name */
  368. false, /* partial_inplace */
  369. 0, /* src_mask */
  370. ENCODE_ITYPE_IMM (-1U), /* dst_mask */
  371. false), /* pcrel_offset */
  372. /* High 12 bits of 32-bit store. */
  373. HOWTO (R_RISCV_LO12_S, /* type */
  374. 0, /* rightshift */
  375. 2, /* size */
  376. 32, /* bitsize */
  377. false, /* pc_relative */
  378. 0, /* bitpos */
  379. complain_overflow_dont, /* complain_on_overflow */
  380. bfd_elf_generic_reloc, /* special_function */
  381. "R_RISCV_LO12_S", /* name */
  382. false, /* partial_inplace */
  383. 0, /* src_mask */
  384. ENCODE_STYPE_IMM (-1U), /* dst_mask */
  385. false), /* pcrel_offset */
  386. /* High 20 bits of TLS LE thread pointer offset. */
  387. HOWTO (R_RISCV_TPREL_HI20, /* type */
  388. 0, /* rightshift */
  389. 2, /* size */
  390. 32, /* bitsize */
  391. false, /* pc_relative */
  392. 0, /* bitpos */
  393. complain_overflow_signed, /* complain_on_overflow */
  394. bfd_elf_generic_reloc, /* special_function */
  395. "R_RISCV_TPREL_HI20", /* name */
  396. true, /* partial_inplace */
  397. 0, /* src_mask */
  398. ENCODE_UTYPE_IMM (-1U), /* dst_mask */
  399. false), /* pcrel_offset */
  400. /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
  401. HOWTO (R_RISCV_TPREL_LO12_I, /* type */
  402. 0, /* rightshift */
  403. 2, /* size */
  404. 32, /* bitsize */
  405. false, /* pc_relative */
  406. 0, /* bitpos */
  407. complain_overflow_signed, /* complain_on_overflow */
  408. bfd_elf_generic_reloc, /* special_function */
  409. "R_RISCV_TPREL_LO12_I", /* name */
  410. false, /* partial_inplace */
  411. 0, /* src_mask */
  412. ENCODE_ITYPE_IMM (-1U), /* dst_mask */
  413. false), /* pcrel_offset */
  414. /* Low 12 bits of TLS LE thread pointer offset for stores. */
  415. HOWTO (R_RISCV_TPREL_LO12_S, /* type */
  416. 0, /* rightshift */
  417. 2, /* size */
  418. 32, /* bitsize */
  419. false, /* pc_relative */
  420. 0, /* bitpos */
  421. complain_overflow_signed, /* complain_on_overflow */
  422. bfd_elf_generic_reloc, /* special_function */
  423. "R_RISCV_TPREL_LO12_S", /* name */
  424. false, /* partial_inplace */
  425. 0, /* src_mask */
  426. ENCODE_STYPE_IMM (-1U), /* dst_mask */
  427. false), /* pcrel_offset */
  428. /* TLS LE thread pointer usage. May be relaxed. */
  429. HOWTO (R_RISCV_TPREL_ADD, /* type */
  430. 0, /* rightshift */
  431. 3, /* size */
  432. 0, /* bitsize */
  433. false, /* pc_relative */
  434. 0, /* bitpos */
  435. complain_overflow_dont, /* complain_on_overflow */
  436. bfd_elf_generic_reloc, /* special_function */
  437. "R_RISCV_TPREL_ADD", /* name */
  438. false, /* partial_inplace */
  439. 0, /* src_mask */
  440. 0, /* dst_mask */
  441. false), /* pcrel_offset */
  442. /* 8-bit in-place addition, for local label subtraction. */
  443. HOWTO (R_RISCV_ADD8, /* type */
  444. 0, /* rightshift */
  445. 0, /* size */
  446. 8, /* bitsize */
  447. false, /* pc_relative */
  448. 0, /* bitpos */
  449. complain_overflow_dont, /* complain_on_overflow */
  450. riscv_elf_add_sub_reloc, /* special_function */
  451. "R_RISCV_ADD8", /* name */
  452. false, /* partial_inplace */
  453. 0, /* src_mask */
  454. 0xff, /* dst_mask */
  455. false), /* pcrel_offset */
  456. /* 16-bit in-place addition, for local label subtraction. */
  457. HOWTO (R_RISCV_ADD16, /* type */
  458. 0, /* rightshift */
  459. 1, /* size */
  460. 16, /* bitsize */
  461. false, /* pc_relative */
  462. 0, /* bitpos */
  463. complain_overflow_dont, /* complain_on_overflow */
  464. riscv_elf_add_sub_reloc, /* special_function */
  465. "R_RISCV_ADD16", /* name */
  466. false, /* partial_inplace */
  467. 0, /* src_mask */
  468. 0xffff, /* dst_mask */
  469. false), /* pcrel_offset */
  470. /* 32-bit in-place addition, for local label subtraction. */
  471. HOWTO (R_RISCV_ADD32, /* type */
  472. 0, /* rightshift */
  473. 2, /* size */
  474. 32, /* bitsize */
  475. false, /* pc_relative */
  476. 0, /* bitpos */
  477. complain_overflow_dont, /* complain_on_overflow */
  478. riscv_elf_add_sub_reloc, /* special_function */
  479. "R_RISCV_ADD32", /* name */
  480. false, /* partial_inplace */
  481. 0, /* src_mask */
  482. 0xffffffff, /* dst_mask */
  483. false), /* pcrel_offset */
  484. /* 64-bit in-place addition, for local label subtraction. */
  485. HOWTO (R_RISCV_ADD64, /* type */
  486. 0, /* rightshift */
  487. 4, /* size */
  488. 64, /* bitsize */
  489. false, /* pc_relative */
  490. 0, /* bitpos */
  491. complain_overflow_dont, /* complain_on_overflow */
  492. riscv_elf_add_sub_reloc, /* special_function */
  493. "R_RISCV_ADD64", /* name */
  494. false, /* partial_inplace */
  495. 0, /* src_mask */
  496. MINUS_ONE, /* dst_mask */
  497. false), /* pcrel_offset */
  498. /* 8-bit in-place addition, for local label subtraction. */
  499. HOWTO (R_RISCV_SUB8, /* type */
  500. 0, /* rightshift */
  501. 0, /* size */
  502. 8, /* bitsize */
  503. false, /* pc_relative */
  504. 0, /* bitpos */
  505. complain_overflow_dont, /* complain_on_overflow */
  506. riscv_elf_add_sub_reloc, /* special_function */
  507. "R_RISCV_SUB8", /* name */
  508. false, /* partial_inplace */
  509. 0, /* src_mask */
  510. 0xff, /* dst_mask */
  511. false), /* pcrel_offset */
  512. /* 16-bit in-place addition, for local label subtraction. */
  513. HOWTO (R_RISCV_SUB16, /* type */
  514. 0, /* rightshift */
  515. 1, /* size */
  516. 16, /* bitsize */
  517. false, /* pc_relative */
  518. 0, /* bitpos */
  519. complain_overflow_dont, /* complain_on_overflow */
  520. riscv_elf_add_sub_reloc, /* special_function */
  521. "R_RISCV_SUB16", /* name */
  522. false, /* partial_inplace */
  523. 0, /* src_mask */
  524. 0xffff, /* dst_mask */
  525. false), /* pcrel_offset */
  526. /* 32-bit in-place addition, for local label subtraction. */
  527. HOWTO (R_RISCV_SUB32, /* type */
  528. 0, /* rightshift */
  529. 2, /* size */
  530. 32, /* bitsize */
  531. false, /* pc_relative */
  532. 0, /* bitpos */
  533. complain_overflow_dont, /* complain_on_overflow */
  534. riscv_elf_add_sub_reloc, /* special_function */
  535. "R_RISCV_SUB32", /* name */
  536. false, /* partial_inplace */
  537. 0, /* src_mask */
  538. 0xffffffff, /* dst_mask */
  539. false), /* pcrel_offset */
  540. /* 64-bit in-place addition, for local label subtraction. */
  541. HOWTO (R_RISCV_SUB64, /* type */
  542. 0, /* rightshift */
  543. 4, /* size */
  544. 64, /* bitsize */
  545. false, /* pc_relative */
  546. 0, /* bitpos */
  547. complain_overflow_dont, /* complain_on_overflow */
  548. riscv_elf_add_sub_reloc, /* special_function */
  549. "R_RISCV_SUB64", /* name */
  550. false, /* partial_inplace */
  551. 0, /* src_mask */
  552. MINUS_ONE, /* dst_mask */
  553. false), /* pcrel_offset */
  554. /* GNU extension to record C++ vtable hierarchy */
  555. HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
  556. 0, /* rightshift */
  557. 4, /* size */
  558. 0, /* bitsize */
  559. false, /* pc_relative */
  560. 0, /* bitpos */
  561. complain_overflow_dont, /* complain_on_overflow */
  562. NULL, /* special_function */
  563. "R_RISCV_GNU_VTINHERIT", /* name */
  564. false, /* partial_inplace */
  565. 0, /* src_mask */
  566. 0, /* dst_mask */
  567. false), /* pcrel_offset */
  568. /* GNU extension to record C++ vtable member usage */
  569. HOWTO (R_RISCV_GNU_VTENTRY, /* type */
  570. 0, /* rightshift */
  571. 4, /* size */
  572. 0, /* bitsize */
  573. false, /* pc_relative */
  574. 0, /* bitpos */
  575. complain_overflow_dont, /* complain_on_overflow */
  576. _bfd_elf_rel_vtable_reloc_fn, /* special_function */
  577. "R_RISCV_GNU_VTENTRY", /* name */
  578. false, /* partial_inplace */
  579. 0, /* src_mask */
  580. 0, /* dst_mask */
  581. false), /* pcrel_offset */
  582. /* Indicates an alignment statement. The addend field encodes how many
  583. bytes of NOPs follow the statement. The desired alignment is the
  584. addend rounded up to the next power of two. */
  585. HOWTO (R_RISCV_ALIGN, /* type */
  586. 0, /* rightshift */
  587. 3, /* size */
  588. 0, /* bitsize */
  589. false, /* pc_relative */
  590. 0, /* bitpos */
  591. complain_overflow_dont, /* complain_on_overflow */
  592. bfd_elf_generic_reloc, /* special_function */
  593. "R_RISCV_ALIGN", /* name */
  594. false, /* partial_inplace */
  595. 0, /* src_mask */
  596. 0, /* dst_mask */
  597. false), /* pcrel_offset */
  598. /* 8-bit PC-relative branch offset. */
  599. HOWTO (R_RISCV_RVC_BRANCH, /* type */
  600. 0, /* rightshift */
  601. 1, /* size */
  602. 16, /* bitsize */
  603. true, /* pc_relative */
  604. 0, /* bitpos */
  605. complain_overflow_signed, /* complain_on_overflow */
  606. bfd_elf_generic_reloc, /* special_function */
  607. "R_RISCV_RVC_BRANCH", /* name */
  608. false, /* partial_inplace */
  609. 0, /* src_mask */
  610. ENCODE_CBTYPE_IMM (-1U), /* dst_mask */
  611. true), /* pcrel_offset */
  612. /* 11-bit PC-relative jump offset. */
  613. HOWTO (R_RISCV_RVC_JUMP, /* type */
  614. 0, /* rightshift */
  615. 1, /* size */
  616. 16, /* bitsize */
  617. true, /* pc_relative */
  618. 0, /* bitpos */
  619. complain_overflow_dont, /* complain_on_overflow */
  620. bfd_elf_generic_reloc, /* special_function */
  621. "R_RISCV_RVC_JUMP", /* name */
  622. false, /* partial_inplace */
  623. 0, /* src_mask */
  624. ENCODE_CJTYPE_IMM (-1U), /* dst_mask */
  625. true), /* pcrel_offset */
  626. /* High 6 bits of 18-bit absolute address. */
  627. HOWTO (R_RISCV_RVC_LUI, /* type */
  628. 0, /* rightshift */
  629. 1, /* size */
  630. 16, /* bitsize */
  631. false, /* pc_relative */
  632. 0, /* bitpos */
  633. complain_overflow_dont, /* complain_on_overflow */
  634. bfd_elf_generic_reloc, /* special_function */
  635. "R_RISCV_RVC_LUI", /* name */
  636. false, /* partial_inplace */
  637. 0, /* src_mask */
  638. ENCODE_CITYPE_IMM (-1U), /* dst_mask */
  639. false), /* pcrel_offset */
  640. /* GP-relative load. */
  641. HOWTO (R_RISCV_GPREL_I, /* type */
  642. 0, /* rightshift */
  643. 2, /* size */
  644. 32, /* bitsize */
  645. false, /* pc_relative */
  646. 0, /* bitpos */
  647. complain_overflow_dont, /* complain_on_overflow */
  648. bfd_elf_generic_reloc, /* special_function */
  649. "R_RISCV_GPREL_I", /* name */
  650. false, /* partial_inplace */
  651. 0, /* src_mask */
  652. ENCODE_ITYPE_IMM (-1U), /* dst_mask */
  653. false), /* pcrel_offset */
  654. /* GP-relative store. */
  655. HOWTO (R_RISCV_GPREL_S, /* type */
  656. 0, /* rightshift */
  657. 2, /* size */
  658. 32, /* bitsize */
  659. false, /* pc_relative */
  660. 0, /* bitpos */
  661. complain_overflow_dont, /* complain_on_overflow */
  662. bfd_elf_generic_reloc, /* special_function */
  663. "R_RISCV_GPREL_S", /* name */
  664. false, /* partial_inplace */
  665. 0, /* src_mask */
  666. ENCODE_STYPE_IMM (-1U), /* dst_mask */
  667. false), /* pcrel_offset */
  668. /* TP-relative TLS LE load. */
  669. HOWTO (R_RISCV_TPREL_I, /* type */
  670. 0, /* rightshift */
  671. 2, /* size */
  672. 32, /* bitsize */
  673. false, /* pc_relative */
  674. 0, /* bitpos */
  675. complain_overflow_signed, /* complain_on_overflow */
  676. bfd_elf_generic_reloc, /* special_function */
  677. "R_RISCV_TPREL_I", /* name */
  678. false, /* partial_inplace */
  679. 0, /* src_mask */
  680. ENCODE_ITYPE_IMM (-1U), /* dst_mask */
  681. false), /* pcrel_offset */
  682. /* TP-relative TLS LE store. */
  683. HOWTO (R_RISCV_TPREL_S, /* type */
  684. 0, /* rightshift */
  685. 2, /* size */
  686. 32, /* bitsize */
  687. false, /* pc_relative */
  688. 0, /* bitpos */
  689. complain_overflow_signed, /* complain_on_overflow */
  690. bfd_elf_generic_reloc, /* special_function */
  691. "R_RISCV_TPREL_S", /* name */
  692. false, /* partial_inplace */
  693. 0, /* src_mask */
  694. ENCODE_STYPE_IMM (-1U), /* dst_mask */
  695. false), /* pcrel_offset */
  696. /* The paired relocation may be relaxed. */
  697. HOWTO (R_RISCV_RELAX, /* type */
  698. 0, /* rightshift */
  699. 3, /* size */
  700. 0, /* bitsize */
  701. false, /* pc_relative */
  702. 0, /* bitpos */
  703. complain_overflow_dont, /* complain_on_overflow */
  704. bfd_elf_generic_reloc, /* special_function */
  705. "R_RISCV_RELAX", /* name */
  706. false, /* partial_inplace */
  707. 0, /* src_mask */
  708. 0, /* dst_mask */
  709. false), /* pcrel_offset */
  710. /* 6-bit in-place addition, for local label subtraction. */
  711. HOWTO (R_RISCV_SUB6, /* type */
  712. 0, /* rightshift */
  713. 0, /* size */
  714. 8, /* bitsize */
  715. false, /* pc_relative */
  716. 0, /* bitpos */
  717. complain_overflow_dont, /* complain_on_overflow */
  718. riscv_elf_add_sub_reloc, /* special_function */
  719. "R_RISCV_SUB6", /* name */
  720. false, /* partial_inplace */
  721. 0, /* src_mask */
  722. 0x3f, /* dst_mask */
  723. false), /* pcrel_offset */
  724. /* 6-bit in-place setting, for local label subtraction. */
  725. HOWTO (R_RISCV_SET6, /* type */
  726. 0, /* rightshift */
  727. 0, /* size */
  728. 8, /* bitsize */
  729. false, /* pc_relative */
  730. 0, /* bitpos */
  731. complain_overflow_dont, /* complain_on_overflow */
  732. bfd_elf_generic_reloc, /* special_function */
  733. "R_RISCV_SET6", /* name */
  734. false, /* partial_inplace */
  735. 0, /* src_mask */
  736. 0x3f, /* dst_mask */
  737. false), /* pcrel_offset */
  738. /* 8-bit in-place setting, for local label subtraction. */
  739. HOWTO (R_RISCV_SET8, /* type */
  740. 0, /* rightshift */
  741. 0, /* size */
  742. 8, /* bitsize */
  743. false, /* pc_relative */
  744. 0, /* bitpos */
  745. complain_overflow_dont, /* complain_on_overflow */
  746. bfd_elf_generic_reloc, /* special_function */
  747. "R_RISCV_SET8", /* name */
  748. false, /* partial_inplace */
  749. 0, /* src_mask */
  750. 0xff, /* dst_mask */
  751. false), /* pcrel_offset */
  752. /* 16-bit in-place setting, for local label subtraction. */
  753. HOWTO (R_RISCV_SET16, /* type */
  754. 0, /* rightshift */
  755. 1, /* size */
  756. 16, /* bitsize */
  757. false, /* pc_relative */
  758. 0, /* bitpos */
  759. complain_overflow_dont, /* complain_on_overflow */
  760. bfd_elf_generic_reloc, /* special_function */
  761. "R_RISCV_SET16", /* name */
  762. false, /* partial_inplace */
  763. 0, /* src_mask */
  764. 0xffff, /* dst_mask */
  765. false), /* pcrel_offset */
  766. /* 32-bit in-place setting, for local label subtraction. */
  767. HOWTO (R_RISCV_SET32, /* type */
  768. 0, /* rightshift */
  769. 2, /* size */
  770. 32, /* bitsize */
  771. false, /* pc_relative */
  772. 0, /* bitpos */
  773. complain_overflow_dont, /* complain_on_overflow */
  774. bfd_elf_generic_reloc, /* special_function */
  775. "R_RISCV_SET32", /* name */
  776. false, /* partial_inplace */
  777. 0, /* src_mask */
  778. 0xffffffff, /* dst_mask */
  779. false), /* pcrel_offset */
  780. /* 32-bit PC relative. */
  781. HOWTO (R_RISCV_32_PCREL, /* type */
  782. 0, /* rightshift */
  783. 2, /* size */
  784. 32, /* bitsize */
  785. true, /* pc_relative */
  786. 0, /* bitpos */
  787. complain_overflow_dont, /* complain_on_overflow */
  788. bfd_elf_generic_reloc, /* special_function */
  789. "R_RISCV_32_PCREL", /* name */
  790. false, /* partial_inplace */
  791. 0, /* src_mask */
  792. 0xffffffff, /* dst_mask */
  793. false), /* pcrel_offset */
  794. /* Relocation against a local ifunc symbol in a shared object. */
  795. HOWTO (R_RISCV_IRELATIVE, /* type */
  796. 0, /* rightshift */
  797. 2, /* size */
  798. 32, /* bitsize */
  799. false, /* pc_relative */
  800. 0, /* bitpos */
  801. complain_overflow_dont, /* complain_on_overflow */
  802. bfd_elf_generic_reloc, /* special_function */
  803. "R_RISCV_IRELATIVE", /* name */
  804. false, /* partial_inplace */
  805. 0, /* src_mask */
  806. 0xffffffff, /* dst_mask */
  807. false), /* pcrel_offset */
  808. };
  809. /* A mapping from BFD reloc types to RISC-V ELF reloc types. */
  810. struct elf_reloc_map
  811. {
  812. bfd_reloc_code_real_type bfd_val;
  813. enum elf_riscv_reloc_type elf_val;
  814. };
  815. static const struct elf_reloc_map riscv_reloc_map[] =
  816. {
  817. { BFD_RELOC_NONE, R_RISCV_NONE },
  818. { BFD_RELOC_32, R_RISCV_32 },
  819. { BFD_RELOC_64, R_RISCV_64 },
  820. { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
  821. { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
  822. { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
  823. { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
  824. { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
  825. { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
  826. { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
  827. { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
  828. { BFD_RELOC_CTOR, R_RISCV_64 },
  829. { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
  830. { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
  831. { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
  832. { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
  833. { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
  834. { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
  835. { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
  836. { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
  837. { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
  838. { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
  839. { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
  840. { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
  841. { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
  842. { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
  843. { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
  844. { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
  845. { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
  846. { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
  847. { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
  848. { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
  849. { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
  850. { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
  851. { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
  852. { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
  853. { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
  854. { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
  855. { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
  856. { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
  857. { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
  858. { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
  859. { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
  860. { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
  861. { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
  862. { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
  863. { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
  864. { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
  865. { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
  866. { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
  867. };
  868. /* Given a BFD reloc type, return a howto structure. */
  869. reloc_howto_type *
  870. riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
  871. bfd_reloc_code_real_type code)
  872. {
  873. unsigned int i;
  874. for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
  875. if (riscv_reloc_map[i].bfd_val == code)
  876. return &howto_table[(int) riscv_reloc_map[i].elf_val];
  877. bfd_set_error (bfd_error_bad_value);
  878. return NULL;
  879. }
  880. reloc_howto_type *
  881. riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
  882. {
  883. unsigned int i;
  884. for (i = 0; i < ARRAY_SIZE (howto_table); i++)
  885. if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
  886. return &howto_table[i];
  887. return NULL;
  888. }
  889. reloc_howto_type *
  890. riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
  891. {
  892. if (r_type >= ARRAY_SIZE (howto_table))
  893. {
  894. (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
  895. abfd, r_type);
  896. bfd_set_error (bfd_error_bad_value);
  897. return NULL;
  898. }
  899. return &howto_table[r_type];
  900. }
  901. /* Special_function of RISCV_ADD and RISCV_SUB relocations. */
  902. static bfd_reloc_status_type
  903. riscv_elf_add_sub_reloc (bfd *abfd,
  904. arelent *reloc_entry,
  905. asymbol *symbol,
  906. void *data,
  907. asection *input_section,
  908. bfd *output_bfd,
  909. char **error_message ATTRIBUTE_UNUSED)
  910. {
  911. reloc_howto_type *howto = reloc_entry->howto;
  912. bfd_vma relocation;
  913. if (output_bfd != NULL
  914. && (symbol->flags & BSF_SECTION_SYM) == 0
  915. && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
  916. {
  917. reloc_entry->address += input_section->output_offset;
  918. return bfd_reloc_ok;
  919. }
  920. if (output_bfd != NULL)
  921. return bfd_reloc_continue;
  922. relocation = symbol->value + symbol->section->output_section->vma
  923. + symbol->section->output_offset + reloc_entry->addend;
  924. bfd_size_type octets = reloc_entry->address
  925. * bfd_octets_per_byte (abfd, input_section);
  926. if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
  927. input_section, octets))
  928. return bfd_reloc_outofrange;
  929. bfd_vma old_value = bfd_get (howto->bitsize, abfd,
  930. data + reloc_entry->address);
  931. switch (howto->type)
  932. {
  933. case R_RISCV_ADD8:
  934. case R_RISCV_ADD16:
  935. case R_RISCV_ADD32:
  936. case R_RISCV_ADD64:
  937. relocation = old_value + relocation;
  938. break;
  939. case R_RISCV_SUB6:
  940. case R_RISCV_SUB8:
  941. case R_RISCV_SUB16:
  942. case R_RISCV_SUB32:
  943. case R_RISCV_SUB64:
  944. relocation = old_value - relocation;
  945. break;
  946. }
  947. bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
  948. return bfd_reloc_ok;
  949. }
  950. /* Always add the IMPLICIT for the SUBSET. */
  951. static bool
  952. check_implicit_always (const char *implicit ATTRIBUTE_UNUSED,
  953. riscv_subset_t *subset ATTRIBUTE_UNUSED)
  954. {
  955. return true;
  956. }
  957. /* Add the IMPLICIT only when the version of SUBSET less than 2.1. */
  958. static bool
  959. check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED,
  960. riscv_subset_t *subset)
  961. {
  962. return (subset->major_version < 2
  963. || (subset->major_version == 2
  964. && subset->minor_version < 1));
  965. }
  966. /* Record all implicit information for the subsets. */
  967. struct riscv_implicit_subset
  968. {
  969. const char *subset_name;
  970. const char *implicit_name;
  971. /* A function to determine if we need to add the implicit subset. */
  972. bool (*check_func) (const char *, riscv_subset_t *);
  973. };
  974. static struct riscv_implicit_subset riscv_implicit_subsets[] =
  975. {
  976. {"e", "i", check_implicit_always},
  977. {"i", "zicsr", check_implicit_for_i},
  978. {"i", "zifencei", check_implicit_for_i},
  979. {"g", "i", check_implicit_always},
  980. {"g", "m", check_implicit_always},
  981. {"g", "a", check_implicit_always},
  982. {"g", "f", check_implicit_always},
  983. {"g", "d", check_implicit_always},
  984. {"g", "zicsr", check_implicit_always},
  985. {"g", "zifencei", check_implicit_always},
  986. {"q", "d", check_implicit_always},
  987. {"v", "d", check_implicit_always},
  988. {"v", "zve64d", check_implicit_always},
  989. {"v", "zvl128b", check_implicit_always},
  990. {"zve64d", "d", check_implicit_always},
  991. {"zve64d", "zve64f", check_implicit_always},
  992. {"zve64f", "zve32f", check_implicit_always},
  993. {"zve64f", "zve64x", check_implicit_always},
  994. {"zve64f", "zvl64b", check_implicit_always},
  995. {"zve32f", "f", check_implicit_always},
  996. {"zve32f", "zvl32b", check_implicit_always},
  997. {"zve32f", "zve32x", check_implicit_always},
  998. {"zve64x", "zve32x", check_implicit_always},
  999. {"zve64x", "zvl64b", check_implicit_always},
  1000. {"zve32x", "zvl32b", check_implicit_always},
  1001. {"zvl65536b", "zvl32768b", check_implicit_always},
  1002. {"zvl32768b", "zvl16384b", check_implicit_always},
  1003. {"zvl16384b", "zvl8192b", check_implicit_always},
  1004. {"zvl8192b", "zvl4096b", check_implicit_always},
  1005. {"zvl4096b", "zvl2048b", check_implicit_always},
  1006. {"zvl2048b", "zvl1024b", check_implicit_always},
  1007. {"zvl1024b", "zvl512b", check_implicit_always},
  1008. {"zvl512b", "zvl256b", check_implicit_always},
  1009. {"zvl256b", "zvl128b", check_implicit_always},
  1010. {"zvl128b", "zvl64b", check_implicit_always},
  1011. {"zvl64b", "zvl32b", check_implicit_always},
  1012. {"d", "f", check_implicit_always},
  1013. {"f", "zicsr", check_implicit_always},
  1014. {"zqinx", "zdinx", check_implicit_always},
  1015. {"zdinx", "zfinx", check_implicit_always},
  1016. {"zk", "zkn", check_implicit_always},
  1017. {"zk", "zkr", check_implicit_always},
  1018. {"zk", "zkt", check_implicit_always},
  1019. {"zkn", "zbkb", check_implicit_always},
  1020. {"zkn", "zbkc", check_implicit_always},
  1021. {"zkn", "zbkx", check_implicit_always},
  1022. {"zkn", "zkne", check_implicit_always},
  1023. {"zkn", "zknd", check_implicit_always},
  1024. {"zkn", "zknh", check_implicit_always},
  1025. {"zks", "zbkb", check_implicit_always},
  1026. {"zks", "zbkc", check_implicit_always},
  1027. {"zks", "zbkx", check_implicit_always},
  1028. {"zks", "zksed", check_implicit_always},
  1029. {"zks", "zksh", check_implicit_always},
  1030. {NULL, NULL, NULL}
  1031. };
  1032. /* For default_enable field, decide if the extension should
  1033. be enbaled by default. */
  1034. #define EXT_DEFAULT 0x1
  1035. /* List all extensions that binutils should know about. */
  1036. struct riscv_supported_ext
  1037. {
  1038. const char *name;
  1039. enum riscv_spec_class isa_spec_class;
  1040. int major_version;
  1041. int minor_version;
  1042. unsigned long default_enable;
  1043. };
  1044. /* The standard extensions must be added in canonical order. */
  1045. static struct riscv_supported_ext riscv_supported_std_ext[] =
  1046. {
  1047. {"e", ISA_SPEC_CLASS_20191213, 1, 9, 0 },
  1048. {"e", ISA_SPEC_CLASS_20190608, 1, 9, 0 },
  1049. {"e", ISA_SPEC_CLASS_2P2, 1, 9, 0 },
  1050. {"i", ISA_SPEC_CLASS_20191213, 2, 1, 0 },
  1051. {"i", ISA_SPEC_CLASS_20190608, 2, 1, 0 },
  1052. {"i", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1053. /* The g is a special case which we don't want to output it,
  1054. but still need it when adding implicit extensions. */
  1055. {"g", ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
  1056. {"m", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
  1057. {"m", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
  1058. {"m", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1059. {"a", ISA_SPEC_CLASS_20191213, 2, 1, 0 },
  1060. {"a", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
  1061. {"a", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1062. {"f", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
  1063. {"f", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
  1064. {"f", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1065. {"d", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
  1066. {"d", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
  1067. {"d", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1068. {"q", ISA_SPEC_CLASS_20191213, 2, 2, 0 },
  1069. {"q", ISA_SPEC_CLASS_20190608, 2, 2, 0 },
  1070. {"q", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1071. {"c", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
  1072. {"c", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
  1073. {"c", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
  1074. {"v", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1075. {NULL, 0, 0, 0, 0}
  1076. };
  1077. static struct riscv_supported_ext riscv_supported_std_z_ext[] =
  1078. {
  1079. {"zicbom", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1080. {"zicbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1081. {"zicboz", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1082. {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
  1083. {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
  1084. {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
  1085. {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
  1086. {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1087. {"zfinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1088. {"zdinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1089. {"zqinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1090. {"zbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1091. {"zba", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1092. {"zbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1093. {"zbs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1094. {"zbkb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1095. {"zbkc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1096. {"zbkx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1097. {"zk", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1098. {"zkn", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1099. {"zknd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1100. {"zkne", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1101. {"zknh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1102. {"zkr", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1103. {"zks", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1104. {"zksed", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1105. {"zksh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1106. {"zkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1107. {"zve32x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1108. {"zve32f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1109. {"zve32d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1110. {"zve64x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1111. {"zve64f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1112. {"zve64d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1113. {"zvl32b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1114. {"zvl64b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1115. {"zvl128b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1116. {"zvl256b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1117. {"zvl512b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1118. {"zvl1024b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1119. {"zvl2048b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1120. {"zvl4096b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1121. {"zvl8192b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1122. {"zvl16384b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1123. {"zvl32768b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1124. {"zvl65536b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1125. {NULL, 0, 0, 0, 0}
  1126. };
  1127. static struct riscv_supported_ext riscv_supported_std_s_ext[] =
  1128. {
  1129. {"svinval", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
  1130. {NULL, 0, 0, 0, 0}
  1131. };
  1132. static struct riscv_supported_ext riscv_supported_std_h_ext[] =
  1133. {
  1134. {NULL, 0, 0, 0, 0}
  1135. };
  1136. static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
  1137. {
  1138. {NULL, 0, 0, 0, 0}
  1139. };
  1140. const struct riscv_supported_ext *riscv_all_supported_ext[] =
  1141. {
  1142. riscv_supported_std_ext,
  1143. riscv_supported_std_z_ext,
  1144. riscv_supported_std_s_ext,
  1145. riscv_supported_std_h_ext,
  1146. riscv_supported_std_zxm_ext,
  1147. NULL
  1148. };
  1149. /* ISA extension prefixed name class. Must define them in parsing order. */
  1150. enum riscv_prefix_ext_class
  1151. {
  1152. RV_ISA_CLASS_Z = 1,
  1153. RV_ISA_CLASS_S,
  1154. RV_ISA_CLASS_H,
  1155. RV_ISA_CLASS_ZXM,
  1156. RV_ISA_CLASS_X,
  1157. RV_ISA_CLASS_UNKNOWN
  1158. };
  1159. /* Record the strings of the prefixed extensions, and their corresponding
  1160. classes. The more letters of the prefix string, the more forward it must
  1161. be defined. Otherwise, the riscv_get_prefix_class will map it to the
  1162. wrong classes. */
  1163. struct riscv_parse_prefix_config
  1164. {
  1165. /* Class of the extension. */
  1166. enum riscv_prefix_ext_class class;
  1167. /* Prefix string for error printing and internal parser usage. */
  1168. const char *prefix;
  1169. };
  1170. static const struct riscv_parse_prefix_config parse_config[] =
  1171. {
  1172. {RV_ISA_CLASS_ZXM, "zxm"},
  1173. {RV_ISA_CLASS_Z, "z"},
  1174. {RV_ISA_CLASS_S, "s"},
  1175. {RV_ISA_CLASS_H, "h"},
  1176. {RV_ISA_CLASS_X, "x"},
  1177. {RV_ISA_CLASS_UNKNOWN, NULL}
  1178. };
  1179. /* Get the prefixed name class for the extensions, the class also
  1180. means the order of the prefixed extensions. */
  1181. static enum riscv_prefix_ext_class
  1182. riscv_get_prefix_class (const char *arch)
  1183. {
  1184. int i = 0;
  1185. while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN)
  1186. {
  1187. if (strncmp (arch, parse_config[i].prefix,
  1188. strlen (parse_config[i].prefix)) == 0)
  1189. return parse_config[i].class;
  1190. i++;
  1191. }
  1192. return RV_ISA_CLASS_UNKNOWN;
  1193. }
  1194. /* Check KNOWN_EXTS to see if the EXT is supported. */
  1195. static bool
  1196. riscv_known_prefixed_ext (const char *ext,
  1197. struct riscv_supported_ext *known_exts)
  1198. {
  1199. size_t i;
  1200. for (i = 0; known_exts[i].name != NULL; ++i)
  1201. if (strcmp (ext, known_exts[i].name) == 0)
  1202. return true;
  1203. return false;
  1204. }
  1205. /* Check whether the prefixed extension is recognized or not. Return
  1206. true if recognized, otehrwise return false. */
  1207. static bool
  1208. riscv_recognized_prefixed_ext (const char *ext)
  1209. {
  1210. enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext);
  1211. switch (class)
  1212. {
  1213. case RV_ISA_CLASS_Z:
  1214. return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext);
  1215. case RV_ISA_CLASS_ZXM:
  1216. return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
  1217. case RV_ISA_CLASS_S:
  1218. return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
  1219. case RV_ISA_CLASS_H:
  1220. return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext);
  1221. case RV_ISA_CLASS_X:
  1222. /* Only the single x is unrecognized. */
  1223. if (strcmp (ext, "x") != 0)
  1224. return true;
  1225. default:
  1226. break;
  1227. }
  1228. return false;
  1229. }
  1230. /* Canonical order for single letter extensions. */
  1231. static const char riscv_ext_canonical_order[] = "eigmafdqlcbjktpvn";
  1232. /* Array is used to compare the orders of standard extensions quickly. */
  1233. static int riscv_ext_order[26] = {0};
  1234. /* Init the riscv_ext_order array. */
  1235. static void
  1236. riscv_init_ext_order (void)
  1237. {
  1238. static bool inited = false;
  1239. if (inited)
  1240. return;
  1241. /* The orders of all standard extensions are positive. */
  1242. int order = 1;
  1243. for (const char *ext = &riscv_ext_canonical_order[0]; *ext; ++ext)
  1244. riscv_ext_order[(*ext - 'a')] = order++;
  1245. /* Some of the prefixed keyword are not single letter, so we set
  1246. their prefixed orders in the riscv_compare_subsets directly,
  1247. not through the riscv_ext_order. */
  1248. inited = true;
  1249. }
  1250. /* Similar to the strcmp. It returns an integer less than, equal to,
  1251. or greater than zero if `subset2` is found, respectively, to be less
  1252. than, to match, or be greater than `subset1`.
  1253. The order values,
  1254. Zero: Preserved keywords.
  1255. Positive number: Standard extensions.
  1256. Negative number: Prefixed keywords. */
  1257. int
  1258. riscv_compare_subsets (const char *subset1, const char *subset2)
  1259. {
  1260. int order1 = riscv_ext_order[(*subset1 - 'a')];
  1261. int order2 = riscv_ext_order[(*subset2 - 'a')];
  1262. /* Compare the standard extension first. */
  1263. if (order1 > 0 && order2 > 0)
  1264. return order1 - order2;
  1265. /* Set the prefixed orders to negative numbers. */
  1266. enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1);
  1267. enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2);
  1268. if (class1 != RV_ISA_CLASS_UNKNOWN)
  1269. order1 = - (int) class1;
  1270. if (class2 != RV_ISA_CLASS_UNKNOWN)
  1271. order2 = - (int) class2;
  1272. if (order1 == order2)
  1273. {
  1274. /* Compare the standard addition z extensions. */
  1275. if (class1 == RV_ISA_CLASS_Z)
  1276. {
  1277. order1 = riscv_ext_order[(*++subset1 - 'a')];
  1278. order2 = riscv_ext_order[(*++subset2 - 'a')];
  1279. if (order1 != order2)
  1280. return order1 - order2;
  1281. }
  1282. return strcasecmp (++subset1, ++subset2);
  1283. }
  1284. return order2 - order1;
  1285. }
  1286. /* Find subset in the list. Return TRUE and set `current` to the subset
  1287. if it is found. Otherwise, return FALSE and set `current` to the place
  1288. where we should insert the subset. However, return FALSE with the NULL
  1289. `current` means we should insert the subset at the head of subset list,
  1290. if needed. */
  1291. bool
  1292. riscv_lookup_subset (const riscv_subset_list_t *subset_list,
  1293. const char *subset,
  1294. riscv_subset_t **current)
  1295. {
  1296. riscv_subset_t *s, *pre_s = NULL;
  1297. /* If the subset is added in order, then just add it at the tail. */
  1298. if (subset_list->tail != NULL
  1299. && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
  1300. {
  1301. *current = subset_list->tail;
  1302. return false;
  1303. }
  1304. for (s = subset_list->head;
  1305. s != NULL;
  1306. pre_s = s, s = s->next)
  1307. {
  1308. int cmp = riscv_compare_subsets (s->name, subset);
  1309. if (cmp == 0)
  1310. {
  1311. *current = s;
  1312. return true;
  1313. }
  1314. else if (cmp > 0)
  1315. break;
  1316. }
  1317. *current = pre_s;
  1318. return false;
  1319. }
  1320. /* Add the extension to the subset list. Search the
  1321. list first, and then find the right place to add. */
  1322. void
  1323. riscv_add_subset (riscv_subset_list_t *subset_list,
  1324. const char *subset,
  1325. int major,
  1326. int minor)
  1327. {
  1328. riscv_subset_t *current, *new;
  1329. if (riscv_lookup_subset (subset_list, subset, &current))
  1330. return;
  1331. new = xmalloc (sizeof *new);
  1332. new->name = xstrdup (subset);
  1333. new->major_version = major;
  1334. new->minor_version = minor;
  1335. new->next = NULL;
  1336. if (current != NULL)
  1337. {
  1338. new->next = current->next;
  1339. current->next = new;
  1340. }
  1341. else
  1342. {
  1343. new->next = subset_list->head;
  1344. subset_list->head = new;
  1345. }
  1346. if (new->next == NULL)
  1347. subset_list->tail = new;
  1348. }
  1349. /* Get the default versions from the riscv_supported_*ext tables. */
  1350. static void
  1351. riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
  1352. const char *name,
  1353. int *major_version,
  1354. int *minor_version)
  1355. {
  1356. if (name == NULL
  1357. || default_isa_spec == NULL
  1358. || *default_isa_spec == ISA_SPEC_CLASS_NONE)
  1359. return;
  1360. struct riscv_supported_ext *table = NULL;
  1361. enum riscv_prefix_ext_class class = riscv_get_prefix_class (name);
  1362. switch (class)
  1363. {
  1364. case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
  1365. case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
  1366. case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
  1367. case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break;
  1368. case RV_ISA_CLASS_X:
  1369. break;
  1370. default:
  1371. table = riscv_supported_std_ext;
  1372. }
  1373. int i = 0;
  1374. while (table != NULL && table[i].name != NULL)
  1375. {
  1376. if (strcmp (table[i].name, name) == 0
  1377. && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
  1378. || table[i].isa_spec_class == *default_isa_spec))
  1379. {
  1380. *major_version = table[i].major_version;
  1381. *minor_version = table[i].minor_version;
  1382. return;
  1383. }
  1384. i++;
  1385. }
  1386. }
  1387. /* Find the default versions for the extension before adding them to
  1388. the subset list, if their versions are RISCV_UNKNOWN_VERSION.
  1389. Afterwards, report errors if we can not find their default versions. */
  1390. static void
  1391. riscv_parse_add_subset (riscv_parse_subset_t *rps,
  1392. const char *subset,
  1393. int major,
  1394. int minor,
  1395. bool implicit)
  1396. {
  1397. int major_version = major;
  1398. int minor_version = minor;
  1399. if (major_version == RISCV_UNKNOWN_VERSION
  1400. || minor_version == RISCV_UNKNOWN_VERSION)
  1401. riscv_get_default_ext_version (rps->isa_spec, subset,
  1402. &major_version, &minor_version);
  1403. /* We don't care the versions of the implicit extensions. */
  1404. if (!implicit
  1405. && (major_version == RISCV_UNKNOWN_VERSION
  1406. || minor_version == RISCV_UNKNOWN_VERSION))
  1407. {
  1408. if (subset[0] == 'x')
  1409. rps->error_handler
  1410. (_("x ISA extension `%s' must be set with the versions"),
  1411. subset);
  1412. /* Allow old ISA spec can recognize zicsr and zifencei. */
  1413. else if (strcmp (subset, "zicsr") != 0
  1414. && strcmp (subset, "zifencei") != 0)
  1415. rps->error_handler
  1416. (_("cannot find default versions of the ISA extension `%s'"),
  1417. subset);
  1418. return;
  1419. }
  1420. riscv_add_subset (rps->subset_list, subset,
  1421. major_version, minor_version);
  1422. }
  1423. /* Release subset list. */
  1424. void
  1425. riscv_release_subset_list (riscv_subset_list_t *subset_list)
  1426. {
  1427. while (subset_list->head != NULL)
  1428. {
  1429. riscv_subset_t *next = subset_list->head->next;
  1430. free ((void *)subset_list->head->name);
  1431. free (subset_list->head);
  1432. subset_list->head = next;
  1433. }
  1434. subset_list->tail = NULL;
  1435. }
  1436. /* Parsing extension version.
  1437. Return Value:
  1438. Points to the end of version
  1439. Arguments:
  1440. `p`: Curent parsing position.
  1441. `major_version`: Parsed major version.
  1442. `minor_version`: Parsed minor version. */
  1443. static const char *
  1444. riscv_parsing_subset_version (const char *p,
  1445. int *major_version,
  1446. int *minor_version)
  1447. {
  1448. bool major_p = true;
  1449. int version = 0;
  1450. char np;
  1451. *major_version = 0;
  1452. *minor_version = 0;
  1453. for (; *p; ++p)
  1454. {
  1455. if (*p == 'p')
  1456. {
  1457. np = *(p + 1);
  1458. /* Might be beginning of `p` extension. */
  1459. if (!ISDIGIT (np))
  1460. break;
  1461. *major_version = version;
  1462. major_p = false;
  1463. version = 0;
  1464. }
  1465. else if (ISDIGIT (*p))
  1466. version = (version * 10) + (*p - '0');
  1467. else
  1468. break;
  1469. }
  1470. if (major_p)
  1471. *major_version = version;
  1472. else
  1473. *minor_version = version;
  1474. /* We can not find any version in string. */
  1475. if (*major_version == 0 && *minor_version == 0)
  1476. {
  1477. *major_version = RISCV_UNKNOWN_VERSION;
  1478. *minor_version = RISCV_UNKNOWN_VERSION;
  1479. }
  1480. return p;
  1481. }
  1482. /* Parsing function for standard extensions.
  1483. Return Value:
  1484. Points to the end of extensions.
  1485. Arguments:
  1486. `rps`: Hooks and status for parsing extensions.
  1487. `arch`: Full ISA string.
  1488. `p`: Curent parsing position. */
  1489. static const char *
  1490. riscv_parse_std_ext (riscv_parse_subset_t *rps,
  1491. const char *arch,
  1492. const char *p)
  1493. {
  1494. /* First letter must start with i, e or g. */
  1495. if (*p != 'e' && *p != 'i' && *p != 'g')
  1496. {
  1497. rps->error_handler
  1498. (_("%s: first ISA extension must be `e', `i' or `g'"),
  1499. arch);
  1500. return NULL;
  1501. }
  1502. while (p != NULL && *p != '\0')
  1503. {
  1504. /* Stop when we parsed the known prefix class. */
  1505. enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
  1506. if (class != RV_ISA_CLASS_UNKNOWN)
  1507. break;
  1508. if (*p == '_')
  1509. {
  1510. p++;
  1511. continue;
  1512. }
  1513. bool implicit = false;
  1514. int major = RISCV_UNKNOWN_VERSION;
  1515. int minor = RISCV_UNKNOWN_VERSION;
  1516. char subset[2] = {0, 0};
  1517. subset[0] = *p;
  1518. /* Check if the standard extension is supported. */
  1519. if (riscv_ext_order[(subset[0] - 'a')] == 0)
  1520. {
  1521. rps->error_handler
  1522. (_("%s: unknown standard ISA extension `%c'"),
  1523. arch, subset[0]);
  1524. return NULL;
  1525. }
  1526. /* Checking canonical order. */
  1527. if (rps->subset_list->tail != NULL
  1528. && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
  1529. {
  1530. rps->error_handler
  1531. (_("%s: standard ISA extension `%c' is not "
  1532. "in canonical order"), arch, subset[0]);
  1533. return NULL;
  1534. }
  1535. p = riscv_parsing_subset_version (++p, &major, &minor);
  1536. /* Added g as an implicit extension. */
  1537. if (subset[0] == 'g')
  1538. {
  1539. implicit = true;
  1540. major = RISCV_UNKNOWN_VERSION;
  1541. minor = RISCV_UNKNOWN_VERSION;
  1542. }
  1543. riscv_parse_add_subset (rps, subset, major, minor, implicit);
  1544. }
  1545. return p;
  1546. }
  1547. /* Parsing function for prefixed extensions.
  1548. Return Value:
  1549. Points to the end of extension.
  1550. Arguments:
  1551. `rps`: Hooks and status for parsing extensions.
  1552. `arch`: Full ISA string.
  1553. `p`: Curent parsing position. */
  1554. static const char *
  1555. riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
  1556. const char *arch,
  1557. const char *p)
  1558. {
  1559. int major_version;
  1560. int minor_version;
  1561. const char *last_name;
  1562. enum riscv_prefix_ext_class class;
  1563. while (*p)
  1564. {
  1565. if (*p == '_')
  1566. {
  1567. p++;
  1568. continue;
  1569. }
  1570. class = riscv_get_prefix_class (p);
  1571. if (class == RV_ISA_CLASS_UNKNOWN)
  1572. {
  1573. rps->error_handler
  1574. (_("%s: unknown prefix class for the ISA extension `%s'"),
  1575. arch, p);
  1576. return NULL;
  1577. }
  1578. char *subset = xstrdup (p);
  1579. char *q = subset;
  1580. const char *end_of_version;
  1581. /* Extract the whole prefixed extension by '_'. */
  1582. while (*++q != '\0' && *q != '_')
  1583. ;
  1584. /* Look forward to the first letter which is not <major>p<minor>. */
  1585. bool find_any_version = false;
  1586. bool find_minor_version = false;
  1587. while (1)
  1588. {
  1589. q--;
  1590. if (ISDIGIT (*q))
  1591. find_any_version = true;
  1592. else if (find_any_version
  1593. && !find_minor_version
  1594. && *q == 'p'
  1595. && ISDIGIT (*(q - 1)))
  1596. find_minor_version = true;
  1597. else
  1598. break;
  1599. }
  1600. q++;
  1601. /* Check if the end of extension is 'p' or not. If yes, then
  1602. the second letter from the end cannot be number. */
  1603. if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
  1604. {
  1605. *q = '\0';
  1606. rps->error_handler
  1607. (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
  1608. arch, subset);
  1609. free (subset);
  1610. return NULL;
  1611. }
  1612. end_of_version =
  1613. riscv_parsing_subset_version (q, &major_version, &minor_version);
  1614. *q = '\0';
  1615. if (end_of_version == NULL)
  1616. {
  1617. free (subset);
  1618. return NULL;
  1619. }
  1620. /* Check that the extension name is well-formed. */
  1621. if (rps->check_unknown_prefixed_ext
  1622. && !riscv_recognized_prefixed_ext (subset))
  1623. {
  1624. rps->error_handler
  1625. (_("%s: unknown prefixed ISA extension `%s'"),
  1626. arch, subset);
  1627. free (subset);
  1628. return NULL;
  1629. }
  1630. /* Check that the extension isn't duplicate. */
  1631. last_name = rps->subset_list->tail->name;
  1632. if (!strcasecmp (last_name, subset))
  1633. {
  1634. rps->error_handler
  1635. (_("%s: duplicate prefixed ISA extension `%s'"),
  1636. arch, subset);
  1637. free (subset);
  1638. return NULL;
  1639. }
  1640. /* Check that the extension is in expected order. */
  1641. if (riscv_compare_subsets (last_name, subset) > 0)
  1642. {
  1643. rps->error_handler
  1644. (_("%s: prefixed ISA extension `%s' is not in expected "
  1645. "order. It must come before `%s'"),
  1646. arch, subset, last_name);
  1647. free (subset);
  1648. return NULL;
  1649. }
  1650. riscv_parse_add_subset (rps, subset,
  1651. major_version,
  1652. minor_version, false);
  1653. p += end_of_version - subset;
  1654. free (subset);
  1655. if (*p != '\0' && *p != '_')
  1656. {
  1657. rps->error_handler
  1658. (_("%s: prefixed ISA extension must separate with _"),
  1659. arch);
  1660. return NULL;
  1661. }
  1662. }
  1663. return p;
  1664. }
  1665. /* Add the implicit extensions. */
  1666. static void
  1667. riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
  1668. {
  1669. struct riscv_implicit_subset *t = riscv_implicit_subsets;
  1670. for (; t->subset_name; t++)
  1671. {
  1672. riscv_subset_t *subset = NULL;
  1673. if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
  1674. && t->check_func (t->implicit_name, subset))
  1675. riscv_parse_add_subset (rps, t->implicit_name,
  1676. RISCV_UNKNOWN_VERSION,
  1677. RISCV_UNKNOWN_VERSION, true);
  1678. }
  1679. }
  1680. /* Check extensions conflicts. */
  1681. static bool
  1682. riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
  1683. {
  1684. riscv_subset_t *subset = NULL;
  1685. int xlen = *rps->xlen;
  1686. bool no_conflict = true;
  1687. if (riscv_lookup_subset (rps->subset_list, "e", &subset)
  1688. && xlen > 32)
  1689. {
  1690. rps->error_handler
  1691. (_("rv%d does not support the `e' extension"), xlen);
  1692. no_conflict = false;
  1693. }
  1694. if (riscv_lookup_subset (rps->subset_list, "q", &subset)
  1695. && xlen < 64)
  1696. {
  1697. rps->error_handler
  1698. (_("rv%d does not support the `q' extension"), xlen);
  1699. no_conflict = false;
  1700. }
  1701. if (riscv_lookup_subset (rps->subset_list, "e", &subset)
  1702. && riscv_lookup_subset (rps->subset_list, "f", &subset))
  1703. {
  1704. rps->error_handler
  1705. (_("rv32e does not support the `f' extension"));
  1706. no_conflict = false;
  1707. }
  1708. if (riscv_lookup_subset (rps->subset_list, "zfinx", &subset)
  1709. && riscv_lookup_subset (rps->subset_list, "f", &subset))
  1710. {
  1711. rps->error_handler
  1712. (_("`zfinx' is conflict with the `f/d/q' extension"));
  1713. no_conflict = false;
  1714. }
  1715. bool support_zve = false;
  1716. bool support_zvl = false;
  1717. riscv_subset_t *s = rps->subset_list->head;
  1718. for (; s != NULL; s = s->next)
  1719. {
  1720. if (!support_zve
  1721. && strncmp (s->name, "zve", 3) == 0)
  1722. support_zve = true;
  1723. if (!support_zvl
  1724. && strncmp (s->name, "zvl", 3) == 0)
  1725. support_zvl = true;
  1726. if (support_zve && support_zvl)
  1727. break;
  1728. }
  1729. if (support_zvl && !support_zve)
  1730. {
  1731. rps->error_handler
  1732. (_("zvl*b extensions need to enable either `v' or `zve' extension"));
  1733. no_conflict = false;
  1734. }
  1735. return no_conflict;
  1736. }
  1737. /* Set the default subset list according to the default_enable field
  1738. of riscv_supported_*ext tables. */
  1739. static void
  1740. riscv_set_default_arch (riscv_parse_subset_t *rps)
  1741. {
  1742. unsigned long enable = EXT_DEFAULT;
  1743. int i, j;
  1744. for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
  1745. {
  1746. const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
  1747. for (j = 0; table[j].name != NULL; j++)
  1748. {
  1749. bool implicit = false;
  1750. if (strcmp (table[j].name, "g") == 0)
  1751. implicit = true;
  1752. if (table[j].default_enable & enable)
  1753. riscv_parse_add_subset (rps, table[j].name,
  1754. RISCV_UNKNOWN_VERSION,
  1755. RISCV_UNKNOWN_VERSION, implicit);
  1756. }
  1757. }
  1758. }
  1759. /* Function for parsing ISA string.
  1760. Return Value:
  1761. Return TRUE on success.
  1762. Arguments:
  1763. `rps`: Hooks and status for parsing extensions.
  1764. `arch`: Full ISA string. */
  1765. bool
  1766. riscv_parse_subset (riscv_parse_subset_t *rps,
  1767. const char *arch)
  1768. {
  1769. const char *p;
  1770. /* Init the riscv_ext_order array to compare the order of extensions
  1771. quickly. */
  1772. riscv_init_ext_order ();
  1773. if (arch == NULL)
  1774. {
  1775. riscv_set_default_arch (rps);
  1776. riscv_parse_add_implicit_subsets (rps);
  1777. return riscv_parse_check_conflicts (rps);
  1778. }
  1779. for (p = arch; *p != '\0'; p++)
  1780. {
  1781. if (ISUPPER (*p))
  1782. {
  1783. rps->error_handler
  1784. (_("%s: ISA string cannot contain uppercase letters"),
  1785. arch);
  1786. return false;
  1787. }
  1788. }
  1789. p = arch;
  1790. if (startswith (p, "rv32"))
  1791. {
  1792. *rps->xlen = 32;
  1793. p += 4;
  1794. }
  1795. else if (startswith (p, "rv64"))
  1796. {
  1797. *rps->xlen = 64;
  1798. p += 4;
  1799. }
  1800. else
  1801. {
  1802. /* ISA string shouldn't be NULL or empty here. For linker,
  1803. it might be empty when we failed to merge the ISA string
  1804. in the riscv_merge_attributes. For assembler, we might
  1805. give an empty string by .attribute arch, "" or -march=.
  1806. However, We have already issued the correct error message
  1807. in another side, so do not issue this error when the ISA
  1808. string is empty. */
  1809. if (strlen (arch))
  1810. rps->error_handler (
  1811. _("%s: ISA string must begin with rv32 or rv64"),
  1812. arch);
  1813. return false;
  1814. }
  1815. /* Parsing standard extension. */
  1816. p = riscv_parse_std_ext (rps, arch, p);
  1817. if (p == NULL)
  1818. return false;
  1819. /* Parse prefixed extensions. */
  1820. p = riscv_parse_prefixed_ext (rps, arch, p);
  1821. if (p == NULL)
  1822. return false;
  1823. /* Finally add implicit extensions according to the current
  1824. extensions. */
  1825. riscv_parse_add_implicit_subsets (rps);
  1826. /* Check the conflicts. */
  1827. return riscv_parse_check_conflicts (rps);
  1828. }
  1829. /* Return the number of digits for the input. */
  1830. size_t
  1831. riscv_estimate_digit (unsigned num)
  1832. {
  1833. size_t digit = 0;
  1834. if (num == 0)
  1835. return 1;
  1836. for (digit = 0; num ; num /= 10)
  1837. digit++;
  1838. return digit;
  1839. }
  1840. /* Auxiliary function to estimate string length of subset list. */
  1841. static size_t
  1842. riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
  1843. {
  1844. if (subset == NULL)
  1845. return 6; /* For rv32/rv64/rv128 and string terminator. */
  1846. return riscv_estimate_arch_strlen1 (subset->next)
  1847. + strlen (subset->name)
  1848. + riscv_estimate_digit (subset->major_version)
  1849. + 1 /* For version seperator 'p'. */
  1850. + riscv_estimate_digit (subset->minor_version)
  1851. + 1 /* For underscore. */;
  1852. }
  1853. /* Estimate the string length of this subset list. */
  1854. static size_t
  1855. riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
  1856. {
  1857. return riscv_estimate_arch_strlen1 (subset_list->head);
  1858. }
  1859. /* Auxiliary function to convert subset info to string. */
  1860. static void
  1861. riscv_arch_str1 (riscv_subset_t *subset,
  1862. char *attr_str, char *buf, size_t bufsz)
  1863. {
  1864. const char *underline = "_";
  1865. riscv_subset_t *subset_t = subset;
  1866. if (subset_t == NULL)
  1867. return;
  1868. /* No underline between rvXX and i/e. */
  1869. if ((strcasecmp (subset_t->name, "i") == 0)
  1870. || (strcasecmp (subset_t->name, "e") == 0))
  1871. underline = "";
  1872. snprintf (buf, bufsz, "%s%s%dp%d",
  1873. underline,
  1874. subset_t->name,
  1875. subset_t->major_version,
  1876. subset_t->minor_version);
  1877. strncat (attr_str, buf, bufsz);
  1878. /* Skip 'i' extension after 'e', or skip extensions which
  1879. versions are unknown. */
  1880. while (subset_t->next
  1881. && ((strcmp (subset_t->name, "e") == 0
  1882. && strcmp (subset_t->next->name, "i") == 0)
  1883. || subset_t->next->major_version == RISCV_UNKNOWN_VERSION
  1884. || subset_t->next->minor_version == RISCV_UNKNOWN_VERSION))
  1885. subset_t = subset_t->next;
  1886. riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
  1887. }
  1888. /* Convert subset information into string with explicit versions. */
  1889. char *
  1890. riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
  1891. {
  1892. size_t arch_str_len = riscv_estimate_arch_strlen (subset);
  1893. char *attr_str = xmalloc (arch_str_len);
  1894. char *buf = xmalloc (arch_str_len);
  1895. snprintf (attr_str, arch_str_len, "rv%u", xlen);
  1896. riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
  1897. free (buf);
  1898. return attr_str;
  1899. }
  1900. /* Copy the subset in the subset list. */
  1901. static struct riscv_subset_t *
  1902. riscv_copy_subset (riscv_subset_list_t *subset_list,
  1903. riscv_subset_t *subset)
  1904. {
  1905. if (subset == NULL)
  1906. return NULL;
  1907. riscv_subset_t *new = xmalloc (sizeof *new);
  1908. new->name = xstrdup (subset->name);
  1909. new->major_version = subset->major_version;
  1910. new->minor_version = subset->minor_version;
  1911. new->next = riscv_copy_subset (subset_list, subset->next);
  1912. if (subset->next == NULL)
  1913. subset_list->tail = new;
  1914. return new;
  1915. }
  1916. /* Copy the subset list. */
  1917. riscv_subset_list_t *
  1918. riscv_copy_subset_list (riscv_subset_list_t *subset_list)
  1919. {
  1920. riscv_subset_list_t *new = xmalloc (sizeof *new);
  1921. new->head = riscv_copy_subset (new, subset_list->head);
  1922. return new;
  1923. }
  1924. /* Remove the SUBSET from the subset list. */
  1925. static void
  1926. riscv_remove_subset (riscv_subset_list_t *subset_list,
  1927. const char *subset)
  1928. {
  1929. riscv_subset_t *current = subset_list->head;
  1930. riscv_subset_t *pre = NULL;
  1931. for (; current != NULL; pre = current, current = current->next)
  1932. {
  1933. if (strcmp (current->name, subset) == 0)
  1934. {
  1935. if (pre == NULL)
  1936. subset_list->head = current->next;
  1937. else
  1938. pre->next = current->next;
  1939. if (current->next == NULL)
  1940. subset_list->tail = pre;
  1941. free ((void *) current->name);
  1942. free (current);
  1943. break;
  1944. }
  1945. }
  1946. }
  1947. /* Add/Remove an extension to/from the subset list. This is used for
  1948. the .option rvc or norvc, and .option arch directives. */
  1949. bool
  1950. riscv_update_subset (riscv_parse_subset_t *rps,
  1951. const char *str)
  1952. {
  1953. const char *p = str;
  1954. do
  1955. {
  1956. int major_version = RISCV_UNKNOWN_VERSION;
  1957. int minor_version = RISCV_UNKNOWN_VERSION;
  1958. bool removed = false;
  1959. switch (*p)
  1960. {
  1961. case '+': removed = false; break;
  1962. case '-': removed = true; break;
  1963. default:
  1964. riscv_release_subset_list (rps->subset_list);
  1965. return riscv_parse_subset (rps, p);
  1966. }
  1967. ++p;
  1968. char *subset = xstrdup (p);
  1969. char *q = subset;
  1970. const char *end_of_version;
  1971. /* Extract the whole prefixed extension by ','. */
  1972. while (*q != '\0' && *q != ',')
  1973. q++;
  1974. /* Look forward to the first letter which is not <major>p<minor>. */
  1975. bool find_any_version = false;
  1976. bool find_minor_version = false;
  1977. size_t len = q - subset;
  1978. size_t i;
  1979. for (i = len; i > 0; i--)
  1980. {
  1981. q--;
  1982. if (ISDIGIT (*q))
  1983. find_any_version = true;
  1984. else if (find_any_version
  1985. && !find_minor_version
  1986. && *q == 'p'
  1987. && ISDIGIT (*(q - 1)))
  1988. find_minor_version = true;
  1989. else
  1990. break;
  1991. }
  1992. if (len > 0)
  1993. q++;
  1994. /* Check if the end of extension is 'p' or not. If yes, then
  1995. the second letter from the end cannot be number. */
  1996. if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
  1997. {
  1998. *q = '\0';
  1999. rps->error_handler
  2000. (_("invalid ISA extension ends with <number>p "
  2001. "in .option arch `%s'"), str);
  2002. free (subset);
  2003. return false;
  2004. }
  2005. end_of_version =
  2006. riscv_parsing_subset_version (q, &major_version, &minor_version);
  2007. *q = '\0';
  2008. if (end_of_version == NULL)
  2009. {
  2010. free (subset);
  2011. return false;
  2012. }
  2013. if (strlen (subset) == 0
  2014. || (strlen (subset) == 1
  2015. && riscv_ext_order[(*subset - 'a')] == 0)
  2016. || (strlen (subset) > 1
  2017. && rps->check_unknown_prefixed_ext
  2018. && !riscv_recognized_prefixed_ext (subset)))
  2019. {
  2020. rps->error_handler
  2021. (_("unknown ISA extension `%s' in .option arch `%s'"),
  2022. subset, str);
  2023. free (subset);
  2024. return false;
  2025. }
  2026. if (strcmp (subset, "i") == 0
  2027. || strcmp (subset, "e") == 0
  2028. || strcmp (subset, "g") == 0)
  2029. {
  2030. rps->error_handler
  2031. (_("cannot + or - base extension `%s' in .option "
  2032. "arch `%s'"), subset, str);
  2033. free (subset);
  2034. return false;
  2035. }
  2036. if (removed)
  2037. riscv_remove_subset (rps->subset_list, subset);
  2038. else
  2039. riscv_parse_add_subset (rps, subset, major_version, minor_version, true);
  2040. p += end_of_version - subset;
  2041. free (subset);
  2042. }
  2043. while (*p++ == ',');
  2044. riscv_parse_add_implicit_subsets (rps);
  2045. return riscv_parse_check_conflicts (rps);
  2046. }
  2047. /* Check if the FEATURE subset is supported or not in the subset list.
  2048. Return true if it is supported; Otherwise, return false. */
  2049. bool
  2050. riscv_subset_supports (riscv_parse_subset_t *rps,
  2051. const char *feature)
  2052. {
  2053. struct riscv_subset_t *subset;
  2054. return riscv_lookup_subset (rps->subset_list, feature, &subset);
  2055. }
  2056. /* Each instuction is belonged to an instruction class INSN_CLASS_*.
  2057. Call riscv_subset_supports to make sure if the instuction is valid. */
  2058. bool
  2059. riscv_multi_subset_supports (riscv_parse_subset_t *rps,
  2060. enum riscv_insn_class insn_class)
  2061. {
  2062. switch (insn_class)
  2063. {
  2064. case INSN_CLASS_I:
  2065. return riscv_subset_supports (rps, "i");
  2066. case INSN_CLASS_ZICBOM:
  2067. return riscv_subset_supports (rps, "zicbom");
  2068. case INSN_CLASS_ZICBOP:
  2069. return riscv_subset_supports (rps, "zicbop");
  2070. case INSN_CLASS_ZICBOZ:
  2071. return riscv_subset_supports (rps, "zicboz");
  2072. case INSN_CLASS_ZICSR:
  2073. return riscv_subset_supports (rps, "zicsr");
  2074. case INSN_CLASS_ZIFENCEI:
  2075. return riscv_subset_supports (rps, "zifencei");
  2076. case INSN_CLASS_ZIHINTPAUSE:
  2077. return riscv_subset_supports (rps, "zihintpause");
  2078. case INSN_CLASS_M:
  2079. return riscv_subset_supports (rps, "m");
  2080. case INSN_CLASS_A:
  2081. return riscv_subset_supports (rps, "a");
  2082. case INSN_CLASS_F:
  2083. return riscv_subset_supports (rps, "f");
  2084. case INSN_CLASS_D:
  2085. return riscv_subset_supports (rps, "d");
  2086. case INSN_CLASS_Q:
  2087. return riscv_subset_supports (rps, "q");
  2088. case INSN_CLASS_C:
  2089. return riscv_subset_supports (rps, "c");
  2090. case INSN_CLASS_F_AND_C:
  2091. return (riscv_subset_supports (rps, "f")
  2092. && riscv_subset_supports (rps, "c"));
  2093. case INSN_CLASS_D_AND_C:
  2094. return (riscv_subset_supports (rps, "d")
  2095. && riscv_subset_supports (rps, "c"));
  2096. case INSN_CLASS_F_OR_ZFINX:
  2097. return (riscv_subset_supports (rps, "f")
  2098. || riscv_subset_supports (rps, "zfinx"));
  2099. case INSN_CLASS_D_OR_ZDINX:
  2100. return (riscv_subset_supports (rps, "d")
  2101. || riscv_subset_supports (rps, "zdinx"));
  2102. case INSN_CLASS_Q_OR_ZQINX:
  2103. return (riscv_subset_supports (rps, "q")
  2104. || riscv_subset_supports (rps, "zqinx"));
  2105. case INSN_CLASS_ZBA:
  2106. return riscv_subset_supports (rps, "zba");
  2107. case INSN_CLASS_ZBB:
  2108. return riscv_subset_supports (rps, "zbb");
  2109. case INSN_CLASS_ZBC:
  2110. return riscv_subset_supports (rps, "zbc");
  2111. case INSN_CLASS_ZBS:
  2112. return riscv_subset_supports (rps, "zbs");
  2113. case INSN_CLASS_ZBKB:
  2114. return riscv_subset_supports (rps, "zbkb");
  2115. case INSN_CLASS_ZBKC:
  2116. return riscv_subset_supports (rps, "zbkc");
  2117. case INSN_CLASS_ZBKX:
  2118. return riscv_subset_supports (rps, "zbkx");
  2119. case INSN_CLASS_ZBB_OR_ZBKB:
  2120. return (riscv_subset_supports (rps, "zbb")
  2121. || riscv_subset_supports (rps, "zbkb"));
  2122. case INSN_CLASS_ZBC_OR_ZBKC:
  2123. return (riscv_subset_supports (rps, "zbc")
  2124. || riscv_subset_supports (rps, "zbkc"));
  2125. case INSN_CLASS_ZKND:
  2126. return riscv_subset_supports (rps, "zknd");
  2127. case INSN_CLASS_ZKNE:
  2128. return riscv_subset_supports (rps, "zkne");
  2129. case INSN_CLASS_ZKNH:
  2130. return riscv_subset_supports (rps, "zknh");
  2131. case INSN_CLASS_ZKND_OR_ZKNE:
  2132. return (riscv_subset_supports (rps, "zknd")
  2133. || riscv_subset_supports (rps, "zkne"));
  2134. case INSN_CLASS_ZKSED:
  2135. return riscv_subset_supports (rps, "zksed");
  2136. case INSN_CLASS_ZKSH:
  2137. return riscv_subset_supports (rps, "zksh");
  2138. case INSN_CLASS_V:
  2139. return (riscv_subset_supports (rps, "v")
  2140. || riscv_subset_supports (rps, "zve64x")
  2141. || riscv_subset_supports (rps, "zve32x"));
  2142. case INSN_CLASS_ZVEF:
  2143. return (riscv_subset_supports (rps, "v")
  2144. || riscv_subset_supports (rps, "zve64d")
  2145. || riscv_subset_supports (rps, "zve64f")
  2146. || riscv_subset_supports (rps, "zve32f"));
  2147. case INSN_CLASS_SVINVAL:
  2148. return riscv_subset_supports (rps, "svinval");
  2149. default:
  2150. rps->error_handler
  2151. (_("internal: unreachable INSN_CLASS_*"));
  2152. return false;
  2153. }
  2154. }
  2155. /* Each instuction is belonged to an instruction class INSN_CLASS_*.
  2156. Call riscv_subset_supports_ext to determine the missing extension. */
  2157. const char *
  2158. riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
  2159. enum riscv_insn_class insn_class)
  2160. {
  2161. switch (insn_class)
  2162. {
  2163. case INSN_CLASS_I:
  2164. return "i";
  2165. case INSN_CLASS_ZICSR:
  2166. return "zicsr";
  2167. case INSN_CLASS_ZIFENCEI:
  2168. return "zifencei";
  2169. case INSN_CLASS_ZIHINTPAUSE:
  2170. return "zihintpause";
  2171. case INSN_CLASS_M:
  2172. return "m";
  2173. case INSN_CLASS_A:
  2174. return "a";
  2175. case INSN_CLASS_F:
  2176. return "f";
  2177. case INSN_CLASS_D:
  2178. return "d";
  2179. case INSN_CLASS_Q:
  2180. return "q";
  2181. case INSN_CLASS_C:
  2182. return "c";
  2183. case INSN_CLASS_F_AND_C:
  2184. if (!riscv_subset_supports (rps, "f")
  2185. && !riscv_subset_supports (rps, "c"))
  2186. return "f' and `c";
  2187. else if (!riscv_subset_supports (rps, "f"))
  2188. return "f";
  2189. else
  2190. return "c";
  2191. case INSN_CLASS_D_AND_C:
  2192. if (!riscv_subset_supports (rps, "d")
  2193. && !riscv_subset_supports (rps, "c"))
  2194. return "d' and `c";
  2195. else if (!riscv_subset_supports (rps, "d"))
  2196. return "d";
  2197. else
  2198. return "c";
  2199. case INSN_CLASS_F_OR_ZFINX:
  2200. return "f' or `zfinx";
  2201. case INSN_CLASS_D_OR_ZDINX:
  2202. return "d' or `zdinx";
  2203. case INSN_CLASS_Q_OR_ZQINX:
  2204. return "q' or `zqinx";
  2205. case INSN_CLASS_ZBA:
  2206. return "zba";
  2207. case INSN_CLASS_ZBB:
  2208. return "zbb";
  2209. case INSN_CLASS_ZBC:
  2210. return "zbc";
  2211. case INSN_CLASS_ZBS:
  2212. return "zbs";
  2213. case INSN_CLASS_ZBKB:
  2214. return "zbkb";
  2215. case INSN_CLASS_ZBKC:
  2216. return "zbkc";
  2217. case INSN_CLASS_ZBKX:
  2218. return "zbkx";
  2219. case INSN_CLASS_ZBB_OR_ZBKB:
  2220. return "zbb' or `zbkb";
  2221. case INSN_CLASS_ZBC_OR_ZBKC:
  2222. return "zbc' or `zbkc";
  2223. case INSN_CLASS_ZKND:
  2224. return "zknd";
  2225. case INSN_CLASS_ZKNE:
  2226. return "zkne";
  2227. case INSN_CLASS_ZKNH:
  2228. return "zknh";
  2229. case INSN_CLASS_ZKND_OR_ZKNE:
  2230. return "zknd' or `zkne";
  2231. case INSN_CLASS_ZKSED:
  2232. return "zksed";
  2233. case INSN_CLASS_ZKSH:
  2234. return "zksh";
  2235. case INSN_CLASS_V:
  2236. return "v' or `zve64x' or `zve32x";
  2237. case INSN_CLASS_ZVEF:
  2238. return "v' or `zve64d' or `zve64f' or `zve32f";
  2239. case INSN_CLASS_SVINVAL:
  2240. return "svinval";
  2241. default:
  2242. rps->error_handler
  2243. (_("internal: unreachable INSN_CLASS_*"));
  2244. return NULL;
  2245. }
  2246. }