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