summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/midipix.c174
-rw-r--r--gcc/config/i386/midipix.h33
-rw-r--r--gcc/config/i386/winnt.c2
-rw-r--r--gcc/defaults.h5
-rw-r--r--gcc/varasm.c17
5 files changed, 176 insertions, 55 deletions
diff --git a/gcc/config/i386/midipix.c b/gcc/config/i386/midipix.c
index bb05cc105..f9b6d4190 100644
--- a/gcc/config/i386/midipix.c
+++ b/gcc/config/i386/midipix.c
@@ -31,12 +31,17 @@
#include "target.h"
#include "i386-protos.h"
#include "function.h"
+#include "cgraph.h"
/* common specs */
const int TARGET_NOP_FUN_DLLIMPORT = 0;
const int use_pe_aligned_common = 1;
const int flag_writable_rel_rdata = 0;
+/* pointer annotation */
+static const char winnt_ptrsize_long[] = ".long";
+static const char winnt_ptrsize_quad[] = ".quad";
+
/* target SEH providers */
#define TARGET_SEH_WINNT (TARGET_SEH && TARGET_NT64)
#define TARGET_SEH_MIDIPIX (TARGET_SEH && TARGET_NT32)
@@ -124,6 +129,83 @@ void midipix_asm_generate_internal_label (
}
+static void midipix_pe_create_got_entry(FILE * stream, const char * name, tree decl)
+{
+ const char * ptrsize = TARGET_64BIT
+ ? winnt_ptrsize_quad
+ : winnt_ptrsize_long;
+
+ fputs("\n",stream);
+ fputs(GAS_SECTION,stream);
+
+ switch (decl->decl_with_vis.visibility) {
+ case VISIBILITY_HIDDEN:
+ fputs(HIDDEN_SECTION_NAME,stream);
+ break;
+
+ case VISIBILITY_INTERNAL:
+ fputs(INTERNAL_SECTION_NAME,stream);
+ break;
+
+ default:
+ fputs(GOT_SECTION_NAME,stream);
+ break;
+ }
+
+ fputs("$",stream);
+ assemble_name(stream,name);
+ fputs(GOT_SECTION_ATTR,stream);
+
+ if (decl->decl_with_vis.weak_flag)
+ fputs("\n\t.global __imp_",stream);
+ else
+ fputs("\n\t.global __imp_",stream);
+
+ assemble_name(stream,name);
+ fputs("\n__imp_",stream);
+ assemble_name(stream,name);
+ fputs(":\n\t",stream);
+ fputs(ptrsize,stream);
+ fputs("\t",stream);
+ assemble_name(stream,name);
+ fputs("\n",stream);
+ fputs("\t.linkonce discard\n\n",stream);
+}
+
+
+void midipix_asm_output_got_entry(
+ FILE * asmout,
+ const char * name,
+ tree decl,
+ section * sect)
+{
+ if (!decl->base.public_flag)
+ return;
+
+ /* .got entry */
+ midipix_pe_create_got_entry(asmout,name,decl);
+
+ /* re-establish generic named section */
+ if (in_section && in_section->common.flags & (SECTION_STYLE_MASK == SECTION_NAMED))
+ targetm.asm_out.named_section(
+ in_section->named.name,
+ in_section->named.common.flags,
+ in_section->named.decl);
+
+ /* re-establish .bss section */
+ else if (sect == bss_noswitch_section)
+ fputs("\t.bss\n",asmout);
+
+ /* re-establish .data section */
+ else if (sect == data_section)
+ fputs("\t.data\n",asmout);
+
+ /* re-establish .text section (default) */
+ else
+ fputs("\t.text\n",asmout);
+}
+
+
void midipix_asm_declare_object_name(FILE * gas_exhaled, const char * name, tree decl)
{
extern void assemble_name (FILE *, const char *);
@@ -159,7 +241,7 @@ void midipix_asm_output_external(
tree decl,
const char * name)
{
- if (TREE_CODE(decl) == FUNCTION_DECL)
+ if (decl->base.code == FUNCTION_DECL)
i386_pe_record_external_function(
decl,name);
}
@@ -181,22 +263,22 @@ void midipix_asm_output_def_from_decls(
{
const char * sym;
- sym = IDENTIFIER_POINTER(
- DECL_ASSEMBLER_NAME(decl));
+ sym = (const char *)decl->decl_with_vis.assembler_name->identifier.id.str;
i386_pe_maybe_record_exported_symbol(
decl,sym,false);
- if (TREE_CODE(decl) == FUNCTION_DECL)
+ if (decl->base.code == FUNCTION_DECL)
i386_pe_declare_function_type(
- asmout,
- sym,
- TREE_PUBLIC(decl));
+ asmout,sym,decl->base.public_flag);
ASM_OUTPUT_DEF(
asmout,
sym,
IDENTIFIER_POINTER(target));
+
+ if (!decl->decl_with_vis.weak_flag)
+ midipix_asm_output_got_entry(asmout,sym,decl,0);
}
@@ -205,14 +287,10 @@ void midipix_i386_pe_assemble_visibility (
tree decl __attribute__((unused)),
int visible __attribute__((unused)))
{
- /* todo: add the symbol to a special section (.hidden),
- and teach the linker to not export symbols that are
- listed under that section. */
+ /* cf. midipix_pe_create_got_entry */
}
-
-
/* seh hook selectors */
void midipix_seh_hook__pe_seh_init(FILE * f)
{
@@ -334,21 +412,16 @@ section * midipix_i386_pe_function_section (
bool exit);
const char * fname;
- char * secname;
- size_t size;
-
bool weak;
section * asm_section;
+ char * secname;
+ size_t size;
- weak = (decl && DECL_WEAK (decl));
-
- if (weak && DECL_ATTRIBUTES(decl) && lookup_attribute (
- "weak_import",
- DECL_ATTRIBUTES(decl)))
- weak = 0;
-
- fname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ /* .got entry */
+ fname = (const char *)decl->decl_with_vis.assembler_name->identifier.id.str;
+ weak = (decl->decl_with_vis.dllimport_flag && decl->decl_with_vis.weak_flag);
+ /* section entry */
#ifdef MIDIPIX_TARGET_DEBUG
fputs ("\t# <", asm_out_file);
assemble_name (asm_out_file, fname);
@@ -389,6 +462,18 @@ section * midipix_i386_pe_function_section (
}
+void midipix_i386_pe_asm_output_aligned_decl_common(
+ FILE * stream,
+ tree decl,
+ const char * name,
+ HOST_WIDE_INT size,
+ HOST_WIDE_INT align)
+{
+ i386_pe_asm_output_aligned_decl_common(
+ stream,decl,name,size,align);
+}
+
+
void midipix_i386_pe_start_function (FILE * gas_exhaled, const char *name, tree decl)
{
#ifdef MIDIPIX_TARGET_DEBUG
@@ -403,16 +488,15 @@ void midipix_i386_pe_start_function (FILE * gas_exhaled, const char *name, tree
void midipix_i386_pe_end_function (FILE * gas_exhaled, const char * name, tree decl)
{
- if ((!TARGET_SEH) || (cfun->is_thunk))
+ if (cfun->is_thunk)
return;
- fputs ("\t.seh_endproc\n", gas_exhaled);
+ if (TARGET_SEH)
+ fputs ("\t.seh_endproc\n", gas_exhaled);
- #ifdef MIDIPIX_TARGET_DEBUG
- fputs ("\t# </", gas_exhaled);
- assemble_name (gas_exhaled, name);
- fputs (">\n\n\n", gas_exhaled);
- #endif
+ /* avoid duplicate GOT entries */
+ if (decl && !decl->decl_with_vis.weak_flag)
+ midipix_asm_output_got_entry(gas_exhaled,name,decl,0);
}
@@ -422,24 +506,11 @@ void midipix_i386_pe_asm_weaken_decl(
const char * name,
const char * alias __attribute__((unused)))
{
- if ((decl) && DECL_EXTERNAL(decl)) {
- #ifdef MIDIPIX_TARGET_DEBUG
- fputs ("\t# (external weak symbol label)\n", gas_exhaled);
- #endif
-
- fputs ("\t.weak\t", gas_exhaled);
- assemble_name (gas_exhaled, name);
- fputs ("\n", gas_exhaled);
- } else {
- #ifdef MIDIPIX_TARGET_DEBUG
- fputs("\t# (normal weak symbol label)\n", gas_exhaled);
- #endif
+ midipix_asm_output_got_entry(gas_exhaled,name,decl,0);
- /* write a patch for ld so that we can use .globl instead */
- fputs("\t.weak\t", gas_exhaled);
- assemble_name (gas_exhaled, name);
- fputs ("\n", gas_exhaled);
- }
+ fputs ("\t.weak\t", gas_exhaled);
+ assemble_name (gas_exhaled, name);
+ fputs ("\n", gas_exhaled);
}
@@ -451,3 +522,12 @@ void midipix_i386_pe_asm_weaken_label(FILE * gas_exhaled, const char * name)
name,
(const char *)0);
}
+
+int midipix_symbol_ref_dllimport_p(rtx symbol)
+{
+ tree decl = SYMBOL_REF_DECL(symbol);
+
+ return decl && decl->base.public_flag &&
+ (!decl->decl_with_vis.visibility_specified
+ || (decl->decl_with_vis.visibility == VISIBILITY_DEFAULT));
+}
diff --git a/gcc/config/i386/midipix.h b/gcc/config/i386/midipix.h
index 3502ba618..2354cf2ce 100644
--- a/gcc/config/i386/midipix.h
+++ b/gcc/config/i386/midipix.h
@@ -68,6 +68,8 @@
? MS_ABI \
: SYSV_ABI
+#undef SYMBOL_REF_DLLIMPORT_P
+#define SYMBOL_REF_DLLIMPORT_P midipix_symbol_ref_dllimport_p
#undef MULTIPLE_SYMBOL_SPACES
#define MULTIPLE_SYMBOL_SPACES (1)
@@ -161,6 +163,21 @@
#undef RODATA_SECTION_NAME
#define RODATA_SECTION_NAME ".rdata,\"r\""
+#undef GOT_SECTION_NAME
+#define GOT_SECTION_NAME ".got"
+
+#undef PROTECTED_SECTION_NAME
+#define PROTECTED_SECTION_NAME GOT_SECTION_NAME
+
+#undef HIDDEN_SECTION_NAME
+#define HIDDEN_SECTION_NAME ".hidden"
+
+#undef INTERNAL_SECTION_NAME
+#define INTERNAL_SECTION_NAME ".intern"
+
+#undef GOT_SECTION_ATTR
+#define GOT_SECTION_ATTR ",\"r\""
+
#undef GAS_PE_ASM_SET_OP
#define GAS_PE_ASM_SET_OP "\t.set\t"
@@ -205,6 +222,9 @@
#undef ASM_OUTPUT_DWARF_OFFSET
#define ASM_OUTPUT_DWARF_OFFSET midipix_asm_output_dwarf_offset
+#undef ASM_OUTPUT_GOT_ENTRY
+#define ASM_OUTPUT_GOT_ENTRY midipix_asm_output_got_entry
+
/* assembler labels */
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX (TARGET_NT64 ? "" : "_")
@@ -260,7 +280,7 @@
#define ASM_OUTPUT_ALIGNED_BSS asm_output_aligned_bss
#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
-#define ASM_OUTPUT_ALIGNED_DECL_COMMON i386_pe_asm_output_aligned_decl_common
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON midipix_i386_pe_asm_output_aligned_decl_common
#undef TARGET_ASM_UNIQUE_SECTION
#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
@@ -348,6 +368,7 @@ extern void midipix_asm_output_external (FILE * asmout, tree decl, const char *
extern void midipix_asm_output_def_from_decls (FILE * asmout, tree decl, tree target);
extern void midipix_asm_output_external_libcall (FILE * asmout, rtx fn);
+extern void midipix_asm_output_got_entry (FILE * asmout, const char * name, tree decl, section * sect);
extern void midipix_asm_declare_object_name (FILE * asmout, const char * name, tree decl);
extern void midipix_i386_pe_start_function (FILE * asmout, const char * name, tree decl);
extern void midipix_i386_pe_end_function (FILE * asmout, const char * name, tree decl);
@@ -366,6 +387,14 @@ extern section * midipix_i386_pe_function_section(
bool startup,
bool exit);
+extern void midipix_i386_pe_asm_output_aligned_decl_common(
+ FILE * stream,
+ tree decl,
+ const char * name,
+ HOST_WIDE_INT size,
+ HOST_WIDE_INT align);
+
+extern int midipix_symbol_ref_dllimport_p(rtx symbol);
/* inlined functions */
static inline void midipix_extra_os_cpp_builtins(void)
@@ -379,6 +408,7 @@ static inline void midipix_extra_os_cpp_builtins(void)
static inline void midipix_target_os_cpp_builtins(void)
{
builtin_define_std("__PE__");
+ builtin_define_std("__PE_VISIBILITY__");
builtin_define_std("__midipix__");
midipix_extra_os_cpp_builtins();
}
@@ -389,3 +419,4 @@ static inline int midipix_i386_pe_reloc_rw_mask (void)
}
#endif
+
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 169832fd3..0712c6956 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -357,7 +357,7 @@ i386_pe_binds_local_p (const_tree exp)
&& DECL_WEAK (exp))
return false;
- return true;
+ return default_binds_local_p_1(exp,0);
}
/* Also strip the fastcall prefix and stdcall suffix. */
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 815ddd243..f72f5fcb1 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -304,6 +304,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define USER_LABEL_PREFIX ""
#endif
+/* optional generation of GOT entries */
+#ifndef ASM_OUTPUT_GOT_ENTRY
+#define ASM_OUTPUT_GOT_ENTRY(STREAM,NAME,DECL,SECTION)
+#endif
+
/* If the target supports weak symbols, define TARGET_ATTRIBUTE_WEAK to
provide a weak attribute. Else define it to nothing.
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 977ca40a0..34890b338 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2045,14 +2045,19 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
gcc_assert (!dont_output_data);
place_block_symbol (symbol);
}
- else if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
- assemble_noswitch_variable (decl, name, sect);
else
{
- switch_to_section (sect);
- if (DECL_ALIGN (decl) > BITS_PER_UNIT)
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
- assemble_variable_contents (decl, name, dont_output_data);
+ ASM_OUTPUT_GOT_ENTRY (asm_out_file,name,decl,sect);
+
+ if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
+ assemble_noswitch_variable (decl, name, sect);
+ else
+ {
+ switch_to_section (sect);
+ if (DECL_ALIGN (decl) > BITS_PER_UNIT)
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
+ assemble_variable_contents (decl, name, dont_output_data);
+ }
}
}