Skip to content

Commit 4955e2d

Browse files
ZacWalkgithub-actions
authored andcommitted
Fix legitimize for aarch64-pe
1 parent 71978c8 commit 4955e2d

File tree

2 files changed

+218
-18
lines changed

2 files changed

+218
-18
lines changed

gcc/config/aarch64/cygming.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ along with GCC; see the file COPYING3. If not see
5454

5555

5656
/* Support hooks for SEH. */
57-
#undef TARGET_ASM_UNWIND_EMIT
58-
#define TARGET_ASM_UNWIND_EMIT i386_pe_seh_unwind_emit
57+
// #undef TARGET_ASM_UNWIND_EMIT
58+
// #define TARGET_ASM_UNWIND_EMIT i386_pe_seh_unwind_emit
5959
#undef TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
6060
#define TARGET_ASM_UNWIND_EMIT_BEFORE_INSN false
6161
// #undef TARGET_ASM_FUNCTION_PROLOGUE
@@ -113,6 +113,7 @@ extern void i386_pe_end_function (FILE *f, const char *, tree);
113113
extern void i386_pe_end_cold_function (FILE *f, const char *, tree);
114114
// extern void aarch64_pe_end_epilogue (FILE *file);
115115
// extern void aarch64_pe_begin_epilogue (FILE *file);
116+
extern void i386_pe_record_external_function (tree, const char *);
116117

117118
#define TARGET_VALID_DLLIMPORT_ATTRIBUTE_P mingw_pe_valid_dllimport_attribute_p
118119

@@ -313,4 +314,17 @@ extern void i386_pe_end_cold_function (FILE *f, const char *, tree);
313314
unwind info for this later allocation. */
314315
#define SEH_MAX_FRAME_SIZE ((2U << 30) - 256)
315316

317+
318+
/* Add an external function to the list of functions to be declared at
319+
the end of the file. */
320+
#undef ASM_OUTPUT_EXTERNAL
321+
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
322+
do \
323+
{ \
324+
if (TREE_CODE (DECL) == FUNCTION_DECL) \
325+
i386_pe_record_external_function ((DECL), (NAME)); \
326+
aarch64_asm_output_external (FILE, DECL, NAME); \
327+
} \
328+
while (0)
329+
316330
#endif

gcc/config/aarch64/winnt.cc

Lines changed: 202 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,53 @@ aarch64_pe_valid_dllimport_attribute_p (const_tree decl)
109109
return true;
110110
}
111111

112+
/* Mark a function appropriately. This should only be called for
113+
functions for which we are not emitting COFF debugging information.
114+
FILE is the assembler output file, NAME is the name of the
115+
function, and PUB is nonzero if the function is globally
116+
visible. */
117+
118+
void
119+
aarch64_pe_declare_function_type (FILE *file, const char *name, int pub)
120+
{
121+
fprintf (file, "\t.def\t");
122+
assemble_name (file, name);
123+
fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
124+
pub ? (int) C_EXT : (int) C_STAT,
125+
(int) DT_FCN << N_BTSHFT);
126+
}
127+
128+
129+
130+
/* Keep a list of external functions. */
131+
132+
struct GTY(()) extern_list
133+
{
134+
struct extern_list *next;
135+
tree decl;
136+
const char *name;
137+
};
138+
139+
static GTY(()) struct extern_list *extern_head;
140+
141+
/* Assemble an external function reference. We need to keep a list of
142+
these, so that we can output the function types at the end of the
143+
assembly. We can't output the types now, because we might see a
144+
definition of the function later on and emit debugging information
145+
for it then. */
146+
147+
void
148+
aarch64_pe_record_external_function (tree decl, const char *name)
149+
{
150+
struct extern_list *p;
151+
152+
p = ggc_alloc<extern_list> ();
153+
p->next = extern_head;
154+
p->decl = decl;
155+
p->name = name;
156+
extern_head = p;
157+
}
158+
112159
/* Keep a list of exported symbols. */
113160

114161
struct GTY(()) export_list
@@ -118,7 +165,16 @@ struct GTY(()) export_list
118165
int is_data; /* used to type tag exported symbols. */
119166
};
120167

168+
/* Keep a list of stub symbols. */
169+
170+
struct GTY(()) stub_list
171+
{
172+
struct stub_list *next;
173+
const char *name;
174+
};
175+
121176
static GTY(()) struct export_list *export_head;
177+
static GTY(()) struct stub_list *stub_head;
122178

123179
/* Assemble an export symbol entry. We need to keep a list of
124180
these, so that we can output the export list at the end of the
@@ -150,22 +206,6 @@ aarch64_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_dat
150206
export_head = p;
151207
}
152208

153-
/* Mark a function appropriately. This should only be called for
154-
functions for which we are not emitting COFF debugging information.
155-
FILE is the assembler output file, NAME is the name of the
156-
function, and PUB is nonzero if the function is globally
157-
visible. */
158-
159-
void
160-
aarch64_pe_declare_function_type (FILE *file, const char *name, int pub)
161-
{
162-
fprintf (file, "\t.def\t");
163-
assemble_name (file, name);
164-
fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
165-
pub ? (int) C_EXT : (int) C_STAT,
166-
(int) DT_FCN << N_BTSHFT);
167-
}
168-
169209
/* Handle a "selectany" attribute;
170210
arguments as in struct attribute_spec.handler. */
171211
tree
@@ -947,4 +987,150 @@ aarch64_pe_override_options (void)
947987
global_options.x_flag_shrink_wrap = false;
948988
}
949989

