1 /* -----------------------------------------------------------------------------
2 * $Id: Linker.c,v 1.19 2001/02/09 12:39:53 sewardj Exp $
4 * (c) The GHC Team, 2000
8 * ---------------------------------------------------------------------------*/
16 #include "StoragePriv.h"
18 #ifdef HAVE_SYS_TYPES_H
19 #include <sys/types.h>
22 #ifdef HAVE_SYS_STAT_H
30 #ifdef GHCI /* endif is right at end of file */
32 #if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS)
34 #elif defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
35 #define OBJFORMAT_PEi386
38 /* A bucket in the symbol hash-table. Primarily, maps symbol names to
39 * absolute addresses. All symbols from a given module are linked
40 * together, so they can be freed at the same time. There's also a
41 * bucket link field for the hash table.
43 typedef struct _SymbolVal {
48 typedef enum { OBJECT_LOADED, OBJECT_RESOLVED } OStatus;
50 /* Indication of section kinds for loaded objects. Needed by
51 the GC for deciding whether or not a pointer on the stack
54 typedef enum { SECTIONKIND_CODE_OR_RODATA,
57 SECTIONKIND_NOINFOAVAIL }
60 typedef struct { void* start; void* end; SectionKind kind; }
63 /* Top-level structure for an object module. One of these is allocated
64 * for each object file in use.
66 typedef struct _ObjectCode {
70 char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */
75 /* ptr to malloc'd lump of memory holding the obj file */
78 /* The section-kind entries for this object module. Dynamically expands. */
82 /* Allow a chain of these things */
83 struct _ObjectCode * next;
87 /* Hash table mapping symbol names to Symbol */
88 /*Str*/HashTable *symhash;
90 /* List of currently loaded objects */
93 #if defined(OBJFORMAT_ELF)
94 static int ocVerifyImage_ELF ( ObjectCode* oc );
95 static int ocGetNames_ELF ( ObjectCode* oc );
96 static int ocResolve_ELF ( ObjectCode* oc );
97 #elif defined(OBJFORMAT_PEi386)
98 static int ocVerifyImage_PEi386 ( ObjectCode* oc );
99 static int ocGetNames_PEi386 ( ObjectCode* oc );
100 static int ocResolve_PEi386 ( ObjectCode* oc );
103 /* -----------------------------------------------------------------------------
104 * Built-in symbols from the RTS
107 #define RTS_SYMBOLS \
109 Sym(stg_gc_enter_1) \
116 Sym(stg_gc_unbx_r1) \
121 SymX(stg_update_PAP) \
122 SymX(stg_ap_2_upd_info) \
123 SymX(stg_ap_3_upd_info) \
124 SymX(stg_ap_4_upd_info) \
125 SymX(stg_ap_5_upd_info) \
126 SymX(stg_ap_6_upd_info) \
127 SymX(stg_ap_7_upd_info) \
128 SymX(stg_ap_8_upd_info) \
129 SymX(stg_sel_0_upd_info) \
130 SymX(stg_sel_1_upd_info) \
131 SymX(stg_sel_2_upd_info) \
132 SymX(stg_sel_3_upd_info) \
133 SymX(stg_sel_4_upd_info) \
134 SymX(stg_sel_5_upd_info) \
135 SymX(stg_sel_6_upd_info) \
136 SymX(stg_sel_7_upd_info) \
137 SymX(stg_sel_8_upd_info) \
138 SymX(stg_sel_9_upd_info) \
139 SymX(stg_sel_10_upd_info) \
140 SymX(stg_sel_11_upd_info) \
141 SymX(stg_sel_12_upd_info) \
142 SymX(stg_sel_13_upd_info) \
143 SymX(stg_sel_14_upd_info) \
144 SymX(stg_sel_15_upd_info) \
145 SymX(stg_upd_frame_info) \
146 SymX(stg_seq_frame_info) \
147 SymX(stg_CAF_BLACKHOLE_info) \
148 SymX(stg_IND_STATIC_info) \
149 SymX(stg_EMPTY_MVAR_info) \
150 SymX(stg_MUT_ARR_PTRS_FROZEN_info) \
151 SymX(stg_WEAK_info) \
152 SymX(stg_CHARLIKE_closure) \
153 SymX(stg_INTLIKE_closure) \
155 SymX(newBCOzh_fast) \
156 SymX(mkApUpd0zh_fast) \
157 SymX(putMVarzh_fast) \
158 SymX(newMVarzh_fast) \
159 SymX(takeMVarzh_fast) \
160 SymX(tryTakeMVarzh_fast) \
166 SymX(killThreadzh_fast) \
167 SymX(waitReadzh_fast) \
168 SymX(waitWritezh_fast) \
169 SymX(suspendThread) \
171 SymX(stackOverflow) \
172 SymX(int2Integerzh_fast) \
173 SymX(word2Integerzh_fast) \
174 SymX(mkForeignObjzh_fast) \
175 SymX(__encodeDouble) \
176 SymX(decodeDoublezh_fast) \
177 SymX(decodeFloatzh_fast) \
178 SymX(gcdIntegerzh_fast) \
179 SymX(newArrayzh_fast) \
180 SymX(unsafeThawArrayzh_fast) \
181 SymX(newByteArrayzh_fast) \
182 SymX(newMutVarzh_fast) \
183 SymX(quotRemIntegerzh_fast) \
184 SymX(quotIntegerzh_fast) \
185 SymX(remIntegerzh_fast) \
186 SymX(divExactIntegerzh_fast) \
187 SymX(divModIntegerzh_fast) \
188 SymX(timesIntegerzh_fast) \
189 SymX(minusIntegerzh_fast) \
190 SymX(plusIntegerzh_fast) \
191 SymX(andIntegerzh_fast) \
192 SymX(orIntegerzh_fast) \
193 SymX(xorIntegerzh_fast) \
194 SymX(complementIntegerzh_fast) \
195 SymX(mkWeakzh_fast) \
196 SymX(makeStableNamezh_fast) \
197 SymX(finalizzeWeakzh_fast) \
198 SymX(blockAsyncExceptionszh_fast) \
199 SymX(unblockAsyncExceptionszh_fast) \
201 SymX(isDoubleInfinite) \
202 SymX(isDoubleDenormalized) \
203 SymX(isDoubleNegativeZero) \
204 SymX(__encodeFloat) \
206 SymX(isFloatInfinite) \
207 SymX(isFloatDenormalized) \
208 SymX(isFloatNegativeZero) \
209 SymX(__int_encodeFloat) \
210 SymX(__int_encodeDouble) \
211 SymX(__gmpz_cmp_si) \
212 SymX(__gmpz_cmp_ui) \
217 SymX(resetNonBlockingFd) \
219 SymX(stable_ptr_table) \
220 SymX(shutdownHaskellAndExit) \
221 Sym(stg_enterStackTop) \
222 Sym(stg_yield_to_interpreter) \
226 Sym(__init_PrelGHC) \
227 SymX(freeHaskellFunctionPtr) \
230 SymX(NoRunnableThreadsHook) \
231 SymX(StackOverflowHook) \
232 SymX(OutOfHeapHook) \
233 SymX(MallocFailHook) \
234 SymX(PatErrorHdrHook) \
237 SymX(PostTraceHook) \
238 SymX(stg_sig_install) \
240 SymX(createAdjustor) \
242 SymX(rts_mkStablePtr) \
245 SymX(rts_checkSchedStatus) \
248 #ifndef SUPPORT_LONG_LONGS
249 #define RTS_LONG_LONG_SYMS /* nothing */
251 #define RTS_LONG_LONG_SYMS \
264 SymX(stg_remWord64) \
265 SymX(stg_quotWord64) \
267 SymX(stg_quotInt64) \
268 SymX(stg_negateInt64) \
269 SymX(stg_plusInt64) \
270 SymX(stg_minusInt64) \
271 SymX(stg_timesInt64) \
277 SymX(stg_shiftRL64) \
278 SymX(stg_iShiftL64) \
279 SymX(stg_iShiftRL64) \
280 SymX(stg_iShiftRA64) \
281 SymX(stg_intToInt64) \
282 SymX(stg_int64ToInt) \
283 SymX(stg_int64ToWord64) \
284 SymX(stg_wordToWord64) \
285 SymX(stg_word64ToWord) \
286 SymX(stg_word64ToInt64) \
287 SymX(int64ToIntegerzh_fast) \
288 SymX(word64ToIntegerzh_fast)
289 #endif /* SUPPORT_LONG_LONGS */
291 /* entirely bogus claims about types of these symbols */
292 #define Sym(vvv) extern void (vvv);
293 #define SymX(vvv) /**/
298 #ifdef LEADING_UNDERSCORE
299 #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
301 #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
304 #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
306 #define SymX(vvv) Sym(vvv)
308 static SymbolVal rtsSyms[] = {
311 { 0, 0 } /* sentinel */
314 /* -----------------------------------------------------------------------------
315 * initialize the object linker
317 static void *dl_prog_handle;
324 symhash = allocStrHashTable();
326 /* populate the symbol table with stuff from the RTS */
327 for (sym = rtsSyms; sym->lbl != NULL; sym++) {
328 insertStrHashTable(symhash, sym->lbl, sym);
331 dl_prog_handle = dlopen(NULL, RTLD_LAZY);
334 /* -----------------------------------------------------------------------------
335 * lookup a symbol in the hash table
338 lookupSymbol( char *lbl )
341 val = lookupStrHashTable(symhash, lbl);
344 return dlsym(dl_prog_handle, lbl);
350 /* -----------------------------------------------------------------------------
351 * Load an obj (populate the global symbol table, but don't resolve yet)
353 * Returns: 1 if ok, 0 on error.
356 loadObj( char *path )
364 /* assert that we haven't already loaded this object */
367 for (o = objects; o; o = o->next)
368 ASSERT(strcmp(o->fileName, path));
372 oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
374 # if defined(OBJFORMAT_ELF)
375 oc->formatName = "ELF";
376 # elif defined(OBJFORMAT_PEi386)
377 oc->formatName = "PEi386";
380 barf("loadObj: not implemented on this platform");
384 if (r == -1) { return 0; }
386 /* sigh, stdup() isn't a POSIX function, so do it the long way */
387 oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
388 strcpy(oc->fileName, path);
390 oc->fileSize = st.st_size;
391 oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
395 /* chain it onto the list of objects */
399 /* load the image into memory */
400 f = fopen(path, "rb");
402 barf("loadObj: can't read `%s'", path);
404 n = fread ( oc->image, 1, oc->fileSize, f );
405 if (n != oc->fileSize) {
407 barf("loadObj: error whilst reading `%s'", path);
410 /* verify the in-memory image */
411 # if defined(OBJFORMAT_ELF)
412 r = ocVerifyImage_ELF ( oc );
413 # elif defined(OBJFORMAT_PEi386)
414 r = ocVerifyImage_PEi386 ( oc );
416 barf("loadObj: no verify method");
418 if (!r) { return r; }
420 /* build the symbol list for this image */
421 # if defined(OBJFORMAT_ELF)
422 r = ocGetNames_ELF ( oc );
423 # elif defined(OBJFORMAT_PEi386)
424 r = ocGetNames_PEi386 ( oc );
426 barf("loadObj: no getNames method");
428 if (!r) { return r; }
430 /* loaded, but not resolved yet */
431 oc->status = OBJECT_LOADED;
436 /* -----------------------------------------------------------------------------
437 * resolve all the currently unlinked objects in memory
439 * Returns: 1 if ok, 0 on error.
447 for (oc = objects; oc; oc = oc->next) {
448 if (oc->status != OBJECT_RESOLVED) {
449 # if defined(OBJFORMAT_ELF)
450 r = ocResolve_ELF ( oc );
451 # elif defined(OBJFORMAT_PEi386)
452 r = ocResolve_PEi386 ( oc );
454 barf("link: not implemented on this platform");
456 if (!r) { return r; }
457 oc->status = OBJECT_RESOLVED;
463 /* -----------------------------------------------------------------------------
464 * delete an object from the pool
467 unloadObj( char *path )
469 ObjectCode *oc, *prev;
472 for (oc = objects; oc; prev = oc, oc = oc->next) {
473 if (!strcmp(oc->fileName,path)) {
475 /* Remove all the mappings for the symbols within this
480 for (s = oc->symbols; s < oc->symbols + oc->n_symbols; s++) {
481 if (s->lbl != NULL) {
482 removeStrHashTable(symhash, s->lbl, NULL);
490 prev->next = oc->next;
493 /* We're going to leave this in place, in case there are
494 any pointers from the heap into it: */
495 /* free(oc->image); */
504 belch("unloadObj: can't find `%s' to unload", path);
508 /* --------------------------------------------------------------------------
509 * PEi386 specifics (Win32 targets)
510 * ------------------------------------------------------------------------*/
512 /* The information for this linker comes from
513 Microsoft Portable Executable
514 and Common Object File Format Specification
515 revision 5.1 January 1998
516 which SimonM says comes from the MS Developer Network CDs.
520 #if defined(OBJFORMAT_PEi386)
524 typedef unsigned char UChar;
525 typedef unsigned short UInt16;
526 typedef unsigned int UInt32;
533 UInt16 NumberOfSections;
534 UInt32 TimeDateStamp;
535 UInt32 PointerToSymbolTable;
536 UInt32 NumberOfSymbols;
537 UInt16 SizeOfOptionalHeader;
538 UInt16 Characteristics;
542 #define sizeof_COFF_header 20
549 UInt32 VirtualAddress;
550 UInt32 SizeOfRawData;
551 UInt32 PointerToRawData;
552 UInt32 PointerToRelocations;
553 UInt32 PointerToLinenumbers;
554 UInt16 NumberOfRelocations;
555 UInt16 NumberOfLineNumbers;
556 UInt32 Characteristics;
560 #define sizeof_COFF_section 40
567 UInt16 SectionNumber;
570 UChar NumberOfAuxSymbols;
574 #define sizeof_COFF_symbol 18
579 UInt32 VirtualAddress;
580 UInt32 SymbolTableIndex;
585 #define sizeof_COFF_reloc 10
588 /* From PE spec doc, section 3.3.2 */
589 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001
590 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
591 #define IMAGE_FILE_DLL 0x2000
592 #define IMAGE_FILE_SYSTEM 0x1000
593 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
594 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
595 #define IMAGE_FILE_32BIT_MACHINE 0x0100
597 /* From PE spec doc, section 5.4.2 and 5.4.4 */
598 #define IMAGE_SYM_CLASS_EXTERNAL 2
599 #define IMAGE_SYM_CLASS_STATIC 3
600 #define IMAGE_SYM_UNDEFINED 0
602 /* From PE spec doc, section 4.1 */
603 #define IMAGE_SCN_CNT_CODE 0x00000020
604 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
606 /* From PE spec doc, section 5.2.1 */
607 #define IMAGE_REL_I386_DIR32 0x0006
608 #define IMAGE_REL_I386_REL32 0x0014
611 /* We use myindex to calculate array addresses, rather than
612 simply doing the normal subscript thing. That's because
613 some of the above structs have sizes which are not
614 a whole number of words. GCC rounds their sizes up to a
615 whole number of words, which means that the address calcs
616 arising from using normal C indexing or pointer arithmetic
617 are just plain wrong. Sigh.
620 myindex ( int scale, int index, void* base )
623 ((UChar*)base) + scale * index;
628 printName ( UChar* name, UChar* strtab )
630 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
631 UInt32 strtab_offset = * (UInt32*)(name+4);
632 fprintf ( stderr, "%s", strtab + strtab_offset );
635 for (i = 0; i < 8; i++) {
636 if (name[i] == 0) break;
637 fprintf ( stderr, "%c", name[i] );
644 copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
646 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
647 UInt32 strtab_offset = * (UInt32*)(name+4);
648 strncpy ( dst, strtab+strtab_offset, dstSize );
654 if (name[i] == 0) break;
664 cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
667 /* If the string is longer than 8 bytes, look in the
668 string table for it -- this will be correctly zero terminated.
670 if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
671 UInt32 strtab_offset = * (UInt32*)(name+4);
672 return ((UChar*)strtab) + strtab_offset;
674 /* Otherwise, if shorter than 8 bytes, return the original,
675 which by defn is correctly terminated.
677 if (name[7]==0) return name;
678 /* The annoying case: 8 bytes. Copy into a temporary
679 (which is never freed ...)
683 strncpy(newstr,name,8);
690 /* Just compares the short names (first 8 chars) */
691 static COFF_section *
692 findPEi386SectionCalled ( ObjectCode* oc, char* name )
696 = (COFF_header*)(oc->image);
699 ((UChar*)(oc->image))
700 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
702 for (i = 0; i < hdr->NumberOfSections; i++) {
705 COFF_section* section_i
707 myindex ( sizeof_COFF_section, i, sectab );
708 n1 = (UChar*) &(section_i->Name);
710 if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
711 n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
712 n1[6]==n2[6] && n1[7]==n2[7])
721 zapTrailingAtSign ( UChar* sym )
724 if (sym[0] == 0) return;
726 while (sym[i] != 0) i++;
729 while (j > 0 && isdigit(sym[j])) j--;
730 if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
735 ocVerifyImage_PEi386 ( ObjectCode* oc )
739 COFF_section* sectab;
743 hdr = (COFF_header*)(oc->image);
744 sectab = (COFF_section*) (
745 ((UChar*)(oc->image))
746 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
748 symtab = (COFF_symbol*) (
749 ((UChar*)(oc->image))
750 + hdr->PointerToSymbolTable
752 strtab = ((UChar*)(oc->image))
753 + hdr->PointerToSymbolTable
754 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
756 if (hdr->Machine != 0x14c) {
757 oc->errMsg("Not x86 PEi386");
760 if (hdr->SizeOfOptionalHeader != 0) {
761 oc->errMsg("PEi386 with nonempty optional header");
764 if ( /* (hdr->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) || */
765 (hdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ||
766 (hdr->Characteristics & IMAGE_FILE_DLL) ||
767 (hdr->Characteristics & IMAGE_FILE_SYSTEM) ) {
768 oc->errMsg("Not a PEi386 object file");
771 if ( (hdr->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI) ||
772 !(hdr->Characteristics & IMAGE_FILE_32BIT_MACHINE) ) {
773 oc->errMsg("Invalid PEi386 word size or endiannness");
777 if (!verb) return TRUE;
778 /* No further verification after this point; only debug printing. */
781 "sectab offset = %d\n", ((UChar*)sectab) - ((UChar*)hdr) );
783 "symtab offset = %d\n", ((UChar*)symtab) - ((UChar*)hdr) );
785 "strtab offset = %d\n", ((UChar*)strtab) - ((UChar*)hdr) );
787 fprintf ( stderr, "\n" );
789 "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
791 "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
793 "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
795 "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
797 "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
799 "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
801 "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
803 fprintf ( stderr, "\n" );
804 fprintf ( stderr, "string table has size 0x%x\n", * (UInt32*)strtab );
805 fprintf ( stderr, "---START of string table---\n");
806 for (i = 4; i < *(UInt32*)strtab; i++) {
808 fprintf ( stderr, "\n"); else
809 fprintf( stderr, "%c", strtab[i] );
811 fprintf ( stderr, "--- END of string table---\n");
813 fprintf ( stderr, "\n" );
814 for (i = 0; i < hdr->NumberOfSections; i++) {
816 COFF_section* sectab_i
818 myindex ( sizeof_COFF_section, i, sectab );
825 printName ( sectab_i->Name, strtab );
834 sectab_i->VirtualSize,
835 sectab_i->VirtualAddress,
836 sectab_i->SizeOfRawData,
837 sectab_i->PointerToRawData,
838 sectab_i->NumberOfRelocations,
839 sectab_i->PointerToRelocations
841 reltab = (COFF_reloc*) (
842 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
844 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
846 COFF_reloc* rel = (COFF_reloc*)
847 myindex ( sizeof_COFF_reloc, j, reltab );
849 " type 0x%-4x vaddr 0x%-8x name `",
851 rel->VirtualAddress );
853 myindex ( sizeof_COFF_symbol, rel->SymbolTableIndex, symtab );
854 printName ( sym->Name, strtab );
855 fprintf ( stderr, "'\n" );
857 fprintf ( stderr, "\n" );
861 fprintf ( stderr, "\n" );
864 COFF_symbol* symtab_i;
865 if (i >= hdr->NumberOfSymbols) break;
866 symtab_i = (COFF_symbol*)
867 myindex ( sizeof_COFF_symbol, i, symtab );
873 printName ( symtab_i->Name, strtab );
882 (Int32)(symtab_i->SectionNumber) - 1,
883 (UInt32)symtab_i->Type,
884 (UInt32)symtab_i->StorageClass,
885 (UInt32)symtab_i->NumberOfAuxSymbols
887 i += symtab_i->NumberOfAuxSymbols;
891 fprintf ( stderr, "\n" );
898 ocGetNames_PEi386 ( ObjectCode* oc )
901 COFF_section* sectab;
909 hdr = (COFF_header*)(oc->image);
910 sectab = (COFF_section*) (
911 ((UChar*)(oc->image))
912 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
914 symtab = (COFF_symbol*) (
915 ((UChar*)(oc->image))
916 + hdr->PointerToSymbolTable
918 strtab = ((UChar*)(oc->image))
919 + hdr->PointerToSymbolTable
920 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
922 /* Copy exported symbols into the ObjectCode. */
925 COFF_symbol* symtab_i;
926 if (i >= hdr->NumberOfSymbols) break;
927 symtab_i = (COFF_symbol*)
928 myindex ( sizeof_COFF_symbol, i, symtab );
930 if (symtab_i->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
931 symtab_i->SectionNumber != IMAGE_SYM_UNDEFINED) {
933 /* This symbol is global and defined, viz, exported */
934 COFF_section* sectabent;
936 sname = cstring_from_COFF_symbol_name (
937 symtab_i->Name, strtab
940 oc->errMsg("Out of memory when copying PEi386 symbol");
944 /* for IMAGE_SYMCLASS_EXTERNAL
945 && !IMAGE_SYM_UNDEFINED,
946 the address of the symbol is:
947 address of relevant section + offset in section
949 sectabent = (COFF_section*)
950 myindex ( sizeof_COFF_section,
951 symtab_i->SectionNumber-1,
953 addr = ((UChar*)(oc->image))
954 + (sectabent->PointerToRawData
956 /* fprintf ( stderr, "addSymbol %p `%s'\n", addr,sname); */
957 if (!addSymbol(oc,sname,addr)) return FALSE;
959 i += symtab_i->NumberOfAuxSymbols;
963 oc->sections = stgMallocBytes( NumberOfSections * sizeof(Section),
964 "ocGetNamesPEi386" );
966 /* Copy section information into the ObjectCode. */
967 for (i = 0; i < hdr->NumberOfSections; i++) {
973 COFF_section* sectab_i
975 myindex ( sizeof_COFF_section, i, sectab );
976 /* fprintf ( stderr, "section name = %s\n", sectab_i->Name ); */
979 /* I'm sure this is the Right Way to do it. However, the
980 alternative of testing the sectab_i->Name field seems to
983 if (sectab_i->Characteristics & IMAGE_SCN_CNT_CODE ||
984 sectab_i->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
985 kind = SECTIONKIND_CODE_OR_RODATA;
988 if (0==strcmp(".text",sectab_i->Name))
989 kind = SECTIONKIND_CODE_OR_RODATA;
990 if (0==strcmp(".data",sectab_i->Name) ||
991 0==strcmp(".bss",sectab_i->Name))
992 kind = SECTIONKIND_RWDATA;
994 start = ((UChar*)(oc->image))
995 + sectab_i->PointerToRawData;
997 + sectab_i->SizeOfRawData - 1;
999 if (kind != SECTIONKIND_OTHER) {
1000 addSection ( oc, start, end, kind );
1002 fprintf ( stderr, "unknown section name = `%s'\n",
1004 oc->errMsg("Unknown PEi386 section name");
1014 ocResolve_PEi386 ( ObjectCode* oc, int verb )
1017 COFF_section* sectab;
1018 COFF_symbol* symtab;
1026 char symbol[1000]; // ToDo
1028 hdr = (COFF_header*)(oc->image);
1029 sectab = (COFF_section*) (
1030 ((UChar*)(oc->image))
1031 + sizeof_COFF_header + hdr->SizeOfOptionalHeader
1033 symtab = (COFF_symbol*) (
1034 ((UChar*)(oc->image))
1035 + hdr->PointerToSymbolTable
1037 strtab = ((UChar*)(oc->image))
1038 + hdr->PointerToSymbolTable
1039 + hdr->NumberOfSymbols * sizeof_COFF_symbol;
1041 for (i = 0; i < hdr->NumberOfSections; i++) {
1042 COFF_section* sectab_i
1044 myindex ( sizeof_COFF_section, i, sectab );
1047 ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
1049 for (j = 0; j < sectab_i->NumberOfRelocations; j++) {
1051 COFF_reloc* reltab_j
1053 myindex ( sizeof_COFF_reloc, j, reltab );
1055 /* the location to patch */
1057 ((UChar*)(oc->image))
1058 + (sectab_i->PointerToRawData
1059 + reltab_j->VirtualAddress)
1061 /* the existing contents of pP */
1063 /* the symbol to connect to */
1064 sym = (COFF_symbol*)
1065 myindex ( sizeof_COFF_symbol,
1066 reltab_j->SymbolTableIndex, symtab );
1069 "reloc sec %2d num %3d: type 0x%-4x "
1070 "vaddr 0x%-8x name `",
1072 (UInt32)reltab_j->Type,
1073 reltab_j->VirtualAddress );
1074 printName ( sym->Name, strtab );
1075 fprintf ( stderr, "'\n" );
1078 if (sym->StorageClass == IMAGE_SYM_CLASS_STATIC) {
1079 COFF_section* section_sym
1080 = findPEi386SectionCalled ( oc, sym->Name );
1082 fprintf ( stderr, "bad section = `%s'\n", sym->Name );
1083 oc->errMsg("Can't find abovementioned PEi386 section");
1086 S = ((UInt32)(oc->image))
1087 + (section_sym->PointerToRawData
1090 copyName ( sym->Name, strtab, symbol, 1000 );
1091 zapTrailingAtSign ( symbol );
1092 S = (UInt32) ocLookupSym ( oc, symbol );
1094 S = (UInt32)(oc->clientLookup ( symbol ));
1096 belch("%s: unresolvable reference to `%s'", oc->fileName, symbol);
1101 switch (reltab_j->Type) {
1102 case IMAGE_REL_I386_DIR32:
1105 case IMAGE_REL_I386_REL32:
1106 /* Tricky. We have to insert a displacement at
1107 pP which, when added to the PC for the _next_
1108 insn, gives the address of the target (S).
1109 Problem is to know the address of the next insn
1110 when we only know pP. We assume that this
1111 literal field is always the last in the insn,
1112 so that the address of the next insn is pP+4
1113 -- hence the constant 4.
1114 Also I don't know if A should be added, but so
1115 far it has always been zero.
1118 *pP = S - ((UInt32)pP) - 4;
1122 "unhandled PEi386 relocation type %d\n",
1124 oc->errMsg("unhandled PEi386 relocation type");
1134 #endif /* defined(OBJFORMAT_PEi386) */
1137 /* --------------------------------------------------------------------------
1139 * ------------------------------------------------------------------------*/
1141 #if defined(OBJFORMAT_ELF)
1146 #if defined(solaris2_TARGET_OS)
1147 # define ELF_TARGET_SPARC /* Used inside <elf.h> */
1153 findElfSection ( void* objImage, Elf32_Word sh_type )
1156 char* ehdrC = (char*)objImage;
1157 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1158 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1160 for (i = 0; i < ehdr->e_shnum; i++) {
1161 if (shdr[i].sh_type == sh_type &&
1162 i != ehdr->e_shstrndx) {
1163 ptr = ehdrC + shdr[i].sh_offset;
1172 ocVerifyImage_ELF ( ObjectCode* oc )
1176 int i, j, nent, nstrtab, nsymtabs;
1180 char* ehdrC = (char*)(oc->image);
1181 Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)ehdrC;
1183 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
1184 ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
1185 ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
1186 ehdr->e_ident[EI_MAG3] != ELFMAG3) {
1187 belch("ocVerifyImage_ELF: not an ELF header");
1190 IF_DEBUG(linker,belch( "Is an ELF header" ));
1192 if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
1193 belch("ocVerifyImage_ELF: not 32 bit ELF" );
1197 IF_DEBUG(linker,belch( "Is 32 bit ELF" ));
1199 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
1200 IF_DEBUG(linker,belch( "Is little-endian" ));
1202 if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
1203 IF_DEBUG(linker,belch( "Is big-endian" ));
1205 belch("ocVerifyImage_ELF: unknown endiannness");
1209 if (ehdr->e_type != ET_REL) {
1210 belch("ocVerifyImage_ELF: not a relocatable object (.o) file");
1213 IF_DEBUG(linker, belch( "Is a relocatable object (.o) file" ));
1215 IF_DEBUG(linker,belch( "Architecture is " ));
1216 switch (ehdr->e_machine) {
1217 case EM_386: IF_DEBUG(linker,belch( "x86" )); break;
1218 case EM_SPARC: IF_DEBUG(linker,belch( "sparc" )); break;
1219 default: IF_DEBUG(linker,belch( "unknown" ));
1220 belch("ocVerifyImage_ELF: unknown architecture");
1224 IF_DEBUG(linker,belch(
1225 "\nSection header table: start %d, n_entries %d, ent_size %d",
1226 ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
1228 ASSERT (ehdr->e_shentsize == sizeof(Elf32_Shdr));
1230 shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1232 if (ehdr->e_shstrndx == SHN_UNDEF) {
1233 belch("ocVerifyImage_ELF: no section header string table");
1236 IF_DEBUG(linker,belch( "Section header string table is section %d",
1238 sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1241 for (i = 0; i < ehdr->e_shnum; i++) {
1242 IF_DEBUG(linker,fprintf(stderr, "%2d: ", i ));
1243 IF_DEBUG(linker,fprintf(stderr, "type=%2d ", (int)shdr[i].sh_type ));
1244 IF_DEBUG(linker,fprintf(stderr, "size=%4d ", (int)shdr[i].sh_size ));
1245 IF_DEBUG(linker,fprintf(stderr, "offs=%4d ", (int)shdr[i].sh_offset ));
1246 IF_DEBUG(linker,fprintf(stderr, " (%p .. %p) ",
1247 ehdrC + shdr[i].sh_offset,
1248 ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
1250 if (shdr[i].sh_type == SHT_REL) {
1251 IF_DEBUG(linker,fprintf(stderr, "Rel " ));
1252 } else if (shdr[i].sh_type == SHT_RELA) {
1253 IF_DEBUG(linker,fprintf(stderr, "RelA " ));
1255 IF_DEBUG(linker,fprintf(stderr," "));
1258 IF_DEBUG(linker,fprintf(stderr, "sname=%s\n", sh_strtab + shdr[i].sh_name ));
1262 IF_DEBUG(linker,belch( "\nString tables" ));
1265 for (i = 0; i < ehdr->e_shnum; i++) {
1266 if (shdr[i].sh_type == SHT_STRTAB &&
1267 i != ehdr->e_shstrndx) {
1268 IF_DEBUG(linker,belch(" section %d is a normal string table", i ));
1269 strtab = ehdrC + shdr[i].sh_offset;
1274 belch("ocVerifyImage_ELF: no string tables, or too many");
1279 IF_DEBUG(linker,belch( "\nSymbol tables" ));
1280 for (i = 0; i < ehdr->e_shnum; i++) {
1281 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1282 IF_DEBUG(linker,belch( "section %d is a symbol table", i ));
1284 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1285 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1286 IF_DEBUG(linker,belch( " number of entries is apparently %d (%d rem)",
1288 shdr[i].sh_size % sizeof(Elf32_Sym)
1290 if (0 != shdr[i].sh_size % sizeof(Elf32_Sym)) {
1291 belch("ocVerifyImage_ELF: non-integral number of symbol table entries");
1294 for (j = 0; j < nent; j++) {
1295 IF_DEBUG(linker,fprintf(stderr, " %2d ", j ));
1296 IF_DEBUG(linker,fprintf(stderr, " sec=%-5d size=%-3d val=%5p ",
1297 (int)stab[j].st_shndx,
1298 (int)stab[j].st_size,
1299 (char*)stab[j].st_value ));
1301 IF_DEBUG(linker,fprintf(stderr, "type=" ));
1302 switch (ELF32_ST_TYPE(stab[j].st_info)) {
1303 case STT_NOTYPE: IF_DEBUG(linker,fprintf(stderr, "notype " )); break;
1304 case STT_OBJECT: IF_DEBUG(linker,fprintf(stderr, "object " )); break;
1305 case STT_FUNC : IF_DEBUG(linker,fprintf(stderr, "func " )); break;
1306 case STT_SECTION: IF_DEBUG(linker,fprintf(stderr, "section" )); break;
1307 case STT_FILE: IF_DEBUG(linker,fprintf(stderr, "file " )); break;
1308 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1310 IF_DEBUG(linker,fprintf(stderr, " " ));
1312 IF_DEBUG(linker,fprintf(stderr, "bind=" ));
1313 switch (ELF32_ST_BIND(stab[j].st_info)) {
1314 case STB_LOCAL : IF_DEBUG(linker,fprintf(stderr, "local " )); break;
1315 case STB_GLOBAL: IF_DEBUG(linker,fprintf(stderr, "global" )); break;
1316 case STB_WEAK : IF_DEBUG(linker,fprintf(stderr, "weak " )); break;
1317 default: IF_DEBUG(linker,fprintf(stderr, "? " )); break;
1319 IF_DEBUG(linker,fprintf(stderr, " " ));
1321 IF_DEBUG(linker,fprintf(stderr, "name=%s\n", strtab + stab[j].st_name ));
1325 if (nsymtabs == 0) {
1326 belch("ocVerifyImage_ELF: didn't find any symbol tables");
1335 ocGetNames_ELF ( ObjectCode* oc )
1340 char* ehdrC = (char*)(oc->image);
1341 Elf32_Ehdr* ehdr = (Elf32_Ehdr*)ehdrC;
1342 char* strtab = findElfSection ( ehdrC, SHT_STRTAB );
1343 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1344 char* sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
1347 belch("ocGetNames_ELF: no strtab");
1352 oc->sections = stgMallocBytes( ehdr->e_shnum * sizeof(Section),
1354 oc->n_sections = ehdr->e_shnum;
1356 for (i = 0; i < ehdr->e_shnum; i++) {
1358 /* make a section entry for relevant sections */
1359 SectionKind kind = SECTIONKIND_OTHER;
1360 if (!strcmp(".data",sh_strtab+shdr[i].sh_name) ||
1361 !strcmp(".data1",sh_strtab+shdr[i].sh_name))
1362 kind = SECTIONKIND_RWDATA;
1363 if (!strcmp(".text",sh_strtab+shdr[i].sh_name) ||
1364 !strcmp(".rodata",sh_strtab+shdr[i].sh_name) ||
1365 !strcmp(".rodata1",sh_strtab+shdr[i].sh_name))
1366 kind = SECTIONKIND_CODE_OR_RODATA;
1368 /* fill in the section info */
1369 oc->sections[i].start = ehdrC + shdr[i].sh_offset;
1370 oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
1371 oc->sections[i].kind = kind;
1373 if (shdr[i].sh_type != SHT_SYMTAB) continue;
1375 /* copy stuff into this module's object symbol table */
1376 stab = (Elf32_Sym*) (ehdrC + shdr[i].sh_offset);
1377 nent = shdr[i].sh_size / sizeof(Elf32_Sym);
1378 oc->symbols = malloc(nent * sizeof(SymbolVal));
1379 oc->n_symbols = nent;
1380 for (j = 0; j < nent; j++) {
1381 if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
1382 /* || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL */
1384 /* and not an undefined symbol */
1385 && stab[j].st_shndx != SHN_UNDEF
1387 /* and it's a not a section or string table or anything silly */
1388 ( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
1389 ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
1390 ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE )
1392 char* nm = strtab + stab[j].st_name;
1394 + shdr[ stab[j].st_shndx ].sh_offset
1398 IF_DEBUG(linker,belch( "addOTabName: %10p %s %s",
1399 ad, oc->fileName, nm ));
1400 oc->symbols[j].lbl = nm;
1401 oc->symbols[j].addr = ad;
1402 insertStrHashTable(symhash, nm, &(oc->symbols[j]));
1405 IF_DEBUG(linker,belch( "skipping `%s'",
1406 strtab + stab[j].st_name ));
1409 "skipping bind = %d, type = %d, shndx = %d `%s'\n",
1410 (int)ELF32_ST_BIND(stab[j].st_info),
1411 (int)ELF32_ST_TYPE(stab[j].st_info),
1412 (int)stab[j].st_shndx,
1413 strtab + stab[j].st_name
1416 oc->symbols[j].lbl = NULL;
1417 oc->symbols[j].addr = NULL;
1426 /* Do ELF relocations which lack an explicit addend. All x86-linux
1427 relocations appear to be of this form. */
1428 static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
1429 Elf32_Shdr* shdr, int shnum,
1430 Elf32_Sym* stab, char* strtab )
1435 Elf32_Rel* rtab = (Elf32_Rel*) (ehdrC + shdr[shnum].sh_offset);
1436 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rel);
1437 int target_shndx = shdr[shnum].sh_info;
1438 int symtab_shndx = shdr[shnum].sh_link;
1439 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1440 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1441 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1442 target_shndx, symtab_shndx ));
1443 for (j = 0; j < nent; j++) {
1444 Elf32_Addr offset = rtab[j].r_offset;
1445 Elf32_Word info = rtab[j].r_info;
1447 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1448 Elf32_Word* pP = (Elf32_Word*)P;
1452 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p) ",
1453 j, (void*)offset, (void*)info ));
1455 IF_DEBUG(linker,belch( " ZERO" ));
1458 /* First see if it is a nameless local symbol. */
1459 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1460 symbol = "(noname)";
1462 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1463 + stab[ELF32_R_SYM(info)].st_value);
1465 /* No? Should be in the symbol table then. */
1466 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1467 (void *)S = lookupSymbol( symbol );
1470 barf("ocResolve_ELF: %s: unknown symbol `%s'",
1471 oc->fileName, symbol);
1473 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1475 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1476 (void*)P, (void*)S, (void*)A ));
1477 switch (ELF32_R_TYPE(info)) {
1478 # if defined(linux_TARGET_OS)
1479 case R_386_32: *pP = S + A; break;
1480 case R_386_PC32: *pP = S + A - P; break;
1483 fprintf(stderr, "unhandled ELF relocation(Rel) type %d\n",
1484 ELF32_R_TYPE(info));
1485 barf("do_Elf32_Rel_relocations: unhandled ELF relocation type");
1494 /* Do ELF relocations for which explicit addends are supplied.
1495 sparc-solaris relocations appear to be of this form. */
1496 static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
1497 Elf32_Shdr* shdr, int shnum,
1498 Elf32_Sym* stab, char* strtab )
1503 Elf32_Rela* rtab = (Elf32_Rela*) (ehdrC + shdr[shnum].sh_offset);
1504 int nent = shdr[shnum].sh_size / sizeof(Elf32_Rela);
1505 int target_shndx = shdr[shnum].sh_info;
1506 int symtab_shndx = shdr[shnum].sh_link;
1507 stab = (Elf32_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
1508 targ = (Elf32_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
1509 IF_DEBUG(linker,belch( "relocations for section %d using symtab %d",
1510 target_shndx, symtab_shndx ));
1511 for (j = 0; j < nent; j++) {
1512 Elf32_Addr offset = rtab[j].r_offset;
1513 Elf32_Word info = rtab[j].r_info;
1514 Elf32_Sword addend = rtab[j].r_addend;
1516 Elf32_Addr P = ((Elf32_Addr)targ) + offset;
1517 Elf32_Word* pP = (Elf32_Word*)P;
1518 Elf32_Addr A = addend;
1522 IF_DEBUG(linker,belch( "Rel entry %3d is raw(%6p %6p %6p) ",
1523 j, (void*)offset, (void*)info,
1526 IF_DEBUG(linker,belch( " ZERO" ));
1529 /* First see if it is a nameless local symbol. */
1530 if (stab[ ELF32_R_SYM(info)].st_name == 0) {
1531 symbol = "(noname)";
1533 (ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
1534 + stab[ELF32_R_SYM(info)].st_value);
1536 /* No? Should be in the symbol table then. */
1537 symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
1538 (void *)S = lookupSymbol( symbol );
1541 barf("ocResolve_ELF: %s: unknown symbol `%s'",
1542 oc->fileName, symbol);
1545 fprintf ( stderr, "S %p A %p S+A %p S+A-P %p\n",S,A,S+A,S+A-P);
1548 IF_DEBUG(linker,belch( "`%s' resolves to %p", symbol, (void*)S ));
1550 IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
1551 (void*)P, (void*)S, (void*)A ));
1552 switch (ELF32_R_TYPE(info)) {
1553 # if defined(solaris2_TARGET_OS)
1554 case R_SPARC_WDISP30:
1555 w1 = *pP & 0xC0000000;
1556 w2 = (Elf32_Word)((S + A - P) >> 2);
1557 ASSERT((w2 & 0xC0000000) == 0);
1562 w1 = *pP & 0xFFC00000;
1563 w2 = (Elf32_Word)((S + A) >> 10);
1564 ASSERT((w2 & 0xFFC00000) == 0);
1570 w2 = (Elf32_Word)((S + A) & 0x3FF);
1571 ASSERT((w2 & ~0x3FF) == 0);
1576 w2 = (Elf32_Word)(S + A);
1579 case R_SPARC_NONE: belch("R_SPARC_NONE");
1584 fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
1585 ELF32_R_TYPE(info));
1586 barf("do_Elf32_Rela_relocations: unhandled ELF relocation type");
1596 ocResolve_ELF ( ObjectCode* oc )
1600 Elf32_Sym* stab = NULL;
1601 char* ehdrC = (char*)(oc->image);
1602 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) ehdrC;
1603 Elf32_Shdr* shdr = (Elf32_Shdr*) (ehdrC + ehdr->e_shoff);
1605 /* first find "the" symbol table */
1606 stab = (Elf32_Sym*) findElfSection ( ehdrC, SHT_SYMTAB );
1608 /* also go find the string table */
1609 strtab = findElfSection ( ehdrC, SHT_STRTAB );
1611 if (stab == NULL || strtab == NULL) {
1612 belch("ocResolve_ELF: can't find string or symbol table");
1616 /* Process the relocation sections. */
1617 for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
1618 if (shdr[shnum].sh_type == SHT_REL ) {
1619 ok = do_Elf32_Rel_relocations ( oc, ehdrC, shdr,
1620 shnum, stab, strtab );
1624 if (shdr[shnum].sh_type == SHT_RELA) {
1625 ok = do_Elf32_Rela_relocations ( oc, ehdrC, shdr,
1626 shnum, stab, strtab );
1637 /* -----------------------------------------------------------------------------
1638 * Look up an address to discover whether it is in text or data space.
1640 * Used by the garbage collector when walking the stack.
1641 * -------------------------------------------------------------------------- */
1643 static __inline__ SectionKind
1644 lookupSection ( void* addr )
1649 for ( oc = objects; oc; oc = oc->next ) {
1650 for (i = 0; i < oc->n_sections; i++) {
1651 if (oc->sections[i].start <= addr
1652 && addr <= oc->sections[i].end)
1653 return oc->sections[i].kind;
1656 return SECTIONKIND_OTHER;
1660 is_dynamically_loaded_code_or_rodata_ptr ( void* p )
1662 SectionKind sk = lookupSection(p);
1663 ASSERT (sk != SECTIONKIND_NOINFOAVAIL);
1664 return (sk == SECTIONKIND_CODE_OR_RODATA);
1669 is_dynamically_loaded_rwdata_ptr ( void* p )
1671 SectionKind sk = lookupSection(p);
1672 ASSERT (sk != SECTIONKIND_NOINFOAVAIL);
1673 return (sk == SECTIONKIND_RWDATA);
1678 is_not_dynamically_loaded_ptr ( void* p )
1680 SectionKind sk = lookupSection(p);
1681 ASSERT (sk != SECTIONKIND_NOINFOAVAIL);
1682 return (sk == SECTIONKIND_OTHER);