[commit: ghc] master: Implement .ctor support for PEi386. (30bf3ed)
git at git.haskell.org
git at git.haskell.org
Sat Sep 14 03:12:05 CEST 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/30bf3ed5aae5603116e45a46923b2cfd67757461/ghc
>---------------------------------------------------------------
commit 30bf3ed5aae5603116e45a46923b2cfd67757461
Author: Edward Z. Yang <ezyang at mit.edu>
Date: Thu Sep 5 23:37:37 2013 -0700
Implement .ctor support for PEi386.
Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
>---------------------------------------------------------------
30bf3ed5aae5603116e45a46923b2cfd67757461
rts/Linker.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/rts/Linker.c b/rts/Linker.c
index 367a9c5..a1ab5b3 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -208,6 +208,7 @@ static int ocAllocateSymbolExtras_ELF ( ObjectCode* oc );
static int ocVerifyImage_PEi386 ( ObjectCode* oc );
static int ocGetNames_PEi386 ( ObjectCode* oc );
static int ocResolve_PEi386 ( ObjectCode* oc );
+static int ocRunInit_PEi386 ( ObjectCode* oc );
static void *lookupSymbolInDLLs ( unsigned char *lbl );
static void zapTrailingAtSign ( unsigned char *sym );
#elif defined(OBJFORMAT_MACHO)
@@ -2775,13 +2776,15 @@ resolveObjs( void )
# endif
if (!r) { return r; }
-#if defined(OBJFORMAT_ELF)
// run init/init_array
+#if defined(OBJFORMAT_ELF)
r = ocRunInit_ELF ( oc );
- if (!r) { return r; }
+#elif defined(OBJFORMAT_PEi386)
+ r = ocRunInit_PEi386 ( oc );
#else
IF_DEBUG(linker, debugBelch("resolveObjs: don't know how to run initializers!\n"));
#endif
+ if (!r) { return r; }
oc->status = OBJECT_RESOLVED;
}
@@ -3834,6 +3837,8 @@ ocGetNames_PEi386 ( ObjectCode* oc )
if (0==strcmp(".data",(char*)secname) ||
0==strcmp(".bss",(char*)secname))
kind = SECTIONKIND_RWDATA;
+ if (0==strcmp(".ctors", (char*)secname))
+ kind = SECTIONKIND_INIT_ARRAY;
ASSERT(sectab_i->SizeOfRawData == 0 || sectab_i->VirtualSize == 0);
sz = sectab_i->SizeOfRawData;
@@ -3850,8 +3855,6 @@ ocGetNames_PEi386 ( ObjectCode* oc )
/* Ignore sections called which contain exception information. */
&& 0 != strcmp(".pdata", (char*)secname)
&& 0 != strcmp(".xdata", (char*)secname)
- /* ignore constructor section for now */
- && 0 != strcmp(".ctors", (char*)secname)
/* ignore section generated from .ident */
&& 0!= strncmp(".debug", (char*)secname, 6)
/* ignore unknown section that appeared in gcc 3.4.5(?) */
@@ -4014,7 +4017,6 @@ ocResolve_PEi386 ( ObjectCode* oc )
|| 0 == strcmp(".stabstr", (char*)secname)
|| 0 == strcmp(".pdata", (char*)secname)
|| 0 == strcmp(".xdata", (char*)secname)
- || 0 == strcmp(".ctors", (char*)secname)
|| 0 == strncmp(".debug", (char*)secname, 6)
|| 0 == strcmp(".rdata$zzz", (char*)secname)) {
stgFree(secname);
@@ -4181,6 +4183,49 @@ ocResolve_PEi386 ( ObjectCode* oc )
return 1;
}
+static int
+ocRunInit_PEi386 ( ObjectCode *oc )
+{
+ COFF_header* hdr;
+ COFF_section* sectab;
+ UChar* strtab;
+ int i;
+
+ hdr = (COFF_header*)(oc->image);
+ sectab = (COFF_section*) (
+ ((UChar*)(oc->image))
+ + sizeof_COFF_header + hdr->SizeOfOptionalHeader
+ );
+ strtab = ((UChar*)(oc->image))
+ + hdr->PointerToSymbolTable
+ + hdr->NumberOfSymbols * sizeof_COFF_symbol;
+
+ int argc, envc;
+ char **argv, **envv;
+
+ getProgArgv(&argc, &argv);
+ getProgEnvv(&envc, &envv);
+
+ for (i = 0; i < hdr->NumberOfSections; i++) {
+ COFF_section* sectab_i
+ = (COFF_section*)
+ myindex ( sizeof_COFF_section, sectab, i );
+ char *secname = cstring_from_section_name(sectab_i->Name, strtab);
+ if (0 == strcmp(".ctors", (char*)secname)) {
+ UChar *init_startC = (UChar*)(oc->image) + sectab_i->PointerToRawData;
+ init_t *init = (init_t*)init_startC;
+ init_t *init_end = (init_t*)(init_startC + sectab_i->SizeOfRawData);
+ // I heard that .ctors might need to be run backwards, but
+ // if that is true then the MinGW toolchain ignores that.
+ for (; init < init_end; init++) {
+ (*init)(argc, argv, envv);
+ }
+ }
+ }
+ freeProgEnvv(envc, envv);
+ return 1;
+}
+
#endif /* defined(OBJFORMAT_PEi386) */
More information about the ghc-commits
mailing list