From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11676 invoked by alias); 29 Apr 2004 06:25:10 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 11638 invoked from network); 29 Apr 2004 06:25:09 -0000 Received: from unknown (HELO sccrmhc12.comcast.net) (204.127.202.56) by sources.redhat.com with SMTP; 29 Apr 2004 06:25:09 -0000 Received: from lucon.org ([24.6.43.109]) by comcast.net (sccrmhc12) with ESMTP id <2004042906250801200nidlge>; Thu, 29 Apr 2004 06:25:08 +0000 Received: by lucon.org (Postfix, from userid 1000) id E73AD64CFF; Wed, 28 Apr 2004 23:25:07 -0700 (PDT) Date: Thu, 29 Apr 2004 15:57:00 -0000 From: "H. J. Lu" To: Zack Weinberg Cc: binutils@sources.redhat.com Subject: PATCH: Support multiple sections with same name Message-ID: <20040429062507.GA10452@lucon.org> References: <20040429003204.GA4634@lucon.org> <87smen1ud5.fsf@egil.codesourcery.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="HlL+5n6rz5pIUxbD" Content-Disposition: inline In-Reply-To: <87smen1ud5.fsf@egil.codesourcery.com> User-Agent: Mutt/1.4.1i X-SW-Source: 2004-04/txt/msg00764.txt.bz2 --HlL+5n6rz5pIUxbD Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 410 On Wed, Apr 28, 2004 at 05:49:10PM -0700, Zack Weinberg wrote: > "H. J. Lu" writes: > > > The current ELF linker doesn't support DWARF for section group. > [...] > > Barf. Why are we continuing to extend the .gnu.linkonce hack, when we > should be using proper ELF comdat groups? > I was wrong to say that gas supported multiple sections with same name. This patch seems to fix it. H.J. --HlL+5n6rz5pIUxbD Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="gas-elf-dup-1.patch" Content-length: 6766 gas/ 2004-04-28 H.J. Lu * config/obj-elf.c (get_section): New function. (obj_elf_change_section): Support multiple sections with same name. gas/testsuite/ 2004-04-28 H.J. Lu * gas/elf/elf.exp: Remove group1, add group1a and group1b for section group. * gas/elf/group1a.d: New file. * gas/elf/group1b.d: Likewise. * gas/elf/group1.e: Removed. --- gas/config/obj-elf.c.same 2004-04-26 21:12:45.000000000 -0700 +++ gas/config/obj-elf.c 2004-04-28 23:17:01.000000000 -0700 @@ -469,6 +469,34 @@ struct section_stack static struct section_stack *section_stack; +struct section_group +{ + const char *name; + const char *group_name; + asection *section; +}; + +static void +get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) +{ + struct section_group *group = inf; + const char *group_name = elf_group_name (sec); + + /* Check if we have found the section we are looking for. */ + if (group->section) + return; + + if ((sec->name == group->name + || (sec->name != NULL + && group->name != NULL + && strcmp (sec->name, group->name) == 0)) + && (group_name == group->group_name + || (group_name != NULL + && group->group_name != NULL + && strcmp (group_name, group->group_name) == 0))) + group->section = sec; +} + /* Handle the .section pseudo-op. This code supports two different syntaxes. @@ -496,10 +524,10 @@ obj_elf_change_section (const char *name int linkonce, int push) { - asection *old_sec; segT sec; flagword flags; const struct bfd_elf_special_section *ssect; + struct section_group group; #ifdef md_flush_pending_output md_flush_pending_output (); @@ -520,8 +548,19 @@ obj_elf_change_section (const char *name previous_section = now_seg; previous_subsection = now_subseg; - old_sec = bfd_get_section_by_name (stdoutput, name); - sec = subseg_new (name, 0); + group.name = name; + group.group_name = group_name; + group.section = NULL; + bfd_map_over_sections (stdoutput, get_section, &group); + + if (group.section) + { + sec = group.section; + subseg_set (sec, 0); + } + else + sec = subseg_force_new (name, 0); + ssect = _bfd_elf_get_sec_type_attr (stdoutput, name); if (ssect != NULL) @@ -532,7 +571,7 @@ obj_elf_change_section (const char *name type = ssect->type; else if (type != ssect->type) { - if (old_sec == NULL + if (group.section == NULL /* FIXME: gcc, as of 2002-10-22, will emit .section .init_array,"aw",@progbits @@ -556,7 +595,7 @@ obj_elf_change_section (const char *name } } - if (old_sec == NULL && (attr & ~ssect->attr) != 0) + if (group.section == NULL && (attr & ~ssect->attr) != 0) { /* As a GNU extension, we permit a .note section to be allocatable. If the linker sees an allocatable .note @@ -582,12 +621,13 @@ obj_elf_change_section (const char *name override = TRUE; else { - as_warn (_("setting incorrect section attributes for %s"), - name); + if (group_name == NULL) + as_warn (_("setting incorrect section attributes for %s"), + name); override = TRUE; } } - if (!override && old_sec == NULL) + if (!override && group.section == NULL) attr |= ssect->attr; } @@ -609,7 +649,10 @@ obj_elf_change_section (const char *name flags = md_elf_section_flags (flags, attr, type); #endif - if (old_sec == NULL) + if (linkonce) + flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; + + if (group.section == NULL) { symbolS *secsym; @@ -617,8 +660,6 @@ obj_elf_change_section (const char *name if (type == SHT_NOBITS) seg_info (sec)->bss = 1; - if (linkonce) - flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; bfd_set_section_flags (stdoutput, sec, flags); if (flags & SEC_MERGE) sec->entsize = entsize; @@ -636,18 +677,15 @@ obj_elf_change_section (const char *name /* If section attributes are specified the second time we see a particular section, then check that they are the same as we saw the first time. */ - if (((old_sec->flags ^ flags) + if (((group.section->flags ^ flags) & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD | SEC_THREAD_LOCAL))) as_warn (_("ignoring changed section attributes for %s"), name); - if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize) + if ((flags & SEC_MERGE) + && group.section->entsize != (unsigned) entsize) as_warn (_("ignoring changed section entity size for %s"), name); - if ((attr & SHF_GROUP) != 0 - && (elf_group_name (old_sec) == NULL - || strcmp (elf_group_name (old_sec), group_name) != 0)) - as_warn (_("ignoring new section group for %s"), name); } #ifdef md_elf_section_change_hook --- gas/testsuite/gas/elf/elf.exp.same 2004-04-26 21:13:06.000000000 -0700 +++ gas/testsuite/gas/elf/elf.exp 2004-04-28 22:56:42.000000000 -0700 @@ -50,7 +50,8 @@ if { ([istarget "*-*-elf*"] run_dump_test "ehopt0" run_dump_test "group0a" run_dump_test "group0b" - run_list_test "group1" "" "" "" + run_dump_test "group1a" + run_dump_test "group1b" run_dump_test "section0" run_dump_test "section1" run_list_test "section2" "$target_machine" "-al" "" --- gas/testsuite/gas/elf/group1.e.same 2004-04-26 21:04:50.000000000 -0700 +++ gas/testsuite/gas/elf/group1.e 2004-04-28 23:18:19.000000000 -0700 @@ -1,7 +0,0 @@ - -Symbol table '.symtab' contains 4 entries: - Num: Value[ ]* Size Type Bind Vis Ndx Name - 0: 0+0 0 NOTYPE LOCAL DEFAULT UND - 1: 0+0 0 SECTION LOCAL DEFAULT 1 - 2: 0+0 0 SECTION LOCAL DEFAULT 2 - 3: 0+0 0 SECTION LOCAL DEFAULT 3 --- gas/testsuite/gas/elf/group1a.d.same 2004-04-28 22:56:15.000000000 -0700 +++ gas/testsuite/gas/elf/group1a.d 2004-04-28 23:01:39.000000000 -0700 @@ -0,0 +1,10 @@ +#readelf: -SW +#name: group section with multiple sections of same name +#source: group1.s + +#... +[ ]*\[.*\][ ]+\.text[ ]+PROGBITS.*[ ]+AX[ ]+.* +#... +[ ]*\[.*\][ ]+\.text[ ]+PROGBITS.*[ ]+AXG[ ]+.* +[ ]*\[.*\][ ]+\.foo_group[ ]+GROUP.* +#pass --- gas/testsuite/gas/elf/group1b.d.same 2004-04-28 22:56:18.000000000 -0700 +++ gas/testsuite/gas/elf/group1b.d 2004-04-28 23:02:08.000000000 -0700 @@ -0,0 +1,9 @@ +#readelf: -g +#name: group section with multiple sections of same name +#source: group1.s + +#... +COMDAT group section `.foo_group' \[.foo_group\] contains 1 sections: +[ ]+\[Index\][ ]+Name +[ ]+\[.*\][ ]+.text +#pass --HlL+5n6rz5pIUxbD--