Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

121 lines
4.4 KiB

/***********************************************************************
* Microsoft (R) 32-Bit Incremental Linker
*
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
*
* File: pe.cpp
*
* File Comments:
*
* Linker behavior specific to the Portable Exe (PE) file format.
*
***********************************************************************/
#include "link.h"
#include "image_.h"
// CbHdr "method" -- computes the file header size. *ibHdrStart gets the
// file position of the header signature (this is not 0 in the case of
// files with DOS stubs).
//
DWORD
CbHdrPE(PIMAGE pimage, DWORD *pibHdrStart, DWORD *pfoSectionHdrs)
{
*pibHdrStart = pimage->Switch.Link.fPE ? pimage->cbDosHeader : 0;
*pfoSectionHdrs = *pibHdrStart
+ sizeof(IMAGE_FILE_HEADER)
+ pimage->ImgFileHdr.SizeOfOptionalHeader;
return *pfoSectionHdrs
+ sizeof(IMAGE_SECTION_HEADER) * pimage->ImgFileHdr.NumberOfSections
+ (IncludeDebugSection ? sizeof(IMAGE_SECTION_HEADER) : 0)
+ blkComment.cb;
}
VOID
WriteSectionHeaderPE (
IN PIMAGE /* pimage */,
IN INT Handle,
IN PSEC /* psec */,
IN PIMAGE_SECTION_HEADER SectionHeader
)
{
// call the normal COFF section-header writing thing ...
//
WriteSectionHeader(Handle, SectionHeader);
}
VOID
WriteHeaderPE(PIMAGE pimage, INT Handle)
{
if (!pimage->Switch.Link.fROM) {
WORD usMaxSecCnt;
DWORD ulMaxImageSize = 0x10000000; // 256M
// Check that the section count isn't too high.
// Note: this check is done by the NT loader before it prints the informative
// "Not an NT image" message...
switch (pimage->ImgFileHdr.Machine) {
// 4k page size
case IMAGE_FILE_MACHINE_I386:
case IMAGE_FILE_MACHINE_R4000:
case IMAGE_FILE_MACHINE_R10000:
case IMAGE_FILE_MACHINE_POWERPC:
usMaxSecCnt = (4096 - sizeof(IMAGE_NT_HEADERS)) / sizeof(IMAGE_SECTION_HEADER);
break;
// 8k page size
case IMAGE_FILE_MACHINE_ALPHA:
usMaxSecCnt = (8192 - sizeof(IMAGE_NT_HEADERS)) / sizeof(IMAGE_SECTION_HEADER);
break;
default:
usMaxSecCnt = 0xFFFF;
break;
}
if (pimage->ImgFileHdr.NumberOfSections > usMaxSecCnt) {
Warning(OutFilename, TOOMANYSECTIONS, pimage->ImgFileHdr.NumberOfSections, usMaxSecCnt);
}
if (pimage->ImgOptHdr.SizeOfImage > ulMaxImageSize) {
Warning(OutFilename, IMAGETOOLARGE, pimage->ImgOptHdr.SizeOfImage, ulMaxImageSize);
}
}
FileSeek(Handle,
pimage->Switch.Link.fPE ? pimage->cbDosHeader : 0,
SEEK_SET);
WriteFileHeader(Handle, &pimage->ImgFileHdr);
if (pimage->Switch.Link.fROM &&
((pimage->ImgFileHdr.Machine == IMAGE_FILE_MACHINE_R4000) ||
(pimage->ImgFileHdr.Machine == IMAGE_FILE_MACHINE_R10000) ||
(pimage->ImgFileHdr.Machine == IMAGE_FILE_MACHINE_ALPHA))) {
IMAGE_ROM_OPTIONAL_HEADER romOptionalHdr;
romOptionalHdr.Magic = IMAGE_ROM_OPTIONAL_HDR_MAGIC;
romOptionalHdr.MajorLinkerVersion = pimage->ImgOptHdr.MajorLinkerVersion;
// The minor version MUST be larger than 34 or the SNI MIPS Firmware won't load it correctly
romOptionalHdr.MinorLinkerVersion = 60+pimage->ImgOptHdr.MinorLinkerVersion;
romOptionalHdr.SizeOfCode = pimage->ImgOptHdr.SizeOfCode;
romOptionalHdr.SizeOfInitializedData = pimage->ImgOptHdr.SizeOfInitializedData;
romOptionalHdr.SizeOfUninitializedData = pimage->ImgOptHdr.SizeOfUninitializedData;
romOptionalHdr.AddressOfEntryPoint = pimage->ImgOptHdr.AddressOfEntryPoint;
romOptionalHdr.BaseOfCode = pimage->ImgOptHdr.BaseOfCode;
romOptionalHdr.BaseOfData = pimage->ImgOptHdr.BaseOfData;
romOptionalHdr.BaseOfBss = pimage->BaseOfBss;
romOptionalHdr.GprMask = 0;
romOptionalHdr.CprMask[0] = 0;
romOptionalHdr.CprMask[1] = 0;
romOptionalHdr.CprMask[2] = 0;
romOptionalHdr.CprMask[3] = 0;
romOptionalHdr.GpValue = pextGp ? pextGp->FinalValue + romOptionalHdr.BaseOfCode : 0;
FileWrite(Handle, &romOptionalHdr, pimage->ImgFileHdr.SizeOfOptionalHeader);
} else {
WriteOptionalHeader(Handle, &pimage->ImgOptHdr, pimage->ImgFileHdr.SizeOfOptionalHeader);
}
}