990+
991+
void
992+
aarch64_pe_record_stub (const char *name)
993+
{
994+
struct stub_list *p;
995+
996+
if (!name || *name == 0)
997+
return;
998+
999+
p = stub_head;
1000+
while (p != NULL)
1001+
{
1002+
if (p->name[0] == *name
1003+
&& !strcmp (p->name, name))
1004+
return;
1005+
p = p->next;
1006+
}
1007+
1008+
p = ggc_alloc<stub_list> ();
1009+
p->next = stub_head;
1010+
p->name = name;
1011+
stub_head = p;
1012+
}
1013+
1014+
1015+
#ifdef CXX_WRAP_SPEC_LIST
1016+
1017+
/* Search for a function named TARGET in the list of library wrappers
1018+
we are using, returning a pointer to it if found or NULL if not.
1019+
This function might be called on quite a few symbols, and we only
1020+
have the list of names of wrapped functions available to us as a
1021+
spec string, so first time round we lazily initialise a hash table
1022+
to make things quicker. */
1023+
1024+
static const char *
1025+
aarch64_find_on_wrapper_list (const char *target)
1026+
{
1027+
static char first_time = 1;
1028+
static hash_table<nofree_string_hash> *wrappers;
1029+
1030+
if (first_time)
1031+
{
1032+
/* Beware that this is not a complicated parser, it assumes
1033+
that any sequence of non-whitespace beginning with an
1034+
underscore is one of the wrapped symbols. For now that's
1035+
adequate to distinguish symbols from spec substitutions
1036+
and command-line options. */
1037+
static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
1038+
char *bufptr;
1039+
/* Breaks up the char array into separated strings
1040+
strings and enter them into the hash table. */
1041+
wrappers = new hash_table<nofree_string_hash> (8);
1042+
for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
1043+
{
1044+
char *found = NULL;
1045+
if (ISSPACE (*bufptr))
1046+
continue;
1047+
if (*bufptr == '_')
1048+
found = bufptr;
1049+
while (*bufptr && !ISSPACE (*bufptr))
1050+
++bufptr;
1051+
if (*bufptr)
1052+
*bufptr = 0;
1053+
if (found)
1054+
*wrappers->find_slot (found, INSERT) = found;
1055+
}
1056+
first_time = 0;
1057+
}
1058+
1059+
return wrappers->find (target);
1060+
}
1061+
1062+
#endif /* CXX_WRAP_SPEC_LIST */
1063+
1064+
/* This is called at the end of assembly. For each external function
1065+
which has not been defined, we output a declaration now. We also
1066+
output the .drectve section. */
1067+
1068+
void
1069+
aarch64_pe_file_end (void)
1070+
{
1071+
struct extern_list *p;
1072+
1073+
for (p = extern_head; p != NULL; p = p->next)
1074+
{
1075+
tree decl;
1076+
1077+
decl = p->decl;
1078+
1079+
/* Positively ensure only one declaration for any given symbol. */
1080+
if (! TREE_ASM_WRITTEN (decl)
1081+
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
1082+
{
1083+
#ifdef CXX_WRAP_SPEC_LIST
1084+
/* To ensure the DLL that provides the corresponding real
1085+
functions is still loaded at runtime, we must reference
1086+
the real function so that an (unused) import is created. */
1087+
const char *realsym = aarch64_find_on_wrapper_list (p->name);
1088+
if (realsym)
1089+
aarch64_pe_declare_function_type (asm_out_file,
1090+
concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
1091+
#endif /* CXX_WRAP_SPEC_LIST */
1092+
TREE_ASM_WRITTEN (decl) = 1;
1093+
aarch64_pe_declare_function_type (asm_out_file, p->name,
1094+
TREE_PUBLIC (decl));
1095+
}
1096+
}
1097+
1098+
if (export_head)
1099+
{
1100+
struct export_list *q;
1101+
drectve_section ();
1102+
for (q = export_head; q != NULL; q = q->next)
1103+
{
1104+
fprintf (asm_out_file, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
1105+
default_strip_name_encoding (q->name),
1106+
(q->is_data ? ",data" : ""));
1107+
}
1108+
}
1109+
1110+
if (stub_head)
1111+
{
1112+
struct stub_list *q;
1113+
1114+
for (q = stub_head; q != NULL; q = q->next)
1115+
{
1116+
const char *name = q->name;
1117+
const char *oname;
1118+
1119+
if (name[0] == '*')
1120+
++name;
1121+
oname = name;
1122+
if (name[0] == '.')
1123+
++name;
1124+
if (!startswith (name, "refptr."))
1125+
continue;
1126+
name += 7;
1127+
fprintf (asm_out_file, "\t.section\t.rdata$%s, \"dr\"\n"
1128+
"\t.globl\t%s\n"
1129+
"\t.align 3\n"
1130+
"\t.linkonce\tdiscard\n", oname, oname);
1131+
fprintf (asm_out_file, "%s:\n\t.quad\t%s\n", oname, name);
1132+
}
1133+
}
1134+
}
1135+
9501136
#include "gt-winnt.h"

0 commit comments

Comments
 (0)