coffswap.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /* Generic COFF swapping routines, for BFD.
  2. Copyright (C) 1990-2022 Free Software Foundation, Inc.
  3. Written by Cygnus Support.
  4. This file is part of BFD, the Binary File Descriptor library.
  5. This program 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 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. /* This file contains routines used to swap COFF data. It is a header
  18. file because the details of swapping depend on the details of the
  19. structures used by each COFF implementation. This is included by
  20. coffcode.h, as well as by the ECOFF backend.
  21. Any file which uses this must first include "coff/internal.h" and
  22. "coff/CPU.h". The functions will then be correct for that CPU. */
  23. #ifndef GET_FCN_LNNOPTR
  24. #define GET_FCN_LNNOPTR(abfd, ext) \
  25. H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
  26. #endif
  27. #ifndef GET_FCN_ENDNDX
  28. #define GET_FCN_ENDNDX(abfd, ext) \
  29. H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
  30. #endif
  31. #ifndef PUT_FCN_LNNOPTR
  32. #define PUT_FCN_LNNOPTR(abfd, in, ext) \
  33. H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
  34. #endif
  35. #ifndef PUT_FCN_ENDNDX
  36. #define PUT_FCN_ENDNDX(abfd, in, ext) \
  37. H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
  38. #endif
  39. #ifndef GET_LNSZ_LNNO
  40. #define GET_LNSZ_LNNO(abfd, ext) \
  41. H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
  42. #endif
  43. #ifndef GET_LNSZ_SIZE
  44. #define GET_LNSZ_SIZE(abfd, ext) \
  45. H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size)
  46. #endif
  47. #ifndef PUT_LNSZ_LNNO
  48. #define PUT_LNSZ_LNNO(abfd, in, ext) \
  49. H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
  50. #endif
  51. #ifndef PUT_LNSZ_SIZE
  52. #define PUT_LNSZ_SIZE(abfd, in, ext) \
  53. H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
  54. #endif
  55. #ifndef GET_SCN_SCNLEN
  56. #define GET_SCN_SCNLEN(abfd, ext) \
  57. H_GET_32 (abfd, ext->x_scn.x_scnlen)
  58. #endif
  59. #ifndef GET_SCN_NRELOC
  60. #define GET_SCN_NRELOC(abfd, ext) \
  61. H_GET_16 (abfd, ext->x_scn.x_nreloc)
  62. #endif
  63. #ifndef GET_SCN_NLINNO
  64. #define GET_SCN_NLINNO(abfd, ext) \
  65. H_GET_16 (abfd, ext->x_scn.x_nlinno)
  66. #endif
  67. #ifndef PUT_SCN_SCNLEN
  68. #define PUT_SCN_SCNLEN(abfd, in, ext) \
  69. H_PUT_32 (abfd, in, ext->x_scn.x_scnlen)
  70. #endif
  71. #ifndef PUT_SCN_NRELOC
  72. #define PUT_SCN_NRELOC(abfd, in, ext) \
  73. H_PUT_16 (abfd, in, ext->x_scn.x_nreloc)
  74. #endif
  75. #ifndef PUT_SCN_NLINNO
  76. #define PUT_SCN_NLINNO(abfd, in, ext) \
  77. H_PUT_16 (abfd, in, ext->x_scn.x_nlinno)
  78. #endif
  79. #ifndef GET_LINENO_LNNO
  80. #define GET_LINENO_LNNO(abfd, ext) \
  81. H_GET_16 (abfd, ext->l_lnno);
  82. #endif
  83. #ifndef PUT_LINENO_LNNO
  84. #define PUT_LINENO_LNNO(abfd, val, ext) \
  85. H_PUT_16 (abfd, val, ext->l_lnno);
  86. #endif
  87. /* The f_symptr field in the filehdr is sometimes 64 bits. */
  88. #ifndef GET_FILEHDR_SYMPTR
  89. #define GET_FILEHDR_SYMPTR H_GET_32
  90. #endif
  91. #ifndef PUT_FILEHDR_SYMPTR
  92. #define PUT_FILEHDR_SYMPTR H_PUT_32
  93. #endif
  94. /* Some fields in the aouthdr are sometimes 64 bits. */
  95. #ifndef GET_AOUTHDR_TSIZE
  96. #define GET_AOUTHDR_TSIZE H_GET_32
  97. #endif
  98. #ifndef PUT_AOUTHDR_TSIZE
  99. #define PUT_AOUTHDR_TSIZE H_PUT_32
  100. #endif
  101. #ifndef GET_AOUTHDR_DSIZE
  102. #define GET_AOUTHDR_DSIZE H_GET_32
  103. #endif
  104. #ifndef PUT_AOUTHDR_DSIZE
  105. #define PUT_AOUTHDR_DSIZE H_PUT_32
  106. #endif
  107. #ifndef GET_AOUTHDR_BSIZE
  108. #define GET_AOUTHDR_BSIZE H_GET_32
  109. #endif
  110. #ifndef PUT_AOUTHDR_BSIZE
  111. #define PUT_AOUTHDR_BSIZE H_PUT_32
  112. #endif
  113. #ifndef GET_AOUTHDR_ENTRY
  114. #define GET_AOUTHDR_ENTRY H_GET_32
  115. #endif
  116. #ifndef PUT_AOUTHDR_ENTRY
  117. #define PUT_AOUTHDR_ENTRY H_PUT_32
  118. #endif
  119. #ifndef GET_AOUTHDR_TEXT_START
  120. #define GET_AOUTHDR_TEXT_START H_GET_32
  121. #endif
  122. #ifndef PUT_AOUTHDR_TEXT_START
  123. #define PUT_AOUTHDR_TEXT_START H_PUT_32
  124. #endif
  125. #ifndef GET_AOUTHDR_DATA_START
  126. #define GET_AOUTHDR_DATA_START H_GET_32
  127. #endif
  128. #ifndef PUT_AOUTHDR_DATA_START
  129. #define PUT_AOUTHDR_DATA_START H_PUT_32
  130. #endif
  131. /* Some fields in the scnhdr are sometimes 64 bits. */
  132. #ifndef GET_SCNHDR_PADDR
  133. #define GET_SCNHDR_PADDR H_GET_32
  134. #endif
  135. #ifndef PUT_SCNHDR_PADDR
  136. #define PUT_SCNHDR_PADDR H_PUT_32
  137. #endif
  138. #ifndef GET_SCNHDR_VADDR
  139. #define GET_SCNHDR_VADDR H_GET_32
  140. #endif
  141. #ifndef PUT_SCNHDR_VADDR
  142. #define PUT_SCNHDR_VADDR H_PUT_32
  143. #endif
  144. #ifndef GET_SCNHDR_SIZE
  145. #define GET_SCNHDR_SIZE H_GET_32
  146. #endif
  147. #ifndef PUT_SCNHDR_SIZE
  148. #define PUT_SCNHDR_SIZE H_PUT_32
  149. #endif
  150. #ifndef GET_SCNHDR_SCNPTR
  151. #define GET_SCNHDR_SCNPTR H_GET_32
  152. #endif
  153. #ifndef PUT_SCNHDR_SCNPTR
  154. #define PUT_SCNHDR_SCNPTR H_PUT_32
  155. #endif
  156. #ifndef GET_SCNHDR_RELPTR
  157. #define GET_SCNHDR_RELPTR H_GET_32
  158. #endif
  159. #ifndef PUT_SCNHDR_RELPTR
  160. #define PUT_SCNHDR_RELPTR H_PUT_32
  161. #endif
  162. #ifndef GET_SCNHDR_LNNOPTR
  163. #define GET_SCNHDR_LNNOPTR H_GET_32
  164. #endif
  165. #ifndef PUT_SCNHDR_LNNOPTR
  166. #define PUT_SCNHDR_LNNOPTR H_PUT_32
  167. #endif
  168. #ifndef GET_SCNHDR_NRELOC
  169. #define GET_SCNHDR_NRELOC H_GET_16
  170. #endif
  171. #ifndef MAX_SCNHDR_NRELOC
  172. #define MAX_SCNHDR_NRELOC 0xffff
  173. #endif
  174. #ifndef PUT_SCNHDR_NRELOC
  175. #define PUT_SCNHDR_NRELOC H_PUT_16
  176. #endif
  177. #ifndef GET_SCNHDR_NLNNO
  178. #define GET_SCNHDR_NLNNO H_GET_16
  179. #endif
  180. #ifndef MAX_SCNHDR_NLNNO
  181. #define MAX_SCNHDR_NLNNO 0xffff
  182. #endif
  183. #ifndef PUT_SCNHDR_NLNNO
  184. #define PUT_SCNHDR_NLNNO H_PUT_16
  185. #endif
  186. #ifndef GET_SCNHDR_FLAGS
  187. #define GET_SCNHDR_FLAGS H_GET_32
  188. #endif
  189. #ifndef PUT_SCNHDR_FLAGS
  190. #define PUT_SCNHDR_FLAGS H_PUT_32
  191. #endif
  192. #ifndef GET_RELOC_VADDR
  193. #define GET_RELOC_VADDR H_GET_32
  194. #endif
  195. #ifndef PUT_RELOC_VADDR
  196. #define PUT_RELOC_VADDR H_PUT_32
  197. #endif
  198. #ifndef NO_COFF_RELOCS
  199. static void
  200. coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
  201. {
  202. RELOC *reloc_src = (RELOC *) src;
  203. struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
  204. reloc_dst->r_vaddr = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
  205. reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
  206. reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
  207. #ifdef SWAP_IN_RELOC_OFFSET
  208. reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
  209. #endif
  210. }
  211. static unsigned int
  212. coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
  213. {
  214. struct internal_reloc *reloc_src = (struct internal_reloc *) src;
  215. struct external_reloc *reloc_dst = (struct external_reloc *) dst;
  216. PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
  217. H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
  218. H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
  219. #ifdef SWAP_OUT_RELOC_OFFSET
  220. SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
  221. #endif
  222. #ifdef SWAP_OUT_RELOC_EXTRA
  223. SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
  224. #endif
  225. return bfd_coff_relsz (abfd);
  226. }
  227. #ifdef TICOFF
  228. static void
  229. coff_swap_reloc_v0_in (bfd *abfd, void *src, void *dst)
  230. {
  231. struct external_reloc_v0 *reloc_src = (struct external_reloc_v0 *) src;
  232. struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
  233. reloc_dst->r_vaddr = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
  234. reloc_dst->r_symndx = H_GET_16 (abfd, reloc_src->r_symndx);
  235. reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
  236. }
  237. static unsigned int
  238. coff_swap_reloc_v0_out (bfd *abfd, void *src, void *dst)
  239. {
  240. struct internal_reloc *reloc_src = (struct internal_reloc *) src;
  241. struct external_reloc_v0 *reloc_dst = (struct external_reloc_v0 *) dst;
  242. PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
  243. H_PUT_16 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
  244. H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
  245. SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
  246. return bfd_coff_relsz (abfd);
  247. }
  248. #endif
  249. #endif /* NO_COFF_RELOCS */
  250. static void
  251. coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
  252. {
  253. FILHDR *filehdr_src = (FILHDR *) src;
  254. struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
  255. #ifdef COFF_ADJUST_FILEHDR_IN_PRE
  256. COFF_ADJUST_FILEHDR_IN_PRE (abfd, src, dst);
  257. #endif
  258. filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->f_magic);
  259. filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns);
  260. filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
  261. filehdr_dst->f_symptr = GET_FILEHDR_SYMPTR (abfd, filehdr_src->f_symptr);
  262. filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms);
  263. filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src->f_opthdr);
  264. filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags);
  265. #ifdef COFF_ADJUST_FILEHDR_IN_POST
  266. COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
  267. #endif
  268. }
  269. static unsigned int
  270. coff_swap_filehdr_out (bfd *abfd, void * in, void * out)
  271. {
  272. struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
  273. FILHDR *filehdr_out = (FILHDR *) out;
  274. #ifdef COFF_ADJUST_FILEHDR_OUT_PRE
  275. COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
  276. #endif
  277. H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
  278. H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
  279. H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
  280. PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
  281. H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
  282. H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
  283. H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
  284. #ifdef COFF_ADJUST_FILEHDR_OUT_POST
  285. COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
  286. #endif
  287. return bfd_coff_filhsz (abfd);
  288. }
  289. #ifndef NO_COFF_SYMBOLS
  290. static void
  291. coff_swap_sym_in (bfd * abfd, void * ext1, void * in1)
  292. {
  293. SYMENT *ext = (SYMENT *) ext1;
  294. struct internal_syment *in = (struct internal_syment *) in1;
  295. if (ext->e.e_name[0] == 0)
  296. {
  297. in->_n._n_n._n_zeroes = 0;
  298. in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
  299. }
  300. else
  301. {
  302. #if SYMNMLEN != E_SYMNMLEN
  303. #error we need to cope with truncating or extending SYMNMLEN
  304. #else
  305. memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
  306. #endif
  307. }
  308. in->n_value = H_GET_32 (abfd, ext->e_value);
  309. in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
  310. if (sizeof (ext->e_type) == 2)
  311. in->n_type = H_GET_16 (abfd, ext->e_type);
  312. else
  313. in->n_type = H_GET_32 (abfd, ext->e_type);
  314. in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
  315. in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
  316. #ifdef COFF_ADJUST_SYM_IN_POST
  317. COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
  318. #endif
  319. }
  320. static unsigned int
  321. coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
  322. {
  323. struct internal_syment *in = (struct internal_syment *) inp;
  324. SYMENT *ext =(SYMENT *) extp;
  325. #ifdef COFF_ADJUST_SYM_OUT_PRE
  326. COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
  327. #endif
  328. if (in->_n._n_name[0] == 0)
  329. {
  330. H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
  331. H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
  332. }
  333. else
  334. {
  335. #if SYMNMLEN != E_SYMNMLEN
  336. #error we need to cope with truncating or extending SYMNMLEN
  337. #else
  338. memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
  339. #endif
  340. }
  341. H_PUT_32 (abfd, in->n_value, ext->e_value);
  342. H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
  343. if (sizeof (ext->e_type) == 2)
  344. H_PUT_16 (abfd, in->n_type, ext->e_type);
  345. else
  346. H_PUT_32 (abfd, in->n_type, ext->e_type);
  347. H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
  348. H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
  349. #ifdef COFF_ADJUST_SYM_OUT_POST
  350. COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
  351. #endif
  352. return SYMESZ;
  353. }
  354. static void
  355. coff_swap_aux_in (bfd *abfd,
  356. void * ext1,
  357. int type,
  358. int in_class,
  359. int indx,
  360. int numaux,
  361. void * in1)
  362. {
  363. AUXENT *ext = (AUXENT *) ext1;
  364. union internal_auxent *in = (union internal_auxent *) in1;
  365. #ifdef COFF_ADJUST_AUX_IN_PRE
  366. COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, in_class, indx, numaux, in1);
  367. #endif
  368. switch (in_class)
  369. {
  370. case C_FILE:
  371. if (ext->x_file.x_fname[0] == 0)
  372. {
  373. in->x_file.x_n.x_n.x_zeroes = 0;
  374. in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
  375. }
  376. else
  377. {
  378. #if FILNMLEN != E_FILNMLEN
  379. #error we need to cope with truncating or extending FILNMLEN
  380. #else
  381. if (numaux > 1 && coff_data (abfd)->pe)
  382. {
  383. if (indx == 0)
  384. memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname,
  385. numaux * sizeof (AUXENT));
  386. }
  387. else
  388. memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
  389. #endif
  390. }
  391. goto end;
  392. case C_STAT:
  393. #ifdef C_LEAFSTAT
  394. case C_LEAFSTAT:
  395. #endif
  396. case C_HIDDEN:
  397. if (type == T_NULL)
  398. {
  399. in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
  400. in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
  401. in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
  402. /* PE defines some extra fields; we zero them out for
  403. safety. */
  404. in->x_scn.x_checksum = 0;
  405. in->x_scn.x_associated = 0;
  406. in->x_scn.x_comdat = 0;
  407. goto end;
  408. }
  409. break;
  410. }
  411. in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
  412. #ifndef NO_TVNDX
  413. in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
  414. #endif
  415. if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
  416. || ISTAG (in_class))
  417. {
  418. in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
  419. in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
  420. }
  421. else
  422. {
  423. #if DIMNUM != E_DIMNUM
  424. #error we need to cope with truncating or extending DIMNUM
  425. #endif
  426. in->x_sym.x_fcnary.x_ary.x_dimen[0] =
  427. H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
  428. in->x_sym.x_fcnary.x_ary.x_dimen[1] =
  429. H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
  430. in->x_sym.x_fcnary.x_ary.x_dimen[2] =
  431. H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
  432. in->x_sym.x_fcnary.x_ary.x_dimen[3] =
  433. H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
  434. }
  435. if (ISFCN (type))
  436. in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
  437. else
  438. {
  439. in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
  440. in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
  441. }
  442. end: ;
  443. #ifdef COFF_ADJUST_AUX_IN_POST
  444. COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, in_class, indx, numaux, in1);
  445. #endif
  446. }
  447. static unsigned int
  448. coff_swap_aux_out (bfd * abfd,
  449. void * inp,
  450. int type,
  451. int in_class,
  452. int indx ATTRIBUTE_UNUSED,
  453. int numaux ATTRIBUTE_UNUSED,
  454. void * extp)
  455. {
  456. union internal_auxent * in = (union internal_auxent *) inp;
  457. AUXENT *ext = (AUXENT *) extp;
  458. #ifdef COFF_ADJUST_AUX_OUT_PRE
  459. COFF_ADJUST_AUX_OUT_PRE (abfd, inp, type, in_class, indx, numaux, extp);
  460. #endif
  461. memset (ext, 0, AUXESZ);
  462. switch (in_class)
  463. {
  464. case C_FILE:
  465. if (in->x_file.x_n.x_fname[0] == 0)
  466. {
  467. H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
  468. H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
  469. }
  470. else
  471. {
  472. #if FILNMLEN != E_FILNMLEN
  473. #error we need to cope with truncating or extending FILNMLEN
  474. #else
  475. memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, FILNMLEN);
  476. #endif
  477. }
  478. goto end;
  479. case C_STAT:
  480. #ifdef C_LEAFSTAT
  481. case C_LEAFSTAT:
  482. #endif
  483. case C_HIDDEN:
  484. if (type == T_NULL)
  485. {
  486. PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
  487. PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
  488. PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
  489. goto end;
  490. }
  491. break;
  492. }
  493. H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
  494. #ifndef NO_TVNDX
  495. H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
  496. #endif
  497. if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
  498. || ISTAG (in_class))
  499. {
  500. PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
  501. PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
  502. }
  503. else
  504. {
  505. #if DIMNUM != E_DIMNUM
  506. #error we need to cope with truncating or extending DIMNUM
  507. #endif
  508. H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
  509. ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
  510. H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
  511. ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
  512. H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
  513. ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
  514. H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
  515. ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
  516. }
  517. if (ISFCN (type))
  518. H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
  519. else
  520. {
  521. PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
  522. PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
  523. }
  524. end:
  525. #ifdef COFF_ADJUST_AUX_OUT_POST
  526. COFF_ADJUST_AUX_OUT_POST (abfd, inp, type, in_class, indx, numaux, extp);
  527. #endif
  528. return AUXESZ;
  529. }
  530. #endif /* NO_COFF_SYMBOLS */
  531. #ifndef NO_COFF_LINENOS
  532. static void
  533. coff_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
  534. {
  535. LINENO *ext = (LINENO *) ext1;
  536. struct internal_lineno *in = (struct internal_lineno *) in1;
  537. in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
  538. in->l_lnno = GET_LINENO_LNNO (abfd, ext);
  539. }
  540. static unsigned int
  541. coff_swap_lineno_out (bfd * abfd, void * inp, void * outp)
  542. {
  543. struct internal_lineno *in = (struct internal_lineno *) inp;
  544. struct external_lineno *ext = (struct external_lineno *) outp;
  545. H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
  546. PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
  547. return LINESZ;
  548. }
  549. #endif /* NO_COFF_LINENOS */
  550. static void
  551. coff_swap_aouthdr_in (bfd * abfd, void * aouthdr_ext1, void * aouthdr_int1)
  552. {
  553. AOUTHDR *aouthdr_ext;
  554. struct internal_aouthdr *aouthdr_int;
  555. aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
  556. aouthdr_int = (struct internal_aouthdr *) aouthdr_int1;
  557. aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
  558. aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
  559. aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
  560. aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
  561. aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
  562. aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
  563. aouthdr_int->text_start =
  564. GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
  565. aouthdr_int->data_start =
  566. GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
  567. #ifdef RS6000COFF_C
  568. #ifdef XCOFF64
  569. aouthdr_int->o_toc = H_GET_64 (abfd, aouthdr_ext->o_toc);
  570. #else
  571. aouthdr_int->o_toc = H_GET_32 (abfd, aouthdr_ext->o_toc);
  572. #endif
  573. aouthdr_int->o_snentry = H_GET_16 (abfd, aouthdr_ext->o_snentry);
  574. aouthdr_int->o_sntext = H_GET_16 (abfd, aouthdr_ext->o_sntext);
  575. aouthdr_int->o_sndata = H_GET_16 (abfd, aouthdr_ext->o_sndata);
  576. aouthdr_int->o_sntoc = H_GET_16 (abfd, aouthdr_ext->o_sntoc);
  577. aouthdr_int->o_snloader = H_GET_16 (abfd, aouthdr_ext->o_snloader);
  578. aouthdr_int->o_snbss = H_GET_16 (abfd, aouthdr_ext->o_snbss);
  579. aouthdr_int->o_algntext = H_GET_16 (abfd, aouthdr_ext->o_algntext);
  580. aouthdr_int->o_algndata = H_GET_16 (abfd, aouthdr_ext->o_algndata);
  581. aouthdr_int->o_modtype = H_GET_16 (abfd, aouthdr_ext->o_modtype);
  582. aouthdr_int->o_cputype = H_GET_16 (abfd, aouthdr_ext->o_cputype);
  583. #ifdef XCOFF64
  584. aouthdr_int->o_maxstack = H_GET_64 (abfd, aouthdr_ext->o_maxstack);
  585. aouthdr_int->o_maxdata = H_GET_64 (abfd, aouthdr_ext->o_maxdata);
  586. #else
  587. aouthdr_int->o_maxstack = H_GET_32 (abfd, aouthdr_ext->o_maxstack);
  588. aouthdr_int->o_maxdata = H_GET_32 (abfd, aouthdr_ext->o_maxdata);
  589. #endif
  590. #endif
  591. #ifdef MIPSECOFF
  592. aouthdr_int->bss_start = H_GET_32 (abfd, aouthdr_ext->bss_start);
  593. aouthdr_int->gp_value = H_GET_32 (abfd, aouthdr_ext->gp_value);
  594. aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask);
  595. aouthdr_int->cprmask[0] = H_GET_32 (abfd, aouthdr_ext->cprmask[0]);
  596. aouthdr_int->cprmask[1] = H_GET_32 (abfd, aouthdr_ext->cprmask[1]);
  597. aouthdr_int->cprmask[2] = H_GET_32 (abfd, aouthdr_ext->cprmask[2]);
  598. aouthdr_int->cprmask[3] = H_GET_32 (abfd, aouthdr_ext->cprmask[3]);
  599. #endif
  600. #ifdef ALPHAECOFF
  601. aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start);
  602. aouthdr_int->gp_value = H_GET_64 (abfd, aouthdr_ext->gp_value);
  603. aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask);
  604. aouthdr_int->fprmask = H_GET_32 (abfd, aouthdr_ext->fprmask);
  605. #endif
  606. }
  607. static unsigned int
  608. coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
  609. {
  610. struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
  611. AOUTHDR *aouthdr_out = (AOUTHDR *) out;
  612. H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->magic);
  613. H_PUT_16 (abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
  614. PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->tsize);
  615. PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->dsize);
  616. PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->bsize);
  617. PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->entry);
  618. PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
  619. aouthdr_out->text_start);
  620. PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
  621. aouthdr_out->data_start);
  622. #ifdef RS6000COFF_C
  623. #ifdef XCOFF64
  624. H_PUT_64 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
  625. #else
  626. H_PUT_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
  627. #endif
  628. H_PUT_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
  629. H_PUT_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
  630. H_PUT_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
  631. H_PUT_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
  632. H_PUT_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
  633. H_PUT_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
  634. H_PUT_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
  635. H_PUT_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
  636. H_PUT_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
  637. H_PUT_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
  638. #ifdef XCOFF64
  639. H_PUT_64 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
  640. H_PUT_64 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
  641. #else
  642. H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
  643. H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
  644. #endif
  645. /* TODO: set o_*psize dynamically */
  646. H_PUT_8 (abfd, 0, aouthdr_out->o_textpsize);
  647. H_PUT_8 (abfd, 0, aouthdr_out->o_datapsize);
  648. H_PUT_8 (abfd, 0, aouthdr_out->o_stackpsize);
  649. H_PUT_8 (abfd, aouthdr_in->o_flags, aouthdr_out->o_flags);
  650. H_PUT_16 (abfd, aouthdr_in->o_sntdata, aouthdr_out->o_sntdata);
  651. H_PUT_16 (abfd, aouthdr_in->o_sntbss, aouthdr_out->o_sntbss);
  652. H_PUT_32 (abfd, 0, aouthdr_out->o_debugger);
  653. #ifdef XCOFF64
  654. H_PUT_16 (abfd, aouthdr_in->o_x64flags, aouthdr_out->o_x64flags);
  655. memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
  656. #endif
  657. #endif
  658. #ifdef MIPSECOFF
  659. H_PUT_32 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
  660. H_PUT_32 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
  661. H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
  662. H_PUT_32 (abfd, aouthdr_in->cprmask[0], aouthdr_out->cprmask[0]);
  663. H_PUT_32 (abfd, aouthdr_in->cprmask[1], aouthdr_out->cprmask[1]);
  664. H_PUT_32 (abfd, aouthdr_in->cprmask[2], aouthdr_out->cprmask[2]);
  665. H_PUT_32 (abfd, aouthdr_in->cprmask[3], aouthdr_out->cprmask[3]);
  666. #endif
  667. #ifdef ALPHAECOFF
  668. /* FIXME: What does bldrev mean? */
  669. H_PUT_16 (abfd, 2, aouthdr_out->bldrev);
  670. H_PUT_16 (abfd, 0, aouthdr_out->padding);
  671. H_PUT_64 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
  672. H_PUT_64 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
  673. H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
  674. H_PUT_32 (abfd, aouthdr_in->fprmask, aouthdr_out->fprmask);
  675. #endif
  676. return AOUTSZ;
  677. }
  678. ATTRIBUTE_UNUSED
  679. static void
  680. coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
  681. {
  682. SCNHDR *scnhdr_ext = (SCNHDR *) ext;
  683. struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
  684. #ifdef COFF_ADJUST_SCNHDR_IN_PRE
  685. COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
  686. #endif
  687. memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
  688. scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
  689. scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
  690. scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
  691. scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
  692. scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
  693. scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
  694. scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
  695. scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
  696. scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
  697. #ifdef COFF_ADJUST_SCNHDR_IN_POST
  698. COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
  699. #endif
  700. }
  701. ATTRIBUTE_UNUSED
  702. static unsigned int
  703. coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
  704. {
  705. struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
  706. SCNHDR *scnhdr_ext = (SCNHDR *) out;
  707. unsigned int ret = bfd_coff_scnhsz (abfd);
  708. #ifdef COFF_ADJUST_SCNHDR_OUT_PRE
  709. COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
  710. #endif
  711. memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
  712. PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
  713. PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
  714. PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
  715. PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
  716. PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
  717. PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
  718. PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
  719. if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
  720. PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
  721. else
  722. {
  723. char buf[sizeof (scnhdr_int->s_name) + 1];
  724. memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
  725. buf[sizeof (scnhdr_int->s_name)] = '\0';
  726. _bfd_error_handler
  727. /* xgettext:c-format */
  728. (_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
  729. abfd, buf, scnhdr_int->s_nlnno);
  730. PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
  731. }
  732. if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
  733. PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
  734. else
  735. {
  736. char buf[sizeof (scnhdr_int->s_name) + 1];
  737. memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
  738. buf[sizeof (scnhdr_int->s_name)] = '\0';
  739. /* xgettext:c-format */
  740. _bfd_error_handler (_("%pB: %s: reloc overflow: 0x%lx > 0xffff"),
  741. abfd, buf, scnhdr_int->s_nreloc);
  742. bfd_set_error (bfd_error_file_truncated);
  743. PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
  744. ret = 0;
  745. }
  746. #ifdef COFF_ADJUST_SCNHDR_OUT_POST
  747. COFF_ADJUST_SCNHDR_OUT_POST (abfd, in, out);
  748. #endif
  749. return ret;
  750. }