diff options
author | midipix <writeonce@midipix.org> | 2019-02-03 15:34:46 -0500 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2019-02-03 17:47:30 -0500 |
commit | 6ca8c253935b236d75f88f6b7ed7cb8a9b833171 (patch) | |
tree | 5508097a6f45c4c8a4eb92f18df96e3847814e59 | |
parent | 4455e16773b86eebb2700b010d99df8250d9f787 (diff) | |
download | cbb-gcc-4.6.4-6ca8c253935b236d75f88f6b7ed7cb8a9b833171.tar.bz2 cbb-gcc-4.6.4-6ca8c253935b236d75f88f6b7ed7cb8a9b833171.tar.xz |
midipix target: properly support dso data references.
-rw-r--r-- | gcc/config/i386/midipix.c | 91 | ||||
-rw-r--r-- | gcc/config/i386/midipix.h | 7 |
2 files changed, 98 insertions, 0 deletions
diff --git a/gcc/config/i386/midipix.c b/gcc/config/i386/midipix.c index 10ccaed2a..7603d2840 100644 --- a/gcc/config/i386/midipix.c +++ b/gcc/config/i386/midipix.c @@ -553,3 +553,94 @@ int midipix_symbol_ref_dllimport_p(rtx symbol) return 0; } + +bool midipix_asm_assemble_integer(rtx x, unsigned int size, int aligned_p) +{ + bool falt; + int visibility; + rtx xref; + rtx xoff; + tree decl; + section * sect; + const char * name; + const char * ptrsize; + + /* xref, xoff */ + if (GET_CODE(x) == CONST) { + xoff = XEXP(x, 0); /* --> PLUS */ + xref = XEXP(xoff,0); /* --> ref */ + xoff = XEXP(xoff,1); /* --> val */ + } else { + xref = x; + xoff = 0; + } + + /* extern symbol ref? */ + falt = (GET_CODE(xref) == SYMBOL_REF) + && ((decl = SYMBOL_REF_DECL(xref))) + && (DECL_P(decl)) + && (DECL_EXTERNAL(decl)) + && (TREE_PUBLIC(decl)); + + /* visibility */ + visibility = falt && decl + ? (decl->decl_with_vis.visibility == VISIBILITY_DEFAULT) + ? default_visibility + : decl->decl_with_vis.visibility + : 0; + + /* defer? */ + if (!falt || (visibility != VISIBILITY_DEFAULT)) + return default_assemble_integer(x,size,aligned_p); + + /* name, ptrsize, sect */ + name = XSTR(xref,0); + + ptrsize = TARGET_64BIT + ? winnt_ptrsize_quad + : winnt_ptrsize_long; + + sect = xoff + ? data_section + : get_variable_section(decl,false); + + /* in-section mark */ + fputs("1:\n",asm_out_file); + + /* in-section address reference */ + fputs("\t",asm_out_file); + fputs(ptrsize,asm_out_file); + fputs("\t" "0",asm_out_file); + + /* array offset */ + if (xoff && (INTVAL(xoff) < 0)) { + fprintf(asm_out_file,HOST_WIDE_INT_PRINT_DEC,INTVAL(xoff)); + } else if (xoff && INTVAL(xoff)) { + fputs("+",asm_out_file); + fprintf (asm_out_file,HOST_WIDE_INT_PRINT_DEC,INTVAL(xoff)); + } + + /* .gotrefs section */ + fputs("\n\n",asm_out_file); + fputs(GAS_SECTION,asm_out_file); + fputs(GOTREFS_SECTION_NAME,asm_out_file); + fputs("\n",asm_out_file); + + /* back reference */ + fputs("\t",asm_out_file); + fputs(ptrsize,asm_out_file); + fputs("\t" "1b" "\n",asm_out_file); + + /* sym reference */ + fputs("\t",asm_out_file); + fputs(ptrsize,asm_out_file); + fputs("\t" "__imp_",asm_out_file); + assemble_name(asm_out_file,name); + fputs("\n\n\n",asm_out_file); + + /* re-establish current section */ + midipix_asm_reestablish_section(asm_out_file,sect); + + /* all done */ + return true; +} diff --git a/gcc/config/i386/midipix.h b/gcc/config/i386/midipix.h index bbd0dcabb..297506430 100644 --- a/gcc/config/i386/midipix.h +++ b/gcc/config/i386/midipix.h @@ -187,6 +187,9 @@ #undef GOT_SECTION_NAME #define GOT_SECTION_NAME ".got" +#undef GOTREFS_SECTION_NAME +#define GOTREFS_SECTION_NAME ".gotrefs" + #undef PROTECTED_SECTION_NAME #define PROTECTED_SECTION_NAME GOT_SECTION_NAME @@ -294,6 +297,9 @@ #undef TARGET_ASM_ASSEMBLE_VISIBILITY #define TARGET_ASM_ASSEMBLE_VISIBILITY midipix_i386_pe_assemble_visibility +#undef TARGET_ASM_INTEGER +#define TARGET_ASM_INTEGER midipix_asm_assemble_integer + #undef TARGET_ASM_FILE_END #define TARGET_ASM_FILE_END i386_pe_file_end @@ -387,6 +393,7 @@ extern void midipix_asm_generate_internal_label (char * strbuf, const char * pre extern int midipix_target_use_local_thunk_alias(tree decl); extern void midipix_i386_pe_assemble_visibility (tree decl, int visible); +extern bool midipix_asm_assemble_integer (rtx, unsigned int size, int aligned_p); extern void midipix_asm_output_external (FILE * asmout, tree decl, const char * name); extern void midipix_asm_output_def_from_decls (FILE * asmout, tree decl, tree target); |