[project @ 2001-02-12 12:22:01 by simonmar]
[ghc-hetmet.git] / ghc / rts / Linker.c
1 /* -----------------------------------------------------------------------------
2  * $Id: Linker.c,v 1.23 2001/02/12 12:22:01 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 "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 /* -----------------------------------------------------------------------------
299  * Load an obj (populate the global symbol table, but don't resolve yet)
300  *
301  * Returns: 1 if ok, 0 on error.
302  */
303 HsInt
304 loadObj( char *path )
305 {
306    ObjectCode* oc;
307    struct stat st;
308    int r, n;
309    FILE *f;
310
311 #ifdef DEBUG
312    /* assert that we haven't already loaded this object */
313    { 
314        ObjectCode *o;
315        for (o = objects; o; o = o->next)
316            ASSERT(strcmp(o->fileName, path));
317    }
318 #endif /* DEBUG */   
319
320    oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
321
322 #  if defined(OBJFORMAT_ELF)
323    oc->formatName = "ELF";
324 #  elif defined(OBJFORMAT_PEi386)
325    oc->formatName = "PEi386";
326 #  else
327    free(oc);
328    barf("loadObj: not implemented on this platform");
329 #  endif
330
331    r = stat(path, &st);
332    if (r == -1) { return 0; }
333
334    /* sigh, stdup() isn't a POSIX function, so do it the long way */
335    oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
336    strcpy(oc->fileName, path);
337
338    oc->fileSize          = st.st_size;
339    oc->image             = stgMallocBytes( st.st_size, "loadObj(image)" );
340    oc->symbols           = NULL;
341    oc->sections          = NULL;
342
343    /* chain it onto the list of objects */
344    oc->next              = objects;
345    objects               = oc;
346
347    /* load the image into memory */
348    f = fopen(path, "rb");
349    if (!f) {
350        barf("loadObj: can't read `%s'", path);
351    }
352    n = fread ( oc->image, 1, oc->fileSize, f );
353    if (n != oc->fileSize) {
354       fclose(f);
355       barf("loadObj: error whilst reading `%s'", path);
356    }
357
358    /* verify the in-memory image */
359 #  if defined(OBJFORMAT_ELF)
360    r = ocVerifyImage_ELF ( oc );
361 #  elif defined(OBJFORMAT_PEi386)
362    r = ocVerifyImage_PEi386 ( oc );
363 #  else
364    barf("loadObj: no verify method");
365 #  endif
366    if (!r) { return r; }
367
368    /* build the symbol list for this image */
369 #  if defined(OBJFORMAT_ELF)
370    r = ocGetNames_ELF ( oc );
371 #  elif defined(OBJFORMAT_PEi386)
372    r = ocGetNames_PEi386 ( oc );
373 #  else
374    barf("loadObj: no getNames method");
375 #  endif
376    if (!r) { return r; }
377
378    /* loaded, but not resolved yet */
379    oc->status = OBJECT_LOADED;
380
381    return 1;
382 }
383
384 /* -----------------------------------------------------------------------------
385  * resolve all the currently unlinked objects in memory
386  *
387  * Returns: 1 if ok, 0 on error.
388  */
389 HsInt 
390 resolveObjs( void )
391 {
392     ObjectCode *oc;
393     int r;
394
395     for (oc = objects; oc; oc = oc->next) {
396         if (oc->status != OBJECT_RESOLVED) {
397 #  if defined(OBJFORMAT_ELF)
398             r = ocResolve_ELF ( oc );
399 #  elif defined(OBJFORMAT_PEi386)
400             r = ocResolve_PEi386 ( oc );
401 #  else
402             barf("link: not implemented on this platform");
403 #  endif
404             if (!r) { return r; }
405             oc->status = OBJECT_RESOLVED;
406         }
407     }
408     return 1;
409 }
410
411 /* -----------------------------------------------------------------------------
412  * delete an object from the pool
413  */
414 HsInt
415 unloadObj( char *path )
416 {
417     ObjectCode *oc, *prev;
418
419     ASSERT(symhash != NULL);
420     ASSERT(objects != NULL);
421
422     prev = NULL;
423     for (oc = objects; oc; prev = oc, oc = oc->next) {
424         if (!strcmp(oc->fileName,path)) {
425
426             /* Remove all the mappings for the symbols within this
427              * object..
428              */
429             { 
430                 SymbolVal *s;
431                 for (s = oc->symbols; s < oc->symbols + oc->n_symbols; s++) {
432                     if (s->lbl != NULL) {
433                         removeStrHashTable(symhash, s->lbl, NULL);
434                     }
435                 }
436             }
437
438             if (prev == NULL) {
439                 objects = oc->next;
440             } else {
441                 prev->next = oc->next;
442             }
443
444             /* We're going to leave this in place, in case there are
445                any pointers from the heap into it: */
446             /* free(oc->image); */
447             free(oc->fileName);
448             free(oc->symbols);
449             free(oc->sections);
450             free(oc);
451             return 1;
452         }
453     }
454
455     belch("unloadObj: can't find `%s' to unload", path);
456     return 0;
457 }
458
459 /* --------------------------------------------------------------------------
460  * PEi386 specifics (Win32 targets)
461  * ------------------------------------------------------------------------*/
462
463 /* The information for this linker comes from 
464       Microsoft Portable Executable 
465       and Common Object File Format Specification
466       revision 5.1 January 1998
467    which SimonM says comes from the MS Developer Network CDs.
468 */
469       
470
471 #if defined(OBJFORMAT_PEi386)
472
473
474
475 typedef unsigned char  UChar;
476 typedef unsigned short UInt16;
477 typedef unsigned int   UInt32;
478 typedef          int   Int32;
479
480
481 typedef 
482    struct {
483       UInt16 Machine;
484       UInt16 NumberOfSections;
485       UInt32 TimeDateStamp;
486       UInt32 PointerToSymbolTable;
487       UInt32 NumberOfSymbols;
488       UInt16 SizeOfOptionalHeader;
489       UInt16 Characteristics;
490    }
491    COFF_header;
492
493 #define sizeof_COFF_header 20
494
495
496 typedef 
497    struct {
498       UChar  Name[8];
499       UInt32 VirtualSize;
500       UInt32 VirtualAddress;
501       UInt32 SizeOfRawData;
502       UInt32 PointerToRawData;
503       UInt32 PointerToRelocations;
504       UInt32 PointerToLinenumbers;
505       UInt16 NumberOfRelocations;
506       UInt16 NumberOfLineNumbers;
507       UInt32 Characteristics; 
508    }
509    COFF_section;
510
511 #define sizeof_COFF_section 40
512
513
514 typedef
515    struct {
516       UChar  Name[8];
517       UInt32 Value;
518       UInt16 SectionNumber;
519       UInt16 Type;
520       UChar  StorageClass;
521       UChar  NumberOfAuxSymbols;
522    }
523    COFF_symbol;
524
525 #define sizeof_COFF_symbol 18
526
527
528 typedef
529    struct {
530       UInt32 VirtualAddress;
531       UInt32 SymbolTableIndex;
532       UInt16 Type;
533    }
534    COFF_reloc;
535
536 #define sizeof_COFF_reloc 10
537
538
539 /* From PE spec doc, section 3.3.2 */
540 #define IMAGE_FILE_RELOCS_STRIPPED     0x0001
541 #define IMAGE_FILE_EXECUTABLE_IMAGE    0x0002
542 #define IMAGE_FILE_DLL                 0x2000
543 #define IMAGE_FILE_SYSTEM              0x1000
544 #define IMAGE_FILE_BYTES_REVERSED_HI   0x8000
545 #define IMAGE_FILE_BYTES_REVERSED_LO   0x0080
546 #define IMAGE_FILE_32BIT_MACHINE       0x0100
547
548 /* From PE spec doc, section 5.4.2 and 5.4.4 */
549 #define IMAGE_SYM_CLASS_EXTERNAL       2
550 #define IMAGE_SYM_CLASS_STATIC         3
551 #define IMAGE_SYM_UNDEFINED            0
552
553 /* From PE spec doc, section 4.1 */
554 #define IMAGE_SCN_CNT_CODE             0x00000020
555 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
556
557 /* From PE spec doc, section 5.2.1 */
558 #define IMAGE_REL_I386_DIR32           0x0006
559 #define IMAGE_REL_I386_REL32           0x0014
560
561
562 /* We use myindex to calculate array addresses, rather than
563    simply doing the normal subscript thing.  That's because
564    some of the above structs have sizes which are not 
565    a whole number of words.  GCC rounds their sizes up to a
566    whole number of words, which means that the address calcs
567    arising from using normal C indexing or pointer arithmetic
568    are just plain wrong.  Sigh.
569 */
570 static UChar *
571 myindex ( int scale, int index, void* base )
572 {
573    return
574       ((UChar*)base) + scale * index;
575 }
576
577
578 static void
579 printName ( UChar* name, UChar* strtab )
580 {
581    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
582       UInt32 strtab_offset = * (UInt32*)(name+4);
583       fprintf ( stderr, "%s", strtab + strtab_offset );
584    } else {
585       int i;
586       for (i = 0; i < 8; i++) {
587          if (name[i] == 0) break;
588          fprintf ( stderr, "%c", name[i] );
589       }
590    }
591 }
592
593
594 static void
595 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
596 {
597    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
598       UInt32 strtab_offset = * (UInt32*)(name+4);
599       strncpy ( dst, strtab+strtab_offset, dstSize );
600       dst[dstSize-1] = 0;
601    } else {
602       int i = 0;
603       while (1) {
604          if (i >= 8) break;
605          if (name[i] == 0) break;
606          dst[i] = name[i];
607          i++;
608       }
609       dst[i] = 0;
610    }
611 }
612
613
614 static UChar *
615 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
616 {
617    UChar* newstr;
618    /* If the string is longer than 8 bytes, look in the
619       string table for it -- this will be correctly zero terminated. 
620    */
621    if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
622       UInt32 strtab_offset = * (UInt32*)(name+4);
623       return ((UChar*)strtab) + strtab_offset;
624    }
625    /* Otherwise, if shorter than 8 bytes, return the original,
626       which by defn is correctly terminated.
627    */
628    if (name[7]==0) return name;
629    /* The annoying case: 8 bytes.  Copy into a temporary
630       (which is never freed ...)
631    */
632    newstr = malloc(9);
633    if (newstr) {
634       strncpy(newstr,name,8);
635       newstr[8] = 0;
636    }
637    return newstr;
638 }
639
640
641 /* Just compares the short names (first 8 chars) */
642 static COFF_section *
643 findPEi386SectionCalled ( ObjectCode* oc,  char* name )
644 {
645    int i;
646    COFF_header* hdr 
647       = (COFF_header*)(oc->image);
648    COFF_section* sectab 
649       = (COFF_section*) (
650            ((UChar*)(oc->image)) 
651            + sizeof_COFF_header + hdr->SizeOfOptionalHeader
652         );
653    for (i = 0; i < hdr->NumberOfSections; i++) {
654       UChar* n1;
655       UChar* n2;
656       COFF_section* section_i 
657          = (COFF_section*)
658            myindex ( sizeof_COFF_section, i, sectab );
659       n1 = (UChar*) &(section_i->Name);
660       n2 = name;
661       if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] && 
662           n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] && 
663           n1[6]==n2[6] && n1[7]==n2[7])
664          return section_i;
665    }
666
667    return NULL;
668 }
669
670
671 static void
672 zapTrailingAtSign ( UChar* sym )
673 {
674    int i, j;
675    if (sym[0] == 0) return;
676    i = 0; 
677    while (sym[i] != 0) i++;
678    i--;
679    j = i;
680    while (j > 0 && isdigit(sym[j])) j--;
681    if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
682 }
683
684
685 static int
686 ocVerifyImage_PEi386 ( ObjectCode* oc )
687 {
688    int i, j;
689    COFF_header*  hdr;
690    COFF_section* sectab;
691    COFF_symbol*  symtab;
692    UChar*        strtab;
693
694    hdr = (COFF_header*)(oc->image);
695    sectab = (COFF_section*) (
696                ((UChar*)(oc->image)) 
697                + sizeof_COFF_header + hdr->SizeOfOptionalHeader
698             );
699    symtab = (COFF_symbol*) (
700                ((UChar*)(oc->image))
701                + hdr->PointerToSymbolTable 
702             );
703    strtab = ((UChar*)(oc->image))
704             + hdr->PointerToSymbolTable
705             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
706
707    if (hdr->Machine != 0x14c) {
708       oc->errMsg("Not x86 PEi386");
709       return FALSE;
710    }
711    if (hdr->SizeOfOptionalHeader != 0) {
712       oc->errMsg("PEi386 with nonempty optional header");
713       return FALSE;
714    }
715    if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
716         (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
717         (hdr->Characteristics & IMAGE_FILE_DLL) ||
718         (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
719       oc->errMsg("Not a PEi386 object file");
720       return FALSE;
721    }
722    if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
723         !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
724       oc->errMsg("Invalid PEi386 word size or endiannness");
725       return FALSE;
726    }
727
728    if (!verb) return TRUE;
729    /* No further verification after this point; only debug printing. */
730
731    fprintf ( stderr, 
732              "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
733    fprintf ( stderr, 
734              "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
735    fprintf ( stderr, 
736              "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
737
738    fprintf ( stderr, "\n" );
739    fprintf ( stderr, 
740              "Machine:           0x%x\n", (UInt32)(hdr->Machine) );
741    fprintf ( stderr, 
742              "# sections:        %d\n",   (UInt32)(hdr->NumberOfSections) );
743    fprintf ( stderr,
744              "time/date:         0x%x\n", (UInt32)(hdr->TimeDateStamp) );
745    fprintf ( stderr,
746              "symtab offset:     %d\n",   (UInt32)(hdr->PointerToSymbolTable) );
747    fprintf ( stderr, 
748              "# symbols:         %d\n",   (UInt32)(hdr->NumberOfSymbols) );
749    fprintf ( stderr, 
750              "sz of opt hdr:     %d\n",   (UInt32)(hdr->SizeOfOptionalHeader) );
751    fprintf ( stderr,
752              "characteristics:   0x%x\n", (UInt32)(hdr->Characteristics) );
753
754    fprintf ( stderr, "\n" );
755    fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
756    fprintf ( stderr, "---START of string table---\n");
757    for (i = 4; i < *(UInt32*)strtab; i++) {
758       if (strtab[i] == 0) 
759          fprintf ( stderr, "\n"); else 
760          fprintf( stderr, "%c", strtab[i] );
761    }
762    fprintf ( stderr, "--- END  of string table---\n");
763
764    fprintf ( stderr, "\n" );
765    for (i = 0; i < hdr->NumberOfSections; i++) {
766       COFF_reloc* reltab;
767       COFF_section* sectab_i
768          = (COFF_section*)
769            myindex ( sizeof_COFF_section, i, sectab );
770       fprintf ( stderr, 
771                 "\n"
772                 "section %d\n"
773                 "     name `",
774                 i 
775               );
776       printName ( sectab_i->Name, strtab );
777       fprintf ( stderr, 
778                 "'\n"
779                 "    vsize %d\n"
780                 "    vaddr %d\n"
781                 "  data sz %d\n"
782                 " data off %d\n"
783                 "  num rel %d\n"
784                 "  off rel %d\n",
785                 sectab_i->VirtualSize,
786                 sectab_i->VirtualAddress,
787                 sectab_i->SizeOfRawData,
788                 sectab_i->PointerToRawData,
789                 sectab_i->NumberOfRelocations,
790                 sectab_i->PointerToRelocations
791               );
792       reltab = (COFF_reloc*) (
793                   ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
794                );
795       for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
796          COFF_symbol* sym;
797          COFF_reloc* rel = (COFF_reloc*)
798                            myindex ( sizeof_COFF_reloc, j, reltab );
799          fprintf ( stderr, 
800                    "        type 0x%-4x   vaddr 0x%-8x   name `",
801                    (UInt32)rel->Type, 
802                    rel->VirtualAddress );
803          sym = (COFF_symbol*)
804                myindex ( sizeof_COFF_symbol, rel->SymbolTableIndex, symtab );
805          printName ( sym->Name, strtab );
806          fprintf ( stderr, "'\n" );
807       }
808       fprintf ( stderr, "\n" );
809    }
810
811
812    fprintf ( stderr, "\n" );
813    i = 0;
814    while (1) {
815       COFF_symbol* symtab_i;
816       if (i >= hdr->NumberOfSymbols) break;
817       symtab_i = (COFF_symbol*)
818                  myindex ( sizeof_COFF_symbol, i, symtab );
819       fprintf ( stderr, 
820                 "symbol %d\n"
821                 "     name `",
822                 i 
823               );
824       printName ( symtab_i->Name, strtab );
825       fprintf ( stderr, 
826                 "'\n"
827                 "    value 0x%x\n"
828                 "     sec# %d\n"
829                 "     type 0x%x\n"
830                 "   sclass 0x%x\n"
831                 "     nAux %d\n",
832                 symtab_i->Value,
833                 (Int32)(symtab_i->SectionNumber) - 1,
834                 (UInt32)symtab_i->Type,
835                 (UInt32)symtab_i->StorageClass,
836                 (UInt32)symtab_i->NumberOfAuxSymbols 
837               );
838       i += symtab_i->NumberOfAuxSymbols;
839       i++;
840    }
841
842    fprintf ( stderr, "\n" );
843
844    return TRUE;
845 }
846
847
848 static int
849 ocGetNames_PEi386 ( ObjectCode* oc )
850 {
851    COFF_header*  hdr;
852    COFF_section* sectab;
853    COFF_symbol*  symtab;
854    UChar*        strtab;
855
856    UChar* sname;
857    void*  addr;
858    int    i;
859    
860    hdr = (COFF_header*)(oc->image);
861    sectab = (COFF_section*) (
862                ((UChar*)(oc->image)) 
863                + sizeof_COFF_header + hdr->SizeOfOptionalHeader
864             );
865    symtab = (COFF_symbol*) (
866                ((UChar*)(oc->image))
867                + hdr->PointerToSymbolTable 
868             );
869    strtab = ((UChar*)(oc->image))
870             + hdr->PointerToSymbolTable
871             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
872
873    /* Copy exported symbols into the ObjectCode. */
874    i = 0;
875    while (1) {
876       COFF_symbol* symtab_i;
877       if (i >= hdr->NumberOfSymbols) break;
878       symtab_i = (COFF_symbol*)
879                  myindex ( sizeof_COFF_symbol, i, symtab );
880
881       if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
882           symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
883
884          /* This symbol is global and defined, viz, exported */
885          COFF_section* sectabent;
886
887          sname = cstring_from_COFF_symbol_name ( 
888                     symtab_i->Name, strtab 
889                  );
890          if (!sname) {
891             oc->errMsg("Out of memory when copying PEi386 symbol");
892             return FALSE;
893          }
894
895          /* for IMAGE_SYMCLASS_EXTERNAL 
896                 && !IMAGE_SYM_UNDEFINED,
897             the address of the symbol is: 
898                 address of relevant section + offset in section
899          */
900          sectabent = (COFF_section*)
901                      myindex ( sizeof_COFF_section, 
902                                symtab_i->SectionNumber-1,
903                                sectab );
904          addr = ((UChar*)(oc->image))
905                 + (sectabent->PointerToRawData
906                    + symtab_i->Value);
907          /* fprintf ( stderr, "addSymbol %p `%s'\n", addr,sname); */
908          if (!addSymbol(oc,sname,addr)) return FALSE;
909       }
910       i += symtab_i->NumberOfAuxSymbols;
911       i++;
912    }
913
914    oc->sections = stgMallocBytes( NumberOfSections * sizeof(Section), 
915                                     "ocGetNamesPEi386" );
916
917    /* Copy section information into the ObjectCode. */
918    for (i = 0; i < hdr->NumberOfSections; i++) {
919       UChar* start;
920       UChar* end;
921
922       SectionKind kind 
923          = SECTIONKIND_OTHER;
924       COFF_section* sectab_i
925          = (COFF_section*)
926            myindex ( sizeof_COFF_section, i, sectab );
927       /* fprintf ( stderr, "section name = %s\n", sectab_i->Name ); */
928
929 #if 0
930       /* I'm sure this is the Right Way to do it.  However, the 
931          alternative of testing the sectab_i->Name field seems to
932          work ok with Cygwin.
933       */
934       if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE || 
935           sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
936          kind = SECTIONKIND_CODE_OR_RODATA;
937 #endif
938
939       if (0==strcmp(".text",sectab_i->Name))
940          kind = SECTIONKIND_CODE_OR_RODATA;
941       if (0==strcmp(".data",sectab_i->Name) ||
942           0==strcmp(".bss",sectab_i->Name))
943          kind = SECTIONKIND_RWDATA;
944
945       start = ((UChar*)(oc->image)) 
946               + sectab_i->PointerToRawData;
947       end   = start 
948               + sectab_i->SizeOfRawData - 1;
949
950       if (kind != SECTIONKIND_OTHER) {
951          addSection ( oc, start, end, kind );
952       } else {
953          fprintf ( stderr, "unknown section name = `%s'\n", 
954                    sectab_i->Name);
955          oc->errMsg("Unknown PEi386 section name");
956          return FALSE;
957       }
958    }
959
960    return TRUE;   
961 }
962
963
964 static int
965 ocResolve_PEi386 ( ObjectCode* oc, int verb )
966 {
967    COFF_header*  hdr;
968    COFF_section* sectab;
969    COFF_symbol*  symtab;
970    UChar*        strtab;
971
972    UInt32        A;
973    UInt32        S;
974    UInt32*       pP;
975
976    int i, j;
977    char symbol[1000]; // ToDo
978    
979    hdr = (COFF_header*)(oc->image);
980    sectab = (COFF_section*) (
981                ((UChar*)(oc->image)) 
982                + sizeof_COFF_header + hdr->SizeOfOptionalHeader
983             );
984    symtab = (COFF_symbol*) (
985                ((UChar*)(oc->image))
986                + hdr->PointerToSymbolTable 
987             );
988    strtab = ((UChar*)(oc->image))
989             + hdr->PointerToSymbolTable
990             + hdr->NumberOfSymbols * sizeof_COFF_symbol;
991
992    for (i = 0; i < hdr->NumberOfSections; i++) {
993       COFF_section* sectab_i
994          = (COFF_section*)
995            myindex ( sizeof_COFF_section, i, sectab );
996       COFF_reloc* reltab
997          = (COFF_reloc*) (
998               ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
999            );
1000       for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1001          COFF_symbol* sym;
1002          COFF_reloc* reltab_j 
1003             = (COFF_reloc*)
1004               myindex ( sizeof_COFF_reloc, j, reltab );
1005
1006          /* the location to patch */
1007          pP = (UInt32*)(
1008                  ((UChar*)(oc->image)) 
1009                  + (sectab_i->PointerToRawData 
1010                     + reltab_j->VirtualAddress)
1011               );
1012          /* the existing contents of pP */
1013          A = *pP;
1014          /* the symbol to connect to */
1015          sym = (COFF_symbol*)
1016                myindex ( sizeof_COFF_symbol, 
1017                          reltab_j->SymbolTableIndex, symtab );
1018          if (verb) {
1019             fprintf ( stderr, 
1020                    "reloc sec %2d num %3d:  type 0x%-4x   "
1021                    "vaddr 0x%-8x   name `",
1022                    i, j,
1023                    (UInt32)reltab_j->Type, 
1024                    reltab_j->VirtualAddress );
1025             printName ( sym->Name, strtab );
1026             fprintf ( stderr, "'\n" );
1027          }
1028
1029          if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1030             COFF_section* section_sym 
1031                = findPEi386SectionCalled ( oc, sym->Name );
1032             if (!section_sym) {
1033                fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1034                oc->errMsg("Can't find abovementioned PEi386 section");
1035                return FALSE;
1036             }
1037             S = ((UInt32)(oc->image))
1038                 + (section_sym->PointerToRawData
1039                    + sym->Value);
1040          } else {
1041          copyName ( sym->Name, strtab, symbol, 1000 );
1042          zapTrailingAtSign ( symbol );
1043          S = (UInt32) ocLookupSym ( oc, symbol );
1044          if (S == 0) 
1045             S = (UInt32)(oc->clientLookup ( symbol ));
1046          if (S == 0) {
1047              belch("%s: unresolvable reference to `%s'", oc->fileName, symbol);
1048              return FALSE;
1049          }
1050          }
1051
1052          switch (reltab_j->Type) {
1053             case IMAGE_REL_I386_DIR32: 
1054                *pP = A + S; 
1055                break;
1056             case IMAGE_REL_I386_REL32:
1057                /* Tricky.  We have to insert a displacement at
1058                   pP which, when added to the PC for the _next_
1059                   insn, gives the address of the target (S).
1060                   Problem is to know the address of the next insn
1061                   when we only know pP.  We assume that this
1062                   literal field is always the last in the insn,
1063                   so that the address of the next insn is pP+4
1064                   -- hence the constant 4.
1065                   Also I don't know if A should be added, but so
1066                   far it has always been zero.
1067                */
1068                ASSERT(A==0);
1069                *pP = S - ((UInt32)pP) - 4;
1070                break;
1071             default: 
1072                fprintf(stderr, 
1073                        "unhandled PEi386 relocation type %d\n",
1074                        reltab_j->Type);
1075                oc->errMsg("unhandled PEi386 relocation type");
1076                return FALSE;
1077          }
1078
1079       }
1080    }
1081    
1082    return TRUE;
1083 }
1084
1085 #endif /* defined(OBJFORMAT_PEi386) */
1086
1087
1088 /* --------------------------------------------------------------------------
1089  * ELF specifics
1090  * ------------------------------------------------------------------------*/
1091
1092 #if defined(OBJFORMAT_ELF)
1093
1094 #define FALSE 0
1095 #define TRUE  1
1096
1097 #if defined(sparc_TARGET_ARCH)
1098 #  define ELF_TARGET_SPARC  /* Used inside <elf.h> */
1099 #endif
1100
1101 #include <elf.h>
1102
1103 static char *
1104 findElfSection ( void* objImage, Elf32_Word sh_type )
1105 {
1106    int i;
1107    char* ehdrC = (char*)objImage;
1108    Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1109    Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1110    char* ptr = NULL;
1111    for (i = 0; i < ehdr->e_shnum; i++) {
1112       if (shdr[i].sh_type == sh_type &&
1113           i !=  ehdr->e_shstrndx) {
1114          ptr = ehdrC + shdr[i].sh_offset;
1115          break;
1116       }
1117    }
1118    return ptr;
1119 }
1120
1121
1122 static int
1123 ocVerifyImage_ELF ( ObjectCode* oc )
1124 {
1125    Elf32_Shdr* shdr;
1126    Elf32_Sym*  stab;
1127    int i, j, nent, nstrtab, nsymtabs;
1128    char* sh_strtab;
1129    char* strtab;
1130
1131    char*       ehdrC = (char*)(oc->image);
1132    Elf32_Ehdr* ehdr  = ( Elf32_Ehdr*)ehdrC;
1133
1134    if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1135        ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1136        ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1137        ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1138       belch("ocVerifyImage_ELF: not an ELF header");
1139       return 0;
1140    }
1141    IF_DEBUG(linker,belch( "Is an ELF header" ));
1142
1143    if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1144       belch("ocVerifyImage_ELF: not 32 bit ELF" );
1145       return 0;
1146    }
1147
1148    IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1149
1150    if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1151        IF_DEBUG(linker,belch( "Is little-endian" ));
1152    } else
1153    if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1154        IF_DEBUG(linker,belch( "Is big-endian" ));
1155    } else {
1156        belch("ocVerifyImage_ELF: unknown endiannness");
1157        return 0;
1158    }
1159
1160    if (ehdr->e_type != ET_REL) {
1161       belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1162       return 0;
1163    }
1164    IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1165
1166    IF_DEBUG(linker,belch( "Architecture is " ));
1167    switch (ehdr->e_machine) {
1168       case EM_386:   IF_DEBUG(linker,belch( "x86" )); break;
1169       case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1170       default:       IF_DEBUG(linker,belch( "unknown" )); 
1171                      belch("ocVerifyImage_ELF: unknown architecture");
1172                      return 0;
1173    }
1174
1175    IF_DEBUG(linker,belch(
1176              "\nSection header table: start %d, n_entries %d, ent_size %d", 
1177              ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize  ));
1178
1179    ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1180
1181    shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1182
1183    if (ehdr->e_shstrndx == SHN_UNDEF) {
1184       belch("ocVerifyImage_ELF: no section header string table");
1185       return 0;
1186    } else {
1187       IF_DEBUG(linker,belch( "Section header string table is section %d", 
1188                           ehdr->e_shstrndx));
1189       sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1190    }
1191
1192    for (i = 0; i < ehdr->e_shnum; i++) {
1193       IF_DEBUG(linker,fprintf(stderr, "%2d:  ", i ));
1194       IF_DEBUG(linker,fprintf(stderr, "type=%2d  ", (int)shdr[i].sh_type ));
1195       IF_DEBUG(linker,fprintf(stderr, "size=%4d  ", (int)shdr[i].sh_size ));
1196       IF_DEBUG(linker,fprintf(stderr, "offs=%4d  ", (int)shdr[i].sh_offset ));
1197       IF_DEBUG(linker,fprintf(stderr, "  (%p .. %p)  ",
1198                ehdrC + shdr[i].sh_offset, 
1199                       ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1200
1201       if (shdr[i].sh_type == SHT_REL) {
1202           IF_DEBUG(linker,fprintf(stderr, "Rel  " ));
1203       } else if (shdr[i].sh_type == SHT_RELA) {
1204           IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1205       } else {
1206           IF_DEBUG(linker,fprintf(stderr,"     "));
1207       }
1208       if (sh_strtab) {
1209           IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1210       }
1211    }
1212
1213    IF_DEBUG(linker,belch( "\nString tables" ));
1214    strtab = NULL;
1215    nstrtab = 0;
1216    for (i = 0; i < ehdr->e_shnum; i++) {
1217       if (shdr[i].sh_type == SHT_STRTAB &&
1218           i !=  ehdr->e_shstrndx) {
1219           IF_DEBUG(linker,belch("   section %d is a normal string table", i ));
1220          strtab = ehdrC + shdr[i].sh_offset;
1221          nstrtab++;
1222       }
1223    }  
1224    if (nstrtab != 1) {
1225       belch("ocVerifyImage_ELF: no string tables, or too many");
1226       return 0;
1227    }
1228
1229    nsymtabs = 0;
1230    IF_DEBUG(linker,belch( "\nSymbol tables" )); 
1231    for (i = 0; i < ehdr->e_shnum; i++) {
1232       if (shdr[i].sh_type != SHT_SYMTAB) continue;
1233       IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1234       nsymtabs++;
1235       stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1236       nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1237       IF_DEBUG(linker,belch( "   number of entries is apparently %d (%d rem)",
1238                nent,
1239                shdr[i].sh_size % sizeof(Elf32_Sym)
1240              ));
1241       if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1242          belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1243          return 0;
1244       }
1245       for (j = 0; j < nent; j++) {
1246          IF_DEBUG(linker,fprintf(stderr, "   %2d  ", j ));
1247          IF_DEBUG(linker,fprintf(stderr, "  sec=%-5d  size=%-3d  val=%5p  ", 
1248                              (int)stab[j].st_shndx,
1249                              (int)stab[j].st_size,
1250                              (char*)stab[j].st_value ));
1251
1252          IF_DEBUG(linker,fprintf(stderr, "type=" ));
1253          switch (ELF32_ST_TYPE(stab[j].st_info)) {
1254             case STT_NOTYPE:  IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1255             case STT_OBJECT:  IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1256             case STT_FUNC  :  IF_DEBUG(linker,fprintf(stderr, "func   " )); break;
1257             case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1258             case STT_FILE:    IF_DEBUG(linker,fprintf(stderr, "file   " )); break;
1259             default:          IF_DEBUG(linker,fprintf(stderr, "?      " )); break;
1260          }
1261          IF_DEBUG(linker,fprintf(stderr, "  " ));
1262
1263          IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1264          switch (ELF32_ST_BIND(stab[j].st_info)) {
1265             case STB_LOCAL :  IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1266             case STB_GLOBAL:  IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1267             case STB_WEAK  :  IF_DEBUG(linker,fprintf(stderr, "weak  " )); break;
1268             default:          IF_DEBUG(linker,fprintf(stderr, "?     " )); break;
1269          }
1270          IF_DEBUG(linker,fprintf(stderr, "  " ));
1271
1272          IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1273       }
1274    }
1275
1276    if (nsymtabs == 0) {
1277       belch("ocVerifyImage_ELF: didn't find any symbol tables");
1278       return 0;
1279    }
1280
1281    return 1;
1282 }
1283
1284
1285 static int
1286 ocGetNames_ELF ( ObjectCode* oc )
1287 {
1288    int i, j, k, nent;
1289    Elf32_Sym* stab;
1290
1291    char*       ehdrC      = (char*)(oc->image);
1292    Elf32_Ehdr* ehdr       = (Elf32_Ehdr*)ehdrC;
1293    char*       strtab     = findElfSection ( ehdrC, SHT_STRTAB );
1294    Elf32_Shdr* shdr       = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1295    char*       sh_strtab  = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1296
1297    ASSERT(symhash != NULL);
1298
1299    if (!strtab) {
1300       belch("ocGetNames_ELF: no strtab");
1301       return 0;
1302    }
1303
1304    k = 0;
1305    oc->sections = stgMallocBytes( ehdr->e_shnum * sizeof(Section), 
1306                                     "ocGetNames_ELF" );
1307    oc->n_sections = ehdr->e_shnum;
1308
1309    for (i = 0; i < ehdr->e_shnum; i++) {
1310
1311       /* make a section entry for relevant sections */
1312       SectionKind kind = SECTIONKIND_OTHER;
1313       if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1314           !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1315           kind = SECTIONKIND_RWDATA;
1316       if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1317           !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1318           !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1319           kind = SECTIONKIND_CODE_OR_RODATA;
1320
1321       /* fill in the section info */
1322       oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1323       oc->sections[i].end   = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1324       oc->sections[i].kind  = kind;
1325       
1326       if (shdr[i].sh_type != SHT_SYMTAB) continue;
1327
1328       /* copy stuff into this module's object symbol table */
1329       stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1330       nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1331       oc->symbols = malloc(nent * sizeof(SymbolVal));
1332       oc->n_symbols = nent;
1333       for (j = 0; j < nent; j++) {
1334          if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1335                 /* || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL */
1336               )
1337               /* and not an undefined symbol */
1338               && stab[j].st_shndx != SHN_UNDEF
1339               &&
1340               /* and it's a not a section or string table or anything silly */
1341               ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1342                 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1343                 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE )
1344                 ) { 
1345             char* nm = strtab + stab[j].st_name;
1346             char* ad = ehdrC 
1347                        + shdr[ stab[j].st_shndx ].sh_offset
1348                        + stab[j].st_value;
1349             ASSERT(nm != NULL);
1350             ASSERT(ad != NULL);
1351             IF_DEBUG(linker,belch( "addOTabName: %10p  %s %s",
1352                        ad, oc->fileName, nm ));
1353             oc->symbols[j].lbl  = nm;
1354             oc->symbols[j].addr = ad;
1355             insertStrHashTable(symhash, nm, &(oc->symbols[j]));
1356          }
1357          else {
1358              IF_DEBUG(linker,belch( "skipping `%s'", 
1359                                     strtab + stab[j].st_name ));
1360              /*
1361              fprintf(stderr, 
1362                      "skipping   bind = %d,  type = %d,  shndx = %d   `%s'\n",
1363                      (int)ELF32_ST_BIND(stab[j].st_info), 
1364                      (int)ELF32_ST_TYPE(stab[j].st_info), 
1365                      (int)stab[j].st_shndx,
1366                      strtab + stab[j].st_name
1367                     );
1368              */
1369              oc->symbols[j].lbl  = NULL;
1370              oc->symbols[j].addr = NULL;
1371          }
1372       }
1373    }
1374
1375    return 1;
1376 }
1377
1378
1379 /* Do ELF relocations which lack an explicit addend.  All x86-linux
1380    relocations appear to be of this form. */
1381 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1382                                       Elf32_Shdr* shdr, int shnum, 
1383                                       Elf32_Sym*  stab, char* strtab )
1384 {
1385    int j;
1386    char *symbol;
1387    Elf32_Word* targ;
1388    Elf32_Rel*  rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1389    int         nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1390    int target_shndx = shdr[shnum].sh_info;
1391    int symtab_shndx = shdr[shnum].sh_link;
1392    stab  = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1393    targ  = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1394    IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1395                           target_shndx, symtab_shndx ));
1396    for (j = 0; j < nent; j++) {
1397       Elf32_Addr offset = rtab[j].r_offset;
1398       Elf32_Word info   = rtab[j].r_info;
1399
1400       Elf32_Addr  P  = ((Elf32_Addr)targ) + offset;
1401       Elf32_Word* pP = (Elf32_Word*)P;
1402       Elf32_Addr  A  = *pP;
1403       Elf32_Addr  S;
1404
1405       IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p)", 
1406                              j, (void*)offset, (void*)info ));
1407       if (!info) {
1408          IF_DEBUG(linker,belch( " ZERO" ));
1409          S = 0;
1410       } else {
1411          /* First see if it is a nameless local symbol. */
1412          if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1413             symbol = "(noname)";
1414             S = (Elf32_Addr)
1415                 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1416                        + stab[ELF32_R_SYM(info)].st_value);
1417          } else {
1418             /* No?  Should be in the symbol table then. */
1419             symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1420             (void *)S = lookupSymbol( symbol );
1421          }
1422          if (!S) {
1423             barf("do_Elf32_Rel_relocations:  %s: unknown symbol `%s'", 
1424                  oc->fileName, symbol);
1425          }
1426          IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1427       }
1428       IF_DEBUG(linker,belch( "Reloc: P = %p   S = %p   A = %p",
1429                              (void*)P, (void*)S, (void*)A )); 
1430       switch (ELF32_R_TYPE(info)) {
1431 #ifdef i386_TARGET_ARCH
1432          case R_386_32:   *pP = S + A;     break;
1433          case R_386_PC32: *pP = S + A - P; break;
1434 #endif
1435          default: 
1436             barf("do_Elf32_Rel_relocations: unhandled ELF relocation(Rel) type %d\n", ELF32_R_TYPE(info));
1437             return 0;
1438       }
1439
1440    }
1441    return 1;
1442 }
1443
1444
1445 /* Do ELF relocations for which explicit addends are supplied.
1446    sparc-solaris relocations appear to be of this form. */
1447 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1448                                        Elf32_Shdr* shdr, int shnum, 
1449                                        Elf32_Sym*  stab, char* strtab )
1450 {
1451    int j;
1452    char *symbol;
1453    Elf32_Word* targ;
1454    Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1455    int         nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1456    int target_shndx = shdr[shnum].sh_info;
1457    int symtab_shndx = shdr[shnum].sh_link;
1458    stab  = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1459    targ  = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1460    IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1461                           target_shndx, symtab_shndx ));
1462    for (j = 0; j < nent; j++) {
1463       Elf32_Addr  offset = rtab[j].r_offset;
1464       Elf32_Word  info   = rtab[j].r_info;
1465       Elf32_Sword addend = rtab[j].r_addend;
1466
1467       Elf32_Addr  P  = ((Elf32_Addr)targ) + offset;
1468       Elf32_Addr  A  = addend;
1469       Elf32_Addr  S;
1470 #     if defined(sparc_TARGET_ARCH)
1471       /* This #ifdef only serves to avoid unused-var warnings. */
1472       Elf32_Word* pP = (Elf32_Word*)P;
1473       Elf32_Word  w1, w2;
1474 #     endif
1475
1476       IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p)   ", 
1477                              j, (void*)offset, (void*)info, 
1478                                 (void*)addend ));
1479       if (!info) {
1480          IF_DEBUG(linker,belch( " ZERO" ));
1481          S = 0;
1482       } else {
1483          /* First see if it is a nameless local symbol. */
1484          if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1485             symbol = "(noname)";
1486             S = (Elf32_Addr)
1487                 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1488                        + stab[ELF32_R_SYM(info)].st_value);
1489          } else {
1490             /* No?  Should be in the symbol table then. */
1491             symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1492             (void *)S = lookupSymbol( symbol );
1493          }
1494          if (!S) {
1495            barf("ocResolve_ELF: %s: unknown symbol `%s'", 
1496                    oc->fileName, symbol);
1497            /* 
1498            S = 0x11223344;
1499            fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1500            */
1501          }
1502          IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1503       }
1504       IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p   S = %p   A = %p\n",
1505                                         (void*)P, (void*)S, (void*)A )); 
1506       switch (ELF32_R_TYPE(info)) {
1507 #        if defined(sparc_TARGET_ARCH)
1508          case R_SPARC_WDISP30: 
1509             w1 = *pP & 0xC0000000;
1510             w2 = (Elf32_Word)((S + A - P) >> 2);
1511             ASSERT((w2 & 0xC0000000) == 0);
1512             w1 |= w2;
1513             *pP = w1;
1514             break;
1515          case R_SPARC_HI22:
1516             w1 = *pP & 0xFFC00000;
1517             w2 = (Elf32_Word)((S + A) >> 10);
1518             ASSERT((w2 & 0xFFC00000) == 0);
1519             w1 |= w2;
1520             *pP = w1;
1521             break;
1522          case R_SPARC_LO10:
1523             w1 = *pP & ~0x3FF;
1524             w2 = (Elf32_Word)((S + A) & 0x3FF);
1525             ASSERT((w2 & ~0x3FF) == 0);
1526             w1 |= w2;
1527             *pP = w1;
1528             break;
1529          case R_SPARC_32:
1530             w2 = (Elf32_Word)(S + A);
1531             *pP = w2;
1532             break;
1533          case R_SPARC_NONE: belch("R_SPARC_NONE");
1534             break;
1535
1536 #        endif
1537          default: 
1538             fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1539                             ELF32_R_TYPE(info));
1540             barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1541             return 0;
1542       }
1543
1544    }
1545    return 1;
1546 }
1547
1548
1549 static int
1550 ocResolve_ELF ( ObjectCode* oc )
1551 {
1552    char *strtab;
1553    int   shnum, ok;
1554    Elf32_Sym*  stab = NULL;
1555    char*       ehdrC = (char*)(oc->image);
1556    Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1557    Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1558
1559    /* first find "the" symbol table */
1560    stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1561
1562    /* also go find the string table */
1563    strtab = findElfSection ( ehdrC, SHT_STRTAB );
1564
1565    if (stab == NULL || strtab == NULL) {
1566       belch("ocResolve_ELF: can't find string or symbol table");
1567       return 0; 
1568    }
1569
1570    /* Process the relocation sections. */
1571    for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1572       if (shdr[shnum].sh_type == SHT_REL ) {
1573          ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr, 
1574                                          shnum, stab, strtab );
1575          if (!ok) return ok;
1576       }
1577       else
1578       if (shdr[shnum].sh_type == SHT_RELA) {
1579          ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr, 
1580                                           shnum, stab, strtab );
1581          if (!ok) return ok;
1582       }
1583    }
1584
1585    return 1;
1586 }
1587
1588
1589 #endif /* ELF */