Commit a56e7c08 by Nick Clifton Committed by Nick Clifton

Add support for generating unique sections for unitialised data.

From-SVN: r31250
parent d6ab24c5
2000-01-05 Nick Clifton <nickc@cygnus.com>
* 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 <m.hayes@elec.canterbury.ac.nz> 2000-01-06 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x/t-c4x (TARGET_LIBGCC2_CFLAGS): Don't redefine SF, DF, * config/c4x/t-c4x (TARGET_LIBGCC2_CFLAGS): Don't redefine SF, DF,
......
...@@ -122,38 +122,90 @@ do { \ ...@@ -122,38 +122,90 @@ do { \
#define NAME__MAIN "__gccmain" #define NAME__MAIN "__gccmain"
#define SYMBOL__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 MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL))
#define UNIQUE_SECTION(DECL,RELOC) \ #define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL) || flag_data_sections)
do { \
int len; \ #define UNIQUE_SECTION(DECL, RELOC) \
char * name, * string, * prefix; \ do \
\ { \
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ int len; \
\ int sec; \
if (! DECL_ONE_ONLY (DECL)) \ char *name; \
{ \ char *string; \
prefix = "."; \ char *prefix; \
if (TREE_CODE (DECL) == FUNCTION_DECL) \ static char *prefixes[4][2] = \
prefix = ".text."; \ { \
else if (DECL_READONLY_SECTION (DECL, RELOC)) \ { ".text.", ".gnu.linkonce.t." }, \
prefix = ".rodata."; \ { ".rodata.", ".gnu.linkonce.r." }, \
else \ { ".data.", ".gnu.linkonce.d." }, \
prefix = ".data."; \ { ".bss.", ".gnu.linkonce.b." } \
} \ }; \
else if (TREE_CODE (DECL) == FUNCTION_DECL) \ \
prefix = ".gnu.linkonce.t."; \ if (TREE_CODE (DECL) == FUNCTION_DECL) \
else if (DECL_READONLY_SECTION (DECL, RELOC)) \ sec = 0; \
prefix = ".gnu.linkonce.r."; \ else if (DECL_INITIAL (DECL) == 0 \
else \ || DECL_INITIAL (DECL) == error_mark_node) \
prefix = ".gnu.linkonce.d."; \ sec = 3; \
\ else if (DECL_READONLY_SECTION (DECL, RELOC)) \
len = strlen (name) + strlen (prefix); \ sec = 1; \
string = alloca (len + 1); \ else \
sprintf (string, "%s%s", prefix, name); \ sec = 2; \
\ \
DECL_SECTION_NAME (DECL) = build_string (len, string); \ prefix = prefixes[sec][DECL_ONE_ONLY(DECL)]; \
} while (0) 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 #ifndef CPP_APCS_PC_DEFAULT_SPEC
#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__" #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
......
...@@ -93,6 +93,9 @@ i386_pe_unique_section (decl, reloc) ...@@ -93,6 +93,9 @@ i386_pe_unique_section (decl, reloc)
without a .rdata section. */ without a .rdata section. */
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
prefix = ".text$"; prefix = ".text$";
else if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)
prefix = "";
else if (DECL_READONLY_SECTION (decl, reloc)) else if (DECL_READONLY_SECTION (decl, reloc))
#ifdef READONLY_DATA_SECTION #ifdef READONLY_DATA_SECTION
prefix = ".rdata$"; prefix = ".rdata$";
......
...@@ -480,6 +480,9 @@ i386_pe_unique_section (decl, reloc) ...@@ -480,6 +480,9 @@ i386_pe_unique_section (decl, reloc)
without a .rdata section. */ without a .rdata section. */
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
prefix = ".text$"; prefix = ".text$";
else if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)
prefix = "";
else if (DECL_READONLY_SECTION (decl, reloc)) else if (DECL_READONLY_SECTION (decl, reloc))
#ifdef READONLY_DATA_SECTION #ifdef READONLY_DATA_SECTION
prefix = ".rdata$"; prefix = ".rdata$";
......
...@@ -212,20 +212,24 @@ do { \ ...@@ -212,20 +212,24 @@ do { \
do { \ do { \
int len, size, sec; \ int len, size, sec; \
char *name, *string, *prefix; \ char *name, *string, *prefix; \
static char *prefixes[4][2] = { \ static char *prefixes[5][2] = { \
{ ".text.", ".gnu.linkonce.t." }, \ { ".text.", ".gnu.linkonce.t." }, \
{ ".rodata.", ".gnu.linkonce.r." }, \ { ".rodata.", ".gnu.linkonce.r." }, \
{ ".data.", ".gnu.linkonce.d." }, \ { ".data.", ".gnu.linkonce.d." }, \
{ ".sdata.", ".gnu.linkonce.s." } \ { ".sdata.", ".gnu.linkonce.s." }, \
{ "", "" } \
}; \ }; \
\ \
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
size = int_size_in_bytes (TREE_TYPE (decl)); \ size = int_size_in_bytes (TREE_TYPE (decl)); \
\ \
/* Determine the base section we are interested in: \ /* 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) \ if (TREE_CODE (DECL) == FUNCTION_DECL) \
sec = 0; \ sec = 0; \
else if (DECL_INITIAL (DECL) == 0 \
|| DECL_INITIAL (DECL) == error_mark_node) \
sec = 4; \
else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) \ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) \
&& TREE_CODE (decl) == STRING_CST \ && TREE_CODE (decl) == STRING_CST \
&& !flag_writable_strings) \ && !flag_writable_strings) \
......
...@@ -197,16 +197,20 @@ do { \ ...@@ -197,16 +197,20 @@ do { \
{ ".text.", ".gnu.linkonce.t." }, \ { ".text.", ".gnu.linkonce.t." }, \
{ ".rodata.", ".gnu.linkonce.r." }, \ { ".rodata.", ".gnu.linkonce.r." }, \
{ ".data.", ".gnu.linkonce.d." }, \ { ".data.", ".gnu.linkonce.d." }, \
{ ".sdata.", ".gnu.linkonce.s." } \ { ".sdata.", ".gnu.linkonce.s." }, \
{ "", "" } \
}; \ }; \
\ \
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
size = int_size_in_bytes (TREE_TYPE (decl)); \ size = int_size_in_bytes (TREE_TYPE (decl)); \
\ \
/* Determine the base section we are interested in: \ /* 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) \ if (TREE_CODE (DECL) == FUNCTION_DECL) \
sec = 0; \ sec = 0; \
else if (DECL_INITIAL (DECL) == 0 \
|| DECL_INITIAL (DECL) == error_mark_node) \
sec = 4; \
else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) \ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16) \
&& TREE_CODE (decl) == STRING_CST \ && TREE_CODE (decl) == STRING_CST \
&& !flag_writable_strings) \ && !flag_writable_strings) \
......
...@@ -49,35 +49,45 @@ Boston, MA 02111-1307, USA. */ ...@@ -49,35 +49,45 @@ Boston, MA 02111-1307, USA. */
/* The GNU linker supports one-only sections. */ /* The GNU linker supports one-only sections. */
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) #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_P(DECL) (DECL_ONE_ONLY (DECL))
#define UNIQUE_SECTION(DECL,RELOC) \ #define UNIQUE_SECTION(DECL, RELOC) \
do { \ do \
int len; \
char *name, *string, *prefix; \
\
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
\
if (! DECL_ONE_ONLY (DECL)) \
{ \ { \
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) \ 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)) \ else if (DECL_READONLY_SECTION (DECL, RELOC)) \
prefix = ".rodata."; \ sec = 1; \
else \ 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) \ while (0)
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)
...@@ -4999,7 +4999,9 @@ A C statement to build up a unique section name, expressed as a ...@@ -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})}. STRING_CST node, and assign it to @samp{DECL_SECTION_NAME (@var{decl})}.
@var{reloc} indicates whether the initial value of @var{exp} requires @var{reloc} indicates whether the initial value of @var{exp} requires
link-time relocations. If you do not define this macro, GCC will use 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 @end table
@node PIC @node PIC
...@@ -5513,7 +5515,6 @@ in place of both @code{ASM_OUTPUT_DECL} and ...@@ -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 @code{ASM_OUTPUT_ALIGNED_DECL}. Define this macro when you need to see
the variable's decl in order to chose what to output. the variable's decl in order to chose what to output.
@findex ASM_OUTPUT_SHARED_LOCAL @findex ASM_OUTPUT_SHARED_LOCAL
@item ASM_OUTPUT_SHARED_LOCAL (@var{stream}, @var{name}, @var{size}, @var{rounded}) @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 If defined, it is similar to @code{ASM_OUTPUT_LOCAL}, except that it
......
...@@ -202,10 +202,12 @@ static enum in_section { no_section, in_text, in_data, in_named ...@@ -202,10 +202,12 @@ static enum in_section { no_section, in_text, in_data, in_named
} in_section = no_section; } in_section = no_section;
/* Return a non-zero value if DECL has a section attribute. */ /* Return a non-zero value if DECL has a section attribute. */
#ifndef IN_NAMED_SECTION
#define IN_NAMED_SECTION(DECL) \ #define IN_NAMED_SECTION(DECL) \
((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
&& DECL_SECTION_NAME (DECL) != NULL_TREE) && DECL_SECTION_NAME (DECL) != NULL_TREE)
#endif
/* Text of section name when in_section == in_named. */ /* Text of section name when in_section == in_named. */
static char *in_named_name; static char *in_named_name;
...@@ -1233,7 +1235,8 @@ asm_emit_uninitialised (decl, name, size, rounded) ...@@ -1233,7 +1235,8 @@ asm_emit_uninitialised (decl, name, size, rounded)
int size; int size;
int rounded ATTRIBUTE_UNUSED; int rounded ATTRIBUTE_UNUSED;
{ {
enum { enum
{
asm_dest_common, asm_dest_common,
asm_dest_bss, asm_dest_bss,
asm_dest_local asm_dest_local
...@@ -1274,6 +1277,12 @@ asm_emit_uninitialised (decl, name, size, rounded) ...@@ -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) switch (destination)
{ {
#ifdef ASM_EMIT_BSS #ifdef ASM_EMIT_BSS
...@@ -1486,7 +1495,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data) ...@@ -1486,7 +1495,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
#if ! defined ASM_EMIT_BSS #if ! defined ASM_EMIT_BSS
&& DECL_COMMON (decl) && DECL_COMMON (decl)
#endif #endif
&& DECL_SECTION_NAME (decl) == 0 && DECL_SECTION_NAME (decl) == NULL_TREE
&& ! dont_output_data) && ! dont_output_data)
{ {
int size = TREE_INT_CST_LOW (size_tree); int size = TREE_INT_CST_LOW (size_tree);
...@@ -1575,8 +1584,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data) ...@@ -1575,8 +1584,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
reloc = output_addressed_constants (DECL_INITIAL (decl)); reloc = output_addressed_constants (DECL_INITIAL (decl));
#ifdef ASM_OUTPUT_SECTION_NAME #ifdef ASM_OUTPUT_SECTION_NAME
if ((flag_data_sections != 0 if ((flag_data_sections != 0 && DECL_SECTION_NAME (decl) == NULL_TREE)
&& DECL_SECTION_NAME (decl) == NULL_TREE)
|| UNIQUE_SECTION_P (decl)) || UNIQUE_SECTION_P (decl))
UNIQUE_SECTION (decl, reloc); UNIQUE_SECTION (decl, reloc);
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment