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