From 7a5252e170f6e2c6c1d483fe7f2ba56e98b1f8a2 Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 18 Jul 2015 16:39:36 -0400 Subject: 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. --- gcc/config/i386/midipix.c | 174 +++++++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 47 deletions(-) (limited to 'gcc/config/i386/midipix.c') 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# \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)); +} -- cgit v1.2.3