coff-go32.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* BFD back-end for Intel 386 COFF files (DJGPP variant).
  2. Copyright (C) 1990-2022 Free Software Foundation, Inc.
  3. Written by DJ Delorie.
  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. #define TARGET_SYM i386_coff_go32_vec
  18. #define TARGET_NAME "coff-go32"
  19. #define TARGET_UNDERSCORE '_'
  20. #define COFF_GO32
  21. #define COFF_LONG_SECTION_NAMES
  22. #define COFF_SUPPORT_GNU_LINKONCE
  23. #define COFF_LONG_FILENAMES
  24. #define COFF_SECTION_ALIGNMENT_ENTRIES \
  25. { COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \
  26. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  27. { COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \
  28. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  29. { COFF_SECTION_NAME_PARTIAL_MATCH (".const"), \
  30. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  31. { COFF_SECTION_NAME_PARTIAL_MATCH (".rodata"), \
  32. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  33. { COFF_SECTION_NAME_PARTIAL_MATCH (".bss"), \
  34. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  35. { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \
  36. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  37. { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \
  38. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  39. { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \
  40. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  41. { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.b"), \
  42. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
  43. { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
  44. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
  45. { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
  46. COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
  47. /* Section contains extended relocations. */
  48. #define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000)
  49. #include "sysdep.h"
  50. #include "bfd.h"
  51. /* The following functions are not static, because they are also
  52. used for coff-go32-exe (coff-stgo32.c). */
  53. bool _bfd_go32_mkobject (bfd *);
  54. void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *);
  55. unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *);
  56. #define coff_mkobject _bfd_go32_mkobject
  57. #define coff_SWAP_scnhdr_in _bfd_go32_swap_scnhdr_in
  58. #define coff_SWAP_scnhdr_out _bfd_go32_swap_scnhdr_out
  59. #include "coff-i386.c"
  60. bool
  61. _bfd_go32_mkobject (bfd * abfd)
  62. {
  63. const bfd_size_type amt = sizeof (coff_data_type);
  64. abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
  65. if (abfd->tdata.coff_obj_data == NULL)
  66. return false;
  67. coff_data (abfd)->go32 = true;
  68. return true;
  69. }
  70. void
  71. _bfd_go32_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
  72. {
  73. SCNHDR *scnhdr_ext = (SCNHDR *) ext;
  74. struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
  75. memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
  76. scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
  77. scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
  78. scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
  79. scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
  80. scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
  81. scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
  82. scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
  83. scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
  84. scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
  85. /* DJGPP follows the same strategy as PE COFF.
  86. Iff the file is an executable then the higher 16 bits
  87. of the line number have been stored in the relocation
  88. counter field. */
  89. if (abfd->flags & EXEC_P && (strcmp (scnhdr_ext->s_name, ".text") == 0))
  90. {
  91. scnhdr_int->s_nlnno
  92. = (GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc) << 16)
  93. + GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
  94. scnhdr_int->s_nreloc = 0;
  95. }
  96. }
  97. unsigned int
  98. _bfd_go32_swap_scnhdr_out (bfd * abfd, void * in, void * out)
  99. {
  100. struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
  101. SCNHDR *scnhdr_ext = (SCNHDR *) out;
  102. unsigned int ret = bfd_coff_scnhsz (abfd);
  103. memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
  104. PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
  105. PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
  106. PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
  107. PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
  108. PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
  109. PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
  110. PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
  111. if (abfd->flags & EXEC_P && (strcmp (scnhdr_int->s_name, ".text") == 0))
  112. {
  113. /* DJGPP follows the same strategy as PE COFF.
  114. By inference from looking at MS output, the 32 bit field
  115. which is the combination of the number_of_relocs and
  116. number_of_linenos is used for the line number count in
  117. executables. A 16-bit field won't do for cc1. The MS
  118. document says that the number of relocs is zero for
  119. executables, but the 17-th bit has been observed to be there.
  120. Overflow is not an issue: a 4G-line program will overflow a
  121. bunch of other fields long before this! */
  122. PUT_SCNHDR_NLNNO (abfd, (scnhdr_int->s_nlnno & 0xffff),
  123. scnhdr_ext->s_nlnno);
  124. PUT_SCNHDR_NRELOC (abfd, (scnhdr_int->s_nlnno >> 16),
  125. scnhdr_ext->s_nreloc);
  126. }
  127. else
  128. {
  129. /* DJGPP follows the same strategy as PE COFF. */
  130. if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
  131. PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
  132. else
  133. {
  134. char buf[sizeof (scnhdr_int->s_name) + 1];
  135. memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
  136. buf[sizeof (scnhdr_int->s_name)] = '\0';
  137. _bfd_error_handler
  138. /* xgettext:c-format */
  139. (_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
  140. abfd, buf, scnhdr_int->s_nlnno);
  141. bfd_set_error (bfd_error_file_truncated);
  142. PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
  143. ret = 0;
  144. }
  145. /* Although we could encode 0xffff relocs here, we do not, to be
  146. consistent with other parts of bfd. Also it lets us warn, as
  147. we should never see 0xffff here w/o having the overflow flag
  148. set. */
  149. if (scnhdr_int->s_nreloc < MAX_SCNHDR_NRELOC)
  150. PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
  151. else
  152. {
  153. /* DJGPP can deal with large #s of relocs, but not here. */
  154. PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
  155. scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
  156. PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
  157. }
  158. }
  159. return ret;
  160. }