From c1711530e652a14bc0df9b603c73e350b5dfe5ec Mon Sep 17 00:00:00 2001 From: Dave Korn Date: Tue, 19 May 2009 16:08:08 +0000 Subject: [PATCH] ==> bfd/ChangeLog <== 2009-05-19 Dave Korn * cofflink.c (process_embedded_commands): Ignore "-aligncomm". ==> gas/ChangeLog <== 2009-05-19 Dave Korn * NEWS: Mention new feature. * config/obj-coff.c (obj_coff_common_parse): New function. (obj_coff_comm): Likewise. (coff_pseudo_table): Override default ".comm" definition on PE. * doc/as.texinfo: Document new feature. ==> gas/testsuite/ChangeLog <== 2009-05-19 Dave Korn * gas/pe/: New directory for PE format-specific tests. * gas/pe/aligncomm-a.d: New test pattern file. * gas/pe/aligncomm-a.s: New test source file. * gas/pe/aligncomm-b.d: New test pattern file. * gas/pe/aligncomm-b.s: New test source file. * gas/pe/aligncomm-c.d: New test pattern file. * gas/pe/aligncomm-c.s: New test source file. * gas/pe/aligncomm-d.d: New test pattern file. * gas/pe/aligncomm-d.s: New test source file. * gas/pe/pe.exp: New test control script. * lib/gas-defs.exp (is_pecoff_format): New function. ==> ld/ChangeLog <== 2009-05-19 Dave Korn * NEWS: Mention new feature. * deffile.h (def_file_aligncomm): Add new struct definition. (def_file): Add new def_file_aligncomm member. * deffilep.y (%token): Add new ALIGNCOMM token. (command): Add production rule for ALIGNCOMM. (def_file_free): Free any chained def_file_aligncomm structs. (diropts[]): Add entry for '-aligncomm' .drectve command. (def_aligncomm): New grammar function. * ld.texinfo: Document new feature. * pe-dll.c (process_def_file): Rename from this ... (process_def_file_and_drectve): ... to this, updating all callers, and process any aligncomms chained to the def file after scanning all .drectve sections. (generate_edata): Updated to match. (pe_dll_build_sections): Likewise. ==> ld/testsuite/ChangeLog <== 2009-05-19 Dave Korn * ld-pe/aligncomm-1.c: New test source file. * ld-pe/aligncomm-2.c: Likewise. * ld-pe/aligncomm-3.c: Likewise. * ld-pe/aligncomm-4.c: Likewise. * ld-pe/aligncomm.d: New test pattern file. * ld-pe/direct.exp: Deleted, and content moved into ... * ld-pe/pe-run.exp: ... New common file for all PE run tests. * ld-pe/vers-script.exp: Deleted, and content merged into ... * ld-pe/pe-compile.exp: ... New common file for PE tests needing a compiler, adding aligned common tests. * ld-pe/pe.exp: Update header comment. --- bfd/ChangeLog | 4 ++ bfd/cofflink.c | 9 +++ gas/ChangeLog | 8 +++ gas/NEWS | 2 + gas/config/obj-coff.c | 69 ++++++++++++++++++++++ gas/doc/as.texinfo | 25 +++++--- gas/testsuite/ChangeLog | 14 +++++ gas/testsuite/gas/pe/aligncomm-a.d | 12 ++++ gas/testsuite/gas/pe/aligncomm-a.s | 11 ++++ gas/testsuite/gas/pe/aligncomm-b.d | 16 +++++ gas/testsuite/gas/pe/aligncomm-b.s | 11 ++++ gas/testsuite/gas/pe/aligncomm-c.d | 8 +++ gas/testsuite/gas/pe/aligncomm-c.s | 5 ++ gas/testsuite/gas/pe/aligncomm-d.d | 12 ++++ gas/testsuite/gas/pe/aligncomm-d.s | 5 ++ gas/testsuite/gas/pe/pe.exp | 34 +++++++++++ gas/testsuite/lib/gas-defs.exp | 12 ++++ ld/ChangeLog | 18 ++++++ ld/NEWS | 4 ++ ld/deffile.h | 10 ++++ ld/deffilep.y | 25 +++++++- ld/ld.texinfo | 11 ++++ ld/pe-dll.c | 28 ++++++++- ld/testsuite/ChangeLog | 17 ++++++ ld/testsuite/ld-pe/aligncomm-1.c | 19 ++++++ ld/testsuite/ld-pe/aligncomm-2.c | 20 +++++++ ld/testsuite/ld-pe/aligncomm-3.c | 21 +++++++ ld/testsuite/ld-pe/aligncomm-4.c | 22 +++++++ ld/testsuite/ld-pe/aligncomm.d | 3 + .../ld-pe/{vers-script.exp => pe-compile.exp} | 21 ++++++- ld/testsuite/ld-pe/{direct.exp => pe-run.exp} | 5 +- ld/testsuite/ld-pe/pe.exp | 2 +- 32 files changed, 464 insertions(+), 19 deletions(-) create mode 100755 gas/testsuite/gas/pe/aligncomm-a.d create mode 100755 gas/testsuite/gas/pe/aligncomm-a.s create mode 100755 gas/testsuite/gas/pe/aligncomm-b.d create mode 100644 gas/testsuite/gas/pe/aligncomm-b.s create mode 100755 gas/testsuite/gas/pe/aligncomm-c.d create mode 100755 gas/testsuite/gas/pe/aligncomm-c.s create mode 100755 gas/testsuite/gas/pe/aligncomm-d.d create mode 100755 gas/testsuite/gas/pe/aligncomm-d.s create mode 100755 gas/testsuite/gas/pe/pe.exp create mode 100755 ld/testsuite/ld-pe/aligncomm-1.c create mode 100755 ld/testsuite/ld-pe/aligncomm-2.c create mode 100755 ld/testsuite/ld-pe/aligncomm-3.c create mode 100755 ld/testsuite/ld-pe/aligncomm-4.c create mode 100755 ld/testsuite/ld-pe/aligncomm.d rename ld/testsuite/ld-pe/{vers-script.exp => pe-compile.exp} (75%) rename ld/testsuite/ld-pe/{direct.exp => pe-run.exp} (96%) mode change 100644 => 100755 diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cf4b73f..8751c26 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2009-05-19 Dave Korn + + * cofflink.c (process_embedded_commands): Ignore "-aligncomm". + 2009-05-15 Andrew Stubbs Paul Brook diff --git a/bfd/cofflink.c b/bfd/cofflink.c index d771168..96870e9 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -1282,6 +1282,15 @@ process_embedded_commands (bfd *output_bfd, else if (CONST_STRNEQ (s, "-stack")) s = dores_com (s + 6, output_bfd, 0); + /* GNU extension for aligned commons. */ + else if (CONST_STRNEQ (s, "-aligncomm:")) + { + /* Common symbols must be aligned on reading, as it + is too late to do anything here, after they have + already been allocated, so just skip the directive. */ + s += 11; + } + else s++; } diff --git a/gas/ChangeLog b/gas/ChangeLog index 907c5d6..7f4fd56 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2009-05-19 Dave Korn + + * NEWS: Mention new feature. + * config/obj-coff.c (obj_coff_common_parse): New function. + (obj_coff_comm): Likewise. + (coff_pseudo_table): Override default ".comm" definition on PE. + * doc/as.texinfo: Document new feature. + 2009-05-17 Kai Tietz * config/obj-coff.c (obj_coff_section): Add 'y' as diff --git a/gas/NEWS b/gas/NEWS index 0650b30..b4b2ca6 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -1,5 +1,7 @@ -*- text -*- +* Add support for common symbol alignment to PE formats. + * Add support for the new discriminator column in the DWARF line table, with a discriminator operand for the .loc directive. diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index b2f4558..98d8d6c 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -169,6 +169,71 @@ obj_coff_bss (int ignore ATTRIBUTE_UNUSED) s_lcomm (0); } +#ifdef TE_PE +/* Called from read.c:s_comm after we've parsed .comm symbol, size. + Parse a possible alignment value. */ + +static symbolS * +obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size) +{ + addressT align = 0; + + if (*input_line_pointer == ',') + { + align = parse_align (0); + if (align == (addressT) -1) + return NULL; + } + + S_SET_VALUE (symbolP, size); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, bfd_com_section_ptr); + + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; + + /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE. + Instead we must add a note to the .drectve section. */ + if (align) + { + segT current_seg = now_seg; + subsegT current_subseg = now_subseg; + flagword oldflags; + asection *sec; + size_t pfxlen, numlen; + char *frag; + char numbuff[20]; + + sec = subseg_new (".drectve", 0); + oldflags = bfd_get_section_flags (stdoutput, sec); + if (oldflags == SEC_NO_FLAGS) + { + if (!bfd_set_section_flags (stdoutput, sec, + TC_COFF_SECTION_DEFAULT_ATTRIBUTES)) + as_warn (_("error setting flags for \"%s\": %s"), + bfd_section_name (stdoutput, sec), + bfd_errmsg (bfd_get_error ())); + } + + /* Emit a string. Note no NUL-termination. */ + pfxlen = strlen (" -aligncomm:") + strlen (S_GET_NAME (symbolP)) + 1; + numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align); + frag = frag_more (pfxlen + numlen); + (void) sprintf (frag, " -aligncomm:%s,", S_GET_NAME (symbolP)); + memcpy (frag + pfxlen, numbuff, numlen); + /* Restore original subseg. */ + subseg_set (current_seg, current_subseg); + } + + return symbolP; +} + +static void +obj_coff_comm (int ignore ATTRIBUTE_UNUSED) +{ + s_comm_internal (ignore, obj_coff_common_parse); +} +#endif /* TE_PE */ + #define GET_FILENAME_STRING(X) \ ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1]) @@ -1784,6 +1849,10 @@ const pseudo_typeS coff_pseudo_table[] = /* We accept the .bss directive for backward compatibility with earlier versions of gas. */ {"bss", obj_coff_bss, 0}, +#ifdef TE_PE + /* PE provides an enhanced version of .comm with alignment. */ + {"comm", obj_coff_comm, 0}, +#endif /* TE_PE */ {"def", obj_coff_def, 0}, {"dim", obj_coff_dim, 0}, {"endef", obj_coff_endef, 0}, diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 9871fe2..e4f7984 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -4308,16 +4308,23 @@ absolute expression. If @code{@value{LD}} sees multiple common symbols with the same name, and they do not all have the same size, it will allocate space using the largest size. -@ifset ELF -When using ELF, the @code{.comm} directive takes an optional third argument. -This is the desired alignment of the symbol, specified as a byte boundary (for -example, an alignment of 16 means that the least significant 4 bits of the -address should be zero). The alignment must be an absolute expression, and it -must be a power of two. If @code{@value{LD}} allocates uninitialized memory -for the common symbol, it will use the alignment when placing the symbol. If -no alignment is specified, @command{@value{AS}} will set the alignment to the +@ifset COFF-ELF +When using ELF or (as a GNU extension) PE, the @code{.comm} directive takes +an optional third argument. This is the desired alignment of the symbol, +specified for ELF as a byte boundary (for example, an alignment of 16 means +that the least significant 4 bits of the address should be zero), and for PE +as a power of two (for example, an alignment of 5 means aligned to a 32-byte +boundary). The alignment must be an absolute expression, and it must be a +power of two. If @code{@value{LD}} allocates uninitialized memory for the +common symbol, it will use the alignment when placing the symbol. If no +alignment is specified, @command{@value{AS}} will set the alignment to the largest power of two less than or equal to the size of the symbol, up to a -maximum of 16. +maximum of 16 on ELF, or the default section alignment of 4 on PE@footnote{This +is not the same as the executable image file alignment controlled by @code{@value{LD}}'s +@samp{--section-alignment} option; image file sections in PE are aligned to +multiples of 4096, which is far too large an alignment for ordinary variables. +It is rather the default alignment for (non-debug) sections within object +(@samp{*.o}) files, which are less strictly aligned.}. @end ifset @ifset HPPA diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index d8b6e49..e5c8a4c 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2009-05-19 Dave Korn + + * gas/pe/: New directory for PE format-specific tests. + * gas/pe/aligncomm-a.d: New test pattern file. + * gas/pe/aligncomm-a.s: New test source file. + * gas/pe/aligncomm-b.d: New test pattern file. + * gas/pe/aligncomm-b.s: New test source file. + * gas/pe/aligncomm-c.d: New test pattern file. + * gas/pe/aligncomm-c.s: New test source file. + * gas/pe/aligncomm-d.d: New test pattern file. + * gas/pe/aligncomm-d.s: New test source file. + * gas/pe/pe.exp: New test control script. + * lib/gas-defs.exp (is_pecoff_format): New function. + 2009-05-05 H.J. Lu * gas/lns/lns-common-1-ia64.s: Add test for discriminator. diff --git a/gas/testsuite/gas/pe/aligncomm-a.d b/gas/testsuite/gas/pe/aligncomm-a.d new file mode 100755 index 0000000..21cad88 --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-a.d @@ -0,0 +1,12 @@ +#objdump: -s -j .drectve +#name: aligned common A + +# Test the aligned form of the .comm pseudo-op. + +.*: .* + +Contents of section .drectve: + 0000 202d616c 69676e63 6f6d6d3a 5f682c35 -aligncomm:_h,5 + 0010 202d616c 69676e63 6f6d6d3a 5f692c34 -aligncomm:_i,4 + 0020 202d616c 69676e63 6f6d6d3a 5f6a2c33 -aligncomm:_j,3 + 0030 202d616c 69676e63 6f6d6d3a 5f6b2c32 -aligncomm:_k,2 diff --git a/gas/testsuite/gas/pe/aligncomm-a.s b/gas/testsuite/gas/pe/aligncomm-a.s new file mode 100755 index 0000000..47bab4d --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-a.s @@ -0,0 +1,11 @@ + .file "a.c" + .comm _h, 16 + .comm _i, 16 + .comm _j, 16 + .comm _k, 16 + .section .drectve + .ascii " -aligncomm:_h,5" + .ascii " -aligncomm:_i,4" + .ascii " -aligncomm:_j,3" + .ascii " -aligncomm:_k,2" + diff --git a/gas/testsuite/gas/pe/aligncomm-b.d b/gas/testsuite/gas/pe/aligncomm-b.d new file mode 100755 index 0000000..9a162be --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-b.d @@ -0,0 +1,16 @@ +#objdump: -s -j .drectve +#name: aligned common B + +# Test the aligned form of the .comm pseudo-op. + +.*: .* + +Contents of section .drectve: + 0000 202d616c 69676e63 6f6d6d3a 5f682c38 -aligncomm:_h,8 + 0010 202d616c 69676e63 6f6d6d3a 5f692c34 -aligncomm:_i,4 + 0020 202d616c 69676e63 6f6d6d3a 5f6a2c32 -aligncomm:_j,2 + 0030 202d616c 69676e63 6f6d6d3a 5f6b2c31 -aligncomm:_k,1 + 0040 202d616c 69676e63 6f6d6d3a 5f682c35 -aligncomm:_h,5 + 0050 202d616c 69676e63 6f6d6d3a 5f692c34 -aligncomm:_i,4 + 0060 202d616c 69676e63 6f6d6d3a 5f6a2c33 -aligncomm:_j,3 + 0070 202d616c 69676e63 6f6d6d3a 5f6b2c32 -aligncomm:_k,2 diff --git a/gas/testsuite/gas/pe/aligncomm-b.s b/gas/testsuite/gas/pe/aligncomm-b.s new file mode 100644 index 0000000..29606e1 --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-b.s @@ -0,0 +1,11 @@ + .file "a.c" + .comm _h, 16, 8 + .comm _i, 16, 4 + .comm _j, 16, 2 + .comm _k, 16, 1 + .section .drectve + .ascii " -aligncomm:_h,5" + .ascii " -aligncomm:_i,4" + .ascii " -aligncomm:_j,3" + .ascii " -aligncomm:_k,2" + diff --git a/gas/testsuite/gas/pe/aligncomm-c.d b/gas/testsuite/gas/pe/aligncomm-c.d new file mode 100755 index 0000000..f9dc3a8 --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-c.d @@ -0,0 +1,8 @@ +#objdump: -s -j .drectve +#name: aligned common C + +# Test the aligned form of the .comm pseudo-op. + +.*: .* + +# No .drectve section emitted. \ No newline at end of file diff --git a/gas/testsuite/gas/pe/aligncomm-c.s b/gas/testsuite/gas/pe/aligncomm-c.s new file mode 100755 index 0000000..154b4bd --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-c.s @@ -0,0 +1,5 @@ + .file "a.c" + .comm _h, 16 + .comm _i, 16 + .comm _j, 16 + .comm _k, 16 diff --git a/gas/testsuite/gas/pe/aligncomm-d.d b/gas/testsuite/gas/pe/aligncomm-d.d new file mode 100755 index 0000000..639d057 --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-d.d @@ -0,0 +1,12 @@ +#objdump: -s -j .drectve +#name: aligned common D + +# Test the aligned form of the .comm pseudo-op. + +.*: .* + +Contents of section .drectve: + 0000 202d616c 69676e63 6f6d6d3a 5f682c38 -aligncomm:_h,8 + 0010 202d616c 69676e63 6f6d6d3a 5f692c34 -aligncomm:_i,4 + 0020 202d616c 69676e63 6f6d6d3a 5f6a2c32 -aligncomm:_j,2 + 0030 202d616c 69676e63 6f6d6d3a 5f6b2c31 -aligncomm:_k,1 diff --git a/gas/testsuite/gas/pe/aligncomm-d.s b/gas/testsuite/gas/pe/aligncomm-d.s new file mode 100755 index 0000000..bf2b397 --- /dev/null +++ b/gas/testsuite/gas/pe/aligncomm-d.s @@ -0,0 +1,5 @@ + .file "a.c" + .comm _h, 16, 8 + .comm _i, 16, 4 + .comm _j, 16, 2 + .comm _k, 16, 1 diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp new file mode 100755 index 0000000..87e2a3e --- /dev/null +++ b/gas/testsuite/gas/pe/pe.exp @@ -0,0 +1,34 @@ +# Expect control script for GAS testsuite PE object-format-specific tests. + +# Copyright (C) 2009 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# binutils@gnu.org + +load_lib gas-dg.exp +load_lib gas-defs.exp + +# These tests can only be run on PE/COFF platforms. +if {![is_pecoff_format]} { + return +} + +run_dump_test "aligncomm-a" +run_dump_test "aligncomm-b" +run_dump_test "aligncomm-c" +run_dump_test "aligncomm-d" diff --git a/gas/testsuite/lib/gas-defs.exp b/gas/testsuite/lib/gas-defs.exp index 1e02847..5eda00a 100644 --- a/gas/testsuite/lib/gas-defs.exp +++ b/gas/testsuite/lib/gas-defs.exp @@ -310,6 +310,18 @@ proc is_elf_format {} { return 1 } +# True if the object format is known to be PE COFF. +# +proc is_pecoff_format {} { + if { ![istarget *-*-mingw*] \ + && ![istarget *-*-cygwin*] \ + && ![istarget *-*-pe*] } { + return 0 + } + + return 1 +} + # run_dump_tests TESTCASES EXTRA_OPTIONS # Wrapper for run_dump_test, which is suitable for invoking as # run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]] diff --git a/ld/ChangeLog b/ld/ChangeLog index 52364ef..15a2475 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,21 @@ +2009-05-19 Dave Korn + + * NEWS: Mention new feature. + * deffile.h (def_file_aligncomm): Add new struct definition. + (def_file): Add new def_file_aligncomm member. + * deffilep.y (%token): Add new ALIGNCOMM token. + (command): Add production rule for ALIGNCOMM. + (def_file_free): Free any chained def_file_aligncomm structs. + (diropts[]): Add entry for '-aligncomm' .drectve command. + (def_aligncomm): New grammar function. + * ld.texinfo: Document new feature. + * pe-dll.c (process_def_file): Rename from this ... + (process_def_file_and_drectve): ... to this, updating all callers, + and process any aligncomms chained to the def file after scanning + all .drectve sections. + (generate_edata): Updated to match. + (pe_dll_build_sections): Likewise. + 2009-05-17 Dave Korn 2008-08-07 Aaron W. LaFramboise diff --git a/ld/NEWS b/ld/NEWS index dce9503..6f05361 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,9 @@ -*- text -*- +* PE targets now support a GNU extension to allow the alignment of common + common symbols to be specified. This support uses custom options in + the .drectve section, which will be disregarded by the native tools. + * PE targets now add primitive support for ELF version scripts; symbols are not versioned, but the local and global symbol visibility directives are respected when filtering symbols in auto-export mode. diff --git a/ld/deffile.h b/ld/deffile.h index 1e7a0cb..79953b3 100644 --- a/ld/deffile.h +++ b/ld/deffile.h @@ -53,6 +53,12 @@ typedef struct def_file_import { int data; /* = 1 if data */ } def_file_import; +typedef struct def_file_aligncomm { + struct def_file_aligncomm *next; /* Chain pointer. */ + char *symbol_name; /* Name of common symbol. */ + unsigned int alignment; /* log-2 alignment. */ +} def_file_aligncomm; + typedef struct def_file { /* From the NAME or LIBRARY command. */ char *name; @@ -83,6 +89,10 @@ typedef struct def_file { /* From the VERSION command, -1 if not specified. */ int version_major, version_minor; + + /* Only expected from .drectve sections, not .DEF files. */ + def_file_aligncomm *aligncomms; + } def_file; extern def_file *def_file_empty (void); diff --git a/ld/deffilep.y b/ld/deffilep.y index 11c075d..5f02727 100644 --- a/ld/deffilep.y +++ b/ld/deffilep.y @@ -89,6 +89,7 @@ static void def_section_alt (const char *, const char *); static void def_stacksize (int, int); static void def_version (int, int); static void def_directive (char *); +static void def_aligncomm (char *str, int align); static int def_parse (void); static int def_error (const char *); static int def_lex (void); @@ -106,7 +107,7 @@ static const char *lex_parse_string_end = 0; %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL -%token PRIVATEU PRIVATEL +%token PRIVATEU PRIVATEL ALIGNCOMM %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE %token ID %token NUMBER @@ -134,6 +135,7 @@ command: | VERSIONK NUMBER { def_version ($2, 0);} | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);} | DIRECTIVE ID { def_directive ($2);} + | ALIGNCOMM ID ',' NUMBER { def_aligncomm ($2, $4);} ; @@ -379,6 +381,14 @@ def_file_free (def_file *def) free (m); } + while (def->aligncomms) + { + def_file_aligncomm *c = def->aligncomms; + def->aligncomms = def->aligncomms->next; + free (c->symbol_name); + free (c); + } + free (def); } @@ -573,6 +583,7 @@ diropts[] = { "-stack", STACKSIZE_K }, { "-attr", SECTIONS }, { "-export", EXPORTS }, + { "-aligncomm", ALIGNCOMM }, { 0, 0 } }; @@ -831,6 +842,18 @@ def_directive (char *str) d->len = strlen (str); } +static void +def_aligncomm (char *str, int align) +{ + def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm)); + + c->symbol_name = xstrdup (str); + c->alignment = (unsigned int) align; + + c->next = def->aligncomms; + def->aligncomms = c; +} + static int def_error (const char *err) { diff --git a/ld/ld.texinfo b/ld/ld.texinfo index bdfa948..2121725 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -6994,6 +6994,17 @@ implemented. As a GNU extension, weak symbols that do not specify an alternate symbol are supported. If the symbol is undefined when linking, the symbol uses a default value. + +@cindex aligned common symbols +@item aligned common symbols +As a GNU extension to the PE file format, it is possible to specify the +desired alignment for a common symbol. This information is conveyed from +the assembler or compiler to the linker by means of GNU-specific commands +carried in the object file's @samp{.drectve} section, which are recognized +by @command{ld} and respected when laying out the common symbols. Native +tools will be able to process object files employing this GNU extension, +but will fail to respect the alignment instructions, and may issue noisy +warnings about unknown linker directives. @end table @ifclear GENERIC diff --git a/ld/pe-dll.c b/ld/pe-dll.c index 3f2815e..f615b2d 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -615,7 +615,7 @@ auto_export (bfd *abfd, def_file *d, const char *n) } static void -process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) +process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) { int i, j; struct bfd_link_hash_entry *blhe; @@ -642,6 +642,28 @@ process_def_file (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) } } + /* Process aligned common symbol information from the + .drectve sections now; common symbol allocation is + done before final link, so it will be too late to + process them in process_embedded_commands() called + from _bfd_coff_link_input_bfd(). */ + if (pe_def_file->aligncomms) + { + def_file_aligncomm *ac = pe_def_file->aligncomms; + while (ac) + { + struct coff_link_hash_entry *sym_hash; + sym_hash = coff_link_hash_lookup (coff_hash_table (info), + ac->symbol_name, FALSE, FALSE, FALSE); + if (sym_hash && sym_hash->root.type == bfd_link_hash_common + && sym_hash->root.u.c.p->alignment_power < (unsigned) ac->alignment) + { + sym_hash->root.u.c.p->alignment_power = (unsigned) ac->alignment; + } + ac = ac->next; + } + } + /* If we are not building a DLL, when there are no exports we do not build an export table at all. */ if (!pe_dll_export_everything && pe_def_file->num_exports == 0 @@ -1057,7 +1079,7 @@ generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) } /* Fill the exported symbol offsets. The preliminary work has already - been done in process_def_file(). */ + been done in process_def_file_and_drectve(). */ static void fill_exported_offsets (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) @@ -3066,7 +3088,7 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info) { pe_dll_id_target (bfd_get_target (abfd)); pe_output_file_set_long_section_names (abfd); - process_def_file (abfd, info); + process_def_file_and_drectve (abfd, info); if (pe_def_file->num_exports == 0 && !info->shared) return; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index c906850..db9fe11 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2009-05-19 Dave Korn + + * ld-pe/aligncomm-1.c: New test source file. + * ld-pe/aligncomm-2.c: Likewise. + * ld-pe/aligncomm-3.c: Likewise. + * ld-pe/aligncomm-4.c: Likewise. + * ld-pe/aligncomm.d: New test pattern file. + + * ld-pe/direct.exp: Deleted, and content moved into ... + * ld-pe/pe-run.exp: ... New common file for all PE run tests. + + * ld-pe/vers-script.exp: Deleted, and content merged into ... + * ld-pe/pe-compile.exp: ... New common file for PE tests needing + a compiler, adding aligned common tests. + + * ld-pe/pe.exp: Update header comment. + 2009-05-17 Aaron W. LaFramboise * ld-pe/exports.d: New file. diff --git a/ld/testsuite/ld-pe/aligncomm-1.c b/ld/testsuite/ld-pe/aligncomm-1.c new file mode 100755 index 0000000..44f576e --- /dev/null +++ b/ld/testsuite/ld-pe/aligncomm-1.c @@ -0,0 +1,19 @@ + +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); + +long s1 = 0; +__m128 r; +__m128 * volatile raddr = &r; + +int main (int argc, const char **argv) +{ + return 15 & (int)raddr; +} + +void __main (void) +{ + asm (".section .drectve\n" + " .ascii \" -aligncomm:_r,4\"\n" + " .ascii \" -aligncomm:r,4\"\n" + " .text"); +} diff --git a/ld/testsuite/ld-pe/aligncomm-2.c b/ld/testsuite/ld-pe/aligncomm-2.c new file mode 100755 index 0000000..3b33362 --- /dev/null +++ b/ld/testsuite/ld-pe/aligncomm-2.c @@ -0,0 +1,20 @@ + +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); + +long s1 = 0; +long s2 = 0; +__m128 r; +__m128 * volatile raddr = &r; + +int main (int argc, const char **argv) +{ + return 15 & (int)raddr; +} + +void __main (void) +{ + asm (".section .drectve\n" + " .ascii \" -aligncomm:_r,4\"\n" + " .ascii \" -aligncomm:r,4\"\n" + " .text"); +} diff --git a/ld/testsuite/ld-pe/aligncomm-3.c b/ld/testsuite/ld-pe/aligncomm-3.c new file mode 100755 index 0000000..04fdfd1 --- /dev/null +++ b/ld/testsuite/ld-pe/aligncomm-3.c @@ -0,0 +1,21 @@ + +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); + +long s1 = 0; +long s2 = 0; +long s3 = 0; +__m128 r; +__m128 * volatile raddr = &r; + +int main (int argc, const char **argv) +{ + return 15 & (int)raddr; +} + +void __main (void) +{ + asm (".section .drectve\n" + " .ascii \" -aligncomm:_r,4\"\n" + " .ascii \" -aligncomm:r,4\"\n" + " .text"); +} diff --git a/ld/testsuite/ld-pe/aligncomm-4.c b/ld/testsuite/ld-pe/aligncomm-4.c new file mode 100755 index 0000000..854d9ba --- /dev/null +++ b/ld/testsuite/ld-pe/aligncomm-4.c @@ -0,0 +1,22 @@ + +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); + +long s1 = 0; +long s2 = 0; +long s3 = 0; +long s4 = 0; +__m128 r; +__m128 * volatile raddr = &r; + +int main (int argc, const char **argv) +{ + return 15 & (int)raddr; +} + +void __main (void) +{ + asm (".section .drectve\n" + " .ascii \" -aligncomm:_r,4\"\n" + " .ascii \" -aligncomm:r,4\"\n" + " .text"); +} diff --git a/ld/testsuite/ld-pe/aligncomm.d b/ld/testsuite/ld-pe/aligncomm.d new file mode 100755 index 0000000..6f33644 --- /dev/null +++ b/ld/testsuite/ld-pe/aligncomm.d @@ -0,0 +1,3 @@ +#... +[0-9a-fA-F]{7,15}0 . r +#... diff --git a/ld/testsuite/ld-pe/vers-script.exp b/ld/testsuite/ld-pe/pe-compile.exp similarity index 75% rename from ld/testsuite/ld-pe/vers-script.exp rename to ld/testsuite/ld-pe/pe-compile.exp index e0638b1..b9bc4af 100755 --- a/ld/testsuite/ld-pe/vers-script.exp +++ b/ld/testsuite/ld-pe/pe-compile.exp @@ -1,4 +1,5 @@ -# Expect script for version-script driven export from dll tests +# Expect script for complex PE tests that require a C compiler +# in addition to the just-built binutils. # Copyright 2009 # Free Software Foundation, Inc. # @@ -20,7 +21,7 @@ # MA 02110-1301, USA. # -# This test can only be run on PE/COFF platforms. +# These tests can only be run on PE/COFF platforms. if {![is_pecoff_format]} { return } @@ -28,6 +29,8 @@ if {![is_pecoff_format]} { # No compiler, no test. if { [which $CC] == 0 } { untested "PE version scripts" + untested "aligned common tests" + # Add more "untested" directives here when adding more tests below. return } @@ -36,7 +39,7 @@ proc build_vers_script_dll_o {} { global CFLAGS global srcdir global subdir - + # Compile the object file. if ![ld_compile "$CC $CFLAGS -shared" $srcdir/$subdir/vers-script-dll.c tmpdir/vers-script-dll.o] { fail "compiling shared lib object" @@ -74,3 +77,15 @@ run_ver_script_test "vers-script-2" run_ver_script_test "vers-script-3" run_ver_script_test "vers-script-4" +set align_tests { + {"aligned common 1" "" "" {aligncomm-1.c} + {{nm -C aligncomm.d}} "aligncomm-1.x"} + {"aligned common 2" "" "" {aligncomm-2.c} + {{nm -C aligncomm.d}} "aligncomm-2.x"} + {"aligned common 3" "" "" {aligncomm-3.c} + {{nm -C aligncomm.d}} "aligncomm-3.x"} + {"aligned common 4" "" "" {aligncomm-4.c} + {{nm -C aligncomm.d}} "aligncomm-4.x"} +} + +run_ld_link_tests $align_tests diff --git a/ld/testsuite/ld-pe/direct.exp b/ld/testsuite/ld-pe/pe-run.exp old mode 100644 new mode 100755 similarity index 96% rename from ld/testsuite/ld-pe/direct.exp rename to ld/testsuite/ld-pe/pe-run.exp index b4bb629..3e7c356 --- a/ld/testsuite/ld-pe/direct.exp +++ b/ld/testsuite/ld-pe/pe-run.exp @@ -1,4 +1,5 @@ -# Expect script for direct linking from dll tests +# Expect script for complex PE tests that require a C compiler and the ability +# to run target executables natively, in addition to the just-built binutils. # Copyright 2006, 2007 # Free Software Foundation, Inc. # @@ -67,7 +68,7 @@ proc test_direct_link_dll {} { global srcdir global subdir global tmpdir - + # Compile the dll. if ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/direct_dll.c $tmpdir/direct_dll.o ] { fail "compiling shared lib" diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp index ad91f06..3fcf8cb 100644 --- a/ld/testsuite/ld-pe/pe.exp +++ b/ld/testsuite/ld-pe/pe.exp @@ -1,4 +1,4 @@ -# Expect script for export table in executables tests +# Expect script for simple PE tests that require the just-built binutils only. # Copyright 2004, 2006, 2007 # Free Software Foundation, Inc. # -- 2.7.4