This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: -fdata-sections implies no .sdata
Geoff Keating <geoffk@geoffk.org> writes:
|> Andreas Schwab <schwab@suse.de> writes:
|>
|> > When -fdata-sections is in effect then small data never goes to .sdata, so
|> > we cannot use @gprel. Since ia64_encode_section_info is called before
|> > resolve_unique_sections it must check flag_data_sections itself.
|>
|> That's a bug somewhere else. Small data should go into .sdata.<varname>,
|> which ends up in .sdata due to linker scripts.
Thanks, I got it now. This is modeled after similar code in
config/alpha/elf.h.
Andreas.
2002-05-13 Andreas Schwab <schwab@suse.de>
* config/ia64/sysv4.h (DO_SELECT_SECTION): Factored out of
SELECT_SECTION.
(UNIQUE_SECTION): Define to get small data correctly.
--- gcc/config/ia64/sysv4.h.~1.20.8.1.~ 2002-04-12 15:49:46.000000000 +0200
+++ gcc/config/ia64/sysv4.h 2002-05-13 21:00:20.000000000 +0200
@@ -140,45 +140,134 @@ do { \
emit_safe_across_calls (STREAM); \
} while (0)
+/* A C statement or statements to switch to the appropriate
+ section for output of DECL. DECL is either a `VAR_DECL' node
+ or a constant of some sort. RELOC indicates whether forming
+ 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 \
+ { \
+ if (TREE_CODE (DECL) == STRING_CST) \
+ { \
+ if (! flag_writable_strings) \
+ SECNUM = 0x101; \
+ else \
+ SECNUM = 2; \
+ } \
+ else if (TREE_CODE (DECL) == VAR_DECL) \
+ { \
+ if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
+ == SDATA_NAME_FLAG_CHAR) \
+ SECNUM = 3; \
+ /* ??? We need the extra RELOC check, because the default \
+ is to only check RELOC if flag_pic is set, and we don't \
+ set flag_pic (yet?). */ \
+ else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC)) \
+ SECNUM = 2; \
+ else if (flag_merge_constants < 2) \
+ /* C and C++ don't allow different variables to share \
+ the same location. -fmerge-all-constants allows \
+ even that (at the expense of not conforming). */ \
+ SECNUM = 1; \
+ else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST) \
+ SECNUM = 0x201; \
+ else \
+ SECNUM = 0x301; \
+ } \
+ /* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
+ in which case we can't put it in a shared library rodata. */ \
+ else if (flag_pic && (RELOC)) \
+ SECNUM = 3; \
+ else \
+ SECNUM = 2; \
+ } \
+ while (0)
+
/* We override svr4.h so that we can support the sdata section. */
#undef SELECT_SECTION
#define SELECT_SECTION(DECL,RELOC,ALIGN) \
-{ \
- if (TREE_CODE (DECL) == STRING_CST) \
+ do \
{ \
- if (! flag_writable_strings) \
- mergeable_string_section ((DECL), (ALIGN), 0); \
- else \
- data_section (); \
+ typedef void (*sec_fn) PARAMS ((void)); \
+ static sec_fn const sec_functions[6] = \
+ { \
+ text_section, \
+ const_section, \
+ data_section, \
+ sdata_section, \
+ bss_section, \
+ sbss_section \
+ }; \
+ \
+ int sec; \
+ \
+ DO_SELECT_SECTION (sec, DECL, RELOC); \
+ \
+ switch (sec) \
+ { \
+ case 0x101: \
+ mergeable_string_section (DECL, ALIGN, 0); \
+ break; \
+ case 0x201: \
+ mergeable_string_section (DECL_INITIAL (DECL), \
+ ALIGN, 0); \
+ break; \
+ case 0x301: \
+ mergeable_constant_section (DECL_MODE (DECL), \
+ ALIGN, 0); \
+ break; \
+ default: \
+ (*sec_functions[sec]) (); \
+ break; \
+ } \
} \
- else if (TREE_CODE (DECL) == VAR_DECL) \
+ while (0)
+
+#undef UNIQUE_SECTION
+#define UNIQUE_SECTION(DECL, RELOC) \
+ do \
{ \
- if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
- == SDATA_NAME_FLAG_CHAR) \
- sdata_section (); \
- /* ??? We need the extra RELOC check, because the default is to \
- only check RELOC if flag_pic is set, and we don't set flag_pic \
- (yet?). */ \
- else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC)) \
- data_section (); \
- else if (flag_merge_constants < 2) \
- /* C and C++ don't allow different variables to share \
- the same location. -fmerge-all-constants allows \
- even that (at the expense of not conforming). */ \
- const_section (); \
- else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST) \
- mergeable_string_section (DECL_INITIAL (DECL), (ALIGN), 0); \
- else \
- mergeable_constant_section (DECL_MODE (DECL), (ALIGN), 0); \
+ static const char * const prefixes[6][2] = \
+ { \
+ { ".text.", ".gnu.linkonce.t." }, \
+ { ".rodata.", ".gnu.linkonce.r." }, \
+ { ".data.", ".gnu.linkonce.d." }, \
+ { ".sdata.", ".gnu.linkonce.s." }, \
+ { ".bss.", ".gnu.linkonce.b." }, \
+ { ".sbss.", ".gnu.linkonce.sb." } \
+ }; \
+ \
+ int nlen, plen, sec; \
+ 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 & 0xff][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); \
} \
- /* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
- in which case we can't put it in a shared library rodata. */ \
- else if (flag_pic && (RELOC)) \
- data_section (); \
- else \
- const_section (); \
-}
+ while (0)
/* Similarly for constant pool data. */
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE GmbH, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."