2 /* --------------------------------------------------------------------------
3 * GHC interface file processing for Hugs
5 * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
6 * All rights reserved. See NOTICE for details and conditions of use etc...
7 * Hugs version 1.4, December 1997
9 * $RCSfile: interface.c,v $
11 * $Date: 1999/10/29 11:41:04 $
12 * ------------------------------------------------------------------------*/
16 * o use vectored CONSTR_entry when appropriate
17 * o generate export list
19 * Needs GHC changes to generate member selectors,
20 * superclass selectors, etc
22 * o dictionary constructors ?
24 * o Get Hugs/GHC to agree on what interface files look like.
25 * o figure out how to replace the Hugs Prelude with the GHC Prelude
34 #include "Assembler.h" /* for wrapping GHC objects */
39 extern void print ( Cell, Int );
41 /* --------------------------------------------------------------------------
42 * The "addGHC*" functions act as "impedence matchers" between GHC
43 * interface files and Hugs. Their main job is to convert abstract
44 * syntax trees into Hugs' internal representations.
46 * The main trick here is how we deal with mutually recursive interface
49 * o As we read an import decl, we add it to a list of required imports
50 * (unless it's already loaded, of course).
52 * o Processing of declarations is split into two phases:
54 * 1) While reading the interface files, we construct all the Names,
55 * Tycons, etc declared in the interface file but we don't try to
56 * resolve references to any entities the declaration mentions.
58 * This is done by the "addGHC*" functions.
60 * 2) After reading all the interface files, we finish processing the
61 * declarations by resolving any references in the declarations
62 * and doing any other processing that may be required.
64 * This is done by the "finishGHC*" functions which use the
65 * "fixup*" functions to assist them.
67 * The interface between these two phases are the "ghc*Decls" which
68 * contain lists of decls that haven't been completed yet.
70 * ------------------------------------------------------------------------*/
72 /* --------------------------------------------------------------------------
74 * ------------------------------------------------------------------------*/
76 static List ghcVarDecls;
77 static List ghcConstrDecls;
78 static List ghcSynonymDecls;
79 static List ghcClassDecls;
80 static List ghcInstanceDecls;
82 /* --------------------------------------------------------------------------
83 * local function prototypes:
84 * ------------------------------------------------------------------------*/
86 static List local addGHCConstrs Args((Int,List,List));
87 static Name local addGHCSel Args((Int,Pair));
88 static Name local addGHCConstr Args((Int,Int,Triple));
91 static Void local finishGHCVar Args((Name));
92 static Void local finishGHCConstr Args((Name));
93 static Void local finishGHCSynonym Args((Tycon));
94 static Void local finishGHCClass Args((Class));
95 static Void local finishGHCInstance Args((Inst));
96 static Void local finishGHCImports Args((Triple));
97 static Void local finishGHCExports Args((Pair));
98 static Void local finishGHCModule Args((Module));
100 static Kinds local tvsToKind Args((List));
101 static Int local arityFromType Args((Type));
102 static Int local arityInclDictParams Args((Type));
105 static List local ifTyvarsIn Args((Type));
107 static Type local tvsToOffsets Args((Int,Type,List));
108 static Type local conidcellsToTycons Args((Int,Type));
110 static Void local resolveReferencesInObjectModule Args((Module,Bool));
111 static Bool local validateOImage Args((void*, Int, Bool));
112 static Void local readSyms Args((Module));
114 static void* local lookupObjName ( char* );
117 /* --------------------------------------------------------------------------
119 * ------------------------------------------------------------------------*/
121 List ifImports; /* [ConId] -- modules imported by current interface */
123 List ghcImports; /* [(Module, Text, [ConId|VarId])]
124 each (m1, m2, names) in this list
125 represents 'module m1 where ... import m2 ( names ) ...'
126 The list acts as a list of names to fix up in
130 List ghcExports; /* [(ConId, -- module name
131 [ ConId | VarId | pair(ConId,[ConId|VarId])] )]
135 List ghcModules; /* [Module] -- modules of the .his loaded in this group */
137 Void addGHCExports(mod,stuff)
140 ghcExports = cons( pair(mod,stuff), ghcExports );
143 static Void local finishGHCExports(paire)
145 Text modTxt = textOf(fst(paire));
146 List entities = snd(paire);
147 Module mod = findModule(modTxt);
149 ERRMSG(0) "Can't find module \"%s\" mentioned in export list",
153 fprintf(stderr, "----------------------------------finishexports\n");
154 /* Assume that each .hi file only contains one export decl */
155 if (nonNull(module(mod).exports))
156 internal("finishGHCExports: non-empty export list");
158 /* Run along what the parser gave us and make export list entries */
159 for (; nonNull(entities); entities=tl(entities)) {
160 Cell ent = hd(entities);
163 switch (whatIs(ent)) {
164 case VARIDCELL: /* variable */
165 c = findName ( snd(ent) );
167 fprintf(stderr, "var %s\n", textToStr(name(c).text));
168 module(mod).exports = cons(c, module(mod).exports);
170 case CONIDCELL: /* non data tycon */
171 c = findTycon ( snd(ent) );
173 fprintf(stderr, "non data tycon %s\n", textToStr(tycon(c).text));
174 module(mod).exports = cons(c, module(mod).exports);
176 default: /* data T = C1 ... Cn or class C where f1 ... fn */
177 if (!isPair(ent)) internal("finishExports(2)");
180 c = findTycon ( snd(ent) );
183 fprintf(stderr, "data %s = ", textToStr(tycon(c).text));
184 module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
185 for (; nonNull(subents); subents = tl(subents)) {
186 Cell ent2 = hd(subents);
188 c = findName ( snd(ent2) );
189 fprintf(stderr, "%s ", textToStr(name(c).text));
191 module(mod).exports = cons(c, module(mod).exports);
193 fprintf(stderr, "\n" );
196 c = findClass ( snd(ent) );
198 fprintf(stderr, "class %s where ", textToStr(cclass(c).text));
199 module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
201 for (; nonNull(subents); subents = tl(subents)) {
202 Cell ent2 = hd(subents);
204 c = findName ( snd(ent2) );
205 fprintf(stderr, "%s ", textToStr(name(c).text));
207 module(mod).exports = cons(c, module(mod).exports);
209 fprintf(stderr, "\n" );
217 static Void local finishGHCImports(triple)
220 Module dstMod = fst3(triple); // the importing module
221 Text srcTxt = snd3(triple);
222 List names = thd3(triple);
223 Module srcMod = findModule ( srcTxt );
224 Module tmpCurrentModule = currentModule;
230 //fprintf(stderr, "finishGHCImports: dst=%s src=%s\n",
231 // textToStr(module(dstMod).text),
232 // textToStr(srcTxt) );
235 /* for each nm in names
236 nm should be in module(src).exports -- if not, error
237 if nm notElem module(dst).names cons it on
240 if (isNull(srcMod)) {
241 /* I don't think this can actually ever happen, but still ... */
242 ERRMSG(0) "Interface for module \"%s\" imports unknown module \"%s\"",
243 textToStr(module(dstMod).text),
247 //printf ( "exports of %s are\n", textToStr(module(srcMod).text) );
248 //print( module(srcMod).exports, 100 );
251 setCurrModule ( srcMod ); // so that later lookups succeed
253 for (; nonNull(names); names=tl(names)) {
255 /* Check the exporting module really exports it. */
257 for (exps=module(srcMod).exports; nonNull(exps); exps=tl(exps)) {
259 //if (isPair(c)) c=fst(c);
260 assert(whatIs(c)==CONIDCELL || whatIs(c)==VARIDCELL);
261 assert(whatIs(nm)==CONIDCELL || whatIs(nm)==VARIDCELL);
262 //printf( " compare `%s' `%s'\n", textToStr(textOf(c)), textToStr(textOf(nm)));
263 if (textOf(c)==textOf(nm)) { found=TRUE; break; }
266 ERRMSG(0) "Interface for module \"%s\" imports \"%s\" from\n"
267 "module \"%s\", but the latter doesn't export it",
268 textToStr(module(dstMod).text), textToStr(textOf(nm)),
269 textToStr(module(srcMod).text)
272 /* Ok, it's exported. Now figure out what it is we're really
279 if (!cellIsMember(x,module(dstMod).names))
280 module(dstMod).names = cons(x, module(dstMod).names);
286 if (!cellIsMember(x,module(dstMod).tycons))
287 module(dstMod).tycons = cons(x, module(dstMod).tycons);
293 if (!cellIsMember(x,module(dstMod).classes))
294 module(dstMod).classes = cons(x, module(dstMod).classes);
298 fprintf(stderr, "\npanic: Can't figure out what this is in finishGHCImports\n"
299 "\t%s\n", textToStr(tnm) );
300 internal("finishGHCImports");
303 setCurrModule(tmpCurrentModule);
307 Void loadInterface(String fname, Long fileSize)
310 parseInterface(fname,fileSize);
311 if (nonNull(ifImports))
316 Void finishInterfaces ( void )
318 /* the order of these doesn't matter
319 * (ToDo: unless synonyms have to be eliminated??)
321 mapProc(finishGHCVar, ghcVarDecls);
322 mapProc(finishGHCConstr, ghcConstrDecls);
323 mapProc(finishGHCSynonym, ghcSynonymDecls);
324 mapProc(finishGHCClass, ghcClassDecls);
325 mapProc(finishGHCInstance, ghcInstanceDecls);
326 mapProc(finishGHCExports, ghcExports);
327 mapProc(finishGHCImports, ghcImports);
328 mapProc(finishGHCModule, ghcModules);
330 ghcConstrDecls = NIL;
331 ghcSynonymDecls = NIL;
333 ghcInstanceDecls = NIL;
340 static Void local finishGHCModule(mod)
342 // do the implicit 'import Prelude' thing
343 List pxs = module(modulePrelude).exports;
344 for (; nonNull(pxs); pxs=tl(pxs)) {
347 switch (whatIs(px)) {
352 module(mod).names = cons ( px, module(mod).names );
355 module(mod).tycons = cons ( px, module(mod).tycons );
358 module(mod).classes = cons ( px, module(mod).classes );
361 fprintf(stderr, "finishGHCModule: unknown tag %d\n", whatIs(px));
366 // Last, but by no means least ...
367 resolveReferencesInObjectModule ( mod, FALSE );
375 Module m = findModule(t);
378 printf ( "new module %s\n", textToStr(t) );
379 } else if (m != modulePrelude) {
380 ERRMSG(0) "Module \"%s\" already loaded", textToStr(t)
384 // sizeObj and nameObj will magically be set to the right
385 // thing when we arrive here.
386 // All this crud should be replaced with mmap when we do this
388 img = malloc ( sizeObj );
390 ERRMSG(0) "Can't allocate memory to load object file for module \"%s\"",
394 f = fopen( nameObj, "rb" );
396 // Really, this shouldn't happen, since makeStackEntry ensures the
397 // object is available. Nevertheless ...
398 ERRMSG(0) "Object file \"%s\" can't be opened to read -- oops!",
402 if (sizeObj != fread ( img, 1, sizeObj, f)) {
403 ERRMSG(0) "Read of object file \"%s\" failed", nameObj
406 if (!validateOImage(img,sizeObj,FALSE)) {
407 ERRMSG(0) "Validation of object file \"%s\" failed", nameObj
411 assert(!module(m).oImage);
412 module(m).oImage = img;
416 if (!cellIsMember(m, ghcModules))
417 ghcModules = cons(m, ghcModules);
423 Void addGHCImports(line,mn,syms)
425 Text mn; /* the module to import from */
426 List syms; { /* [ConId | VarId] -- the names to import */
430 printf("\naddGHCImport %s\n", textToStr(mn) );
433 // Hack to avoid chasing Prel* junk right now
434 if (strncmp(textToStr(mn), "Prel",4)==0) return;
437 for (t=ifImports; nonNull(t); t=tl(t)) {
438 if (textOf(hd(t)) == mn) {
444 ifImports = cons(mkCon(mn),ifImports);
445 ghcImports = cons( triple(currentModule,mn,syms), ghcImports );
449 void addGHCVar(line,v,ty)
457 /* if this var is the name of a ghc-compiled dictionary,
458 ie, starts zdfC where C is a capital,
463 printf("\nbegin addGHCVar %s\n", s);
465 if (s[0]=='z' && s[1]=='d' && s[2]=='f' && isupper((int)s[3])) {
467 printf(" ignoring %s\n", s);
473 ERRMSG(0) "Attempt to redefine variable \"%s\"", textToStr(v)
478 tvs = nubList(ifTyvarsIn(ty));
479 for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
480 hd(tmp) = pair(hd(tmp),STAR);
482 ty = mkPolyType(tvsToKind(tvs),ty);
484 ty = tvsToOffsets(line,ty,tvs);
486 /* prepare for finishGHCVar */
488 name(n).arity = arityInclDictParams(ty);
490 ghcVarDecls = cons(n,ghcVarDecls);
492 printf("end addGHCVar %s\n", s);
496 static Void local finishGHCVar(Name n)
498 Int line = name(n).line;
499 Type ty = name(n).type;
501 fprintf(stderr, "\nbegin finishGHCVar %s\n", textToStr(name(n).text) );
503 setCurrModule(name(n).mod);
504 name(n).type = conidcellsToTycons(line,ty);
506 fprintf(stderr, "end finishGHCVar %s\n", textToStr(name(n).text) );
510 Void addGHCSynonym(line,tycon,tvs,ty)
512 Cell tycon; /* ConId */
513 List tvs; /* [(VarId,Kind)] */
515 /* ToDo: worry about being given a decl for (->) ?
516 * and worry about qualidents for ()
518 Text t = textOf(tycon);
519 if (nonNull(findTycon(t))) {
520 ERRMSG(line) "Repeated definition of type constructor \"%s\"",
524 Tycon tc = newTycon(t);
525 tycon(tc).line = line;
526 tycon(tc).arity = length(tvs);
527 tycon(tc).what = SYNONYM;
528 tycon(tc).kind = tvsToKind(tvs);
530 /* prepare for finishGHCSynonym */
531 tycon(tc).defn = tvsToOffsets(line,ty,tvs);
532 ghcSynonymDecls = cons(tc,ghcSynonymDecls);
536 static Void local finishGHCSynonym(Tycon tc)
538 Int line = tycon(tc).line;
540 setCurrModule(tycon(tc).mod);
541 tycon(tc).defn = conidcellsToTycons(line,tycon(tc).defn);
543 /* ToDo: can't really do this until I've done all synonyms
544 * and then I have to do them in order
545 * tycon(tc).defn = fullExpand(ty);
549 Void addGHCDataDecl(line,ctx0,tycon,ktyvars,constrs0)
551 List ctx0; /* [(QConId,VarId)] */
552 Cell tycon; /* ConId */
553 List ktyvars; /* [(VarId,Kind)] */
554 List constrs0; /* [(ConId,[(Type,Text)],NIL)]
555 The NIL will become the constr's type
556 The Text is an optional field name */
557 /* ToDo: worry about being given a decl for (->) ?
558 * and worry about qualidents for ()
561 Type ty, resTy, selTy, conArgTy;
562 List tmp, conArgs, sels, constrs, fields, tyvarsMentioned;
566 Pair conArg, ctxElem;
569 Text t = textOf(tycon);
571 fprintf(stderr, "\nbegin addGHCDataDecl %s\n",textToStr(t));
573 if (nonNull(findTycon(t))) {
574 ERRMSG(line) "Repeated definition of type constructor \"%s\"",
578 Tycon tc = newTycon(t);
580 tycon(tc).line = line;
581 tycon(tc).arity = length(ktyvars);
582 tycon(tc).kind = tvsToKind(ktyvars);
583 tycon(tc).what = DATATYPE;
585 /* a list to accumulate selectors in :: [(VarId,Type)] */
588 /* make resTy the result type of the constr, T v1 ... vn */
590 for (tmp=ktyvars; nonNull(tmp); tmp=tl(tmp))
591 resTy = ap(resTy,fst(hd(tmp)));
593 /* for each constructor ... */
594 for (constrs=constrs0; nonNull(constrs); constrs=tl(constrs)) {
595 constr = hd(constrs);
596 conid = fst3(constr);
597 fields = snd3(constr);
598 assert(isNull(thd3(constr)));
600 /* Build type of constr and handle any selectors found.
601 Also collect up tyvars occurring in the constr's arg
602 types, so we can throw away irrelevant parts of the
606 tyvarsMentioned = NIL; /* [VarId] */
607 conArgs = reverse(fields);
608 for (; nonNull(conArgs); conArgs=tl(conArgs)) {
609 conArg = hd(conArgs); /* (Type,Text) */
610 conArgTy = fst(conArg);
611 conArgNm = snd(conArg);
612 tyvarsMentioned = dupListOnto(ifTyvarsIn(conArgTy),
614 ty = fn(conArgTy,ty);
615 if (nonNull(conArgNm)) {
616 /* a field name is mentioned too */
617 selTy = fn(resTy,conArgTy);
618 if (whatIs(tycon(tc).kind) != STAR)
619 selTy = pair(POLYTYPE,pair(tycon(tc).kind, selTy));
620 selTy = tvsToOffsets(line,selTy, ktyvars);
622 sels = cons( pair(conArgNm,selTy), sels);
626 /* Now ty is the constructor's type, not including context.
627 Throw away any parts of the context not mentioned in
628 tyvarsMentioned, and use it to qualify ty.
631 for (ctx=ctx0; nonNull(ctx); ctx=tl(ctx)) {
632 ctxElem = hd(ctx); /* (QConId,VarId) */
633 if (nonNull(cellIsMember(textOf(snd(ctxElem)),tyvarsMentioned)))
634 ctx2 = cons(ctxElem, ctx2);
637 ty = ap(QUAL,pair(ctx2,ty));
639 /* stick the tycon's kind on, if not simply STAR */
640 if (whatIs(tycon(tc).kind) != STAR)
641 ty = pair(POLYTYPE,pair(tycon(tc).kind, ty));
643 ty = tvsToOffsets(line,ty, ktyvars);
645 /* Finally, stick the constructor's type onto it. */
646 thd3(hd(constrs)) = ty;
649 /* Final result is that
650 constrs :: [(ConId,[(Type,Text)],Type)]
651 lists the constructors and their types
652 sels :: [(VarId,Type)]
653 lists the selectors and their types
655 tycon(tc).defn = addGHCConstrs(line,constrs0,sels);
658 fprintf(stderr, "end addGHCDataDecl %s\n",textToStr(t));
663 static List local addGHCConstrs(line,cons,sels)
665 List cons; /* [(ConId,[(Type,Text)],Type)] */
666 List sels; { /* [(VarId,Type)] */
668 Int conNo = 0; /* or maybe 1? */
669 for(cs=cons; nonNull(cs); cs=tl(cs), conNo++) {
670 Name c = addGHCConstr(line,conNo,hd(cs));
673 for(ss=sels; nonNull(ss); ss=tl(ss)) {
674 hd(ss) = addGHCSel(line,hd(ss));
676 return appendOnto(cons,sels);
679 static Name local addGHCSel(line,sel)
681 Pair sel; /* (VarId,Type) */
683 Text t = textOf(fst(sel));
684 Type type = snd(sel);
686 Name n = findName(t);
688 ERRMSG(line) "Repeated definition for selector \"%s\"",
695 name(n).number = SELNAME;
699 /* prepare for finishGHCVar */
701 ghcVarDecls = cons(n,ghcVarDecls);
706 static Name local addGHCConstr(line,conNo,constr)
709 Triple constr; { /* (ConId,[(Type,Text)],Type) */
710 /* ToDo: add rank2 annotation and existential annotation
711 * these affect how constr can be used.
713 Text con = textOf(fst3(constr));
714 Type type = thd3(constr);
715 Int arity = arityFromType(type);
716 Name n = findName(con); /* Allocate constructor fun name */
718 n = newName(con,NIL);
719 } else if (name(n).defn!=PREDEFINED) {
720 ERRMSG(line) "Repeated definition for constructor \"%s\"",
724 name(n).arity = arity; /* Save constructor fun details */
726 name(n).number = cfunNo(conNo);
728 /* prepare for finishGHCCon */
730 ghcConstrDecls = cons(n,ghcConstrDecls);
735 static Void local finishGHCConstr(Name n)
737 Int line = name(n).line;
738 Type ty = name(n).type;
739 setCurrModule(name(n).mod);
741 printf ( "\nbegin finishGHCConstr %s\n", textToStr(name(n).text));
743 name(n).type = conidcellsToTycons(line,ty);
745 printf ( "end finishGHCConstr %s\n", textToStr(name(n).text));
750 Void addGHCNewType(line,ctx0,tycon,tvs,constr)
752 List ctx0; /* [(QConId,VarId)] */
753 Cell tycon; /* ConId | QualConId */
754 List tvs; /* [(VarId,Kind)] */
755 Cell constr; { /* (ConId,Type) */
756 /* ToDo: worry about being given a decl for (->) ?
757 * and worry about qualidents for ()
761 Text t = textOf(tycon);
762 if (nonNull(findTycon(t))) {
763 ERRMSG(line) "Repeated definition of type constructor \"%s\"",
767 Tycon tc = newTycon(t);
768 tycon(tc).line = line;
769 tycon(tc).arity = length(tvs);
770 tycon(tc).what = NEWTYPE;
771 tycon(tc).kind = tvsToKind(tvs);
772 /* can't really do this until I've read in all synonyms */
774 assert(nonNull(constr));
775 if (isNull(constr)) {
776 tycon(tc).defn = NIL;
778 /* constr :: (ConId,Type) */
779 Text con = textOf(fst(constr));
780 Type type = snd(constr);
781 Name n = findName(con); /* Allocate constructor fun name */
783 n = newName(con,NIL);
784 } else if (name(n).defn!=PREDEFINED) {
785 ERRMSG(line) "Repeated definition for constructor \"%s\"",
789 name(n).arity = 1; /* Save constructor fun details */
791 name(n).number = cfunNo(0);
792 name(n).defn = nameId;
793 tycon(tc).defn = singleton(n);
795 /* prepare for finishGHCCon */
796 /* ToDo: we use finishGHCCon instead of finishGHCVar in case
797 * there's any existential quantification in the newtype -
798 * but I don't think that's allowed in newtype constrs.
799 * Still, no harm done by doing it this way...
802 /* make resTy the result type of the constr, T v1 ... vn */
804 for (tmp=tvs; nonNull(tmp); tmp=tl(tmp))
805 resTy = ap(resTy,fst(hd(tmp)));
806 type = fn(type,resTy);
808 type = ap(QUAL,pair(ctx0,type));
810 type = tvsToOffsets(line,type,tvs);
813 ghcConstrDecls = cons(n,ghcConstrDecls);
818 Void addGHCClass(line,ctxt,tc_name,tv,mems0)
820 List ctxt; /* [(QConId, VarId)] */
821 Cell tc_name; /* ConId */
823 List mems0; { /* [(VarId, Type)] */
824 List mems; /* [(VarId, Type)] */
825 List tvsInT; /* [VarId] and then [(VarId,Kind)] */
826 List tvs; /* [(VarId,Kind)] */
827 Text ct = textOf(tc_name);
828 Pair newCtx = pair(tc_name, tv);
830 printf ( "\nbegin addGHCclass %s\n", textToStr(ct) );
832 if (nonNull(findClass(ct))) {
833 ERRMSG(line) "Repeated definition of class \"%s\"",
836 } else if (nonNull(findTycon(ct))) {
837 ERRMSG(line) "\"%s\" used as both class and type constructor",
841 Class nw = newClass(ct);
842 cclass(nw).text = ct;
843 cclass(nw).line = line;
844 cclass(nw).arity = 1;
845 cclass(nw).head = ap(nw,mkOffset(0));
846 cclass(nw).kinds = singleton(STAR); /* absolutely no idea at all */
847 cclass(nw).instances = NIL; /* what the kind should be */
848 cclass(nw).numSupers = length(ctxt);
850 /* Kludge to map the single tyvar in the context to Offset 0.
851 Need to do something better for multiparam type classes.
853 cclass(nw).supers = tvsToOffsets(line,ctxt,
854 singleton(pair(tv,STAR)));
856 for (mems=mems0; nonNull(mems); mems=tl(mems)) {
858 Type memT = snd(mem);
859 Text mnt = textOf(fst(mem));
862 /* Stick the new context on the member type */
863 if (whatIs(memT)==POLYTYPE) internal("addGHCClass");
864 if (whatIs(memT)==QUAL) {
866 pair(cons(newCtx,fst(snd(memT))),snd(snd(memT))));
869 pair(singleton(newCtx),memT));
872 /* Cook up a kind for the type. */
873 tvsInT = nubList(ifTyvarsIn(memT));
875 /* ToDo: maximally bogus */
876 for (tvs=tvsInT; nonNull(tvs); tvs=tl(tvs))
877 hd(tvs) = pair(hd(tvs),STAR);
879 memT = mkPolyType(tvsToKind(tvsInT),memT);
880 memT = tvsToOffsets(line,memT,tvsInT);
882 /* Park the type back on the member */
885 /* Bind code to the member */
889 "Repeated definition for class method \"%s\"",
893 mn = newName(mnt,NIL);
896 cclass(nw).members = mems0;
897 cclass(nw).numMembers = length(mems0);
898 ghcClassDecls = cons(nw,ghcClassDecls);
901 * cclass(nw).dsels = ?;
902 * cclass(nw).dbuild = ?;
903 * cclass(nm).dcon = ?;
904 * cclass(nm).defaults = ?;
908 printf ( "end addGHCclass %s\n", textToStr(ct) );
912 static Void local finishGHCClass(Class nw)
915 Int line = cclass(nw).line;
916 Int ctr = - length(cclass(nw).members);
919 printf ( "\nbegin finishGHCclass %s\n", textToStr(cclass(nw).text) );
922 setCurrModule(cclass(nw).mod);
924 cclass(nw).level = 0; /* ToDo: 1 + max (map level supers) */
925 cclass(nw).head = conidcellsToTycons(line,cclass(nw).head);
926 cclass(nw).supers = conidcellsToTycons(line,cclass(nw).supers);
927 cclass(nw).members = conidcellsToTycons(line,cclass(nw).members);
929 for (mems=cclass(nw).members; nonNull(mems); mems=tl(mems)) {
930 Pair mem = hd(mems); /* (VarId, Type) */
931 Text txt = textOf(fst(mem));
933 Name n = findName(txt);
935 name(n).line = cclass(nw).line;
937 name(n).number = ctr++;
941 printf ( "end finishGHCclass %s\n", textToStr(cclass(nw).text) );
945 Void addGHCInstance (line,ctxt0,cls,var)
947 List ctxt0; /* [(QConId, Type)] */
948 Pair cls; /* (ConId, [Type]) */
949 Text var; { /* Text */
953 printf ( "\nbegin addGHCInstance\n" );
956 /* Make tvs into a list of tyvars with bogus kinds. */
957 tvs = nubList(ifTyvarsIn(snd(cls)));
959 for (tmp = tvs; nonNull(tmp); tmp=tl(tmp)) {
960 hd(tmp) = pair(hd(tmp),STAR);
964 inst(in).line = line;
965 inst(in).implements = NIL;
967 inst(in).specifics = tvsToOffsets(line,ctxt0,tvs);
968 inst(in).numSpecifics = length(ctxt0);
969 inst(in).head = tvsToOffsets(line,cls,tvs);
971 Is this still needed?
973 Name b = newName(inventText(),NIL);
975 name(b).arity = length(ctxt); /* unused? */
976 name(b).number = DFUNNAME;
977 inst(in).builder = b;
978 bindNameToClosure(b, lookupGHCClosure(inst(in).mod,var));
981 ghcInstanceDecls = cons(in, ghcInstanceDecls);
983 printf ( "end addGHCInstance\n" );
987 static Void local finishGHCInstance(Inst in)
989 Int line = inst(in).line;
990 Cell cl = fst(inst(in).head);
993 printf ( "\nbegin finishGHCInstance\n" );
996 setCurrModule(inst(in).mod);
997 c = findClass(textOf(cl));
999 ERRMSG(line) "Unknown class \"%s\" in instance",
1000 textToStr(textOf(cl))
1003 inst(in).head = conidcellsToTycons(line,inst(in).head);
1004 inst(in).specifics = conidcellsToTycons(line,inst(in).specifics);
1005 cclass(c).instances = cons(in,cclass(c).instances);
1007 printf ( "end finishGHCInstance\n" );
1011 /* --------------------------------------------------------------------------
1013 * ------------------------------------------------------------------------*/
1015 /* This is called from the addGHC* functions. It traverses a structure
1016 and converts varidcells, ie, type variables parsed by the interface
1017 parser, into Offsets, which is how Hugs wants to see them internally.
1018 The Offset for a type variable is determined by its place in the list
1019 passed as the second arg; the associated kinds are irrelevant.
1021 static Type local tvsToOffsets(line,type,ktyvars)
1024 List ktyvars; { /* [(VarId|Text,Kind)] */
1025 switch (whatIs(type)) {
1033 return ap( tvsToOffsets(line,fun(type),ktyvars),
1034 tvsToOffsets(line,arg(type),ktyvars) );
1038 tvsToOffsets(line,monotypeOf(type),ktyvars)
1042 return pair(QUAL,pair(tvsToOffsets(line,fst(snd(type)),ktyvars),
1043 tvsToOffsets(line,snd(snd(type)),ktyvars)));
1044 case VARIDCELL: /* Ha! some real work to do! */
1046 Text tv = textOf(type);
1047 for (; nonNull(ktyvars); i++,ktyvars=tl(ktyvars)) {
1048 Cell varid = fst(hd(ktyvars));
1049 Text tt = isVar(varid) ? textOf(varid) : varid;
1050 if (tv == tt) return mkOffset(i);
1052 ERRMSG(line) "Undefined type variable \"%s\"", textToStr(tv)
1057 fprintf(stderr, "tvsToOffsets: unknown stuff %d\n", whatIs(type));
1059 fprintf(stderr,"\n");
1063 return NIL; /* NOTREACHED */
1067 /* This is called from the finishGHC* functions. It traverses a structure
1068 and converts conidcells, ie, type constructors parsed by the interface
1069 parser, into Tycons (or Classes), which is how Hugs wants to see them
1070 internally. Calls to this fn have to be deferred to the second phase
1071 of interface loading (finishGHC* rather than addGHC*) so that all relevant
1072 Tycons or Classes have been loaded into the symbol tables and can be
1075 static Type local conidcellsToTycons(line,type)
1078 switch (whatIs(type)) {
1087 Text m = qmodOf(type);
1088 Text v = qtextOf(type);
1089 Module mod = findModule(m);
1090 //printf ( "lookup qualident " ); print(type,100); printf("\n");
1093 "Undefined module in qualified name \"%s\"",
1098 for (t=module(mod).tycons; nonNull(t); t=tl(t))
1099 if (v == tycon(hd(t)).text) return hd(t);
1100 for (t=module(mod).classes; nonNull(t); t=tl(t))
1101 if (v == cclass(hd(t)).text) return hd(t);
1103 "Undefined qualified class or type \"%s\"",
1111 tc = findQualTycon(type);
1112 if (nonNull(tc)) return tc;
1113 cl = findQualClass(type);
1114 if (nonNull(cl)) return cl;
1116 "Undefined class or type constructor \"%s\"",
1122 return ap( conidcellsToTycons(line,fun(type)),
1123 conidcellsToTycons(line,arg(type)) );
1127 conidcellsToTycons(line,monotypeOf(type))
1131 return pair(QUAL,pair(conidcellsToTycons(line,fst(snd(type))),
1132 conidcellsToTycons(line,snd(snd(type)))));
1134 fprintf(stderr, "conidcellsToTycons: unknown stuff %d\n",
1137 fprintf(stderr,"\n");
1141 return NIL; /* NOTREACHED */
1145 /* --------------------------------------------------------------------------
1148 * None of these do lookups or require that lookups have been resolved
1149 * so they can be performed while reading interfaces.
1150 * ------------------------------------------------------------------------*/
1152 static Kinds local tvsToKind(tvs)
1153 List tvs; { /* [(VarId,Kind)] */
1156 for (rs=reverse(tvs); nonNull(rs); rs=tl(rs)) {
1157 r = ap(snd(hd(rs)),r);
1163 static Int local arityInclDictParams ( Type type )
1166 if (isPolyType(type)) type = monotypeOf(type);
1168 if (whatIs(type) == QUAL)
1170 arity += length ( fst(snd(type)) );
1171 type = snd(snd(type));
1173 while (isAp(type) && getHead(type)==typeArrow) {
1180 /* arity of a constructor with this type */
1181 static Int local arityFromType(type)
1184 if (isPolyType(type)) {
1185 type = monotypeOf(type);
1187 if (whatIs(type) == QUAL) {
1188 type = snd(snd(type));
1190 if (whatIs(type) == EXIST) {
1191 type = snd(snd(type));
1193 if (whatIs(type)==RANK2) {
1194 type = snd(snd(type));
1196 while (isAp(type) && getHead(type)==typeArrow) {
1204 static List local ifTyvarsIn(type)
1206 List vs = typeVarsIn(type,NIL,NIL,NIL);
1208 for (; nonNull(vs2); vs2=tl(vs2)) {
1210 if (whatIs(v)==VARIDCELL || whatIs(v)==VAROPCELL) {
1211 hd(vs2) = textOf(hd(vs2));
1213 internal("ifTyvarsIn");
1220 /* --------------------------------------------------------------------------
1222 * ------------------------------------------------------------------------*/
1224 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
1228 static char* local findElfSection ( void* objImage, Elf32_Word sh_type )
1231 char* ehdrC = (char*)objImage;
1232 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1233 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1235 for (i = 0; i < ehdr->e_shnum; i++) {
1236 if (shdr[i].sh_type == sh_type &&
1237 i != ehdr->e_shstrndx) {
1238 ptr = ehdrC + shdr[i].sh_offset;
1246 static Void local resolveReferencesInObjectModule_elf ( Module m,
1249 char symbol[1000]; // ToDo
1253 char* ehdrC = (char*)(module(m).oImage);
1254 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1255 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1257 // first find "the" symbol table
1258 //stab = findElfSection ( objImage, SHT_SYMTAB );
1260 // also go find the string table
1261 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1263 if (!stab || !strtab)
1264 internal("resolveReferencesInObjectModule_elf");
1266 for (i = 0; i < ehdr->e_shnum; i++) {
1267 if (shdr[i].sh_type == SHT_REL ) {
1268 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[i].sh_offset);
1269 Int nent = shdr[i].sh_size / sizeof(Elf32_Rel);
1270 Int target_shndx = shdr[i].sh_info;
1271 Int symtab_shndx = shdr[i].sh_link;
1272 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1273 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1276 "relocations for section %d using symtab %d\n",
1277 target_shndx, symtab_shndx );
1278 for (j = 0; j < nent; j++) {
1279 Elf32_Addr offset = rtab[j].r_offset;
1280 Elf32_Word info = rtab[j].r_info;
1282 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1283 Elf32_Word* pP = (Elf32_Word*)P;
1287 if (verb) fprintf ( stderr, "Rel entry %3d is raw(%6p %6p) ",
1288 j, (void*)offset, (void*)info );
1290 if (verb) fprintf ( stderr, " ZERO\n" );
1293 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1294 if (verb) fprintf ( stderr, "(noname) ");
1295 /* nameless (local) symbol */
1296 S = (Elf32_Addr)(ehdrC
1297 + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1298 + stab[ELF32_R_SYM(info)].st_value
1300 strcpy ( symbol, "(noname)");
1302 strcpy ( symbol, strtab+stab[ ELF32_R_SYM(info)].st_name );
1303 if (verb) fprintf ( stderr, "`%s' ", symbol );
1304 S = (Elf32_Addr)lookupObjName ( symbol );
1306 if (verb) fprintf ( stderr, "resolves to %p\n", (void*)S );
1308 fprintf ( stderr, "link failure for `%s'\n",
1309 strtab+stab[ ELF32_R_SYM(info)].st_name );
1313 //fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n\n",
1314 // (void*)P, (void*)S, (void*)A );
1315 switch (ELF32_R_TYPE(info)) {
1316 case R_386_32: *pP = S + A; break;
1317 case R_386_PC32: *pP = S + A - P; break;
1318 default: fprintf(stderr,
1319 "unhandled ELF relocation type %d\n",
1320 ELF32_R_TYPE(info));
1327 if (shdr[i].sh_type == SHT_RELA) {
1328 fprintf ( stderr, "RelA style reloc table -- not yet done" );
1335 static Bool local validateOImage_elf ( void* imgV,
1341 int i, j, nent, nstrtab, nsymtabs;
1345 char* ehdrC = (char*)imgV;
1346 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1348 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1349 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1350 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1351 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1352 if (verb) fprintf ( stderr, "Not an ELF header\n" );
1355 if (verb) fprintf ( stderr, "Is an ELF header\n" );
1357 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1358 if (verb) fprintf ( stderr, "Not 32 bit ELF\n" );
1361 if (verb) fprintf ( stderr, "Is 32 bit ELF\n" );
1363 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1364 if (verb) fprintf ( stderr, "Is little-endian\n" );
1366 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1367 if (verb) fprintf ( stderr, "Is big-endian\n" );
1369 if (verb) fprintf ( stderr, "Unknown endiannness\n" );
1373 if (ehdr->e_type != ET_REL) {
1374 if (verb) fprintf ( stderr, "Not a relocatable object (.o) file\n" );
1377 if (verb) fprintf ( stderr, "Is a relocatable object (.o) file\n" );
1379 if (verb) fprintf ( stderr, "Architecture is " );
1380 switch (ehdr->e_machine) {
1381 case EM_386: if (verb) fprintf ( stderr, "x86\n" ); break;
1382 case EM_SPARC: if (verb) fprintf ( stderr, "sparc\n" ); break;
1383 default: if (verb) fprintf ( stderr, "unknown\n" ); return FALSE;
1388 "\nSection header table: start %d, n_entries %d, ent_size %d\n",
1389 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize );
1391 assert (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1393 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1395 if (ehdr->e_shstrndx == SHN_UNDEF) {
1396 if (verb) fprintf ( stderr, "No section header string table\n" );
1400 if (verb) fprintf ( stderr,"Section header string table is section %d\n",
1402 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1405 for (i = 0; i < ehdr->e_shnum; i++) {
1406 if (verb) fprintf ( stderr, "%2d: ", i );
1407 if (verb) fprintf ( stderr, "type=%2d ", shdr[i].sh_type );
1408 if (verb) fprintf ( stderr, "size=%4d ", shdr[i].sh_size );
1409 if (verb) fprintf ( stderr, "offs=%4d ", shdr[i].sh_offset );
1410 if (verb) fprintf ( stderr, " (%p .. %p) ",
1411 ehdrC + shdr[i].sh_offset,
1412 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
1414 if (shdr[i].sh_type == SHT_REL && verb) fprintf ( stderr, "Rel " ); else
1415 if (shdr[i].sh_type == SHT_RELA && verb) fprintf ( stderr, "RelA " ); else
1416 if (verb) fprintf ( stderr, " " );
1417 if (sh_strtab && verb) fprintf ( stderr, "sname=%s", sh_strtab + shdr[i].sh_name );
1418 if (verb) fprintf ( stderr, "\n" );
1421 if (verb) fprintf ( stderr, "\n\nString tables\n" );
1424 for (i = 0; i < ehdr->e_shnum; i++) {
1425 if (shdr[i].sh_type == SHT_STRTAB &&
1426 i != ehdr->e_shstrndx) {
1427 if (verb) fprintf ( stderr, " section %d is a normal string table\n", i );
1428 strtab = ehdrC + shdr[i].sh_offset;
1433 if (verb) fprintf ( stderr, "WARNING: no string tables, or too many\n" );
1438 if (verb) fprintf ( stderr, "\n\nSymbol tables\n" );
1439 for (i = 0; i < ehdr->e_shnum; i++) {
1440 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1441 if (verb) fprintf ( stderr, "section %d is a symbol table\n", i );
1443 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1444 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1445 if (verb) fprintf ( stderr, " number of entries is apparently %d (%d rem)\n",
1447 shdr[i].sh_size % sizeof(Elf32_Sym)
1449 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1450 if (verb) fprintf ( stderr, "non-integral number of symbol table entries\n");
1453 for (j = 0; j < nent; j++) {
1454 if (verb) fprintf ( stderr, " %2d ", j );
1455 if (verb) fprintf ( stderr, " sec=%-5d size=%-3d val=%-5p ",
1456 (int)stab[j].st_shndx,
1457 (int)stab[j].st_size,
1458 (char*)stab[j].st_value );
1460 if (verb) fprintf ( stderr, "type=" );
1461 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1462 case STT_NOTYPE: if (verb) fprintf ( stderr, "notype " ); break;
1463 case STT_OBJECT: if (verb) fprintf ( stderr, "object " ); break;
1464 case STT_FUNC : if (verb) fprintf ( stderr, "func " ); break;
1465 case STT_SECTION: if (verb) fprintf ( stderr, "section" ); break;
1466 case STT_FILE: if (verb) fprintf ( stderr, "file " ); break;
1467 default: if (verb) fprintf ( stderr, "? " ); break;
1469 if (verb) fprintf ( stderr, " " );
1471 if (verb) fprintf ( stderr, "bind=" );
1472 switch (ELF32_ST_BIND(stab[j].st_info)) {
1473 case STB_LOCAL : if (verb) fprintf ( stderr, "local " ); break;
1474 case STB_GLOBAL: if (verb) fprintf ( stderr, "global" ); break;
1475 case STB_WEAK : if (verb) fprintf ( stderr, "weak " ); break;
1476 default: if (verb) fprintf ( stderr, "? " ); break;
1478 if (verb) fprintf ( stderr, " " );
1480 if (verb) fprintf ( stderr, "name=%s\n", strtab + stab[j].st_name );
1484 if (nsymtabs == 0) {
1485 if (verb) fprintf ( stderr, "Didn't find any symbol tables\n" );
1493 static void readSyms_elf ( Module m )
1498 char* ehdrC = (char*)(module(m).oImage);
1499 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1500 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1501 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1502 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1504 if (!strtab) internal("readSyms_elf");
1507 for (i = 0; i < ehdr->e_shnum; i++) {
1509 /* make a HugsDLSection entry for relevant sections */
1510 DLSect kind = HUGS_DL_SECTION_OTHER;
1511 if (0==strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1512 0==strcmp(".data1",sh_strtab+shdr[i].sh_name))
1513 kind = HUGS_DL_SECTION_RWDATA;
1514 if (0==strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1515 0==strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1516 0==strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1517 kind = HUGS_DL_SECTION_CODE_OR_RODATA;
1518 if (kind != HUGS_DL_SECTION_OTHER)
1521 ehdrC + shdr[i].sh_offset,
1522 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1,
1526 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1528 /* copy stuff into this module's object symbol table */
1529 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1530 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1531 for (j = 0; j < nent; j++) {
1532 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL ||
1533 ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
1536 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1537 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT )
1539 char* nm = strtab + stab[j].st_name;
1541 + shdr[ stab[j].st_shndx ].sh_offset
1545 /* fprintf(stderr, "addOTabName: %s %s %p\n",
1546 textToStr(module(m).text), nm, ad );
1548 addOTabName ( m, nm, ad );
1555 #endif /* defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) */
1558 /* --------------------------------------------------------------------------
1559 * Arch-independent interface to the runtime linker
1560 * ------------------------------------------------------------------------*/
1562 static Bool local validateOImage ( void* img, Int size, Bool verb )
1564 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
1566 validateOImage_elf ( img, size, verb );
1568 internal("validateOImage: not implemented on this platform");
1573 static Void local resolveReferencesInObjectModule ( Module m, Bool verb )
1575 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
1576 resolveReferencesInObjectModule_elf ( m, verb );
1578 internal("resolveReferencesInObjectModule: not implemented on this platform");
1583 static Void local readSyms ( Module m )
1585 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
1588 internal("readSyms: not implemented on this platform");
1593 /* --------------------------------------------------------------------------
1594 * General object symbol query stuff
1595 * ------------------------------------------------------------------------*/
1597 /* entirely bogus claims about types of these symbols */
1598 extern int stg_gc_enter_1;
1599 extern int stg_chk_0;
1600 extern int stg_chk_1;
1601 extern int stg_update_PAP;
1602 extern int __ap_2_upd_info;
1603 extern int MainRegTable;
1604 extern int Upd_frame_info;
1608 { "stg_gc_enter_1", &stg_gc_enter_1 },
1609 { "stg_chk_0", &stg_chk_0 },
1610 { "stg_chk_1", &stg_chk_1 },
1611 { "stg_update_PAP", &stg_update_PAP },
1612 { "__ap_2_upd_info", &__ap_2_upd_info },
1613 { "MainRegTable", &MainRegTable },
1614 { "Upd_frame_info", &Upd_frame_info },
1619 void* lookupObjName ( char* nm )
1629 strncpy(nm2,nm,200);
1631 // first see if it's an RTS name
1632 for (k = 0; rtsTab[k].nm; k++)
1633 if (0==strcmp(nm2,rtsTab[k].nm))
1634 return rtsTab[k].ad;
1636 // if not an RTS name, look in the
1637 // relevant module's object symbol table
1638 pp = strchr(nm2, '_');
1639 if (!pp) goto not_found;
1643 if (isNull(m)) goto not_found;
1644 a = lookupOTabName ( m, nm );
1649 "lookupObjName: can't resolve name `%s'\n",
1655 int is_dynamically_loaded_code_or_rodata_ptr ( char* p )
1658 lookupDLSect(p) == HUGS_DL_SECTION_CODE_OR_RODATA;
1662 int is_dynamically_loaded_rwdata_ptr ( char* p )
1665 lookupDLSect(p) == HUGS_DL_SECTION_RWDATA;
1669 int is_not_dynamically_loaded_ptr ( char* p )
1672 lookupDLSect(p) == HUGS_DL_SECTION_OTHER;
1676 /* --------------------------------------------------------------------------
1678 * ------------------------------------------------------------------------*/
1680 Void interface(what)
1687 ghcConstrDecls = NIL;
1688 ghcSynonymDecls = NIL;
1689 ghcClassDecls = NIL;
1690 ghcInstanceDecls = NIL;
1698 mark(ghcConstrDecls);
1699 mark(ghcSynonymDecls);
1700 mark(ghcClassDecls);
1701 mark(ghcInstanceDecls);
1709 /*-------------------------------------------------------------------------*/