obj-aout.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /* a.out object file format
  2. Copyright (C) 1989-2015 Free Software Foundation, Inc.
  3. This file is part of GAS, the GNU Assembler.
  4. GAS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as
  6. published by the Free Software Foundation; either version 3,
  7. or (at your option) any later version.
  8. GAS is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  11. the GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GAS; see the file COPYING. If not, write to the Free
  14. Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
  15. 02110-1301, USA. */
  16. #define OBJ_HEADER "obj-aout.h"
  17. #include "as.h"
  18. #undef NO_RELOC
  19. #include "aout/aout64.h"
  20. void
  21. obj_aout_frob_symbol (symbolS *sym, int *punt ATTRIBUTE_UNUSED)
  22. {
  23. flagword flags;
  24. asection *sec;
  25. int type;
  26. flags = symbol_get_bfdsym (sym)->flags;
  27. type = aout_symbol (symbol_get_bfdsym (sym))->type;
  28. sec = S_GET_SEGMENT (sym);
  29. /* Only frob simple symbols this way right now. */
  30. if (! (type & ~ (N_TYPE | N_EXT)))
  31. {
  32. if (type == (N_UNDF | N_EXT)
  33. && sec == bfd_abs_section_ptr)
  34. {
  35. sec = bfd_und_section_ptr;
  36. S_SET_SEGMENT (sym, sec);
  37. }
  38. if ((type & N_TYPE) != N_INDR
  39. && (type & N_TYPE) != N_SETA
  40. && (type & N_TYPE) != N_SETT
  41. && (type & N_TYPE) != N_SETD
  42. && (type & N_TYPE) != N_SETB
  43. && type != N_WARNING
  44. && (sec == bfd_abs_section_ptr
  45. || sec == bfd_und_section_ptr))
  46. return;
  47. if (flags & BSF_EXPORT)
  48. type |= N_EXT;
  49. switch (type & N_TYPE)
  50. {
  51. case N_SETA:
  52. case N_SETT:
  53. case N_SETD:
  54. case N_SETB:
  55. /* Set the debugging flag for constructor symbols so that
  56. BFD leaves them alone. */
  57. symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
  58. /* You can't put a common symbol in a set. The way a set
  59. element works is that the symbol has a definition and a
  60. name, and the linker adds the definition to the set of
  61. that name. That does not work for a common symbol,
  62. because the linker can't tell which common symbol the
  63. user means. FIXME: Using as_bad here may be
  64. inappropriate, since the user may want to force a
  65. particular type without regard to the semantics of sets;
  66. on the other hand, we certainly don't want anybody to be
  67. mislead into thinking that their code will work. */
  68. if (S_IS_COMMON (sym))
  69. as_bad (_("Attempt to put a common symbol into set %s"),
  70. S_GET_NAME (sym));
  71. /* Similarly, you can't put an undefined symbol in a set. */
  72. else if (! S_IS_DEFINED (sym))
  73. as_bad (_("Attempt to put an undefined symbol into set %s"),
  74. S_GET_NAME (sym));
  75. break;
  76. case N_INDR:
  77. /* Put indirect symbols in the indirect section. */
  78. S_SET_SEGMENT (sym, bfd_ind_section_ptr);
  79. symbol_get_bfdsym (sym)->flags |= BSF_INDIRECT;
  80. if (type & N_EXT)
  81. {
  82. symbol_get_bfdsym (sym)->flags |= BSF_EXPORT;
  83. symbol_get_bfdsym (sym)->flags &=~ BSF_LOCAL;
  84. }
  85. break;
  86. case N_WARNING:
  87. /* Mark warning symbols. */
  88. symbol_get_bfdsym (sym)->flags |= BSF_WARNING;
  89. break;
  90. }
  91. }
  92. else
  93. symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
  94. aout_symbol (symbol_get_bfdsym (sym))->type = type;
  95. /* Double check weak symbols. */
  96. if (S_IS_WEAK (sym) && S_IS_COMMON (sym))
  97. as_bad (_("Symbol `%s' can not be both weak and common"),
  98. S_GET_NAME (sym));
  99. }
  100. void
  101. obj_aout_frob_file_before_fix (void)
  102. {
  103. /* Relocation processing may require knowing the VMAs of the sections.
  104. Since writing to a section will cause the BFD back end to compute the
  105. VMAs, fake it out here.... */
  106. bfd_byte b = 0;
  107. bfd_boolean x = TRUE;
  108. if (bfd_section_size (stdoutput, text_section) != 0)
  109. x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
  110. (bfd_size_type) 1);
  111. else if (bfd_section_size (stdoutput, data_section) != 0)
  112. x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
  113. (bfd_size_type) 1);
  114. gas_assert (x);
  115. }
  116. static void
  117. obj_aout_line (int ignore ATTRIBUTE_UNUSED)
  118. {
  119. /* Assume delimiter is part of expression.
  120. BSD4.2 as fails with delightful bug, so we
  121. are not being incompatible here. */
  122. new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
  123. demand_empty_rest_of_line ();
  124. }
  125. /* Handle .weak. This is a GNU extension. */
  126. static void
  127. obj_aout_weak (int ignore ATTRIBUTE_UNUSED)
  128. {
  129. char *name;
  130. int c;
  131. symbolS *symbolP;
  132. do
  133. {
  134. c = get_symbol_name (&name);
  135. symbolP = symbol_find_or_make (name);
  136. (void) restore_line_pointer (c);
  137. SKIP_WHITESPACE ();
  138. S_SET_WEAK (symbolP);
  139. if (c == ',')
  140. {
  141. input_line_pointer++;
  142. SKIP_WHITESPACE ();
  143. if (*input_line_pointer == '\n')
  144. c = '\n';
  145. }
  146. }
  147. while (c == ',');
  148. demand_empty_rest_of_line ();
  149. }
  150. /* Handle .type. On {Net,Open}BSD, this is used to set the n_other field,
  151. which is then apparently used when doing dynamic linking. Older
  152. versions of gas ignored the .type pseudo-op, so we also ignore it if
  153. we can't parse it. */
  154. static void
  155. obj_aout_type (int ignore ATTRIBUTE_UNUSED)
  156. {
  157. char *name;
  158. int c;
  159. symbolS *sym;
  160. c = get_symbol_name (&name);
  161. sym = symbol_find_or_make (name);
  162. (void) restore_line_pointer (c);
  163. SKIP_WHITESPACE ();
  164. if (*input_line_pointer == ',')
  165. {
  166. ++input_line_pointer;
  167. SKIP_WHITESPACE ();
  168. if (*input_line_pointer == '@')
  169. {
  170. ++input_line_pointer;
  171. if (strncmp (input_line_pointer, "object", 6) == 0)
  172. S_SET_OTHER (sym, 1);
  173. else if (strncmp (input_line_pointer, "function", 8) == 0)
  174. S_SET_OTHER (sym, 2);
  175. }
  176. }
  177. /* Ignore everything else on the line. */
  178. s_ignore (0);
  179. }
  180. /* Support for an AOUT emulation. */
  181. static void
  182. aout_pop_insert (void)
  183. {
  184. pop_insert (aout_pseudo_table);
  185. }
  186. static int
  187. obj_aout_s_get_other (symbolS *sym)
  188. {
  189. return aout_symbol (symbol_get_bfdsym (sym))->other;
  190. }
  191. static void
  192. obj_aout_s_set_other (symbolS *sym, int o)
  193. {
  194. aout_symbol (symbol_get_bfdsym (sym))->other = o;
  195. }
  196. static int
  197. obj_aout_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
  198. {
  199. return obj_sec_sym_ok_for_reloc (sec);
  200. }
  201. static void
  202. obj_aout_process_stab (segT seg ATTRIBUTE_UNUSED,
  203. int w,
  204. const char *s,
  205. int t,
  206. int o,
  207. int d)
  208. {
  209. aout_process_stab (w, s, t, o, d);
  210. }
  211. static int
  212. obj_aout_s_get_desc (symbolS *sym)
  213. {
  214. return aout_symbol (symbol_get_bfdsym (sym))->desc;
  215. }
  216. static void
  217. obj_aout_s_set_desc (symbolS *sym, int d)
  218. {
  219. aout_symbol (symbol_get_bfdsym (sym))->desc = d;
  220. }
  221. static int
  222. obj_aout_s_get_type (symbolS *sym)
  223. {
  224. return aout_symbol (symbol_get_bfdsym (sym))->type;
  225. }
  226. static void
  227. obj_aout_s_set_type (symbolS *sym, int t)
  228. {
  229. aout_symbol (symbol_get_bfdsym (sym))->type = t;
  230. }
  231. static int
  232. obj_aout_separate_stab_sections (void)
  233. {
  234. return 0;
  235. }
  236. /* When changed, make sure these table entries match the single-format
  237. definitions in obj-aout.h. */
  238. const struct format_ops aout_format_ops =
  239. {
  240. bfd_target_aout_flavour,
  241. 1, /* dfl_leading_underscore. */
  242. 0, /* emit_section_symbols. */
  243. 0, /* begin. */
  244. 0, /* app_file. */
  245. obj_aout_frob_symbol,
  246. 0, /* frob_file. */
  247. 0, /* frob_file_before_adjust. */
  248. obj_aout_frob_file_before_fix,
  249. 0, /* frob_file_after_relocs. */
  250. 0, /* s_get_size. */
  251. 0, /* s_set_size. */
  252. 0, /* s_get_align. */
  253. 0, /* s_set_align. */
  254. obj_aout_s_get_other,
  255. obj_aout_s_set_other,
  256. obj_aout_s_get_desc,
  257. obj_aout_s_set_desc,
  258. obj_aout_s_get_type,
  259. obj_aout_s_set_type,
  260. 0, /* copy_symbol_attributes. */
  261. 0, /* generate_asm_lineno. */
  262. obj_aout_process_stab,
  263. obj_aout_separate_stab_sections,
  264. 0, /* init_stab_section. */
  265. obj_aout_sec_sym_ok_for_reloc,
  266. aout_pop_insert,
  267. 0, /* ecoff_set_ext. */
  268. 0, /* read_begin_hook. */
  269. 0, /* symbol_new_hook. */
  270. 0, /* symbol_clone_hook. */
  271. 0 /* adjust_symtab. */
  272. };
  273. const pseudo_typeS aout_pseudo_table[] =
  274. {
  275. {"line", obj_aout_line, 0}, /* Source code line number. */
  276. {"ln", obj_aout_line, 0}, /* COFF line number that we use anyway. */
  277. {"weak", obj_aout_weak, 0}, /* Mark symbol as weak. */
  278. {"type", obj_aout_type, 0},
  279. /* coff debug pseudos (ignored) */
  280. {"def", s_ignore, 0},
  281. {"dim", s_ignore, 0},
  282. {"endef", s_ignore, 0},
  283. {"ident", s_ignore, 0},
  284. {"line", s_ignore, 0},
  285. {"ln", s_ignore, 0},
  286. {"scl", s_ignore, 0},
  287. {"size", s_ignore, 0},
  288. {"tag", s_ignore, 0},
  289. {"val", s_ignore, 0},
  290. {"version", s_ignore, 0},
  291. {"optim", s_ignore, 0}, /* For sun386i cc (?). */
  292. /* other stuff */
  293. {"ABORT", s_abort, 0},
  294. {NULL, NULL, 0}
  295. };