diff options
Diffstat (limited to 'rts/Linker.c')
-rw-r--r-- | rts/Linker.c | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/rts/Linker.c b/rts/Linker.c index a1f72e5cca..ef909f0ad9 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -3497,6 +3497,26 @@ ocVerifyImage_PEi386 ( ObjectCode* oc ) } #endif + /* .BSS Section is initialized in ocGetNames_PEi386 + but we need the Sections array initialized here already. */ + Section *sections; + sections = (Section*)stgCallocBytes( + sizeof(Section), + hdr->NumberOfSections + 1, /* +1 for the global BSS section see ocGetNames_PEi386 */ + "ocVerifyImage_PEi386(sections)"); + oc->sections = sections; + oc->n_sections = hdr->NumberOfSections + 1; + + /* Initialize the Sections */ + for (i = 0; i < hdr->NumberOfSections; i++) { + COFF_section* sectab_i + = (COFF_section*) + myindex(sizeof_COFF_section, sectab, i); + + /* Calculate the start of the data section */ + sections[i].start = oc->image + sectab_i->PointerToRawData; + } + /* No further verification after this point; only debug printing. */ i = 0; IF_DEBUG(linker, i=1); @@ -3525,6 +3545,7 @@ ocVerifyImage_PEi386 ( ObjectCode* oc ) COFF_section* sectab_i = (COFF_section*) myindex ( sizeof_COFF_section, sectab, i ); + Section section = sections[i]; debugBelch( "\n" "section %d\n" @@ -3537,14 +3558,14 @@ ocVerifyImage_PEi386 ( ObjectCode* oc ) " vsize %d\n" " vaddr %d\n" " data sz %d\n" - " data off %d\n" + " data off 0x%p\n" " num rel %d\n" " off rel %d\n" " ptr raw 0x%x\n", sectab_i->VirtualSize, sectab_i->VirtualAddress, sectab_i->SizeOfRawData, - sectab_i->PointerToRawData, + section.start, sectab_i->NumberOfRelocations, sectab_i->PointerToRelocations, sectab_i->PointerToRawData @@ -3690,25 +3711,16 @@ ocGetNames_PEi386 ( ObjectCode* oc ) * triggered this is libraries/base/cbits/dirUtils.c:__hscore_getFolderPath()) */ if (sectab_i->VirtualSize == 0 && sectab_i->SizeOfRawData == 0) continue; - /* This is a non-empty .bss section. Allocate zeroed space for - it, and set its PointerToRawData field such that oc->image + - PointerToRawData == addr_of_zeroed_space. */ + /* This is a non-empty .bss section. + Allocate zeroed space for it */ bss_sz = sectab_i->VirtualSize; if ( bss_sz < sectab_i->SizeOfRawData) { bss_sz = sectab_i->SizeOfRawData; } zspace = stgCallocBytes(1, bss_sz, "ocGetNames_PEi386(anonymous bss)"); - sectab_i->PointerToRawData = ((UChar*)zspace) - ((UChar*)(oc->image)); + oc->sections[i].start = zspace; addProddableBlock(oc, zspace, bss_sz); /* debugBelch("BSS anon section at 0x%x\n", zspace); */ } - Section *sections; - sections = (Section*)stgCallocBytes( - sizeof(Section), - hdr->NumberOfSections + 1, /* +1 for the global BSS section see below */ - "ocGetNames_PEi386(sections)"); - oc->sections = sections; - oc->n_sections = hdr->NumberOfSections + 1; - /* Copy section information into the ObjectCode. */ for (i = 0; i < hdr->NumberOfSections; i++) { @@ -3722,6 +3734,7 @@ ocGetNames_PEi386 ( ObjectCode* oc ) COFF_section* sectab_i = (COFF_section*) myindex ( sizeof_COFF_section, sectab, i ); + Section section = oc->sections[i]; char *secname = cstring_from_section_name(sectab_i->Name, strtab); @@ -3748,11 +3761,11 @@ ocGetNames_PEi386 ( ObjectCode* oc ) sz = sectab_i->SizeOfRawData; if (sz < sectab_i->VirtualSize) sz = sectab_i->VirtualSize; - start = ((UChar*)(oc->image)) + sectab_i->PointerToRawData; + start = section.start; end = start + sz - 1; if (kind != SECTIONKIND_OTHER && end >= start) { - addSection(§ions[i], kind, SECTION_NOMEM, start, sz, 0, 0, 0); + addSection(&oc->sections[i], kind, SECTION_NOMEM, start, sz, 0, 0, 0); addProddableBlock(oc, start, sz); } @@ -3784,13 +3797,13 @@ ocGetNames_PEi386 ( ObjectCode* oc ) if (globalBssSize > 0) { bss = stgCallocBytes(1, globalBssSize, "ocGetNames_PEi386(non-anonymous bss)"); - addSection(§ions[oc->n_sections-1], + addSection(&oc->sections[oc->n_sections-1], SECTIONKIND_RWDATA, SECTION_MALLOC, bss, globalBssSize, 0, 0, 0); IF_DEBUG(linker, debugBelch("bss @ %p %" FMT_Word "\n", bss, globalBssSize)); addProddableBlock(oc, bss, globalBssSize); } else { - addSection(§ions[oc->n_sections-1], + addSection(&oc->sections[oc->n_sections-1], SECTIONKIND_OTHER, SECTION_NOMEM, NULL, 0, 0, 0, 0); } @@ -3817,9 +3830,8 @@ ocGetNames_PEi386 ( ObjectCode* oc ) || ( symtab_i->StorageClass == MYIMAGE_SYM_CLASS_STATIC && sectabent->Characteristics & MYIMAGE_SCN_LNK_COMDAT) ) { - addr = ((UChar*)(oc->image)) - + (sectabent->PointerToRawData - + symtab_i->Value); + addr = (void*)((size_t)oc->sections[symtab_i->SectionNumber-1].start + + symtab_i->Value); if (sectabent->Characteristics & MYIMAGE_SCN_LNK_COMDAT) { isWeak = HS_BOOL_TRUE; } @@ -3969,6 +3981,7 @@ ocResolve_PEi386 ( ObjectCode* oc ) = (COFF_reloc*) ( ((UChar*)(oc->image)) + sectab_i->PointerToRelocations ); + Section section = oc->sections[i]; char *secname = cstring_from_section_name(sectab_i->Name, strtab); @@ -4020,11 +4033,10 @@ ocResolve_PEi386 ( ObjectCode* oc ) myindex ( sizeof_COFF_reloc, reltab, j ); /* the location to patch */ - pP = ( - ((UChar*)(oc->image)) - + (sectab_i->PointerToRawData - + reltab_j->VirtualAddress - - sectab_i->VirtualAddress ) + pP = (void*)( + (size_t)section.start + + reltab_j->VirtualAddress + - sectab_i->VirtualAddress ); /* the existing contents of pP */ A = *(UInt32*)pP; @@ -4043,10 +4055,8 @@ ocResolve_PEi386 ( ObjectCode* oc ) debugBelch("'\n" )); if (sym->StorageClass == MYIMAGE_SYM_CLASS_STATIC) { - COFF_section* section_sym - = (COFF_section*) myindex ( sizeof_COFF_section, sectab, sym->SectionNumber-1 ); - S = ((size_t)(oc->image)) - + ((size_t)(section_sym->PointerToRawData)) + Section section = oc->sections[sym->SectionNumber-1]; + S = ((size_t)(section.start)) + ((size_t)(sym->Value)); } else { copyName ( sym->Name, strtab, symbol, 1000-1 ); @@ -4201,9 +4211,10 @@ ocRunInit_PEi386 ( ObjectCode *oc ) COFF_section* sectab_i = (COFF_section*) myindex ( sizeof_COFF_section, sectab, i ); + Section section = oc->sections[i]; char *secname = cstring_from_section_name(sectab_i->Name, strtab); if (0 == strcmp(".ctors", (char*)secname)) { - UChar *init_startC = (UChar*)(oc->image) + sectab_i->PointerToRawData; + UChar *init_startC = section.start; init_t *init_start, *init_end, *init; init_start = (init_t*)init_startC; init_end = (init_t*)(init_startC + sectab_i->SizeOfRawData); |