[project @ 2000-11-13 14:40:36 by simonmar]
[ghc-hetmet.git] / ghc / rts / Linker.c
1 /* -----------------------------------------------------------------------------
2  * $Id: Linker.c,v 1.2 2000/11/13 14:40:37 simonmar Exp $
3  *
4  * (c) The GHC Team, 2000
5  *
6  * RTS Object Linker
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "Rts.h"
11 #include "RtsFlags.h"
12 #include "HsFFI.h"
13 #include "Hash.h"
14 #include "Linker.h"
15 #include "RtsUtils.h"
16
17 /* These two are POSIX headers */
18 #include <sys/types.h>
19 #include <sys/stat.h>
20
21 /* ToDo: configure this */
22 #include <dlfcn.h>
23
24 /* A bucket in the symbol hash-table.  Primarily, maps symbol names to
25  * absolute addresses.  All symbols from a given module are linked
26  * together, so they can be freed at the same time.  There's also a
27  * bucket link field for the hash table.
28  */
29 typedef struct _SymbolVal {
30     char   *lbl;
31     void   *addr;
32 } SymbolVal;
33
34 typedef enum { OBJECT_LOADED, OBJECT_RESOLVED } OStatus;
35
36 /* Indication of section kinds for loaded objects.  Needed by
37    the GC for deciding whether or not a pointer on the stack
38    is a code pointer.
39 */
40 typedef enum { SECTIONKIND_CODE_OR_RODATA,
41                SECTIONKIND_RWDATA,
42                SECTIONKIND_OTHER,
43                SECTIONKIND_NOINFOAVAIL } 
44    SectionKind;
45
46 typedef struct { void* start; void* end; SectionKind kind; } 
47    Section;
48
49 /* Top-level structure for an object module.  One of these is allocated
50  * for each object file in use.
51  */
52 typedef struct _ObjectCode {
53     OStatus   status;
54     char*     fileName;
55     int       fileSize;
56     char*     formatName;            /* eg "ELF32", "DLL", "COFF", etc. */
57
58     SymbolVal *symbols;
59     int       n_symbols;
60
61     /* ptr to malloc'd lump of memory holding the obj file */
62     void*     image;
63
64     /* The section-kind entries for this object module.  Dynamically expands. */
65     Section*  sections;
66     int       n_sections;
67     
68     /* Allow a chain of these things */
69     struct _ObjectCode * next;
70 } ObjectCode;
71
72
73 /* Hash table mapping symbol names to Symbol */
74 /*Str*/HashTable *symhash;
75
76 /* List of currently loaded objects */
77 ObjectCode *objects;
78
79 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
80 static int ocVerifyImage_ELF    ( ObjectCode* oc );
81 static int ocGetNames_ELF       ( ObjectCode* oc );
82 static int ocResolve_ELF        ( ObjectCode* oc );
83 #elif defined(cygwin32_TARGET_OS)               
84 static int ocVerifyImage_PEi386 ( ObjectCode* oc );
85 static int ocGetNames_PEi386    ( ObjectCode* oc );
86 static int ocResolve_PEi386     ( ObjectCode* oc );
87 #endif
88
89 /* -----------------------------------------------------------------------------
90  * Built-in symbols from the RTS
91  */
92
93 #define RTS_SYMBOLS                             \
94       SymX(MainRegTable)                        \
95       Sym(stg_gc_enter_1)                       \
96       Sym(stg_gc_noregs)                        \
97       Sym(stg_gc_seq_1)                         \
98       Sym(stg_gc_d1)                            \
99       Sym(stg_gc_f1)                            \
100       Sym(stg_gc_ut_1_0)                        \
101       Sym(stg_gc_ut_0_1)                        \
102       Sym(stg_gc_unbx_r1)                       \
103       Sym(stg_chk_0)                            \
104       Sym(stg_chk_1)                            \
105       Sym(stg_gen_chk)                          \
106       SymX(stg_exit)                            \
107       SymX(stg_update_PAP)                      \
108       SymX(stg_ap_2_upd_info)                   \
109       SymX(stg_ap_3_upd_info)                   \
110       SymX(stg_ap_4_upd_info)                   \
111       SymX(stg_ap_5_upd_info)                   \
112       SymX(stg_ap_6_upd_info)                   \
113       SymX(stg_ap_7_upd_info)                   \
114       SymX(stg_ap_8_upd_info)                   \
115       SymX(stg_sel_0_upd_info)                  \
116       SymX(stg_sel_1_upd_info)                  \
117       SymX(stg_sel_2_upd_info)                  \
118       SymX(stg_sel_3_upd_info)                  \
119       SymX(stg_sel_4_upd_info)                  \
120       SymX(stg_sel_5_upd_info)                  \
121       SymX(stg_sel_6_upd_info)                  \
122       SymX(stg_sel_7_upd_info)                  \
123       SymX(stg_sel_8_upd_info)                  \
124       SymX(stg_sel_9_upd_info)                  \
125       SymX(stg_sel_10_upd_info)                 \
126       SymX(stg_sel_11_upd_info)                 \
127       SymX(stg_sel_12_upd_info)                 \
128       SymX(stg_upd_frame_info)                  \
129       SymX(stg_seq_frame_info)                  \
130       SymX(stg_CAF_BLACKHOLE_info)              \
131       SymX(stg_IND_STATIC_info)                 \
132       SymX(stg_EMPTY_MVAR_info)                 \
133       SymX(stg_MUT_ARR_PTRS_FROZEN_info)        \
134       SymX(stg_CHARLIKE_closure)                \
135       SymX(stg_INTLIKE_closure)                 \
136       SymX(stg_CAF_UNENTERED_entry)             \
137       SymX(newCAF)                              \
138       SymX(putMVarzh_fast)                      \
139       SymX(newMVarzh_fast)                      \
140       SymX(takeMVarzh_fast)                     \
141       SymX(tryTakeMVarzh_fast)                  \
142       SymX(catchzh_fast)                        \
143       SymX(raisezh_fast)                        \
144       SymX(delayzh_fast)                        \
145       SymX(yieldzh_fast)                        \
146       SymX(killThreadzh_fast)                   \
147       SymX(waitReadzh_fast)                     \
148       SymX(waitWritezh_fast)                    \
149       SymX(suspendThread)                       \
150       SymX(resumeThread)                        \
151       SymX(stackOverflow)                       \
152       SymX(int2Integerzh_fast)                  \
153       SymX(ErrorHdrHook)                        \
154       SymX(mkForeignObjzh_fast)                 \
155       SymX(__encodeDouble)                      \
156       SymX(decodeDoublezh_fast)                 \
157       SymX(isDoubleNaN)                         \
158       SymX(isDoubleInfinite)                    \
159       SymX(isDoubleDenormalized)                \
160       SymX(isDoubleNegativeZero)                \
161       SymX(__encodeFloat)                       \
162       SymX(decodeFloatzh_fast)                  \
163       SymX(isFloatNaN)                          \
164       SymX(isFloatInfinite)                     \
165       SymX(isFloatDenormalized)                 \
166       SymX(isFloatNegativeZero)                 \
167       SymX(__int_encodeFloat)                   \
168       SymX(__int_encodeDouble)                  \
169       SymX(__gmpz_cmp_si)                       \
170       SymX(__gmpz_cmp)                          \
171       SymX(__gmpn_gcd_1)                        \
172       SymX(gcdIntegerzh_fast)                   \
173       SymX(newArrayzh_fast)                     \
174       SymX(unsafeThawArrayzh_fast)              \
175       SymX(newDoubleArrayzh_fast)               \
176       SymX(newFloatArrayzh_fast)                \
177       SymX(newAddrArrayzh_fast)                 \
178       SymX(newWordArrayzh_fast)                 \
179       SymX(newIntArrayzh_fast)                  \
180       SymX(newCharArrayzh_fast)                 \
181       SymX(newMutVarzh_fast)                    \
182       SymX(quotRemIntegerzh_fast)               \
183       SymX(quotIntegerzh_fast)                  \
184       SymX(remIntegerzh_fast)                   \
185       SymX(divExactIntegerzh_fast)              \
186       SymX(divModIntegerzh_fast)                \
187       SymX(timesIntegerzh_fast)                 \
188       SymX(minusIntegerzh_fast)                 \
189       SymX(plusIntegerzh_fast)                  \
190       SymX(mkWeakzh_fast)                       \
191       SymX(prog_argv)                           \
192       SymX(prog_argc)                           \
193       SymX(resetNonBlockingFd)                  \
194       SymX(getStablePtr)                        \
195       SymX(stable_ptr_table)                    \
196       SymX(shutdownHaskellAndExit)              \
197       Sym(stg_enterStackTop)                    \
198       Sym(stg_yield_to_Hugs)                    \
199       Sym(StgReturn)                            \
200       Sym(init_stack)                           \
201       SymX(blockAsyncExceptionszh_fast)         \
202       SymX(unblockAsyncExceptionszh_fast)       \
203       Sym(__init_PrelGHC)
204
205 /* entirely bogus claims about types of these symbols */
206 #define Sym(vvv)  extern void (vvv);
207 #define SymX(vvv) /**/
208 RTS_SYMBOLS
209 #undef Sym
210 #undef SymX
211
212 #ifdef LEADING_UNDERSCORE
213 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
214 #else
215 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
216 #endif
217
218 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
219                     (void*)(&(vvv)) },
220 #define SymX(vvv) Sym(vvv)
221
222 static SymbolVal rtsSyms[] = {
223       RTS_SYMBOLS
224       { 0, 0 } /* sentinel */
225 };
226
227 /* -----------------------------------------------------------------------------
228  * initialize the object linker
229  */
230 static void *dl_prog_handle;
231
232 void
233 initLinker( void )
234 {
235     SymbolVal *sym;
236
237     symhash = allocStrHashTable();
238
239     /* populate the symbol table with stuff from the RTS */
240     for (sym = rtsSyms; sym->lbl != NULL; sym++) {
241         insertStrHashTable(symhash, sym->lbl, sym);
242     }
243
244     dl_prog_handle = dlopen(NULL, RTLD_LAZY);
245 }
246
247 /* -----------------------------------------------------------------------------
248  * lookup a symbol in the hash table
249  */  
250 void *
251 lookupSymbol( char *lbl )
252 {
253     SymbolVal *val;
254     val = lookupStrHashTable(symhash, lbl);
255
256     if (val == NULL) {
257         return dlsym(dl_prog_handle, lbl);
258     } else {
259         return val->addr;
260     }
261 }
262
263 /* -----------------------------------------------------------------------------
264  * Load an obj (populate the global symbol table, but don't resolve yet)
265  *
266  * Returns: 1 if ok, 0 on error.
267  */
268 HsInt
269 loadObj( char *path )
270 {
271    ObjectCode* oc;
272    struct stat st;
273    int r, n;
274    FILE *f;
275
276 #ifdef DEBUG
277    /* assert that we haven't already loaded this object */
278    { 
279        ObjectCode *o;
280        for (o = objects; o; o = o->next)
281            ASSERT(strcmp(o->fileName, path));
282    }
283 #endif /* DEBUG */   
284
285    oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
286
287 #  if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
288    oc->formatName = "ELF";
289 #  elif defined(cygwin32_TARGET_OS)
290    oc->formatName = "PEi386";
291 #  else
292    free(oc);
293    barf("loadObj: not implemented on this platform");
294 #  endif
295
296    r = stat(path, &st);
297    if (r == -1) { return 0; }
298
299    oc->fileName          = path;
300    oc->fileSize          = st.st_size;
301    oc->image             = stgMallocBytes( st.st_size, "loadObj(image)" );
302    oc->symbols           = NULL;
303    oc->sections          = NULL;
304
305    /* chain it onto the list of objects */
306    oc->next              = objects;
307    objects               = oc;
308
309    /* load the image into memory */
310    f = fopen(path, "rb");
311    if (!f) {
312        barf("loadObj: can't read `%s'", path);
313    }
314    n = fread ( oc->image, 1, oc->fileSize, f );
315    if (n != oc->fileSize) {
316       fclose(f);
317       barf("loadObj: error whilst reading `%s'", path);
318    }
319
320    /* verify the in-memory image */
321 #  if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
322    r = ocVerifyImage_ELF ( oc );
323 #  elif defined(cygwin32_TARGET_OS)
324    r = ocVerifyImage_PEi386 ( oc );
325 #  else
326    barf("loadObj: no verify method");
327 #  endif
328    if (!r) { return r; }
329
330    /* build the symbol list for this image */
331 #  if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
332    r = ocGetNames_ELF ( oc );
333 #  elif defined(cygwin32_TARGET_OS)
334    r = ocGetNames_PEi386 ( oc );
335 #  else
336    barf("loadObj: no getNames method");
337 #  endif
338    if (!r) { return r; }
339
340    /* loaded, but not resolved yet */
341    oc->status = OBJECT_LOADED;
342
343    return 1;
344 }
345
346 /* -----------------------------------------------------------------------------
347  * resolve all the currently unlinked objects in memory
348  *
349  * Returns: 1 if ok, 0 on error.
350  */
351 HsInt 
352 resolveObjs( void )
353 {
354     ObjectCode *oc;
355     int r;
356
357     for (oc = objects; oc; oc = oc->next) {
358         if (oc->status != OBJECT_RESOLVED) {
359 #  if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
360             r = ocResolve_ELF ( oc );
361 #  elif defined(cygwin32_TARGET_OS)
362             r = ocResolve_PEi386 ( oc );
363 #  else
364             barf("link: not implemented on this platform");
365 #  endif
366             if (!r) { return r; }
367             oc->status = OBJECT_RESOLVED;
368         }
369     }
370     return 1;
371 }
372
373 /* -----------------------------------------------------------------------------
374  * delete an object from the pool
375  */
376 HsInt
377 unloadObj( char *path )
378 {
379     ObjectCode *oc;
380
381     for (oc = objects; oc; oc = oc->next) {
382         if (!strcmp(oc->fileName,path)) {
383
384             /* Remove all the mappings for the symbols within this
385              * object..
386              */
387             { 
388                 SymbolVal *s;
389                 for (s = oc->symbols; s < oc->symbols + oc->n_symbols; s++) {
390                     removeStrHashTable(symhash, s->lbl, NULL);
391                 }
392             }
393
394             /* We're going to leave this in place, in case there are
395                any pointers from the heap into it: */
396             /* free(oc->image); */
397             free(oc->symbols);
398             free(oc->sections);
399             free(oc);
400             return 1;
401         }
402     }
403     
404     belch("unloadObj: can't find `%s' to unload", path);
405     return 0;
406 }
407
408 /* --------------------------------------------------------------------------
409  * PEi386 specifics (cygwin32)
410  * ------------------------------------------------------------------------*/
411
412 /* The information for this linker comes from 
413       Microsoft Portable Executable 
414       and Common Object File Format Specification
415       revision 5.1 January 1998
416    which SimonM says comes from the MS Developer Network CDs.
417 */
418       
419
420 #if defined(cygwin32_TARGET_OS)
421
422
423
424 typedef unsigned char  UChar;
425 typedef unsigned short UInt16;
426 typedef unsigned int   UInt32;
427 typedef          int   Int32;
428
429
430 typedef 
431    struct {
432       UInt16 Machine;
433       UInt16 NumberOfSections;
434       UInt32 TimeDateStamp;
435       UInt32 PointerToSymbolTable;
436       UInt32 NumberOfSymbols;
437       UInt16 SizeOfOptionalHeader;
438       UInt16 Characteristics;
439    }
440    COFF_header;
441
442 #define sizeof_COFF_header 20
443
444
445 typedef 
446    struct {
447       UChar  Name[8];
448       UInt32 VirtualSize;
449       UInt32 VirtualAddress;
450       UInt32 SizeOfRawData;
451       UInt32 PointerToRawData;
452       UInt32 PointerToRelocations;
453       UInt32 PointerToLinenumbers;
454       UInt16 NumberOfRelocations;
455       UInt16 NumberOfLineNumbers;
456       UInt32 Characteristics; 
457    }
458    COFF_section;
459
460 #define sizeof_COFF_section 40
461
462
463 typedef
464    struct {
465       UChar  Name[8];
466       UInt32 Value;
467       UInt16 SectionNumber;
468       UInt16 Type;
469       UChar  StorageClass;
470       UChar  NumberOfAuxSymbols;
471    }
472    COFF_symbol;
473
474 #define sizeof_COFF_symbol 18
475
476
477 typedef
478    struct {
479       UInt32 VirtualAddress;
480       UInt32 SymbolTableIndex;
481       UInt16 Type;
482    }
483    COFF_reloc;
484
485 #define sizeof_COFF_reloc 10
486
487
488 /* From PE spec doc, section 3.3.2 */
489 #define IMAGE_FILE_RELOCS_STRIPPED     0x0001
490 #define IMAGE_FILE_EXECUTABLE_IMAGE    0x0002
491 #define IMAGE_FILE_DLL                 0x2000
492 #define IMAGE_FILE_SYSTEM              0x1000
493 #define IMAGE_FILE_BYTES_REVERSED_HI   0x8000
494 #define IMAGE_FILE_BYTES_REVERSED_LO   0x0080
495 #define IMAGE_FILE_32BIT_MACHINE       0x0100
496
497 /* From PE spec doc, section 5.4.2 and 5.4.4 */
498 #define IMAGE_SYM_CLASS_EXTERNAL       2
499 #define IMAGE_SYM_CLASS_STATIC         3
500 #define IMAGE_SYM_UNDEFINED            0
501
502 /* From PE spec doc, section 4.1 */
503 #define IMAGE_SCN_CNT_CODE             0x00000020
504 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
505
506 /* From PE spec doc, section 5.2.1 */
507 #define IMAGE_REL_I386_DIR32           0x0006
508 #define IMAGE_REL_I386_REL32           0x0014
509
510
511 /* We use myindex to calculate array addresses, rather than
512    simply doing the normal subscript thing.  That's because
513    some of the above structs have sizes which are not 
514    a whole number of words.  GCC rounds their sizes up to a
515    whole number of words, which means that the address calcs
516    arising from using normal C indexing or pointer arithmetic
517    are just plain wrong.  Sigh.
518 */
519 static UChar *
520 myindex ( int scale, int index, void* base )
521 {
522    return
523       ((UChar*)base) + scale * index;
524 }
525
526
527 static void
528 printName ( UChar* name, UChar* strtab )
529 {
530    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
531       UInt32 strtab_offset = * (UInt32*)(name+4);
532       fprintf ( stderr, "%s", strtab + strtab_offset );
533    } else {
534       int i;
535       for (i = 0; i < 8; i++) {
536          if (name[i] == 0) break;
537          fprintf ( stderr, "%c", name[i] );
538       }
539    }
540 }
541
542
543 static void
544 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
545 {
546    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
547       UInt32 strtab_offset = * (UInt32*)(name+4);
548       strncpy ( dst, strtab+strtab_offset, dstSize );
549       dst[dstSize-1] = 0;
550    } else {
551       int i = 0;
552       while (1) {
553          if (i >= 8) break;
554          if (name[i] == 0) break;
555          dst[i] = name[i];
556          i++;
557       }
558       dst[i] = 0;
559    }
560 }
561
562
563 static UChar *
564 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
565 {
566    UChar* newstr;
567    /* If the string is longer than 8 bytes, look in the
568       string table for it -- this will be correctly zero terminated. 
569    */
570    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
571       UInt32 strtab_offset = * (UInt32*)(name+4);
572       return ((UChar*)strtab) + strtab_offset;
573    }
574    /* Otherwise, if shorter than 8 bytes, return the original,
575       which by defn is correctly terminated.
576    */
577    if (name[7]==0) return name;
578    /* The annoying case: 8 bytes.  Copy into a temporary
579       (which is never freed ...)
580    */
581    newstr = malloc(9);
582    if (newstr) {
583       strncpy(newstr,name,8);
584       newstr[8] = 0;
585    }
586    return newstr;
587 }
588
589
590 /* Just compares the short names (first 8 chars) */
591 static COFF_section *
592 findPEi386SectionCalled ( ObjectCode* oc,  char* name )
593 {
594    int i;
595    COFF_header* hdr 
596       = (COFF_header*)(oc->image);
597    COFF_section* sectab 
598       = (COFF_section*) (
599            ((UChar*)(oc->image)) 
600            + sizeof_COFF_header + hdr->SizeOfOptionalHeader
601         );
602    for (i = 0; i < hdr->NumberOfSections; i++) {
603       UChar* n1;
604       UChar* n2;
605       COFF_section* section_i 
606          = (COFF_section*)
607            myindex ( sizeof_COFF_section, i, sectab );
608       n1 = (UChar*) &(section_i->Name);
609       n2 = name;
610       if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] && 
611           n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] && 
612           n1[6]==n2[6] && n1[7]==n2[7])
613          return section_i;
614    }
615
616    return NULL;
617 }
618
619
620 static void
621 zapTrailingAtSign ( UChar* sym )
622 {
623    int i, j;
624    if (sym[0] == 0) return;
625    i = 0; 
626    while (sym[i] != 0) i++;
627    i--;
628    j = i;
629    while (j > 0 && isdigit(sym[j])) j--;
630    if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
631 }
632
633
634 static int
635 ocVerifyImage_PEi386 ( ObjectCode* oc )
636 {
637    int i, j;
638    COFF_header*  hdr;
639    COFF_section* sectab;
640    COFF_symbol*  symtab;
641    UChar*        strtab;
642
643    hdr = (COFF_header*)(oc->image);
644    sectab = (COFF_section*) (
645                ((UChar*)(oc->image)) 
646                + sizeof_COFF_header + hdr->SizeOfOptionalHeader
647             );
648    symtab = (COFF_symbol*) (
649                ((UChar*)(oc->image))
650                + hdr->PointerToSymbolTable 
651             );
652    strtab = ((UChar*)(oc->image))
653             + hdr->PointerToSymbolTable
654             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
655
656    if (hdr->Machine != 0x14c) {
657       oc->errMsg("Not x86 PEi386");
658       return FALSE;
659    }
660    if (hdr->SizeOfOptionalHeader != 0) {
661       oc->errMsg("PEi386 with nonempty optional header");
662       return FALSE;
663    }
664    if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
665         (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
666         (hdr->Characteristics & IMAGE_FILE_DLL) ||
667         (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
668       oc->errMsg("Not a PEi386 object file");
669       return FALSE;
670    }
671    if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
672         !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
673       oc->errMsg("Invalid PEi386 word size or endiannness");
674       return FALSE;
675    }
676
677    if (!verb) return TRUE;
678    /* No further verification after this point; only debug printing. */
679
680    fprintf ( stderr, 
681              "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
682    fprintf ( stderr, 
683              "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
684    fprintf ( stderr, 
685              "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
686
687    fprintf ( stderr, "\n" );
688    fprintf ( stderr, 
689              "Machine:           0x%x\n", (UInt32)(hdr->Machine) );
690    fprintf ( stderr, 
691              "# sections:        %d\n",   (UInt32)(hdr->NumberOfSections) );
692    fprintf ( stderr,
693              "time/date:         0x%x\n", (UInt32)(hdr->TimeDateStamp) );
694    fprintf ( stderr,
695              "symtab offset:     %d\n",   (UInt32)(hdr->PointerToSymbolTable) );
696    fprintf ( stderr, 
697              "# symbols:         %d\n",   (UInt32)(hdr->NumberOfSymbols) );
698    fprintf ( stderr, 
699              "sz of opt hdr:     %d\n",   (UInt32)(hdr->SizeOfOptionalHeader) );
700    fprintf ( stderr,
701              "characteristics:   0x%x\n", (UInt32)(hdr->Characteristics) );
702
703    fprintf ( stderr, "\n" );
704    fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
705    fprintf ( stderr, "---START of string table---\n");
706    for (i = 4; i < *(UInt32*)strtab; i++) {
707       if (strtab[i] == 0) 
708          fprintf ( stderr, "\n"); else 
709          fprintf( stderr, "%c", strtab[i] );
710    }
711    fprintf ( stderr, "--- END  of string table---\n");
712
713    fprintf ( stderr, "\n" );
714    for (i = 0; i < hdr->NumberOfSections; i++) {
715       COFF_reloc* reltab;
716       COFF_section* sectab_i
717          = (COFF_section*)
718            myindex ( sizeof_COFF_section, i, sectab );
719       fprintf ( stderr, 
720                 "\n"
721                 "section %d\n"
722                 "     name `",
723                 i 
724               );
725       printName ( sectab_i->Name, strtab );
726       fprintf ( stderr, 
727                 "'\n"
728                 "    vsize %d\n"
729                 "    vaddr %d\n"
730                 "  data sz %d\n"
731                 " data off %d\n"
732                 "  num rel %d\n"
733                 "  off rel %d\n",
734                 sectab_i->VirtualSize,
735                 sectab_i->VirtualAddress,
736                 sectab_i->SizeOfRawData,
737                 sectab_i->PointerToRawData,
738                 sectab_i->NumberOfRelocations,
739                 sectab_i->PointerToRelocations
740               );
741       reltab = (COFF_reloc*) (
742                   ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
743                );
744       for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
745          COFF_symbol* sym;
746          COFF_reloc* rel = (COFF_reloc*)
747                            myindex ( sizeof_COFF_reloc, j, reltab );
748          fprintf ( stderr, 
749                    "        type 0x%-4x   vaddr 0x%-8x   name `",
750                    (UInt32)rel->Type, 
751                    rel->VirtualAddress );
752          sym = (COFF_symbol*)
753                myindex ( sizeof_COFF_symbol, rel->SymbolTableIndex, symtab );
754          printName ( sym->Name, strtab );
755          fprintf ( stderr, "'\n" );
756       }
757       fprintf ( stderr, "\n" );
758    }
759
760
761    fprintf ( stderr, "\n" );
762    i = 0;
763    while (1) {
764       COFF_symbol* symtab_i;
765       if (i >= hdr->NumberOfSymbols) break;
766       symtab_i = (COFF_symbol*)
767                  myindex ( sizeof_COFF_symbol, i, symtab );
768       fprintf ( stderr, 
769                 "symbol %d\n"
770                 "     name `",
771                 i 
772               );
773       printName ( symtab_i->Name, strtab );
774       fprintf ( stderr, 
775                 "'\n"
776                 "    value 0x%x\n"
777                 "     sec# %d\n"
778                 "     type 0x%x\n"
779                 "   sclass 0x%x\n"
780                 "     nAux %d\n",
781                 symtab_i->Value,
782                 (Int32)(symtab_i->SectionNumber) - 1,
783                 (UInt32)symtab_i->Type,
784                 (UInt32)symtab_i->StorageClass,
785                 (UInt32)symtab_i->NumberOfAuxSymbols 
786               );
787       i += symtab_i->NumberOfAuxSymbols;
788       i++;
789    }
790
791    fprintf ( stderr, "\n" );
792
793    return TRUE;
794 }
795
796
797 static int
798 ocGetNames_PEi386 ( ObjectCode* oc )
799 {
800    COFF_header*  hdr;
801    COFF_section* sectab;
802    COFF_symbol*  symtab;
803    UChar*        strtab;
804
805    UChar* sname;
806    void*  addr;
807    int    i;
808    
809    hdr = (COFF_header*)(oc->image);
810    sectab = (COFF_section*) (
811                ((UChar*)(oc->image)) 
812                + sizeof_COFF_header + hdr->SizeOfOptionalHeader
813             );
814    symtab = (COFF_symbol*) (
815                ((UChar*)(oc->image))
816                + hdr->PointerToSymbolTable 
817             );
818    strtab = ((UChar*)(oc->image))
819             + hdr->PointerToSymbolTable
820             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
821
822    /* Copy exported symbols into the ObjectCode. */
823    i = 0;
824    while (1) {
825       COFF_symbol* symtab_i;
826       if (i >= hdr->NumberOfSymbols) break;
827       symtab_i = (COFF_symbol*)
828                  myindex ( sizeof_COFF_symbol, i, symtab );
829
830       if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
831           symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
832
833          /* This symbol is global and defined, viz, exported */
834          COFF_section* sectabent;
835
836          sname = cstring_from_COFF_symbol_name ( 
837                     symtab_i->Name, strtab 
838                  );
839          if (!sname) {
840             oc->errMsg("Out of memory when copying PEi386 symbol");
841             return FALSE;
842          }
843
844          /* for IMAGE_SYMCLASS_EXTERNAL 
845                 && !IMAGE_SYM_UNDEFINED,
846             the address of the symbol is: 
847                 address of relevant section + offset in section
848          */
849          sectabent = (COFF_section*)
850                      myindex ( sizeof_COFF_section, 
851                                symtab_i->SectionNumber-1,
852                                sectab );
853          addr = ((UChar*)(oc->image))
854                 + (sectabent->PointerToRawData
855                    + symtab_i->Value);
856          /* fprintf ( stderr, "addSymbol %p `%s'\n", addr,sname); */
857          if (!addSymbol(oc,sname,addr)) return FALSE;
858       }
859       i += symtab_i->NumberOfAuxSymbols;
860       i++;
861    }
862
863    oc->sections = stgMallocBytes( NumberOfSections * sizeof(Section), 
864                                     "ocGetNamesPEi386" );
865
866    /* Copy section information into the ObjectCode. */
867    for (i = 0; i < hdr->NumberOfSections; i++) {
868       UChar* start;
869       UChar* end;
870
871       SectionKind kind 
872          = SECTIONKIND_OTHER;
873       COFF_section* sectab_i
874          = (COFF_section*)
875            myindex ( sizeof_COFF_section, i, sectab );
876       /* fprintf ( stderr, "section name = %s\n", sectab_i->Name ); */
877
878 #if 0
879       /* I'm sure this is the Right Way to do it.  However, the 
880          alternative of testing the sectab_i->Name field seems to
881          work ok with Cygwin.
882       */
883       if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE || 
884           sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
885          kind = SECTIONKIND_CODE_OR_RODATA;
886 #endif
887
888       if (0==strcmp(".text",sectab_i->Name))
889          kind = SECTIONKIND_CODE_OR_RODATA;
890       if (0==strcmp(".data",sectab_i->Name) ||
891           0==strcmp(".bss",sectab_i->Name))
892          kind = SECTIONKIND_RWDATA;
893
894       start = ((UChar*)(oc->image)) 
895               + sectab_i->PointerToRawData;
896       end   = start 
897               + sectab_i->SizeOfRawData - 1;
898
899       if (kind != SECTIONKIND_OTHER) {
900          addSection ( oc, start, end, kind );
901       } else {
902          fprintf ( stderr, "unknown section name = `%s'\n", 
903                    sectab_i->Name);
904          oc->errMsg("Unknown PEi386 section name");
905          return FALSE;
906       }
907    }
908
909    return TRUE;   
910 }
911
912
913 static int
914 ocResolve_PEi386 ( ObjectCode* oc, int verb )
915 {
916    COFF_header*  hdr;
917    COFF_section* sectab;
918    COFF_symbol*  symtab;
919    UChar*        strtab;
920
921    UInt32        A;
922    UInt32        S;
923    UInt32*       pP;
924
925    int i, j;
926    char symbol[1000]; // ToDo
927    
928    hdr = (COFF_header*)(oc->image);
929    sectab = (COFF_section*) (
930                ((UChar*)(oc->image)) 
931                + sizeof_COFF_header + hdr->SizeOfOptionalHeader
932             );
933    symtab = (COFF_symbol*) (
934                ((UChar*)(oc->image))
935                + hdr->PointerToSymbolTable 
936             );
937    strtab = ((UChar*)(oc->image))
938             + hdr->PointerToSymbolTable
939             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
940
941    for (i = 0; i < hdr->NumberOfSections; i++) {
942       COFF_section* sectab_i
943          = (COFF_section*)
944            myindex ( sizeof_COFF_section, i, sectab );
945       COFF_reloc* reltab
946          = (COFF_reloc*) (
947               ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
948            );
949       for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
950          COFF_symbol* sym;
951          COFF_reloc* reltab_j 
952             = (COFF_reloc*)
953               myindex ( sizeof_COFF_reloc, j, reltab );
954
955          /* the location to patch */
956          pP = (UInt32*)(
957                  ((UChar*)(oc->image)) 
958                  + (sectab_i->PointerToRawData 
959                     + reltab_j->VirtualAddress)
960               );
961          /* the existing contents of pP */
962          A = *pP;
963          /* the symbol to connect to */
964          sym = (COFF_symbol*)
965                myindex ( sizeof_COFF_symbol, 
966                          reltab_j->SymbolTableIndex, symtab );
967          if (verb) {
968             fprintf ( stderr, 
969                    "reloc sec %2d num %3d:  type 0x%-4x   "
970                    "vaddr 0x%-8x   name `",
971                    i, j,
972                    (UInt32)reltab_j->Type, 
973                    reltab_j->VirtualAddress );
974             printName ( sym->Name, strtab );
975             fprintf ( stderr, "'\n" );
976          }
977
978          if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
979             COFF_section* section_sym 
980                = findPEi386SectionCalled ( oc, sym->Name );
981             if (!section_sym) {
982                fprintf ( stderr, "bad section = `%s'\n", sym->Name );
983                oc->errMsg("Can't find abovementioned PEi386 section");
984                return FALSE;
985             }
986             S = ((UInt32)(oc->image))
987                 + (section_sym->PointerToRawData
988                    + sym->Value);
989          } else {
990          copyName ( sym->Name, strtab, symbol, 1000 );
991          zapTrailingAtSign ( symbol );
992          S = (UInt32) ocLookupSym ( oc, symbol );
993          if (S == 0) 
994             S = (UInt32)(oc->clientLookup ( symbol ));
995          if (S == 0) {
996              belch("%s: unresolvable reference to `%s'", oc->fileName, symbol);
997              return FALSE;
998          }
999          }
1000
1001          switch (reltab_j->Type) {
1002             case IMAGE_REL_I386_DIR32: 
1003                *pP = A + S; 
1004                break;
1005             case IMAGE_REL_I386_REL32:
1006                /* Tricky.  We have to insert a displacement at
1007                   pP which, when added to the PC for the _next_
1008                   insn, gives the address of the target (S).
1009                   Problem is to know the address of the next insn
1010                   when we only know pP.  We assume that this
1011                   literal field is always the last in the insn,
1012                   so that the address of the next insn is pP+4
1013                   -- hence the constant 4.
1014                   Also I don't know if A should be added, but so
1015                   far it has always been zero.
1016                */
1017                ASSERT(A==0);
1018                *pP = S - ((UInt32)pP) - 4;
1019                break;
1020             default: 
1021                fprintf(stderr, 
1022                        "unhandled PEi386 relocation type %d\n",
1023                        reltab_j->Type);
1024                oc->errMsg("unhandled PEi386 relocation type");
1025                return FALSE;
1026          }
1027
1028       }
1029    }
1030    
1031    return TRUE;
1032 }
1033
1034 #endif /* defined(cygwin32_TARGET_OS) */
1035
1036
1037 /* --------------------------------------------------------------------------
1038  * ELF specifics (Linux, Solaris)
1039  * ------------------------------------------------------------------------*/
1040
1041 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS)
1042
1043 #define FALSE 0
1044 #define TRUE  1
1045
1046 #include <elf.h>
1047
1048 static char *
1049 findElfSection ( void* objImage, Elf32_Word sh_type )
1050 {
1051    int i;
1052    char* ehdrC = (char*)objImage;
1053    Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1054    Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1055    char* ptr = NULL;
1056    for (i = 0; i < ehdr->e_shnum; i++) {
1057       if (shdr[i].sh_type == sh_type &&
1058           i !=  ehdr->e_shstrndx) {
1059          ptr = ehdrC + shdr[i].sh_offset;
1060          break;
1061       }
1062    }
1063    return ptr;
1064 }
1065
1066
1067 static int
1068 ocVerifyImage_ELF ( ObjectCode* oc )
1069 {
1070    Elf32_Shdr* shdr;
1071    Elf32_Sym*  stab;
1072    int i, j, nent, nstrtab, nsymtabs;
1073    char* sh_strtab;
1074    char* strtab;
1075
1076    char*       ehdrC = (char*)(oc->image);
1077    Elf32_Ehdr* ehdr  = ( Elf32_Ehdr*)ehdrC;
1078
1079    if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1080        ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1081        ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1082        ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1083       belch("ocVerifyImage_ELF: not an ELF header");
1084       return 0;
1085    }
1086    IF_DEBUG(linker,belch( "Is an ELF header" ));
1087
1088    if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1089       belch("ocVerifyImage_ELF: not 32 bit ELF" );
1090       return 0;
1091    }
1092
1093    IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1094
1095    if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1096        IF_DEBUG(linker,belch( "Is little-endian" ));
1097    } else
1098    if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1099        IF_DEBUG(linker,belch( "Is big-endian" ));
1100    } else {
1101        belch("ocVerifyImage_ELF: unknown endiannness");
1102        return 0;
1103    }
1104
1105    if (ehdr->e_type != ET_REL) {
1106       belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1107       return 0;
1108    }
1109    IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1110
1111    IF_DEBUG(linker,belch( "Architecture is " ));
1112    switch (ehdr->e_machine) {
1113       case EM_386:   IF_DEBUG(linker,belch( "x86" )); break;
1114       case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1115       default:       IF_DEBUG(linker,belch( "unknown" )); 
1116                      belch("ocVerifyImage_ELF: unknown architecture");
1117                      return 0;
1118    }
1119
1120    IF_DEBUG(linker,belch(
1121              "\nSection header table: start %d, n_entries %d, ent_size %d", 
1122              ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize  ));
1123
1124    ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1125
1126    shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1127
1128    if (ehdr->e_shstrndx == SHN_UNDEF) {
1129       belch("ocVerifyImage_ELF: no section header string table");
1130       return 0;
1131    } else {
1132       IF_DEBUG(linker,belch( "Section header string table is section %d", 
1133                           ehdr->e_shstrndx));
1134       sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1135    }
1136
1137    for (i = 0; i < ehdr->e_shnum; i++) {
1138       IF_DEBUG(linker,fprintf(stderr, "%2d:  ", i ));
1139       IF_DEBUG(linker,fprintf(stderr, "type=%2d  ", shdr[i].sh_type ));
1140       IF_DEBUG(linker,fprintf(stderr, "size=%4d  ", shdr[i].sh_size ));
1141       IF_DEBUG(linker,fprintf(stderr, "offs=%4d  ", shdr[i].sh_offset ));
1142       IF_DEBUG(linker,fprintf(stderr, "  (%p .. %p)  ",
1143                ehdrC + shdr[i].sh_offset, 
1144                       ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1145
1146       if (shdr[i].sh_type == SHT_REL) {
1147           IF_DEBUG(linker,fprintf(stderr, "Rel  " ));
1148       } else if (shdr[i].sh_type == SHT_RELA) {
1149           IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1150       } else {
1151           IF_DEBUG(linker,fprintf(stderr,"     "));
1152       }
1153       if (sh_strtab) {
1154           IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1155       }
1156    }
1157
1158    IF_DEBUG(linker,belch( "\nString tables" ));
1159    strtab = NULL;
1160    nstrtab = 0;
1161    for (i = 0; i < ehdr->e_shnum; i++) {
1162       if (shdr[i].sh_type == SHT_STRTAB &&
1163           i !=  ehdr->e_shstrndx) {
1164           IF_DEBUG(linker,belch("   section %d is a normal string table", i ));
1165          strtab = ehdrC + shdr[i].sh_offset;
1166          nstrtab++;
1167       }
1168    }  
1169    if (nstrtab != 1) {
1170       belch("ocVerifyImage_ELF: no string tables, or too many");
1171       return 0;
1172    }
1173
1174    nsymtabs = 0;
1175    IF_DEBUG(linker,belch( "\nSymbol tables" )); 
1176    for (i = 0; i < ehdr->e_shnum; i++) {
1177       if (shdr[i].sh_type != SHT_SYMTAB) continue;
1178       IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1179       nsymtabs++;
1180       stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1181       nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1182       IF_DEBUG(linker,belch( "   number of entries is apparently %d (%d rem)",
1183                nent,
1184                shdr[i].sh_size % sizeof(Elf32_Sym)
1185              ));
1186       if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1187          belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1188          return 0;
1189       }
1190       for (j = 0; j < nent; j++) {
1191          IF_DEBUG(linker,fprintf(stderr, "   %2d  ", j ));
1192          IF_DEBUG(linker,fprintf(stderr, "  sec=%-5d  size=%-3d  val=%5p  ", 
1193                              (int)stab[j].st_shndx,
1194                              (int)stab[j].st_size,
1195                              (char*)stab[j].st_value ));
1196
1197          IF_DEBUG(linker,fprintf(stderr, "type=" ));
1198          switch (ELF32_ST_TYPE(stab[j].st_info)) {
1199             case STT_NOTYPE:  IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1200             case STT_OBJECT:  IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1201             case STT_FUNC  :  IF_DEBUG(linker,fprintf(stderr, "func   " )); break;
1202             case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1203             case STT_FILE:    IF_DEBUG(linker,fprintf(stderr, "file   " )); break;
1204             default:          IF_DEBUG(linker,fprintf(stderr, "?      " )); break;
1205          }
1206          IF_DEBUG(linker,fprintf(stderr, "  " ));
1207
1208          IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1209          switch (ELF32_ST_BIND(stab[j].st_info)) {
1210             case STB_LOCAL :  IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1211             case STB_GLOBAL:  IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1212             case STB_WEAK  :  IF_DEBUG(linker,fprintf(stderr, "weak  " )); break;
1213             default:          IF_DEBUG(linker,fprintf(stderr, "?     " )); break;
1214          }
1215          IF_DEBUG(linker,fprintf(stderr, "  " ));
1216
1217          IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1218       }
1219    }
1220
1221    if (nsymtabs == 0) {
1222       belch("ocVerifyImage_ELF: didn't find any symbol tables");
1223       return 0;
1224    }
1225
1226    return 1;
1227 }
1228
1229
1230 static int
1231 ocGetNames_ELF ( ObjectCode* oc )
1232 {
1233    int i, j, k, nent;
1234    Elf32_Sym* stab;
1235
1236    char*       ehdrC      = (char*)(oc->image);
1237    Elf32_Ehdr* ehdr       = (Elf32_Ehdr*)ehdrC;
1238    char*       strtab     = findElfSection ( ehdrC, SHT_STRTAB );
1239    Elf32_Shdr* shdr       = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1240    char*       sh_strtab  = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1241
1242    if (!strtab) {
1243       belch("ocGetNames_ELF: no strtab");
1244       return 0;
1245    }
1246
1247    k = 0;
1248    oc->sections = stgMallocBytes( ehdr->e_shnum * sizeof(Section), 
1249                                     "ocGetNames_ELF" );
1250    oc->n_sections = ehdr->e_shnum;
1251
1252    for (i = 0; i < ehdr->e_shnum; i++) {
1253
1254       /* make a section entry for relevant sections */
1255       SectionKind kind = SECTIONKIND_OTHER;
1256       if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1257           !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1258           kind = SECTIONKIND_RWDATA;
1259       if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1260           !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1261           !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1262           kind = SECTIONKIND_CODE_OR_RODATA;
1263
1264       /* fill in the section info */
1265       oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1266       oc->sections[i].end   = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1267       oc->sections[i].kind  = kind;
1268       
1269       if (shdr[i].sh_type != SHT_SYMTAB) continue;
1270
1271       /* copy stuff into this module's object symbol table */
1272       stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1273       nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1274       oc->symbols = malloc(nent * sizeof(SymbolVal));
1275       for (j = 0; j < nent; j++) {
1276          if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL /* ||
1277                 ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL */
1278               )
1279               /* and not an undefined symbol */
1280               && stab[j].st_shndx != SHN_UNDEF
1281               &&
1282               /* and it's a not a section or string table or anything silly */
1283               ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1284                 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1285                 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE )
1286                 ) { 
1287             char* nm = strtab + stab[j].st_name;
1288             char* ad = ehdrC 
1289                        + shdr[ stab[j].st_shndx ].sh_offset
1290                        + stab[j].st_value;
1291             ASSERT(nm != NULL);
1292             ASSERT(ad != NULL);
1293             IF_DEBUG(linker,belch( "addOTabName: %10p  %s %s",
1294                        ad, oc->fileName, nm ));
1295             oc->symbols[j].lbl  = nm;
1296             oc->symbols[j].addr = ad;
1297             insertStrHashTable(symhash, nm, &(oc->symbols[j]));
1298          }
1299          else {
1300              IF_DEBUG(linker,belch( "skipping `%s'", strtab +
1301                              stab[j].st_name ));
1302              oc->symbols[j].lbl  = NULL;
1303              oc->symbols[j].addr = NULL;
1304          }
1305       }
1306    }
1307
1308    return 1;
1309 }
1310
1311
1312 static int
1313 ocResolve_ELF ( ObjectCode* oc )
1314 {
1315    char *strtab, *symbol;
1316    int   i, j;
1317    Elf32_Sym*  stab = NULL;
1318    char*       ehdrC = (char*)(oc->image);
1319    Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1320    Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1321    Elf32_Word* targ;
1322
1323    /* first find "the" symbol table */
1324    stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1325
1326    /* also go find the string table */
1327    strtab = findElfSection ( ehdrC, SHT_STRTAB );
1328
1329    if (stab == NULL || strtab == NULL) {
1330       belch("ocResolve_ELF: can't find string or symbol table");
1331       return 0; 
1332    }
1333
1334    for (i = 0; i < ehdr->e_shnum; i++) {
1335       if (shdr[i].sh_type == SHT_REL ) {
1336          Elf32_Rel*  rtab = (Elf32_Rel*) (ehdrC + shdr[i].sh_offset);
1337          int         nent = shdr[i].sh_size / sizeof(Elf32_Rel);
1338          int target_shndx = shdr[i].sh_info;
1339          int symtab_shndx = shdr[i].sh_link;
1340          stab  = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1341          targ  = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1342          IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1343                          target_shndx, symtab_shndx ));
1344          for (j = 0; j < nent; j++) {
1345             Elf32_Addr offset = rtab[j].r_offset;
1346             Elf32_Word info   = rtab[j].r_info;
1347
1348             Elf32_Addr  P = ((Elf32_Addr)targ) + offset;
1349             Elf32_Word* pP = (Elf32_Word*)P;
1350             Elf32_Addr  A = *pP;
1351             Elf32_Addr  S;
1352
1353             IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)   ", 
1354                                 j, (void*)offset, (void*)info ));
1355             if (!info) {
1356                IF_DEBUG(linker,belch( " ZERO" ));
1357                S = 0;
1358             } else {
1359                /* First see if it is a nameless local symbol. */
1360                if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1361                    symbol = "(noname)";
1362                    S = (Elf32_Addr)(ehdrC
1363                                     + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1364                                     + stab[ELF32_R_SYM(info)].st_value
1365                        );
1366                } else {
1367                    /* No?  Should be in the symbol table then. */
1368                    symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1369                    (void *)S = lookupSymbol( symbol );
1370                }
1371                if (!S) {
1372                    barf("ocResolve_ELF: %s: unknown symbol `%s'",
1373                         oc->fileName, symbol);
1374                }
1375                IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1376             }
1377             IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p   S = %p   A = %p\n", (void*)P, (void*)S, (void*)A )); 
1378             switch (ELF32_R_TYPE(info)) {
1379                case R_386_32:   *pP = S + A;     break;
1380                case R_386_PC32: *pP = S + A - P; break;
1381                default: fprintf(stderr, 
1382                                 "unhandled ELF relocation type %d",
1383                                 ELF32_R_TYPE(info));
1384                         belch("ocResolve_ELF: unhandled ELF relocation type");
1385                         return 0;
1386             }
1387
1388          }
1389       }
1390       else
1391       if (shdr[i].sh_type == SHT_RELA) {
1392          belch("ocResolve_ELF: RelA style reloc table -- not yet done");
1393          return 0;
1394       }
1395    }
1396
1397    return 1;
1398 }
1399
1400
1401 #endif /* defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) */
1402
1403 /* -----------------------------------------------------------------------------
1404  * Look up an address to discover whether it is in text or data space.
1405  *
1406  * Used by the garbage collector when walking the stack.
1407  * -------------------------------------------------------------------------- */
1408
1409 SectionKind
1410 lookupSection ( void* addr )
1411 {
1412    int          i;
1413    ObjectCode*  oc;
1414    
1415    for ( oc = objects; oc; oc = oc->next ) {
1416        for (i = 0; i < oc->n_sections; i++) {
1417            if (oc->sections[i].start <= addr 
1418                && addr <= oc->sections[i].end)
1419                return oc->sections[i].kind;
1420        }
1421    }
1422    return SECTIONKIND_OTHER;
1423 }
1424
1425 int
1426 is_dynamically_loaded_code_or_rodata_ptr ( char* p )
1427 {
1428    SectionKind sk = lookupSection(p);
1429    assert (sk != SECTIONKIND_NOINFOAVAIL);
1430    return (sk == SECTIONKIND_CODE_OR_RODATA);
1431 }
1432
1433
1434 int
1435 is_dynamically_loaded_rwdata_ptr ( char* p )
1436 {
1437    SectionKind sk = lookupSection(p);
1438    assert (sk != SECTIONKIND_NOINFOAVAIL);
1439    return (sk == SECTIONKIND_RWDATA);
1440 }
1441
1442
1443 int
1444 is_not_dynamically_loaded_ptr ( char* p )
1445 {
1446    SectionKind sk = lookupSection(p);
1447    assert (sk != SECTIONKIND_NOINFOAVAIL);
1448    return (sk == SECTIONKIND_OTHER);
1449 }
1450