@@ -1804,11 +1804,10 @@ coff_frob_section (segT sec)
}
void
-obj_coff_init_stab_section (segT seg)
+obj_coff_init_stab_section (segT stab ATTRIBUTE_UNUSED, segT stabstr)
{
const char *file;
char *p;
- char *stabstr_name;
unsigned int stroff;
/* Make space for this first symbol. */
@@ -1816,8 +1815,7 @@ obj_coff_init_stab_section (segT seg)
/* Zero it out. */
memset (p, 0, 12);
file = as_where ((unsigned int *) NULL);
- stabstr_name = concat (seg->name, "str", (char *) NULL);
- stroff = get_stab_string_offset (file, stabstr_name, true);
+ stroff = get_stab_string_offset (file, stabstr);
know (stroff == 1);
md_number_to_chars (p, stroff, 4);
}
@@ -299,7 +299,7 @@ extern const pseudo_typeS coff_pseudo_table[];
/* We need 12 bytes at the start of the section to hold some initial
information. */
-#define INIT_STAB_SECTION(seg) obj_coff_init_stab_section (seg)
+#define INIT_STAB_SECTION(stab, str) obj_coff_init_stab_section (stab, str)
/* Store the number of relocations in the section aux entry. */
#ifdef OBJ_XCOFF
@@ -342,7 +342,7 @@ extern segT s_get_segment (symbolS *);
extern void tc_coff_symbol_emit_hook (symbolS *);
#endif
extern void obj_coff_pe_handle_link_once (void);
-extern void obj_coff_init_stab_section (segT);
+extern void obj_coff_init_stab_section (segT, segT);
extern void c_section_header (struct internal_scnhdr *,
char *, long, long, long, long,
long, long, long, long);
@@ -2525,27 +2525,25 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
/* The first entry in a .stabs section is special. */
void
-obj_elf_init_stab_section (segT seg)
+obj_elf_init_stab_section (segT stab, segT stabstr)
{
char *file;
char *p;
- char *stabstr_name;
unsigned int stroff;
/* Force the section to align to a longword boundary. Without this,
UnixWare ar crashes. */
- bfd_set_section_alignment (seg, 2);
+ bfd_set_section_alignment (stab, 2);
/* Make space for this first symbol. */
p = frag_more (12);
/* Zero it out. */
memset (p, 0, 12);
file = remap_debug_filename (as_where (NULL));
- stabstr_name = concat (segment_name (seg), "str", (char *) NULL);
- stroff = get_stab_string_offset (file, stabstr_name, true);
+ stroff = get_stab_string_offset (file, stabstr);
know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
md_number_to_chars (p, stroff, 4);
- seg_info (seg)->stabu.p = p;
+ seg_info (stab)->stabu.p = p;
free (file);
}
@@ -3137,12 +3135,12 @@ elf_separate_stab_sections (void)
}
static void
-elf_init_stab_section (segT seg)
+elf_init_stab_section (segT stab, segT stabstr)
{
#ifdef NEED_ECOFF_DEBUG
if (!ECOFF_DEBUGGING)
#endif
- obj_elf_init_stab_section (seg);
+ obj_elf_init_stab_section (stab, stabstr);
}
/* This is called when the assembler starts. */
@@ -242,7 +242,7 @@ void elf_adjust_symtab (void);
#ifndef SEPARATE_STAB_SECTIONS
/* Avoid ifndef each separate macro setting by wrapping the whole of the
stab group on the assumption that whoever sets SEPARATE_STAB_SECTIONS
- caters to ECOFF_DEBUGGING and the right setting of INIT_STAB_SECTIONS
+ caters to ECOFF_DEBUGGING and the right setting of INIT_STAB_SECTION
and OBJ_PROCESS_STAB too, without needing the tweaks below. */
/* Stabs go in a separate section. */
@@ -250,8 +250,8 @@ void elf_adjust_symtab (void);
/* We need 12 bytes at the start of the section to hold some initial
information. */
-extern void obj_elf_init_stab_section (segT);
-#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg)
+extern void obj_elf_init_stab_section (segT, segT);
+#define INIT_STAB_SECTION(stab, str) obj_elf_init_stab_section (stab, str)
#ifdef ECOFF_DEBUGGING
/* We smuggle stabs in ECOFF rather than using a separate section.
@@ -261,8 +261,8 @@ extern void obj_elf_init_stab_section (segT);
#define SEPARATE_STAB_SECTIONS (!ECOFF_DEBUGGING)
#undef INIT_STAB_SECTION
-#define INIT_STAB_SECTION(seg) \
- ((void) (ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (seg), 0)))
+#define INIT_STAB_SECTION(stab, str) \
+ ((void) (ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (stab, str), 0)))
#undef OBJ_PROCESS_STAB
#define OBJ_PROCESS_STAB(what, string, type, other, desc) \
@@ -153,9 +153,9 @@
#define SEPARATE_STAB_SECTIONS \
((*this_format->separate_stab_sections) ())
-#define INIT_STAB_SECTION(S) \
+#define INIT_STAB_SECTION(STAB, STR) \
(this_format->init_stab_section \
- ? (*this_format->init_stab_section) (S) \
+ ? (*this_format->init_stab_section) (STAB, STR) \
: (void) 0)
#define EMIT_SECTION_SYMBOLS (this_format->emit_section_symbols)
@@ -205,7 +205,7 @@ obj_som_copyright (int unused ATTRIBUTE_UNUSED)
which BFD does not understand. */
void
-obj_som_init_stab_section (segT seg)
+obj_som_init_stab_section (segT stab, segT stabstr)
{
segT saved_seg = now_seg;
segT space;
@@ -234,8 +234,8 @@ obj_som_init_stab_section (segT seg)
(just created above). Also set some attributes which BFD does
not understand. In particular, access bits, sort keys, and load
quadrant. */
- obj_set_subsection_attributes (seg, space, 0x1f, 73, 0, 0, 0, 0);
- bfd_set_section_alignment (seg, 2);
+ obj_set_subsection_attributes (stab, space, 0x1f, 73, 0, 0, 0, 0);
+ bfd_set_section_alignment (stab, 2);
/* Make some space for the first special stab entry and zero the memory.
It contains information about the length of this file's
@@ -247,18 +247,17 @@ obj_som_init_stab_section (segT seg)
p = frag_more (12);
memset (p, 0, 12);
file = as_where ((unsigned int *) NULL);
- stroff = get_stab_string_offset (file, "$GDB_STRINGS$", false);
+ stroff = get_stab_string_offset (file, stabstr);
know (stroff == 1);
md_number_to_chars (p, stroff, 4);
- seg_info (seg)->stabu.p = p;
+ seg_info (stab)->stabu.p = p;
/* Set the containing space for both stab sections to be $GDB_DEBUG$
(just created above). Also set some attributes which BFD does
not understand. In particular, access bits, sort keys, and load
quadrant. */
- seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
- obj_set_subsection_attributes (seg, space, 0x1f, 72, 0, 0, 0, 0);
- bfd_set_section_alignment (seg, 2);
+ obj_set_subsection_attributes (stabstr, space, 0x1f, 72, 0, 0, 0, 0);
+ bfd_set_section_alignment (stabstr, 2);
subseg_set (saved_seg, saved_subseg);
}
@@ -36,7 +36,7 @@
extern void som_file_symbol (char *);
extern void som_frob_file (void);
extern void obj_som_version (int);
-extern void obj_som_init_stab_section (segT);
+extern void obj_som_init_stab_section (segT, segT);
extern void obj_som_copyright (int);
extern void obj_som_compiler (int);
@@ -60,7 +60,7 @@ extern void obj_som_compiler (int);
/* We use INIT_STAB_SECTION to record the space/subspace relationships
for the various debugging sections. */
-#define INIT_STAB_SECTION(seg) obj_som_init_stab_section (seg)
+#define INIT_STAB_SECTION(stab, str) obj_som_init_stab_section (stab, str)
/* We'll be updating the magic 1st stab entry once the entire assembly
fail has been processed. */
@@ -65,7 +65,7 @@ struct format_ops {
void (*generate_asm_lineno) (void);
void (*process_stab) (int, const char *, int, int, int);
int (*separate_stab_sections) (void);
- void (*init_stab_section) (segT);
+ void (*init_stab_section) (segT, segT);
int (*sec_sym_ok_for_reloc) (asection *);
void (*pop_insert) (void);
/* For configurations using ECOFF_DEBUGGING, this callback is used. */
@@ -113,8 +113,7 @@ extern char original_case_string[];
#endif
extern void pop_insert (const pseudo_typeS *);
-extern unsigned int get_stab_string_offset
- (const char *, const char *, bool);
+extern unsigned int get_stab_string_offset (const char *, segT);
extern void aout_process_stab (int, const char *, int, int, int);
extern char *demand_copy_string (int *lenP);
extern char *demand_copy_C_string (int *len_pointer);
@@ -52,9 +52,6 @@ static void generate_asm_file (int, const char *);
apply to assembler code assembled with -gstabs. */
static const char *current_function_label;
-/* Current stab section when SEPARATE_STAB_SECTIONS. */
-static segT cached_sec;
-
/* State used by generate_asm_file. */
static char *last_asm_file;
static int file_label_count;
@@ -95,14 +92,12 @@ static int endfunc_label_count;
#endif
unsigned int
-get_stab_string_offset (const char *string, const char *stabstr_secname,
- bool free_stabstr_secname)
+get_stab_string_offset (const char *string, segT stabstr)
{
unsigned int length;
unsigned int retval;
segT save_seg;
subsegT save_subseg;
- segT seg;
char *p;
if (! SEPARATE_STAB_SECTIONS)
@@ -113,19 +108,16 @@ get_stab_string_offset (const char *string, const char *stabstr_secname,
save_seg = now_seg;
save_subseg = now_subseg;
- /* Create the stab string section, if it doesn't already exist. */
- seg = subseg_new (stabstr_secname, 0);
- if (free_stabstr_secname && seg->name != stabstr_secname)
- free ((char *) stabstr_secname);
+ subseg_set (stabstr, 0);
- retval = seg_info (seg)->stabu.stab_string_size;
+ retval = seg_info (stabstr)->stabu.stab_string_size;
if (retval <= 0)
{
/* Make sure the first string is empty. */
p = frag_more (1);
*p = 0;
- retval = seg_info (seg)->stabu.stab_string_size = 1;
- bfd_set_section_flags (seg, SEC_READONLY | SEC_DEBUGGING);
+ retval = seg_info (stabstr)->stabu.stab_string_size = 1;
+ bfd_set_section_flags (stabstr, SEC_READONLY | SEC_DEBUGGING);
}
if (length > 0)
@@ -133,7 +125,7 @@ get_stab_string_offset (const char *string, const char *stabstr_secname,
p = frag_more (length + 1);
strcpy (p, string);
- seg_info (seg)->stabu.stab_string_size += length + 1;
+ seg_info (stabstr)->stabu.stab_string_size += length + 1;
}
else
retval = 0;
@@ -184,23 +176,71 @@ aout_process_stab (int what, const char *string, int type, int other, int desc)
}
#endif
+static bool
+eat_comma (int what)
+{
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ return true;
+ }
+ as_warn (_(".stab%c: missing comma"), what);
+ ignore_rest_of_line ();
+ return false;
+}
+
/* This can handle different kinds of stabs (s,n,d) and different
- kinds of stab sections. If STAB_SECNAME_OBSTACK_END is non-NULL,
- then STAB_SECNAME and STABSTR_SECNAME will be freed if possible
- before this function returns (the former by obstack_free). */
+ kinds of stab sections. If FREENAMES is true, then STAB_SECNAME
+ and STABSTR_SECNAME are allocated in that order on the notes
+ obstack and will be freed if possible. */
static void
s_stab_generic (int what,
const char *stab_secname,
const char *stabstr_secname,
- const char *stab_secname_obstack_end)
+ bool freenames)
{
- long longint;
const char *string;
char *saved_string_obstack_end;
int type;
int other;
int desc;
+ segT stab, stabstr = NULL;
+ segT saved_seg = now_seg;
+ subsegT saved_subseg = now_subseg;
+ fragS *saved_frag = frag_now;
+ valueT dot = 0;
+
+ if (SEPARATE_STAB_SECTIONS)
+ /* Output the stab information in a separate section. This is used
+ at least for COFF and ELF. */
+ {
+ dot = frag_now_fix ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+ stab = subseg_new (stab_secname, 0);
+ stabstr = subseg_new (stabstr_secname, 0);
+
+ if (freenames
+ && stab->name != stab_secname
+ && stabstr->name != stabstr_secname)
+ obstack_free (¬es, stab_secname);
+
+ subseg_set (stab, 0);
+ if (!seg_info (stab)->hadone)
+ {
+ bfd_set_section_flags (stab,
+ SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+#ifdef INIT_STAB_SECTION
+ INIT_STAB_SECTION (stab, stabstr);
+#endif
+ seg_info (stab)->hadone = 1;
+ }
+ }
+ else if (freenames)
+ obstack_free (¬es, stab_secname);
/* The general format is:
.stabs "STRING",TYPE,OTHER,DESC,VALUE
@@ -210,11 +250,9 @@ s_stab_generic (int what,
any trailing whitespace. The argument what is one of 's', 'n' or
'd' indicating which type of .stab this is. */
+ saved_string_obstack_end = NULL;
if (what != 's')
- {
- string = "";
- saved_string_obstack_end = 0;
- }
+ string = "";
else
{
int length;
@@ -224,38 +262,24 @@ s_stab_generic (int what,
{
as_warn (_(".stab%c: missing string"), what);
ignore_rest_of_line ();
- return;
+ goto out;
}
/* FIXME: We should probably find some other temporary storage
for string, rather than leaking memory if someone else
happens to use the notes obstack. */
saved_string_obstack_end = obstack_next_free (¬es);
SKIP_WHITESPACE ();
- if (*input_line_pointer == ',')
- input_line_pointer++;
- else
- {
- as_warn (_(".stab%c: missing comma"), what);
- ignore_rest_of_line ();
- return;
- }
+ if (!eat_comma (what))
+ goto out;
}
- if (get_absolute_expression_and_terminator (&longint) != ',')
- {
- as_warn (_(".stab%c: missing comma"), what);
- ignore_rest_of_line ();
- return;
- }
- type = longint;
+ type = get_absolute_expression ();
+ if (!eat_comma (what))
+ goto out;
- if (get_absolute_expression_and_terminator (&longint) != ',')
- {
- as_warn (_(".stab%c: missing comma"), what);
- ignore_rest_of_line ();
- return;
- }
- other = longint;
+ other = get_absolute_expression ();
+ if (!eat_comma (what))
+ goto out;
desc = get_absolute_expression ();
@@ -268,13 +292,8 @@ s_stab_generic (int what,
if (what == 's' || what == 'n')
{
- if (*input_line_pointer != ',')
- {
- as_warn (_(".stab%c: missing comma"), what);
- ignore_rest_of_line ();
- return;
- }
- input_line_pointer++;
+ if (!eat_comma (what))
+ goto out;
SKIP_WHITESPACE ();
}
@@ -322,54 +341,16 @@ s_stab_generic (int what,
/* Output the stab information in a separate section. This is used
at least for COFF and ELF. */
{
- segT saved_seg = now_seg;
- subsegT saved_subseg = now_subseg;
- fragS *saved_frag = frag_now;
- valueT dot;
- segT seg;
unsigned int stroff;
char *p;
- dot = frag_now_fix ();
-
-#ifdef md_flush_pending_output
- md_flush_pending_output ();
-#endif
+ stroff = get_stab_string_offset (string, stabstr);
- if (cached_sec && strcmp (cached_sec->name, stab_secname) == 0)
- {
- seg = cached_sec;
- subseg_set (seg, 0);
- }
- else
- {
- seg = subseg_new (stab_secname, 0);
- cached_sec = seg;
- }
-
- if (! seg_info (seg)->hadone)
- {
- bfd_set_section_flags (seg,
- SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
-#ifdef INIT_STAB_SECTION
- INIT_STAB_SECTION (seg);
-#endif
- seg_info (seg)->hadone = 1;
- }
-
- stroff = get_stab_string_offset (string, stabstr_secname,
- stab_secname_obstack_end != NULL);
-
- /* Release the string, if nobody else has used the obstack. */
- if (saved_string_obstack_end != NULL
- && saved_string_obstack_end == obstack_next_free (¬es))
+ /* Release the string, if nobody else has used the obstack.
+ This must be done before creating symbols below, which uses
+ the notes obstack. */
+ if (saved_string_obstack_end == obstack_next_free (¬es))
obstack_free (¬es, string);
- /* Similarly for the section name. This must be done before
- creating symbols below, which uses the notes obstack. */
- if (seg->name != stab_secname
- && stab_secname_obstack_end != NULL
- && stab_secname_obstack_end == obstack_next_free (¬es))
- obstack_free (¬es, stab_secname);
/* At least for now, stabs in a special stab section are always
output as 12 byte blocks of information. */
@@ -403,17 +384,9 @@ s_stab_generic (int what,
#ifdef OBJ_PROCESS_STAB
OBJ_PROCESS_STAB (what, string, type, other, desc);
#endif
-
- subseg_set (saved_seg, saved_subseg);
}
else
{
- if (stab_secname_obstack_end != NULL)
- {
- free ((char *) stabstr_secname);
- if (stab_secname_obstack_end == obstack_next_free (¬es))
- obstack_free (¬es, stab_secname);
- }
#ifdef OBJ_PROCESS_STAB
OBJ_PROCESS_STAB (what, string, type, other, desc);
#else
@@ -422,6 +395,10 @@ s_stab_generic (int what,
}
demand_empty_rest_of_line ();
+ out:
+ if (saved_string_obstack_end == obstack_next_free (¬es))
+ obstack_free (¬es, string);
+ subseg_set (saved_seg, saved_subseg);
}
/* Regular stab directive. */
@@ -429,7 +406,7 @@ s_stab_generic (int what,
void
s_stab (int what)
{
- s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, NULL);
+ s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME, false);
}
/* "Extended stabs", used in Solaris only now. */
@@ -438,25 +415,23 @@ void
s_xstab (int what)
{
int length;
- char *stab_secname, *stabstr_secname, *stab_secname_obstack_end;
+ char *stab_secname, *stabstr_secname;
stab_secname = demand_copy_C_string (&length);
- stab_secname_obstack_end = obstack_next_free (¬es);
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
- input_line_pointer++;
+ {
+ input_line_pointer++;
+ /* To get the name of the stab string section, simply add
+ "str" to the stab section name. */
+ stabstr_secname = notes_concat (stab_secname, "str", (char *) NULL);
+ s_stab_generic (what, stab_secname, stabstr_secname, true);
+ }
else
{
as_bad (_("comma missing in .xstabs"));
ignore_rest_of_line ();
- return;
}
-
- /* To get the name of the stab string section, simply add "str" to
- the stab section name. */
- stabstr_secname = concat (stab_secname, "str", (char *) NULL);
- s_stab_generic (what, stab_secname, stabstr_secname,
- stab_secname_obstack_end);
}
#ifdef S_SET_DESC
@@ -707,7 +682,6 @@ void
stabs_begin (void)
{
current_function_label = NULL;
- cached_sec = NULL;
last_asm_file = NULL;
file_label_count = 0;
line_label_count = 0;