simple.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /* simple.c -- BFD simple client routines
  2. Copyright (C) 2002-2022 Free Software Foundation, Inc.
  3. Contributed by MontaVista Software, Inc.
  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. #include "sysdep.h"
  18. #include "bfd.h"
  19. #include "libbfd.h"
  20. #include "bfdlink.h"
  21. static void
  22. simple_dummy_add_to_set (struct bfd_link_info * info ATTRIBUTE_UNUSED,
  23. struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
  24. bfd_reloc_code_real_type reloc ATTRIBUTE_UNUSED,
  25. bfd *abfd ATTRIBUTE_UNUSED,
  26. asection *sec ATTRIBUTE_UNUSED,
  27. bfd_vma value ATTRIBUTE_UNUSED)
  28. {
  29. }
  30. static void
  31. simple_dummy_constructor (struct bfd_link_info * info ATTRIBUTE_UNUSED,
  32. bool constructor ATTRIBUTE_UNUSED,
  33. const char *name ATTRIBUTE_UNUSED,
  34. bfd *abfd ATTRIBUTE_UNUSED,
  35. asection *sec ATTRIBUTE_UNUSED,
  36. bfd_vma value ATTRIBUTE_UNUSED)
  37. {
  38. }
  39. static void
  40. simple_dummy_multiple_common (struct bfd_link_info * info ATTRIBUTE_UNUSED,
  41. struct bfd_link_hash_entry * entry ATTRIBUTE_UNUSED,
  42. bfd * abfd ATTRIBUTE_UNUSED,
  43. enum bfd_link_hash_type type ATTRIBUTE_UNUSED,
  44. bfd_vma size ATTRIBUTE_UNUSED)
  45. {
  46. }
  47. static void
  48. simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  49. const char *warning ATTRIBUTE_UNUSED,
  50. const char *symbol ATTRIBUTE_UNUSED,
  51. bfd *abfd ATTRIBUTE_UNUSED,
  52. asection *section ATTRIBUTE_UNUSED,
  53. bfd_vma address ATTRIBUTE_UNUSED)
  54. {
  55. }
  56. static void
  57. simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  58. const char *name ATTRIBUTE_UNUSED,
  59. bfd *abfd ATTRIBUTE_UNUSED,
  60. asection *section ATTRIBUTE_UNUSED,
  61. bfd_vma address ATTRIBUTE_UNUSED,
  62. bool fatal ATTRIBUTE_UNUSED)
  63. {
  64. }
  65. static void
  66. simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  67. struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
  68. const char *name ATTRIBUTE_UNUSED,
  69. const char *reloc_name ATTRIBUTE_UNUSED,
  70. bfd_vma addend ATTRIBUTE_UNUSED,
  71. bfd *abfd ATTRIBUTE_UNUSED,
  72. asection *section ATTRIBUTE_UNUSED,
  73. bfd_vma address ATTRIBUTE_UNUSED)
  74. {
  75. }
  76. static void
  77. simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  78. const char *message ATTRIBUTE_UNUSED,
  79. bfd *abfd ATTRIBUTE_UNUSED,
  80. asection *section ATTRIBUTE_UNUSED,
  81. bfd_vma address ATTRIBUTE_UNUSED)
  82. {
  83. }
  84. static void
  85. simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  86. const char *name ATTRIBUTE_UNUSED,
  87. bfd *abfd ATTRIBUTE_UNUSED,
  88. asection *section ATTRIBUTE_UNUSED,
  89. bfd_vma address ATTRIBUTE_UNUSED)
  90. {
  91. }
  92. static void
  93. simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  94. struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
  95. bfd *nbfd ATTRIBUTE_UNUSED,
  96. asection *nsec ATTRIBUTE_UNUSED,
  97. bfd_vma nval ATTRIBUTE_UNUSED)
  98. {
  99. }
  100. static void
  101. simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
  102. {
  103. }
  104. struct saved_output_info
  105. {
  106. bfd_vma offset;
  107. asection *section;
  108. };
  109. struct saved_offsets
  110. {
  111. unsigned int section_count;
  112. struct saved_output_info *sections;
  113. };
  114. /* The sections in ABFD may already have output sections and offsets
  115. set if we are here during linking.
  116. DWARF-2 specifies offsets into debug sections in many cases and
  117. bfd_simple_get_relocated_section_contents is called to relocate
  118. debug info for a single relocatable object file. So we want
  119. offsets relative to that object file's sections, not offsets in the
  120. output file. For that reason, reset a debug section->output_offset
  121. to zero.
  122. If not called during linking then set section->output_section to
  123. point back to the input section, because output_section must not be
  124. NULL when calling the relocation routines.
  125. Save the original output offset and section to restore later. */
  126. static void
  127. simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
  128. asection *section,
  129. void *ptr)
  130. {
  131. struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
  132. struct saved_output_info *output_info;
  133. output_info = &saved_offsets->sections[section->index];
  134. output_info->offset = section->output_offset;
  135. output_info->section = section->output_section;
  136. if ((section->flags & SEC_DEBUGGING) != 0
  137. || section->output_section == NULL)
  138. {
  139. section->output_offset = 0;
  140. section->output_section = section;
  141. }
  142. }
  143. static void
  144. simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
  145. asection *section,
  146. void *ptr)
  147. {
  148. struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
  149. struct saved_output_info *output_info;
  150. if (section->index >= saved_offsets->section_count)
  151. return;
  152. output_info = &saved_offsets->sections[section->index];
  153. section->output_offset = output_info->offset;
  154. section->output_section = output_info->section;
  155. }
  156. /*
  157. FUNCTION
  158. bfd_simple_relocate_secton
  159. SYNOPSIS
  160. bfd_byte *bfd_simple_get_relocated_section_contents
  161. (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
  162. DESCRIPTION
  163. Returns the relocated contents of section @var{sec}. The symbols in
  164. @var{symbol_table} will be used, or the symbols from @var{abfd} if
  165. @var{symbol_table} is NULL. The output offsets for debug sections will
  166. be temporarily reset to 0. The result will be stored at @var{outbuf}
  167. or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
  168. Returns @code{NULL} on a fatal error; ignores errors applying
  169. particular relocations.
  170. */
  171. bfd_byte *
  172. bfd_simple_get_relocated_section_contents (bfd *abfd,
  173. asection *sec,
  174. bfd_byte *outbuf,
  175. asymbol **symbol_table)
  176. {
  177. struct bfd_link_info link_info;
  178. struct bfd_link_order link_order;
  179. struct bfd_link_callbacks callbacks;
  180. bfd_byte *contents, *data;
  181. int storage_needed;
  182. struct saved_offsets saved_offsets;
  183. bfd *link_next;
  184. /* Don't apply relocation on executable and shared library. See
  185. PR 4756. */
  186. if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC
  187. || ! (sec->flags & SEC_RELOC))
  188. {
  189. contents = outbuf;
  190. if (!bfd_get_full_section_contents (abfd, sec, &contents))
  191. return NULL;
  192. return contents;
  193. }
  194. /* In order to use bfd_get_relocated_section_contents, we need
  195. to forge some data structures that it expects. */
  196. /* Fill in the bare minimum number of fields for our purposes. */
  197. memset (&link_info, 0, sizeof (link_info));
  198. link_info.output_bfd = abfd;
  199. link_info.input_bfds = abfd;
  200. link_info.input_bfds_tail = &abfd->link.next;
  201. link_next = abfd->link.next;
  202. abfd->link.next = NULL;
  203. link_info.hash = _bfd_generic_link_hash_table_create (abfd);
  204. link_info.callbacks = &callbacks;
  205. /* Make sure that any fields not initialised below do not
  206. result in a potential indirection via a random address. */
  207. memset (&callbacks, 0, sizeof callbacks);
  208. callbacks.warning = simple_dummy_warning;
  209. callbacks.undefined_symbol = simple_dummy_undefined_symbol;
  210. callbacks.reloc_overflow = simple_dummy_reloc_overflow;
  211. callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
  212. callbacks.unattached_reloc = simple_dummy_unattached_reloc;
  213. callbacks.multiple_definition = simple_dummy_multiple_definition;
  214. callbacks.einfo = simple_dummy_einfo;
  215. callbacks.multiple_common = simple_dummy_multiple_common;
  216. callbacks.constructor = simple_dummy_constructor;
  217. callbacks.add_to_set = simple_dummy_add_to_set;
  218. memset (&link_order, 0, sizeof (link_order));
  219. link_order.next = NULL;
  220. link_order.type = bfd_indirect_link_order;
  221. link_order.offset = 0;
  222. link_order.size = sec->size;
  223. link_order.u.indirect.section = sec;
  224. data = NULL;
  225. if (outbuf == NULL)
  226. {
  227. bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
  228. data = (bfd_byte *) bfd_malloc (amt);
  229. if (data == NULL)
  230. {
  231. _bfd_generic_link_hash_table_free (abfd);
  232. abfd->link.next = link_next;
  233. return NULL;
  234. }
  235. outbuf = data;
  236. }
  237. saved_offsets.section_count = abfd->section_count;
  238. saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
  239. * saved_offsets.section_count);
  240. if (saved_offsets.sections == NULL)
  241. {
  242. free (data);
  243. _bfd_generic_link_hash_table_free (abfd);
  244. abfd->link.next = link_next;
  245. return NULL;
  246. }
  247. bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
  248. if (symbol_table == NULL)
  249. {
  250. _bfd_generic_link_add_symbols (abfd, &link_info);
  251. storage_needed = bfd_get_symtab_upper_bound (abfd);
  252. symbol_table = (asymbol **) bfd_malloc (storage_needed);
  253. bfd_canonicalize_symtab (abfd, symbol_table);
  254. }
  255. else
  256. storage_needed = 0;
  257. contents = bfd_get_relocated_section_contents (abfd,
  258. &link_info,
  259. &link_order,
  260. outbuf,
  261. 0,
  262. symbol_table);
  263. if (contents == NULL)
  264. free (data);
  265. bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
  266. free (saved_offsets.sections);
  267. _bfd_generic_link_hash_table_free (abfd);
  268. abfd->link.next = link_next;
  269. return contents;
  270. }