Commit ef7d91cd by Richard Henderson Committed by Richard Henderson

elf.h (ASM_OUTPUT_SECTION_NAME): Copy elfos.h defn.

        * config/alpha/elf.h (ASM_OUTPUT_SECTION_NAME): Copy elfos.h defn.
        (DO_SELECT_SECTION): New.
        (SELECT_SECTION): Use it.
        (UNIQUE_SECTION_P): New.
        (UNIQUE_SECTION): New.

From-SVN: r37903
parent be10afdf
2000-11-30 Richard Henderson <rth@redhat.com>
* config/alpha/elf.h (ASM_OUTPUT_SECTION_NAME): Copy elfos.h defn.
(DO_SELECT_SECTION): New.
(SELECT_SECTION): Use it.
(UNIQUE_SECTION_P): New.
(UNIQUE_SECTION): New.
2000-11-30 Alexandre Oliva <aoliva@redhat.com> 2000-11-30 Alexandre Oliva <aoliva@redhat.com>
* c-common.c (status_warning) [! ANSI_PROTOTYPES]: Load status * c-common.c (status_warning) [! ANSI_PROTOTYPES]: Load status
......
...@@ -318,16 +318,67 @@ void FN () \ ...@@ -318,16 +318,67 @@ void FN () \
/* Switch into a generic section. /* Switch into a generic section.
This is currently only used to support section attributes.
We make the section read-only and executable for a function decl, We make the section read-only and executable for a function decl,
read-only for a const data decl, and writable for a non-const data decl. */ read-only for a const data decl, and writable for a non-const data decl.
#undef ASM_OUTPUT_SECTION_NAME
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
(DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
(DECL) && DECL_READONLY_SECTION (DECL, RELOC) ? "a" : "aw")
If the section has already been defined, we must not emit the
attributes here. The SVR4 assembler does not recognize section
redefinitions. If DECL is NULL, no attributes are emitted. */
#undef ASM_OUTPUT_SECTION_NAME
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
do \
{ \
static htab_t htab; \
\
struct section_info \
{ \
enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
}; \
\
struct section_info *s; \
const char *mode; \
enum sect_enum type; \
PTR* slot; \
\
/* The names we put in the hashtable will always be the unique \
versions gived to us by the stringtable, so we can just use \
their addresses as the keys. */ \
if (!htab) \
htab = htab_create (31, \
htab_hash_pointer, \
htab_eq_pointer, \
NULL); \
\
if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
type = SECT_EXEC, mode = "ax"; \
else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
type = SECT_RO, mode = "a"; \
else \
type = SECT_RW, mode = "aw"; \
\
/* See if we already have an entry for this section. */ \
slot = htab_find_slot (htab, NAME, INSERT); \
if (!*slot) \
{ \
s = (struct section_info *) xmalloc (sizeof (* s)); \
s->type = type; \
*slot = s; \
fprintf (FILE, "\t.section\t%s,\"%s\",@progbits\n", \
NAME, mode); \
} \
else \
{ \
s = (struct section_info *) *slot; \
if (DECL && s->type != type) \
error_with_decl (DECL, \
"%s causes a section type conflict"); \
\
fprintf (FILE, "\t.section\t%s\n", NAME); \
} \
} \
while (0)
/* A C statement (sans semicolon) to output an element in the table of /* A C statement (sans semicolon) to output an element in the table of
global constructors. */ global constructors. */
...@@ -354,53 +405,118 @@ void FN () \ ...@@ -354,53 +405,118 @@ void FN () \
/* A C statement or statements to switch to the appropriate /* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations. */ the initial value of DECL requires link-time relocations.
Set SECNUM to:
0 .text
1 .rodata
2 .data
3 .sdata
4 .bss
5 .sbss
*/
#define DO_SELECT_SECTION(SECNUM, DECL, RELOC) \
do \
{ \
SECNUM = 1; \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
SECNUM = 0; \
else if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (flag_writable_strings) \
SECNUM = 2; \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if (DECL_INITIAL (DECL) == NULL \
|| DECL_INITIAL (DECL) == error_mark_node) \
SECNUM = 4; \
else if ((flag_pic && RELOC) \
|| ! TREE_READONLY (DECL) \
|| TREE_SIDE_EFFECTS (DECL) \
|| ! TREE_CONSTANT (DECL_INITIAL (DECL))) \
SECNUM = 2; \
} \
else if (TREE_CODE (DECL) == CONSTRUCTOR) \
{ \
if ((flag_pic && RELOC) \
|| ! TREE_READONLY (DECL) \
|| TREE_SIDE_EFFECTS (DECL) \
|| ! TREE_CONSTANT (DECL)) \
SECNUM = 2; \
} \
\
/* Select small data sections based on size. */ \
if (SECNUM >= 2) \
{ \
int size = int_size_in_bytes (TREE_TYPE (DECL)); \
if (size >= 0 && size <= g_switch_value) \
SECNUM += 1; \
} \
} \
while (0)
#undef SELECT_SECTION #undef SELECT_SECTION
#define SELECT_SECTION(DECL, RELOC) \ #define SELECT_SECTION(DECL, RELOC) \
{ \ do \
if (TREE_CODE (DECL) == STRING_CST) \ { \
{ \ typedef void (*sec_fn) PARAMS ((void)); \
if (! flag_writable_strings) \ static sec_fn const sec_functions[6] = \
const_section (); \ { \
else \ text_section, \
data_section (); \ const_section, \
} \ data_section, \
else if (TREE_CODE (DECL) == VAR_DECL) \ sdata_section, \
{ \ bss_section, \
if ((flag_pic && RELOC) \ sbss_section \
|| ! TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ }; \
|| ! DECL_INITIAL (DECL) \ \
|| (DECL_INITIAL (DECL) != error_mark_node \ int sec; \
&& !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ \
{ \ DO_SELECT_SECTION (sec, DECL, RELOC); \
int size = int_size_in_bytes (TREE_TYPE (DECL)); \ \
if (size >= 0 && size <= g_switch_value) \ (*sec_functions[sec]) (); \
sdata_section (); \ } \
else \ while (0)
data_section (); \
} \ #define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL))
else \
const_section (); \ #undef UNIQUE_SECTION
} \ #define UNIQUE_SECTION(DECL, RELOC) \
else if (TREE_CODE (DECL) == CONSTRUCTOR) \ do \
{ \ { \
if ((flag_pic && RELOC) \ static const char * const prefixes[6][2] = \
|| ! TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ { \
|| ! TREE_CONSTANT (DECL)) \ { ".text.", ".gnu.linkonce.t." }, \
{ \ { ".rodata.", ".gnu.linkonce.r." }, \
int size = int_size_in_bytes (TREE_TYPE (DECL)); \ { ".data.", ".gnu.linkonce.d." }, \
if (size >= 0 && size <= g_switch_value) \ { ".sdata.", ".gnu.linkonce.s." }, \
sdata_section (); \ { ".bss.", ".gnu.linkonce.b." }, \
else \ { ".sbss.", ".gnu.linkonce.sb." } \
data_section (); \ }; \
} \ \
else \ int nlen, plen, sec; \
const_section (); \ const char *name, *prefix; \
char *string; \
\
DO_SELECT_SECTION (sec, DECL, RELOC); \
\
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
STRIP_NAME_ENCODING (name, name); \
nlen = strlen (name); \
\
prefix = prefixes[sec][DECL_ONE_ONLY(DECL)]; \
plen = strlen (prefix); \
\
string = alloca (nlen + plen + 1); \
\
memcpy (string, prefix, plen); \
memcpy (string + plen, name, nlen + 1); \
\
DECL_SECTION_NAME (DECL) = build_string (nlen + plen, string); \
} \ } \
else \ while (0)
const_section (); \
}
/* A C statement or statements to switch to the appropriate /* A C statement or statements to switch to the appropriate
section for output of RTX in mode MODE. RTX is some kind section for output of RTX in mode MODE. RTX is some kind
......
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