X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FLinker.c;h=1d4711e9c4ef4f6080ea42e0e726fab51f0c9350;hb=d182db3a49ecb720293666fb278c1acd54c5b31d;hp=31a21dbbf2042d3308e01768549a4dbebb570051;hpb=830c1108833bbdfb9eb1309bd136aedf0b7d141f;p=ghc-hetmet.git diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index 31a21db..1d4711e 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Linker.c,v 1.78 2002/01/23 11:29:12 sewardj Exp $ + * $Id: Linker.c,v 1.83 2002/02/12 15:17:22 simonmar Exp $ * * (c) The GHC Team, 2000, 2001 * @@ -161,7 +161,7 @@ typedef struct _RtsSymbolVal { Maybe_ForeignObj \ Maybe_Stable_Names \ Sym(StgReturn) \ - Sym(__stginit_PrelGHC) \ + Sym(__stginit_GHCziPrim) \ Sym(init_stack) \ SymX(__stg_chk_0) \ SymX(__stg_chk_1) \ @@ -857,6 +857,10 @@ static void addSection ( ObjectCode* oc, SectionKind kind, s->kind = kind; s->next = oc->sections; oc->sections = s; + /* + fprintf(stderr, "addSection: %p-%p (size %d), kind %d\n", + start, ((char*)end)-1, end - start + 1, kind ); + */ } @@ -870,6 +874,33 @@ static void addSection ( ObjectCode* oc, SectionKind kind, and Common Object File Format Specification revision 5.1 January 1998 which SimonM says comes from the MS Developer Network CDs. + + It can be found there (on older CDs), but can also be found + online at: + + http://www.microsoft.com/hwdev/hardware/PECOFF.asp + + (this is Rev 6.0 from February 1999). + + Things move, so if that fails, try searching for it via + + http://www.google.com/search?q=PE+COFF+specification + + The ultimate reference for the PE format is the Winnt.h + header file that comes with the Platform SDKs; as always, + implementations will drift wrt their documentation. + + A good background article on the PE format is Matt Pietrek's + March 1994 article in Microsoft System Journal (MSJ) + (Vol.9, No. 3): "Peering Inside the PE: A Tour of the + Win32 Portable Executable File Format." The info in there + has recently been updated in a two part article in + MSDN magazine, issues Feb and March 2002, + "Inside Windows: An In-Depth Look into the Win32 Portable + Executable File Format" + + John Levine's book "Linkers and Loaders" contains useful + info on PE too. */ @@ -961,6 +992,7 @@ typedef /* From PE spec doc, section 4.1 */ #define MYIMAGE_SCN_CNT_CODE 0x00000020 #define MYIMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define MYIMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* From PE spec doc, section 5.2.1 */ #define MYIMAGE_REL_I386_DIR32 0x0006 @@ -1094,7 +1126,8 @@ zapTrailingAtSign ( UChar* sym ) static int ocVerifyImage_PEi386 ( ObjectCode* oc ) { - int i, j; + int i; + UInt32 j, noRelocs; COFF_header* hdr; COFF_section* sectab; COFF_symbol* symtab; @@ -1137,13 +1170,15 @@ ocVerifyImage_PEi386 ( ObjectCode* oc ) there are more than 64k relocations, despite claims to the contrary. Hence this test. */ /* fprintf(stderr, "strtab size %d\n", * (UInt32*)strtab); */ - if (* (UInt32*)strtab > 600000) { +#if 0 + if ( (*(UInt32*)strtab) > 600000 ) { /* Note that 600k has no special significance other than being big enough to handle the almost-2MB-sized lumps that constitute HSwin32*.o. */ belch("PEi386 object has suspiciously large string table; > 64k relocs?"); return 0; } +#endif /* No further verification after this point; only debug printing. */ i = 0; @@ -1207,8 +1242,23 @@ ocVerifyImage_PEi386 ( ObjectCode* oc ) reltab = (COFF_reloc*) ( ((UChar*)(oc->image)) + sectab_i->PointerToRelocations ); + + if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) { + /* If the relocation field (a short) has overflowed, the + * real count can be found in the first reloc entry. + * + * See Section 4.1 (last para) of the PE spec (rev6.0). + */ + COFF_reloc* rel = (COFF_reloc*) + myindex ( sizeof_COFF_reloc, reltab, 0 ); + noRelocs = rel->VirtualAddress; + j = 1; + } else { + noRelocs = sectab_i->NumberOfRelocations; + j = 0; + } - for (j = 0; j < sectab_i->NumberOfRelocations; j++) { + for (; j < noRelocs; j++) { COFF_symbol* sym; COFF_reloc* rel = (COFF_reloc*) myindex ( sizeof_COFF_reloc, reltab, j ); @@ -1218,6 +1268,7 @@ ocVerifyImage_PEi386 ( ObjectCode* oc ) rel->VirtualAddress ); sym = (COFF_symbol*) myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex ); + /* Hmm..mysterious looking offset - what's it for? SOF */ printName ( sym->Name, strtab -10 ); fprintf ( stderr, "'\n" ); } @@ -1414,9 +1465,9 @@ ocGetNames_PEi386 ( ObjectCode* oc ) /* fprintf(stderr, "BSS section at 0x%x\n", addr); */ } - if (addr != NULL) { + if (addr != NULL ) { sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab ); - /* fprintf(stderr,"addSymbol %p `%s'\n", addr,sname); */ + /* fprintf(stderr,"addSymbol %p `%s \n", addr,sname); */ IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);) ASSERT(i >= 0 && i < oc->n_symbols); /* cstring_from_COFF_symbol_name always succeeds. */ @@ -1466,7 +1517,8 @@ ocResolve_PEi386 ( ObjectCode* oc ) UInt32 S; UInt32* pP; - int i, j; + int i; + UInt32 j, noRelocs; /* ToDo: should be variable-sized? But is at least safe in the sense of buffer-overrun-proof. */ @@ -1501,7 +1553,24 @@ ocResolve_PEi386 ( ObjectCode* oc ) || 0 == strcmp(".stabstr", sectab_i->Name)) continue; - for (j = 0; j < sectab_i->NumberOfRelocations; j++) { + if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) { + /* If the relocation field (a short) has overflowed, the + * real count can be found in the first reloc entry. + * + * See Section 4.1 (last para) of the PE spec (rev6.0). + */ + COFF_reloc* rel = (COFF_reloc*) + myindex ( sizeof_COFF_reloc, reltab, 0 ); + noRelocs = rel->VirtualAddress; + fprintf(stderr, "Overflown relocs: %u\n", noRelocs); + j = 1; + } else { + noRelocs = sectab_i->NumberOfRelocations; + j = 0; + } + + + for (; j < noRelocs; j++) { COFF_symbol* sym; COFF_reloc* reltab_j = (COFF_reloc*) @@ -1871,10 +1940,11 @@ ocGetNames_ELF ( ObjectCode* oc ) } /* fill in the section info */ - addSection(oc, kind, ehdrC + shdr[i].sh_offset, - ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1); - if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0) + if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0) { addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size); + addSection(oc, kind, ehdrC + shdr[i].sh_offset, + ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1); + } if (shdr[i].sh_type != SHT_SYMTAB) continue;