From a56e7c0854c156a0555743d1b98597c650cf6499 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 5 Jan 2000 23:26:06 +0000 Subject: [PATCH] Add support for generating unique sections for unitialised data. From-SVN: r31250 --- gcc/ChangeLog | 34 +++++++++++ gcc/config/arm/unknown-elf.h | 114 +++++++++++++++++++++++++---------- gcc/config/i386/interix.c | 3 + gcc/config/i386/winnt.c | 3 + gcc/config/mips/elf.h | 10 ++- gcc/config/mips/elf64.h | 8 ++- gcc/config/mips/iris6gld.h | 62 +++++++++++-------- gcc/tm.texi | 5 +- gcc/varasm.c | 18 ++++-- 9 files changed, 188 insertions(+), 69 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e99b3d7baae..b3456025bfd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +2000-01-05 Nick Clifton + + * varasm.c (IN_NAMED_SECTION): Allow targets to provide their + own definition of this macro. + (asm_emit_uninitialised): Invoke UNIQUE_SECTION if either + flag_data_sections or UNIQUE_SECTION_P are true. + + * tm.texi (UNIQUE)SECTION): Document that it can be called for + unitialised data decls. + + * config/i386/winnt.c (i386_pe_unique_section): Cope with + being called for uninitialised data. + + * config/i386/interix.c (i386_pe_unique_section): Cope with + being called for uninitialised data. + + * config/mips/elf.h (UNIQUE_SECTION): Cope with being called + for uninitialised data. + + * config/mips/elf64.h (UNIQUE_SECTION): Cope with being called + for uninitialised data. + + * config/mips/iri6gld.h (UNIQUE_SECTION): Cope with being called + for uninitialised data. + + * config/arm/unknown-elf.h (IN_NAMED_SECTION): Define. + (UNIQUE_SECTION_P): Always generate a unique section if + flag_data_sections is true. + (UNIQUE_SECTION): Also generate unique sections for + uninitialised data. + (ASM_OUTPUT_ALIGNED_BSS): Redefine to use named_section(). + (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Redefine to use + named_section(). + 2000-01-06 Michael Hayes * config/c4x/t-c4x (TARGET_LIBGCC2_CFLAGS): Don't redefine SF, DF, diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h index aeddcdf15f5..33bd9af459d 100644 --- a/gcc/config/arm/unknown-elf.h +++ b/gcc/config/arm/unknown-elf.h @@ -122,38 +122,90 @@ do { \ #define NAME__MAIN "__gccmain" #define SYMBOL__MAIN __gccmain +/* Return a non-zero value if DECL has a section attribute. */ +#define IN_NAMED_SECTION(DECL) \ + ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ + && DECL_SECTION_NAME (DECL) != NULL_TREE) + + #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) -#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL)) -#define UNIQUE_SECTION(DECL,RELOC) \ -do { \ - int len; \ - char * name, * string, * prefix; \ - \ - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ - \ - if (! DECL_ONE_ONLY (DECL)) \ - { \ - prefix = "."; \ - if (TREE_CODE (DECL) == FUNCTION_DECL) \ - prefix = ".text."; \ - else if (DECL_READONLY_SECTION (DECL, RELOC)) \ - prefix = ".rodata."; \ - else \ - prefix = ".data."; \ - } \ - else if (TREE_CODE (DECL) == FUNCTION_DECL) \ - prefix = ".gnu.linkonce.t."; \ - else if (DECL_READONLY_SECTION (DECL, RELOC)) \ - prefix = ".gnu.linkonce.r."; \ - else \ - prefix = ".gnu.linkonce.d."; \ - \ - len = strlen (name) + strlen (prefix); \ - string = alloca (len + 1); \ - sprintf (string, "%s%s", prefix, name); \ - \ - DECL_SECTION_NAME (DECL) = build_string (len, string); \ -} while (0) + +#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL) || flag_data_sections) + +#define UNIQUE_SECTION(DECL, RELOC) \ + do \ + { \ + int len; \ + int sec; \ + char *name; \ + char *string; \ + char *prefix; \ + static char *prefixes[4][2] = \ + { \ + { ".text.", ".gnu.linkonce.t." }, \ + { ".rodata.", ".gnu.linkonce.r." }, \ + { ".data.", ".gnu.linkonce.d." }, \ + { ".bss.", ".gnu.linkonce.b." } \ + }; \ + \ + if (TREE_CODE (DECL) == FUNCTION_DECL) \ + sec = 0; \ + else if (DECL_INITIAL (DECL) == 0 \ + || DECL_INITIAL (DECL) == error_mark_node) \ + sec = 3; \ + else if (DECL_READONLY_SECTION (DECL, RELOC)) \ + sec = 1; \ + else \ + sec = 2; \ + \ + prefix = prefixes[sec][DECL_ONE_ONLY(DECL)]; \ + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ + \ + /* Strip off any encoding in name. */ \ + STRIP_NAME_ENCODING (name, name); \ + \ + len = strlen (name) + strlen (prefix); \ + string = alloca (len + 1); \ + \ + sprintf (string, "%s%s", prefix, name); \ + \ + DECL_SECTION_NAME (DECL) = build_string (len, string); \ + } \ + while (0) + +#undef ASM_OUTPUT_ALIGNED_BSS +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ + do \ + { \ + if (IN_NAMED_SECTION (DECL)) \ + named_section (DECL, NULL, 0); \ + else \ + bss_section (); \ + \ + ASM_GLOBALIZE_LABEL (FILE, NAME); \ + \ + ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \ + \ + last_assemble_variable_decl = DECL; \ + ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL); \ + ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1); \ + } \ + while (0) + +#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL +#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \ + do \ + { \ + if (IN_NAMED_SECTION (DECL)) \ + named_section (DECL, NULL, 0); \ + else \ + bss_section (); \ + \ + ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \ + ASM_OUTPUT_LABEL (FILE, NAME); \ + fprintf (FILE, "\t.space\t%d\n", SIZE); \ + } \ + while (0) #ifndef CPP_APCS_PC_DEFAULT_SPEC #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__" diff --git a/gcc/config/i386/interix.c b/gcc/config/i386/interix.c index 5a2b8b6ab41..4f4f8233e18 100644 --- a/gcc/config/i386/interix.c +++ b/gcc/config/i386/interix.c @@ -93,6 +93,9 @@ i386_pe_unique_section (decl, reloc) without a .rdata section. */ if (TREE_CODE (decl) == FUNCTION_DECL) prefix = ".text$"; + else if (DECL_INITIAL (decl) == 0 + || DECL_INITIAL (decl) == error_mark_node) + prefix = ""; else if (DECL_READONLY_SECTION (decl, reloc)) #ifdef READONLY_DATA_SECTION prefix = ".rdata$"; diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 2c2ce763359..13701e2c4e2 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -480,6 +480,9 @@ i386_pe_unique_section (decl, reloc) without a .rdata section. */ if (TREE_CODE (decl) == FUNCTION_DECL) prefix = ".text$"; + else if (DECL_INITIAL (decl) == 0 + || DECL_INITIAL (decl) == error_mark_node) + prefix = ""; else if (DECL_READONLY_SECTION (decl, reloc)) #ifdef READONLY_DATA_SECTION prefix = ".rdata$"; diff --git a/gcc/config/mips/elf.h b/gcc/config/mips/elf.h index 9299ac819a3..b265295f5c2 100644 --- a/gcc/config/mips/elf.h +++ b/gcc/config/mips/elf.h @@ -212,20 +212,24 @@ do { \ do { \ int len, size, sec; \ char *name, *string, *prefix; \ - static char *prefixes[4][2] = { \ + static char *prefixes[5][2] = { \ { ".text.", ".gnu.linkonce.t." }, \ { ".rodata.", ".gnu.linkonce.r." }, \ { ".data.", ".gnu.linkonce.d." }, \ - { ".sdata.", ".gnu.linkonce.s." } \ + { ".sdata.", ".gnu.linkonce.s." }, \ + { "", "" } \ }; \ \ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ size = int_size_in_bytes (TREE_TYPE (decl)); \ \ /* Determine the base section we are interested in: \ - 0=text, 1=rodata, 2=data, 3=sdata. */ \ + 0=text, 1=rodata, 2=data, 3=sdata, [4=bss]. */ \ if (TREE_CODE (DECL) == FUNCTION_DECL) \ sec = 0; \ + else if (DECL_INITIAL (DECL) == 0 \ + || DECL_INITIAL (DECL) == error_mark_node) \ + sec = 4; \ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) \ && TREE_CODE (decl) == STRING_CST \ && !flag_writable_strings) \ diff --git a/gcc/config/mips/elf64.h b/gcc/config/mips/elf64.h index 5d6632e1c5f..907e4cb0cca 100644 --- a/gcc/config/mips/elf64.h +++ b/gcc/config/mips/elf64.h @@ -197,16 +197,20 @@ do { \ { ".text.", ".gnu.linkonce.t." }, \ { ".rodata.", ".gnu.linkonce.r." }, \ { ".data.", ".gnu.linkonce.d." }, \ - { ".sdata.", ".gnu.linkonce.s." } \ + { ".sdata.", ".gnu.linkonce.s." }, \ + { "", "" } \ }; \ \ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ size = int_size_in_bytes (TREE_TYPE (decl)); \ \ /* Determine the base section we are interested in: \ - 0=text, 1=rodata, 2=data, 3=sdata. */ \ + 0=text, 1=rodata, 2=data, 3=sdata, [4=bss]. */ \ if (TREE_CODE (DECL) == FUNCTION_DECL) \ sec = 0; \ + else if (DECL_INITIAL (DECL) == 0 \ + || DECL_INITIAL (DECL) == error_mark_node) \ + sec = 4; \ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) \ && TREE_CODE (decl) == STRING_CST \ && !flag_writable_strings) \ diff --git a/gcc/config/mips/iris6gld.h b/gcc/config/mips/iris6gld.h index 860733f201a..142402115e7 100644 --- a/gcc/config/mips/iris6gld.h +++ b/gcc/config/mips/iris6gld.h @@ -49,35 +49,45 @@ Boston, MA 02111-1307, USA. */ /* The GNU linker supports one-only sections. */ #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) -#undef UNIQUE_SECTION_P +#undef UNIQUE_SECTION_P #define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL)) -#define UNIQUE_SECTION(DECL,RELOC) \ -do { \ - int len; \ - char *name, *string, *prefix; \ - \ - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ - \ - if (! DECL_ONE_ONLY (DECL)) \ +#define UNIQUE_SECTION(DECL, RELOC) \ + do \ { \ - prefix = "."; \ + int len; \ + int sec; \ + char *name; \ + char *string; \ + char *prefix; \ + static char *prefixes[4][2] = \ + { \ + { ".text.", ".gnu.linkonce.t." }, \ + { ".rodata.", ".gnu.linkonce.r." }, \ + { ".data.", ".gnu.linkonce.d." }, \ + /* Do not generate unique sections for uninitialised \ + data since we do not have support for this in the \ + linker scripts yet... \ + { ".bss.", ".gnu.linkonce.b." } */ \ + { "", "" } \ + }; \ + \ if (TREE_CODE (DECL) == FUNCTION_DECL) \ - prefix = ".text."; \ + sec = 0; \ + else if (DECL_INITIAL (DECL) == 0 \ + || DECL_INITIAL (DECL) == error_mark_node) \ + sec = 3; \ else if (DECL_READONLY_SECTION (DECL, RELOC)) \ - prefix = ".rodata."; \ + sec = 1; \ else \ - prefix = ".data."; \ + sec = 2; \ + \ + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ + prefix = prefixes[sec][DECL_ONE_ONLY(DECL)]; \ + len = strlen (name) + strlen (prefix); \ + string = alloca (len + 1); \ + \ + sprintf (string, "%s%s", prefix, name); \ + \ + DECL_SECTION_NAME (DECL) = build_string (len, string); \ } \ - else if (TREE_CODE (DECL) == FUNCTION_DECL) \ - prefix = ".gnu.linkonce.t."; \ - else if (DECL_READONLY_SECTION (DECL, RELOC)) \ - prefix = ".gnu.linkonce.r."; \ - else \ - prefix = ".gnu.linkonce.d."; \ - \ - len = strlen (name) + strlen (prefix); \ - string = alloca (len + 1); \ - sprintf (string, "%s%s", prefix, name); \ - \ - DECL_SECTION_NAME (DECL) = build_string (len, string); \ -} while (0) + while (0) diff --git a/gcc/tm.texi b/gcc/tm.texi index 6a3ff5185d5..b2d43c954ac 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -4999,7 +4999,9 @@ A C statement to build up a unique section name, expressed as a STRING_CST node, and assign it to @samp{DECL_SECTION_NAME (@var{decl})}. @var{reloc} indicates whether the initial value of @var{exp} requires link-time relocations. If you do not define this macro, GCC will use -the symbol name prefixed by @samp{.} as the section name. +the symbol name prefixed by @samp{.} as the section name. Note - this +macro can now be called for unitialised data items as well as +initialised data and functions. @end table @node PIC @@ -5513,7 +5515,6 @@ in place of both @code{ASM_OUTPUT_DECL} and @code{ASM_OUTPUT_ALIGNED_DECL}. Define this macro when you need to see the variable's decl in order to chose what to output. - @findex ASM_OUTPUT_SHARED_LOCAL @item ASM_OUTPUT_SHARED_LOCAL (@var{stream}, @var{name}, @var{size}, @var{rounded}) If defined, it is similar to @code{ASM_OUTPUT_LOCAL}, except that it diff --git a/gcc/varasm.c b/gcc/varasm.c index 6087c7bad19..2743abe709b 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -202,10 +202,12 @@ static enum in_section { no_section, in_text, in_data, in_named } in_section = no_section; /* Return a non-zero value if DECL has a section attribute. */ +#ifndef IN_NAMED_SECTION #define IN_NAMED_SECTION(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ && DECL_SECTION_NAME (DECL) != NULL_TREE) - +#endif + /* Text of section name when in_section == in_named. */ static char *in_named_name; @@ -1233,7 +1235,8 @@ asm_emit_uninitialised (decl, name, size, rounded) int size; int rounded ATTRIBUTE_UNUSED; { - enum { + enum + { asm_dest_common, asm_dest_bss, asm_dest_local @@ -1274,6 +1277,12 @@ asm_emit_uninitialised (decl, name, size, rounded) } } +#ifdef ASM_OUTPUT_SECTION_NAME + /* We already know that DECL_SECTION_NAME() == NULL. */ + if (flag_data_sections != 0 || UNIQUE_SECTION_P (decl)) + UNIQUE_SECTION (decl, NULL); +#endif + switch (destination) { #ifdef ASM_EMIT_BSS @@ -1486,7 +1495,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data) #if ! defined ASM_EMIT_BSS && DECL_COMMON (decl) #endif - && DECL_SECTION_NAME (decl) == 0 + && DECL_SECTION_NAME (decl) == NULL_TREE && ! dont_output_data) { int size = TREE_INT_CST_LOW (size_tree); @@ -1575,8 +1584,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data) reloc = output_addressed_constants (DECL_INITIAL (decl)); #ifdef ASM_OUTPUT_SECTION_NAME - if ((flag_data_sections != 0 - && DECL_SECTION_NAME (decl) == NULL_TREE) + if ((flag_data_sections != 0 && DECL_SECTION_NAME (decl) == NULL_TREE) || UNIQUE_SECTION_P (decl)) UNIQUE_SECTION (decl, reloc); #endif -- 2.30.2