archive64.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /* Support for 64-bit archives.
  2. Copyright (C) 1996-2022 Free Software Foundation, Inc.
  3. Ian Lance Taylor, Cygnus Support
  4. Linker support added by Mark Mitchell, CodeSourcery, LLC.
  5. <mark@codesourcery.com>
  6. This file is part of BFD, the Binary File Descriptor library.
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 3 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  18. MA 02110-1301, USA. */
  19. /* This file supports the 64-bit archives. We use the same format as
  20. the 64-bit (MIPS) ELF archives. */
  21. #include "sysdep.h"
  22. #include "bfd.h"
  23. #include "libbfd.h"
  24. #include "aout/ar.h"
  25. /* Irix 6 defines a 64bit archive map format, so that they can
  26. have archives more than 4 GB in size. */
  27. /* Read an Irix 6 armap. */
  28. bool
  29. _bfd_archive_64_bit_slurp_armap (bfd *abfd)
  30. {
  31. struct artdata *ardata = bfd_ardata (abfd);
  32. char nextname[17];
  33. bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
  34. struct areltdata *mapdata;
  35. bfd_byte int_buf[8];
  36. char *stringbase;
  37. char *stringend;
  38. bfd_byte *raw_armap = NULL;
  39. carsym *carsyms;
  40. bfd_size_type amt;
  41. ufile_ptr filesize;
  42. ardata->symdefs = NULL;
  43. /* Get the name of the first element. */
  44. i = bfd_bread (nextname, 16, abfd);
  45. if (i == 0)
  46. return true;
  47. if (i != 16)
  48. return false;
  49. if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
  50. return false;
  51. /* Archives with traditional armaps are still permitted. */
  52. if (startswith (nextname, "/ "))
  53. return bfd_slurp_armap (abfd);
  54. if (! startswith (nextname, "/SYM64/ "))
  55. {
  56. abfd->has_armap = false;
  57. return true;
  58. }
  59. mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
  60. if (mapdata == NULL)
  61. return false;
  62. parsed_size = mapdata->parsed_size;
  63. free (mapdata);
  64. filesize = bfd_get_file_size (abfd);
  65. if (filesize != 0 && parsed_size > filesize)
  66. {
  67. bfd_set_error (bfd_error_malformed_archive);
  68. return false;
  69. }
  70. if (bfd_bread (int_buf, 8, abfd) != 8)
  71. {
  72. if (bfd_get_error () != bfd_error_system_call)
  73. bfd_set_error (bfd_error_malformed_archive);
  74. return false;
  75. }
  76. nsymz = bfd_getb64 (int_buf);
  77. stringsize = parsed_size - 8 * nsymz - 8;
  78. carsym_size = nsymz * sizeof (carsym);
  79. ptrsize = 8 * nsymz;
  80. amt = carsym_size + stringsize + 1;
  81. if (/* Catch overflow in stringsize (and ptrsize) expression. */
  82. nsymz >= (bfd_size_type) -1 / 8
  83. || stringsize > parsed_size
  84. /* Catch overflow in carsym_size expression. */
  85. || nsymz > (bfd_size_type) -1 / sizeof (carsym)
  86. /* Catch overflow in amt expression. */
  87. || amt <= carsym_size
  88. || amt <= stringsize)
  89. {
  90. bfd_set_error (bfd_error_malformed_archive);
  91. return false;
  92. }
  93. ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
  94. if (ardata->symdefs == NULL)
  95. return false;
  96. carsyms = ardata->symdefs;
  97. stringbase = ((char *) ardata->symdefs) + carsym_size;
  98. raw_armap = (bfd_byte *) _bfd_alloc_and_read (abfd, ptrsize, ptrsize);
  99. if (raw_armap == NULL
  100. || bfd_bread (stringbase, stringsize, abfd) != stringsize)
  101. {
  102. if (bfd_get_error () != bfd_error_system_call)
  103. bfd_set_error (bfd_error_malformed_archive);
  104. goto release_symdefs;
  105. }
  106. stringend = stringbase + stringsize;
  107. *stringend = 0;
  108. for (i = 0; i < nsymz; i++)
  109. {
  110. carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
  111. carsyms->name = stringbase;
  112. stringbase += strlen (stringbase);
  113. if (stringbase != stringend)
  114. ++stringbase;
  115. ++carsyms;
  116. }
  117. ardata->symdef_count = nsymz;
  118. ardata->first_file_filepos = bfd_tell (abfd);
  119. /* Pad to an even boundary if you have to. */
  120. ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
  121. abfd->has_armap = true;
  122. bfd_release (abfd, raw_armap);
  123. return true;
  124. release_symdefs:
  125. bfd_release (abfd, ardata->symdefs);
  126. return false;
  127. }
  128. /* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
  129. able to handle ordinary ELF armaps, but at least on Irix 6.2 the
  130. linker crashes. */
  131. bool
  132. _bfd_archive_64_bit_write_armap (bfd *arch,
  133. unsigned int elength,
  134. struct orl *map,
  135. unsigned int symbol_count,
  136. int stridx)
  137. {
  138. unsigned int ranlibsize = (symbol_count * 8) + 8;
  139. unsigned int stringsize = stridx;
  140. unsigned int mapsize = stringsize + ranlibsize;
  141. file_ptr archive_member_file_ptr;
  142. bfd *current = arch->archive_head;
  143. unsigned int count;
  144. struct ar_hdr hdr;
  145. int padding;
  146. bfd_byte buf[8];
  147. padding = BFD_ALIGN (mapsize, 8) - mapsize;
  148. mapsize += padding;
  149. /* work out where the first object file will go in the archive */
  150. archive_member_file_ptr = (mapsize
  151. + elength
  152. + sizeof (struct ar_hdr)
  153. + SARMAG);
  154. memset (&hdr, ' ', sizeof (struct ar_hdr));
  155. memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
  156. if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
  157. return false;
  158. _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
  159. time (NULL));
  160. /* This, at least, is what Intel coff sets the values to.: */
  161. _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
  162. _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
  163. _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
  164. memcpy (hdr.ar_fmag, ARFMAG, 2);
  165. /* Write the ar header for this item and the number of symbols */
  166. if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
  167. != sizeof (struct ar_hdr))
  168. return false;
  169. bfd_putb64 ((bfd_vma) symbol_count, buf);
  170. if (bfd_bwrite (buf, 8, arch) != 8)
  171. return false;
  172. /* Two passes, first write the file offsets for each symbol -
  173. remembering that each offset is on a two byte boundary. */
  174. /* Write out the file offset for the file associated with each
  175. symbol, and remember to keep the offsets padded out. */
  176. count = 0;
  177. for (current = arch->archive_head;
  178. current != NULL && count < symbol_count;
  179. current = current->archive_next)
  180. {
  181. /* For each symbol which is used defined in this object, write out
  182. the object file's address in the archive. */
  183. for (;
  184. count < symbol_count && map[count].u.abfd == current;
  185. count++)
  186. {
  187. bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
  188. if (bfd_bwrite (buf, 8, arch) != 8)
  189. return false;
  190. }
  191. /* Add size of this archive entry */
  192. archive_member_file_ptr += sizeof (struct ar_hdr);
  193. if (! bfd_is_thin_archive (arch))
  194. archive_member_file_ptr += arelt_size (current);
  195. /* remember about the even alignment */
  196. archive_member_file_ptr += archive_member_file_ptr % 2;
  197. }
  198. /* now write the strings themselves */
  199. for (count = 0; count < symbol_count; count++)
  200. {
  201. size_t len = strlen (*map[count].name) + 1;
  202. if (bfd_bwrite (*map[count].name, len, arch) != len)
  203. return false;
  204. }
  205. /* The spec says that this should be padded to an 8 byte boundary.
  206. However, the Irix 6.2 tools do not appear to do this. */
  207. while (padding != 0)
  208. {
  209. if (bfd_bwrite ("", 1, arch) != 1)
  210. return false;
  211. --padding;
  212. }
  213. return true;
  214. }