From fa20b8bfd563b7640450910bcffa3cd9676bd544 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 26 Oct 1993 21:01:15 +0000 Subject: [PATCH] * config/obj-elf.c (obj_elf_init_stab_section): Align .stab section to a longword boundary. --- gas/ChangeLog | 5 + gas/config/obj-elf.c | 286 +++++++++++++++++++++++++++++-------------- 2 files changed, 198 insertions(+), 93 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 2ea132cff02..0f665204f00 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +Tue Oct 26 16:58:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * config/obj-elf.c (obj_elf_init_stab_section): Align .stab + section to a longword boundary. + Tue Oct 26 10:24:31 1993 Ken Raeburn (raeburn@cygnus.com) * Makefile.in (CHECKFLAGS): Pass down RUNTESTFLAGS. diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 86997bb9dd9..ab4676253ea 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -93,6 +93,7 @@ obj_elf_common (ignore) char *p; int temp, size; symbolS *symbolP; + int have_align; name = input_line_pointer; c = get_symbol_end (); @@ -133,20 +134,25 @@ obj_elf_common (ignore) } know (symbolP->sy_frag == &zero_address_frag); if (*input_line_pointer != ',') + have_align = 0; + else { - as_bad ("Expected comma after common length"); - ignore_rest_of_line (); - return; + have_align = 1; + input_line_pointer++; + SKIP_WHITESPACE (); } - input_line_pointer++; - SKIP_WHITESPACE (); - if (*input_line_pointer != '"') + if (! have_align || *input_line_pointer != '"') { - temp = get_absolute_expression (); - if (temp < 0) + if (! have_align) + temp = 0; + else { - temp = 0; - as_warn ("Common alignment negative; 0 assumed"); + temp = get_absolute_expression (); + if (temp < 0) + { + temp = 0; + as_warn ("Common alignment negative; 0 assumed"); + } } if (symbolP->local) { @@ -280,33 +286,56 @@ obj_elf_weak (ignore) static segT previous_section; static int previous_subsection; +/* Handle the .section pseudo-op. This code supports two different + syntaxes. + + The first is found on Solaris, and looks like + .section ".sec1",#alloc,#execinstr,#write + Here the names after '#' are the SHF_* flags to turn on for the + section. I'm not sure how it determines the SHT_* type (BFD + doesn't really give us control over the type, anyhow). + + The second format is found on UnixWare, and probably most SVR4 + machines, and looks like + .section .sec1,"a",@progbits + The quoted string may contain any combination of a, w, x, and + represents the SHF_* flags to turn on for the section. The string + beginning with '@' can be progbits or nobits. There should be + other possibilities, but I don't know what they are. In any case, + BFD doesn't really let us set the section type. */ + void obj_elf_section (xxx) int xxx; { char *string; - asection *sec; int new_sec; + segT sec; + flagword flags; - /* Initialize this with inclusive-or of all flags that can be cleared - by attributes, but not set by them. Also include flags that won't - get set properly in the assembler, but which the user/compiler - shouldn't be expected to set. */ - flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC | SEC_LOAD; - /* Initialize this with the default flags to be used if none are - specified. */ - flagword default_flags = 0; - - SKIP_WHITESPACE (); /* Get name of section. */ + SKIP_WHITESPACE (); if (*input_line_pointer == '"') - string = demand_copy_C_string (&xxx); + { + string = demand_copy_C_string (&xxx); + if (string == NULL) + { + ignore_rest_of_line (); + return; + } + } else { char *p = input_line_pointer; char c; while (0 == strchr ("\n\t,; ", *p)) p++; + if (p == input_line_pointer) + { + as_warn ("Missing section name"); + ignore_rest_of_line (); + return; + } c = *p; *p = 0; string = xmalloc ((unsigned long) (p - input_line_pointer + 1)); @@ -314,83 +343,154 @@ obj_elf_section (xxx) *p = c; input_line_pointer = p; } - if (!strcmp (string, ".rodata") - || !strcmp (string, ".rodata1")) - default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC | SEC_LOAD; - else if (!strcmp (string, ".init") - || !strcmp (string, ".fini")) - default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC | SEC_CODE | SEC_LOAD; + + /* Switch to the section, creating it if necessary. */ + previous_section = now_seg; + previous_subsection = now_subseg; + + new_sec = bfd_get_section_by_name (stdoutput, string) == NULL; + sec = subseg_new (string, 0); + + /* If this section already existed, we don't bother to change the + flag values. */ + if (! new_sec) + { + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + ++input_line_pointer; + return; + } SKIP_WHITESPACE (); if (*input_line_pointer != ',') - flags = default_flags; - while (*input_line_pointer == ',') { - flagword bit; - unsigned int len; - int inv; - char *p, oldp; - - input_line_pointer++; + /* No flags given. Guess at some useful defaults. */ + if (strcmp (string, ".data") == 0 + || strcmp (string, ".data1") == 0 + || strcmp (string, ".sdata") == 0 + || strcmp (string, ".rodata") == 0 + || strcmp (string, ".rodata1") == 0) + flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA; + else if (strcmp (string, ".text") == 0 + || strcmp (string, ".init") == 0 + || strcmp (string, ".fini") == 0) + flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_CODE; + else if (strcmp (string, ".bss") == 0 + || strcmp (string, ".sbss") == 0) + flags = SEC_ALLOC; + else + flags = SEC_RELOC; + } + else + { + /* Skip the comma. */ + ++input_line_pointer; - /* Under i386-svr4, gcc emits a string here. I don't know what this - string is supposed to signify or how to handle it. Ignore it for - now, unless it becomes a problem. */ + SKIP_WHITESPACE (); if (*input_line_pointer == '"') { - demand_copy_C_string (&xxx); + /* Pick up a string with a combination of a, w, x. */ + flags = SEC_READONLY | SEC_RELOC; + ++input_line_pointer; + while (*input_line_pointer != '"') + { + switch (*input_line_pointer) + { + case 'a': + flags |= SEC_ALLOC | SEC_LOAD; + break; + case 'w': + flags &=~ SEC_READONLY; + break; + case 'x': + flags |= SEC_CODE; + break; + default: + as_warn ("Bad .section directive: want a,w,x in string"); + ignore_rest_of_line (); + return; + } + ++input_line_pointer; + } + + /* Skip the closing quote. */ + ++input_line_pointer; + SKIP_WHITESPACE (); - continue; + if (*input_line_pointer == ',') + { + ++input_line_pointer; + SKIP_WHITESPACE (); + if (*input_line_pointer == '@') + { + ++input_line_pointer; + if (strncmp (input_line_pointer, "progbits", + sizeof "progbits" - 1) == 0) + { + flags |= SEC_ALLOC | SEC_LOAD; + input_line_pointer += sizeof "progbits" - 1; + } + else if (strncmp (input_line_pointer, "nobits", + sizeof "nobits" - 1) == 0) + { + flags &=~ SEC_LOAD; + input_line_pointer += sizeof "nobits" - 1; + } + else + { + as_warn ("Unrecognized section type"); + ignore_rest_of_line (); + } + } + } } - - if (*input_line_pointer != '#' && *input_line_pointer != '@') + else { - as_bad ("unrecognized syntax in .section command"); - ignore_rest_of_line (); - break; + flags = SEC_READONLY | SEC_RELOC; + do + { + SKIP_WHITESPACE (); + if (*input_line_pointer != '#') + { + as_warn ("Bad .section directive"); + ignore_rest_of_line (); + return; + } + ++input_line_pointer; + if (strncmp (input_line_pointer, "write", + sizeof "write" - 1) == 0) + { + flags &=~ SEC_READONLY; + input_line_pointer += sizeof "write" - 1; + } + else if (strncmp (input_line_pointer, "alloc", + sizeof "alloc" - 1) == 0) + { + flags |= SEC_ALLOC | SEC_LOAD; + input_line_pointer += sizeof "alloc" - 1; + } + else if (strncmp (input_line_pointer, "execinstr", + sizeof "execinstr" - 1) == 0) + { + flags |= SEC_CODE; + input_line_pointer += sizeof "execinstr" - 1; + } + else + { + as_warn ("Unrecognized section attribute"); + ignore_rest_of_line (); + return; + } + SKIP_WHITESPACE (); + } + while (*input_line_pointer++ == ','); + --input_line_pointer; } - input_line_pointer++; - -#define CHECK(X,BIT,NEG) \ - if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \ - bit = BIT; inv = NEG; goto match; } - - CHECK ("write", SEC_READONLY, 1); - CHECK ("alloc", SEC_ALLOC | SEC_LOAD, 0); - CHECK ("execinstr", SEC_CODE, 1); - CHECK ("progbits", SEC_ALLOC | SEC_LOAD, 1); -#undef CHECK - - p = input_line_pointer; - while (!is_end_of_line[(unsigned char) *p] && *p != 0 && *p != ',') - p++; - *p = 0; - oldp = *p; - as_bad ("unrecognized section attribute `%s' ignored", - input_line_pointer); - *p = oldp; - continue; - - match: - if (inv) - flags &= ~bit; - else - flags |= bit; - input_line_pointer += len; } - demand_empty_rest_of_line (); - /* If the C string wasn't valid, `string' could be null. */ - if (!string) - return; - - previous_section = now_seg; - previous_subsection = now_subseg; + bfd_set_section_flags (stdoutput, sec, flags); - new_sec = bfd_get_section_by_name (stdoutput, string) == NULL; - sec = subseg_new (string, 0); - if (new_sec) - bfd_set_section_flags (stdoutput, sec, flags); + demand_empty_rest_of_line (); } /* Change to the .data section. */ @@ -704,7 +804,8 @@ obj_elf_ident (ignore) { char *p; comment_section = subseg_new (".comment", 0); - bfd_set_section_flags (stdoutput, comment_section, SEC_HAS_CONTENTS); + bfd_set_section_flags (stdoutput, comment_section, + SEC_READONLY | SEC_HAS_CONTENTS); p = frag_more (1); *p = 0; } @@ -720,17 +821,16 @@ void obj_elf_init_stab_section (seg) segT seg; { - extern char *logical_input_file, *physical_input_file; + char *file; char *p; - const char *file; unsigned int stroff; + /* Force the section to align to a longword boundary. Without this, + UnixWare ar crashes. */ + bfd_set_section_alignment (stdoutput, seg, 2); + p = frag_more (12); - file = logical_input_file; - if (file == NULL) - file = physical_input_file; - if (file == NULL) - file = "UNKNOWN"; + as_where (&file, (unsigned int *) NULL); stroff = get_stab_string_offset (file, segment_name (seg)); know (stroff == 1); md_number_to_chars (p, stroff, 4); -- 2.30.2