xref: /openbsd-src/gnu/usr.bin/binutils/gas/config/obj-bout.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* b.out object file format
2c074d1c9Sdrahn    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002
3191aa565Sniklas    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas    This file is part of GAS, the GNU Assembler.
62159047fSniklas 
72159047fSniklas    GAS is free software; you can redistribute it and/or modify
82159047fSniklas    it under the terms of the GNU General Public License as
92159047fSniklas    published by the Free Software Foundation; either version 2,
102159047fSniklas    or (at your option) any later version.
112159047fSniklas 
122159047fSniklas    GAS is distributed in the hope that it will be useful, but
132159047fSniklas    WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
152159047fSniklas    the GNU General Public License for more details.
162159047fSniklas 
17b305b0f1Sespie    You should have received a copy of the GNU General Public License
18b305b0f1Sespie    along with GAS; see the file COPYING.  If not, write to the Free
19b305b0f1Sespie    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20b305b0f1Sespie    02111-1307, USA.  */
212159047fSniklas 
222159047fSniklas #include "as.h"
232159047fSniklas #include "obstack.h"
24b55d4692Sfgsch 
25b55d4692Sfgsch /* In: segT   Out: N_TYPE bits  */
26b55d4692Sfgsch const short seg_N_TYPE[] =
272159047fSniklas {
282159047fSniklas   N_ABS,
292159047fSniklas   N_TEXT,
302159047fSniklas   N_DATA,
312159047fSniklas   N_BSS,
322159047fSniklas   N_UNDF,			/* unknown  */
332159047fSniklas   N_UNDF,			/* error  */
342159047fSniklas   N_UNDF,			/* expression  */
352159047fSniklas   N_UNDF,			/* debug  */
362159047fSniklas   N_UNDF,			/* ntv  */
372159047fSniklas   N_UNDF,			/* ptv  */
382159047fSniklas   N_REGISTER,			/* register  */
392159047fSniklas };
402159047fSniklas 
412159047fSniklas const segT N_TYPE_seg[N_TYPE + 2] =
422159047fSniklas {				/* N_TYPE == 0x1E = 32-2  */
432159047fSniklas   SEG_UNKNOWN,			/* N_UNDF == 0  */
442159047fSniklas   SEG_GOOF,
452159047fSniklas   SEG_ABSOLUTE,			/* N_ABS == 2  */
462159047fSniklas   SEG_GOOF,
472159047fSniklas   SEG_TEXT,			/* N_TEXT == 4  */
482159047fSniklas   SEG_GOOF,
492159047fSniklas   SEG_DATA,			/* N_DATA == 6  */
502159047fSniklas   SEG_GOOF,
512159047fSniklas   SEG_BSS,			/* N_BSS == 8  */
522159047fSniklas   SEG_GOOF,
532159047fSniklas   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
542159047fSniklas   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
552159047fSniklas   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
562159047fSniklas   SEG_REGISTER,			/* dummy N_REGISTER for regs = 30  */
572159047fSniklas   SEG_GOOF,
582159047fSniklas };
592159047fSniklas 
602159047fSniklas static void obj_bout_line PARAMS ((int));
612159047fSniklas 
622159047fSniklas const pseudo_typeS obj_pseudo_table[] =
632159047fSniklas {
64b55d4692Sfgsch   {"line", obj_bout_line, 0},	/* Source code line number.  */
652159047fSniklas 
66b55d4692Sfgsch /* coff debugging directives.  Currently ignored silently.  */
672159047fSniklas   {"def", s_ignore, 0},
682159047fSniklas   {"dim", s_ignore, 0},
692159047fSniklas   {"endef", s_ignore, 0},
702159047fSniklas   {"ln", s_ignore, 0},
712159047fSniklas   {"scl", s_ignore, 0},
722159047fSniklas   {"size", s_ignore, 0},
732159047fSniklas   {"tag", s_ignore, 0},
742159047fSniklas   {"type", s_ignore, 0},
752159047fSniklas   {"val", s_ignore, 0},
762159047fSniklas 
772159047fSniklas /* other stuff we don't handle */
782159047fSniklas   {"ABORT", s_ignore, 0},
792159047fSniklas   {"ident", s_ignore, 0},
802159047fSniklas 
81c074d1c9Sdrahn   {NULL, NULL, 0}		/* End sentinel.  */
82b55d4692Sfgsch };
832159047fSniklas 
842159047fSniklas /* Relocation.  */
852159047fSniklas 
86b55d4692Sfgsch /* Crawl along a fixS chain. Emit the segment's relocations.  */
87b55d4692Sfgsch 
882159047fSniklas void
obj_emit_relocations(where,fixP,segment_address_in_file)892159047fSniklas obj_emit_relocations (where, fixP, segment_address_in_file)
902159047fSniklas      char **where;
912159047fSniklas      fixS *fixP;		/* Fixup chain for this segment.  */
922159047fSniklas      relax_addressT segment_address_in_file;
932159047fSniklas {
942159047fSniklas   for (; fixP; fixP = fixP->fx_next)
952159047fSniklas     {
962159047fSniklas       if (fixP->fx_done == 0
972159047fSniklas 	  || fixP->fx_r_type != NO_RELOC)
982159047fSniklas 	{
99191aa565Sniklas 	  symbolS *sym;
100191aa565Sniklas 
101191aa565Sniklas 	  sym = fixP->fx_addsy;
102191aa565Sniklas 	  while (sym->sy_value.X_op == O_symbol
103191aa565Sniklas 		 && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
104191aa565Sniklas 	    sym = sym->sy_value.X_add_symbol;
105191aa565Sniklas 	  fixP->fx_addsy = sym;
106191aa565Sniklas 
1072159047fSniklas 	  tc_bout_fix_to_chars (*where, fixP, segment_address_in_file);
1082159047fSniklas 	  *where += sizeof (struct relocation_info);
1092159047fSniklas 	}			/* if there's a symbol  */
1102159047fSniklas     }				/* for each fixup  */
111b55d4692Sfgsch }
1122159047fSniklas 
113b55d4692Sfgsch /* Aout file generation & utilities .  */
1142159047fSniklas 
115b55d4692Sfgsch /* Convert a lvalue to machine dependent data.  */
1162159047fSniklas 
1172159047fSniklas void
obj_header_append(where,headers)1182159047fSniklas obj_header_append (where, headers)
1192159047fSniklas      char **where;
1202159047fSniklas      object_headers *headers;
1212159047fSniklas {
122b55d4692Sfgsch   /* Always leave in host byte order.  */
1232159047fSniklas 
1242159047fSniklas   headers->header.a_talign = section_alignment[SEG_TEXT];
1252159047fSniklas 
126b55d4692Sfgsch   /* Force to at least 2.  */
1272159047fSniklas   if (headers->header.a_talign < 2)
1282159047fSniklas     {
1292159047fSniklas       headers->header.a_talign = 2;
130b55d4692Sfgsch     }
1312159047fSniklas 
1322159047fSniklas   headers->header.a_dalign = section_alignment[SEG_DATA];
1332159047fSniklas   headers->header.a_balign = section_alignment[SEG_BSS];
1342159047fSniklas 
1352159047fSniklas   headers->header.a_tload = 0;
136b55d4692Sfgsch   headers->header.a_dload =
137b55d4692Sfgsch     md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers));
1382159047fSniklas 
1392159047fSniklas   headers->header.a_relaxable = linkrelax;
1402159047fSniklas 
1412159047fSniklas #ifdef CROSS_COMPILE
1422159047fSniklas   md_number_to_chars (*where, headers->header.a_magic, sizeof (headers->header.a_magic));
1432159047fSniklas   *where += sizeof (headers->header.a_magic);
1442159047fSniklas   md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
1452159047fSniklas   *where += sizeof (headers->header.a_text);
1462159047fSniklas   md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
1472159047fSniklas   *where += sizeof (headers->header.a_data);
1482159047fSniklas   md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
1492159047fSniklas   *where += sizeof (headers->header.a_bss);
1502159047fSniklas   md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
1512159047fSniklas   *where += sizeof (headers->header.a_syms);
1522159047fSniklas   md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
1532159047fSniklas   *where += sizeof (headers->header.a_entry);
1542159047fSniklas   md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
1552159047fSniklas   *where += sizeof (headers->header.a_trsize);
1562159047fSniklas   md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
1572159047fSniklas   *where += sizeof (headers->header.a_drsize);
1582159047fSniklas   md_number_to_chars (*where, headers->header.a_tload, sizeof (headers->header.a_tload));
1592159047fSniklas   *where += sizeof (headers->header.a_tload);
1602159047fSniklas   md_number_to_chars (*where, headers->header.a_dload, sizeof (headers->header.a_dload));
1612159047fSniklas   *where += sizeof (headers->header.a_dload);
1622159047fSniklas   md_number_to_chars (*where, headers->header.a_talign, sizeof (headers->header.a_talign));
1632159047fSniklas   *where += sizeof (headers->header.a_talign);
1642159047fSniklas   md_number_to_chars (*where, headers->header.a_dalign, sizeof (headers->header.a_dalign));
1652159047fSniklas   *where += sizeof (headers->header.a_dalign);
1662159047fSniklas   md_number_to_chars (*where, headers->header.a_balign, sizeof (headers->header.a_balign));
1672159047fSniklas   *where += sizeof (headers->header.a_balign);
1682159047fSniklas   md_number_to_chars (*where, headers->header.a_relaxable, sizeof (headers->header.a_relaxable));
1692159047fSniklas   *where += sizeof (headers->header.a_relaxable);
1702159047fSniklas #else /* ! CROSS_COMPILE */
1712159047fSniklas   append (where, (char *) &headers->header, sizeof (headers->header));
1722159047fSniklas #endif /* ! CROSS_COMPILE */
173b55d4692Sfgsch }
1742159047fSniklas 
1752159047fSniklas void
obj_symbol_to_chars(where,symbolP)1762159047fSniklas obj_symbol_to_chars (where, symbolP)
1772159047fSniklas      char **where;
1782159047fSniklas      symbolS *symbolP;
1792159047fSniklas {
180b55d4692Sfgsch   md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)),
181b55d4692Sfgsch 		      S_GET_OFFSET (symbolP),
182b55d4692Sfgsch 		      sizeof (S_GET_OFFSET (symbolP)));
183b55d4692Sfgsch 
184b55d4692Sfgsch   md_number_to_chars ((char *) &(S_GET_DESC (symbolP)),
185b55d4692Sfgsch 		      S_GET_DESC (symbolP),
186b55d4692Sfgsch 		      sizeof (S_GET_DESC (symbolP)));
187b55d4692Sfgsch 
188b55d4692Sfgsch   md_number_to_chars ((char *) &symbolP->sy_symbol.n_value,
189b55d4692Sfgsch 		      S_GET_VALUE (symbolP),
190b55d4692Sfgsch 		      sizeof (symbolP->sy_symbol.n_value));
1912159047fSniklas 
1922159047fSniklas   append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
193b55d4692Sfgsch }
1942159047fSniklas 
1952159047fSniklas void
obj_emit_symbols(where,symbol_rootP)1962159047fSniklas obj_emit_symbols (where, symbol_rootP)
1972159047fSniklas      char **where;
1982159047fSniklas      symbolS *symbol_rootP;
1992159047fSniklas {
2002159047fSniklas   symbolS *symbolP;
2012159047fSniklas 
202b55d4692Sfgsch   /* Emit all symbols left in the symbol chain.  */
2032159047fSniklas   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
2042159047fSniklas     {
205b55d4692Sfgsch       /* Used to save the offset of the name.  It is used to point to
206b55d4692Sfgsch 	 the string in memory but must be a file offset.  */
2072159047fSniklas       char *temp;
2082159047fSniklas 
2092159047fSniklas       temp = S_GET_NAME (symbolP);
2102159047fSniklas       S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
2112159047fSniklas 
2122159047fSniklas       /* Any symbol still undefined and is not a dbg symbol is made N_EXT.  */
2132159047fSniklas       if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
2142159047fSniklas 	S_SET_EXTERNAL (symbolP);
2152159047fSniklas 
2162159047fSniklas       obj_symbol_to_chars (where, symbolP);
2172159047fSniklas       S_SET_NAME (symbolP, temp);
2182159047fSniklas     }
219b55d4692Sfgsch }
2202159047fSniklas 
2212159047fSniklas void
obj_symbol_new_hook(symbolP)2222159047fSniklas obj_symbol_new_hook (symbolP)
2232159047fSniklas      symbolS *symbolP;
2242159047fSniklas {
2252159047fSniklas   S_SET_OTHER (symbolP, 0);
2262159047fSniklas   S_SET_DESC (symbolP, 0);
2272159047fSniklas }
2282159047fSniklas 
2292159047fSniklas static void
obj_bout_line(ignore)2302159047fSniklas obj_bout_line (ignore)
231c074d1c9Sdrahn      int ignore ATTRIBUTE_UNUSED;
2322159047fSniklas {
2332159047fSniklas   /* Assume delimiter is part of expression.  */
234b55d4692Sfgsch   /* BSD4.2 as fails with delightful bug, so we are not being
235b55d4692Sfgsch      incompatible here.  */
2362159047fSniklas   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
2372159047fSniklas   demand_empty_rest_of_line ();
238b55d4692Sfgsch }
2392159047fSniklas 
2402159047fSniklas void
obj_read_begin_hook()2412159047fSniklas obj_read_begin_hook ()
2422159047fSniklas {
2432159047fSniklas }
2442159047fSniklas 
2452159047fSniklas void
obj_crawl_symbol_chain(headers)2462159047fSniklas obj_crawl_symbol_chain (headers)
2472159047fSniklas      object_headers *headers;
2482159047fSniklas {
2492159047fSniklas   symbolS **symbolPP;
2502159047fSniklas   symbolS *symbolP;
2512159047fSniklas   int symbol_number = 0;
2522159047fSniklas 
2532159047fSniklas   tc_crawl_symbol_chain (headers);
2542159047fSniklas 
2552159047fSniklas   symbolPP = &symbol_rootP;	/* -> last symbol chain link.  */
2562159047fSniklas   while ((symbolP = *symbolPP) != NULL)
2572159047fSniklas     {
2582159047fSniklas       if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
2592159047fSniklas 	{
2602159047fSniklas 	  S_SET_SEGMENT (symbolP, SEG_TEXT);
261*007c2a45Smiod 	}			/* if pushing data into text  */
2622159047fSniklas 
263c074d1c9Sdrahn       resolve_symbol_value (symbolP);
2642159047fSniklas 
265191aa565Sniklas       /* Skip symbols which were equated to undefined or common
266191aa565Sniklas 	 symbols.  */
267191aa565Sniklas       if (symbolP->sy_value.X_op == O_symbol
268191aa565Sniklas 	  && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
269191aa565Sniklas 	{
270191aa565Sniklas 	  *symbolPP = symbol_next (symbolP);
271191aa565Sniklas 	  continue;
272191aa565Sniklas 	}
273191aa565Sniklas 
2742159047fSniklas       /* OK, here is how we decide which symbols go out into the
2752159047fSniklas 	 brave new symtab.  Symbols that do are:
2762159047fSniklas 
2772159047fSniklas 	 * symbols with no name (stabd's?)
2782159047fSniklas 	 * symbols with debug info in their N_TYPE
2792159047fSniklas 
2802159047fSniklas 	 Symbols that don't are:
2812159047fSniklas 	 * symbols that are registers
2822159047fSniklas 	 * symbols with \1 as their 3rd character (numeric labels)
2832159047fSniklas 	 * "local labels" as defined by S_LOCAL_NAME(name)
2842159047fSniklas 	 if the -L switch was passed to gas.
2852159047fSniklas 
2862159047fSniklas 	 All other symbols are output.  We complain if a deleted
2872159047fSniklas 	 symbol was marked external.  */
2882159047fSniklas 
2892159047fSniklas       if (1
2902159047fSniklas 	  && !S_IS_REGISTER (symbolP)
2912159047fSniklas 	  && (!S_GET_NAME (symbolP)
2922159047fSniklas 	      || S_IS_DEBUG (symbolP)
2932159047fSniklas #ifdef TC_I960
2942159047fSniklas       /* FIXME-SOON this ifdef seems highly dubious to me.  xoxorich.  */
2952159047fSniklas 	      || !S_IS_DEFINED (symbolP)
2962159047fSniklas 	      || S_IS_EXTERNAL (symbolP)
2972159047fSniklas #endif /* TC_I960 */
298b55d4692Sfgsch 	      || (S_GET_NAME (symbolP)[0] != '\001'
299b55d4692Sfgsch 		  && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
3002159047fSniklas 	{
3012159047fSniklas 	  symbolP->sy_number = symbol_number++;
3022159047fSniklas 
303b55d4692Sfgsch 	  /* The + 1 after strlen account for the \0 at the end of
304b55d4692Sfgsch 	     each string.  */
3052159047fSniklas 	  if (!S_IS_STABD (symbolP))
3062159047fSniklas 	    {
3072159047fSniklas 	      /* Ordinary case.  */
3082159047fSniklas 	      symbolP->sy_name_offset = string_byte_count;
3092159047fSniklas 	      string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
3102159047fSniklas 	    }
3112159047fSniklas 	  else			/* .Stabd case.  */
3122159047fSniklas 	    symbolP->sy_name_offset = 0;
313b55d4692Sfgsch 	  symbolPP = &(symbolP->sy_next);
3142159047fSniklas 	}
3152159047fSniklas       else
3162159047fSniklas 	{
3172159047fSniklas 	  if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
3182159047fSniklas 	    {
319b55d4692Sfgsch 	      as_bad (_("Local symbol %s never defined"),
320b55d4692Sfgsch 		      S_GET_NAME (symbolP));
321b55d4692Sfgsch 	    }			/* Oops.  */
3222159047fSniklas 
323b55d4692Sfgsch 	  /* Unhook it from the chain.  */
3242159047fSniklas 	  *symbolPP = symbol_next (symbolP);
3252159047fSniklas 	}			/* if this symbol should be in the output  */
3262159047fSniklas     }				/* for each symbol  */
3272159047fSniklas 
3282159047fSniklas   H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
3292159047fSniklas }
3302159047fSniklas 
331b55d4692Sfgsch /* Find strings by crawling along symbol table chain.  */
3322159047fSniklas 
3332159047fSniklas void
obj_emit_strings(where)3342159047fSniklas obj_emit_strings (where)
3352159047fSniklas      char **where;
3362159047fSniklas {
3372159047fSniklas   symbolS *symbolP;
3382159047fSniklas 
3392159047fSniklas #ifdef CROSS_COMPILE
3402159047fSniklas   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
3412159047fSniklas   md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
3422159047fSniklas   *where += sizeof (string_byte_count);
3432159047fSniklas #else /* CROSS_COMPILE */
344b55d4692Sfgsch   append (where, (char *) &string_byte_count,
345b55d4692Sfgsch 	  (unsigned long) sizeof (string_byte_count));
3462159047fSniklas #endif /* CROSS_COMPILE */
3472159047fSniklas 
3482159047fSniklas   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
3492159047fSniklas     {
3502159047fSniklas       if (S_GET_NAME (symbolP))
351b55d4692Sfgsch 	append (where, S_GET_NAME (symbolP),
352b55d4692Sfgsch 		(unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
353b55d4692Sfgsch     }				/* Walk symbol chain.  */
3542159047fSniklas }
355