summaryrefslogtreecommitdiff
path: root/gcc/config/i386/midipix.c
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-07-18 16:39:36 -0400
committermidipix <writeonce@midipix.org>2015-07-18 16:39:36 -0400
commit7a5252e170f6e2c6c1d483fe7f2ba56e98b1f8a2 (patch)
tree6366afc8ae9639a8fe936bd05edc3602fd489bd9 /gcc/config/i386/midipix.c
parent49e286b1a48614877b448f7638d5d348a7dba9f5 (diff)
downloadcbb-gcc-4.6.4-7a5252e170f6e2c6c1d483fe7f2ba56e98b1f8a2.tar.bz2
cbb-gcc-4.6.4-7a5252e170f6e2c6c1d483fe7f2ba56e98b1f8a2.tar.xz
initial implementation of GOT entries and initial support of PE visibility
for the midipix targets. signed-off by Z. Gilboa; see copying.midipix (9cd0746c) for additional information.
Diffstat (limited to 'gcc/config/i386/midipix.c')
-rw-r--r--gcc/config/i386/midipix.c174
1 files changed, 127 insertions, 47 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));
+}