#include "as.h"
#include "subsegs.h"
#include "aout/stab_gnu.h"
#include "obstack.h"
static void obj_som_weak PARAMS ((int));
static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
const pseudo_typeS obj_pseudo_table[] =
{
{"weak", obj_som_weak, 0},
{NULL, NULL, 0}
};
static int version_seen = 0;
static int copyright_seen = 0;
static int compiler_seen = 0;
void
obj_read_begin_hook ()
{
}
void
obj_som_compiler (unused)
int unused ATTRIBUTE_UNUSED;
{
char *buf;
char c;
char *filename;
char *language_name;
char *p;
char *version_id;
if (compiler_seen)
{
as_bad ("Only one .compiler pseudo-op per file!");
ignore_rest_of_line ();
return;
}
SKIP_WHITESPACE ();
if (*input_line_pointer == '\"')
{
buf = input_line_pointer;
++input_line_pointer;
while (is_a_char (next_char_of_string ()))
;
c = *input_line_pointer;
*input_line_pointer = '\000';
}
else
{
as_bad ("Expected quoted string");
ignore_rest_of_line ();
return;
}
filename = buf + 1;
p = filename;
while (*p != ' ' && *p != '\000')
p++;
if (*p == '\000')
{
as_bad (".compiler directive missing language and version");
return;
}
*p = '\000';
language_name = ++p;
while (*p != ' ' && *p != '\000')
p++;
if (*p == '\000')
{
as_bad (".compiler directive missing version");
return;
}
*p = '\000';
version_id = ++p;
while (*p != '\000')
p++;
*(--p) = '\000';
compiler_seen = 1;
if (! bfd_som_attach_compilation_unit (stdoutput, filename, language_name,
"GNU Tools", version_id))
{
bfd_perror (stdoutput->filename);
as_fatal ("FATAL: Attaching compiler header %s", stdoutput->filename);
}
*input_line_pointer = c;
demand_empty_rest_of_line ();
}
void
obj_som_version (unused)
int unused ATTRIBUTE_UNUSED;
{
char *version, c;
if (version_seen)
{
as_bad (_("Only one .version pseudo-op per file!"));
ignore_rest_of_line ();
return;
}
SKIP_WHITESPACE ();
if (*input_line_pointer == '\"')
{
version = input_line_pointer;
++input_line_pointer;
while (is_a_char (next_char_of_string ()))
;
c = *input_line_pointer;
*input_line_pointer = '\000';
}
else
{
as_bad (_("Expected quoted string"));
ignore_rest_of_line ();
return;
}
version_seen = 1;
if (!bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version))
{
bfd_perror (stdoutput->filename);
as_perror (_("FATAL: Attaching version header %s"),
stdoutput->filename);
exit (EXIT_FAILURE);
}
*input_line_pointer = c;
demand_empty_rest_of_line ();
}
void
obj_som_copyright (unused)
int unused ATTRIBUTE_UNUSED;
{
char *copyright, c;
if (copyright_seen)
{
as_bad (_("Only one .copyright pseudo-op per file!"));
ignore_rest_of_line ();
return;
}
SKIP_WHITESPACE ();
if (*input_line_pointer == '\"')
{
copyright = input_line_pointer;
++input_line_pointer;
while (is_a_char (next_char_of_string ()))
;
c = *input_line_pointer;
*input_line_pointer = '\000';
}
else
{
as_bad (_("Expected quoted string"));
ignore_rest_of_line ();
return;
}
copyright_seen = 1;
if (!bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright))
{
bfd_perror (stdoutput->filename);
as_perror (_("FATAL: Attaching copyright header %s"),
stdoutput->filename);
exit (EXIT_FAILURE);
}
*input_line_pointer = c;
demand_empty_rest_of_line ();
}
void
obj_som_init_stab_section (seg)
segT seg;
{
segT saved_seg = now_seg;
segT space;
subsegT saved_subseg = now_subseg;
char *p, *file;
unsigned int stroff;
space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$");
obj_set_section_attributes (space, 1, 1, 72, 2);
bfd_set_section_alignment (stdoutput, space, 2);
obj_set_subsection_attributes (seg, space, 0x1f, 73, 0, 0, 0, 0);
bfd_set_section_alignment (stdoutput, seg, 2);
p = frag_more (12);
memset (p, 0, 12);
as_where (&file, (unsigned int *) NULL);
stroff = get_stab_string_offset (file, "$GDB_STRINGS$");
know (stroff == 1);
md_number_to_chars (p, stroff, 4);
seg_info (seg)->stabu.p = p;
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 (stdoutput, seg, 2);
subseg_set (saved_seg, saved_subseg);
}
static void
adjust_stab_sections (abfd, sec, xxx)
bfd *abfd;
asection *sec;
PTR xxx ATTRIBUTE_UNUSED;
{
asection *strsec;
char *p;
int strsz, nsyms;
if (strcmp ("$GDB_SYMBOLS$", sec->name))
return;
strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
if (strsec)
strsz = bfd_section_size (abfd, strsec);
else
strsz = 0;
nsyms = bfd_section_size (abfd, sec) / 12 - 1;
p = seg_info (sec)->stabu.p;
assert (p != 0);
bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
}
void
som_frob_file ()
{
bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
}
static void
obj_som_weak (ignore)
int ignore ATTRIBUTE_UNUSED;
{
char *name;
int c;
symbolS *symbolP;
do
{
name = input_line_pointer;
c = get_symbol_end ();
symbolP = symbol_find_or_make (name);
*input_line_pointer = c;
SKIP_WHITESPACE ();
S_SET_WEAK (symbolP);
if (c == ',')
{
input_line_pointer++;
SKIP_WHITESPACE ();
if (*input_line_pointer == '\n')
c = '\n';
}
}
while (c == ',');
demand_empty_rest_of_line ();
}