📄 imgdata.cpp
字号:
// Got it!
*ppbData = (dwVirtualAddr - dwAddr) + pb;
*ppSection = pSection;
goto Error;
}
dwAddr += pCmd->cBytesCompressed;
pb += pCmd->cBytesUncompressed;
}
} else {
// This entire section is uncompressed, so we must have it...
*ppbData = (dwVirtualAddr - dwAddr) + pb;
*ppSection = pSection;
goto Error;
}
}
}
hr = E_FAIL;
Error:
return hr;
} /* CImageData::FindDataPtr()
*/
CModuleData::CModuleData(CImageData *pImg, TOCentry *pTocEntry, e32_rom *pE32,
o32_rom *pO32List) :
m_pImg(pImg), m_pTOCentry(pTocEntry), m_pE32(pE32), m_pO32List(pO32List)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
} /* CModuleData::CModuleData()
*/
CSecDiv::CSecDiv() : m_cSections(0), m_pSections(NULL)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
} /* CSecDiv::CSecDiv()
*/
CSecDiv::~CSecDiv()
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
LocalFree(m_pSections);
} /* CSecDiv::~CSecDiv()
*/
HRESULT
CSecDiv::Add(LPBYTE pbSec)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
HRESULT hr = NOERROR;
if (m_cSections % NUM_SECTIONS == 0) {
CHR(SafeRealloc((LPVOID*)&m_pSections, (m_cSections + NUM_SECTIONS) * sizeof(LPBYTE)));
}
m_pSections[m_cSections] = pbSec;
m_cSections++;
Error:
return hr;
} /* CSecDiv::Add()
*/
BOOL
CSecDiv::IsSecDiv(UCHAR* pbBuf)
/*---------------------------------------------------------------------------*\
* Return TRUE iff "pbBuf" is a division between sections in the old image file
\*---------------------------------------------------------------------------*/
{
UINT32 iSec = 0;
if (*pbBuf != SEC_DIV_CHAR) {
return FALSE;
}
while ((iSec < m_cSections) && (m_pSections[iSec] < pbBuf)) {
++iSec;
}
return ((iSec < m_cSections) && (m_pSections[iSec] == pbBuf));
} /* CSecDiv::IsSecDiv()
*/
HRESULT
CSectionData::BeginReloc(DWORD dwFixupOffset)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
HRESULT hr = NOERROR;
DWORD dwOffset;
// dwFixupOffset is the amount that we fixed up to do the Reverse fixup.
// the instruction we need to write into the file to do the proper fixup
// is the instruction for -dwFixupOffset;
dwOffset = -dwFixupOffset;
if(dwOffset != m_dwCurrentRelocOffset) {
m_dwCurrentRelocOffset = dwOffset;
CHR(FlushPrevCmd());
m_dwPrevCmd = RELOC_CMDTYPE_OFFSET << RELOC_CMD_SHIFT;
m_dwPrevCmdData = dwOffset;
}
Error:
return hr;
} /* CSectionData::BeginReloc()
*/
DWORD
GetNextPattern(DWORD dwCmd, DWORD dwData)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
ASSERT(GetRelocCmd(dwCmd) & RELOC_CMDTYPE_PATTERN);
return dwData + ((GetRelocSkip(dwCmd) + 1) * (GetRelocCount(dwCmd) + 2)) * sizeof(DWORD);
} /* GetNextPattern()
*/
DWORD
GetEndOfPattern(DWORD dwCmd, DWORD dwData)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
ASSERT(GetRelocCmd(dwCmd) & RELOC_CMDTYPE_PATTERN);
return dwData + ((GetRelocSkip(dwCmd) + 1) * (GetRelocCount(dwCmd) + 1)) * sizeof(DWORD);
} /* GetEndOfPattern()
*/
HRESULT
CSectionData::FlushPrevCmdVarInt(UINT32 u)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
HRESULT hr = NOERROR;
BYTE b;
do {
b = u & 0x7f;
if(u >>= 7) {
b |= RELOC_VARINT_CONTINUATION_BIT;
}
CHR(AddRelocCmd(&b, 1));
} while(u > 0);
Error:
return hr;
} /* CSectionData::FlushPrevCmdVarInt()
*/
HRESULT
CSectionData::FlushPrevCmd()
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
HRESULT hr = NOERROR;
BYTE b;
if(m_dwPrevCmd != INVALID_CMD) {
DWORD dwAddr = m_dwPrevCmdData - m_dwSecondtoLastCmdData;
switch(GetRelocCmd(m_dwPrevCmd)) {
case RELOC_CMDTYPE_OFFSET:
b = m_dwPrevCmd;
// We don't use the diff for an Offset command
dwAddr = m_dwPrevCmdData;
// Check for 64k alignment
if((dwAddr & 0xFFFF) == 0) {
// 64k aligned!
dwAddr >>= 16;
b |= RELOC_OFFSET_64K_ALIGN_BIT;
}
b |= dwAddr & 0x0f;
if(dwAddr >>= 4) {
b |= RELOC_OFFSET_CONTINUATION_BIT;
}
CHR(AddRelocCmd(&b, 1));
if(dwAddr) {
CHR(FlushPrevCmdVarInt(dwAddr));
}
// We want the command after an OFFSET command
// to diff against 0.
m_dwPrevCmdData = 0;
break;
case RELOC_CMDTYPE_SINGLE:
b = m_dwPrevCmd;
b |= dwAddr & 0x1f;
if(dwAddr >>= 5) {
b |= RELOC_SINGLE_CONTINUATION_BIT;
}
CHR(AddRelocCmd(&b, 1));
if(dwAddr) {
CHR(FlushPrevCmdVarInt(dwAddr));
}
break;
case RELOC_CMDTYPE_PATTERN:
case RELOC_CMDTYPE_PATTERN2:
b = m_dwPrevCmd;
CHR(AddRelocCmd(&b, 1));
CHR(FlushPrevCmdVarInt(dwAddr));
// Update the previous address so that the next command will
// be from the diff of the last entry in the pattern, isntead
// of the first. This will minimize the distance to the next
// fixup.
m_dwPrevCmdData = GetEndOfPattern(m_dwPrevCmd, m_dwPrevCmdData);
break;
default:
ASSERT(0);
break;
}
m_dwSecondtoLastCmdData = m_dwPrevCmdData;
m_dwPrevCmdData = 0;
m_dwPrevCmd = INVALID_CMD;
}
Error:
return hr;
} /* CSectionData::FlushPrevCmd()
*/
HRESULT
CSectionData::AddReloc(DWORD dwFixupLoc)
/*---------------------------------------------------------------------------*\
*
\*---------------------------------------------------------------------------*/
{
HRESULT hr = NOERROR;
if(m_dwPrevCmd != INVALID_CMD) {
// There is a previous command. Let's see if we can extend it...
DWORD dwPrevCmdData;
DWORD dwCmdData;
// We can only make patterns if we have DWORD aligned fixups...
// If this fixup (or the previous one) is NOT DWORD aligned, then we
// have to make this into a Single
if(((dwFixupLoc & 0x0003) != 0) || ((m_dwPrevCmdData & 0x0003) != 0)) {
goto MakeSingle;
}
dwPrevCmdData = m_dwPrevCmdData >> 2;
dwCmdData = dwFixupLoc >> 2;
switch(GetRelocCmd(m_dwPrevCmd)) {
case RELOC_CMDTYPE_OFFSET:
// Nope, can't extend an offset command
goto MakeSingle;
case RELOC_CMDTYPE_SINGLE:
{
// First check for pattern:
DWORD dwSkip = dwCmdData - dwPrevCmdData - 1;
if(dwSkip <= MAX_SKIP) {
// We can build a pattern out of these two commands
// Let's go modify the previous command to be a
// pattern command.
DWORD dwNewCmd = RELOC_CMDTYPE_PATTERN << RELOC_CMD_SHIFT;
dwNewCmd |= dwSkip << RELOC_SKIP_SHIFT;
// The count field should be set to 0, since a 0 in
// the count field means 2 times through the pattern.
// m_dwPrevCmdData is already set to the fixup address
// of the first item in the pattern, so we are ready
// to go... Just set that up as the new "last cmd" and
// return.
m_dwPrevCmd = dwNewCmd;
goto Error;
} else {
// This entry is too far away from the last entry
// to make a pattern entry. Let's just make a single
// entry instead...
goto MakeSingle;
}
}
break;
case RELOC_CMDTYPE_PATTERN:
case RELOC_CMDTYPE_PATTERN2:
{
if(dwFixupLoc == GetNextPattern(m_dwPrevCmd, m_dwPrevCmdData)) {
// Awesome... this fixup fits nicely into our pattern. Let's
// just extend the pattern one more count...
DWORD dwNewCmd = RELOC_CMDTYPE_PATTERN << RELOC_CMD_SHIFT;
dwNewCmd |= GetRelocSkip(m_dwPrevCmd) << RELOC_SKIP_SHIFT;
dwNewCmd |= (GetRelocCount(m_dwPrevCmd) + 1) << RELOC_COUNT_SHIFT;
m_dwPrevCmd = dwNewCmd;
if(GetRelocCount(m_dwPrevCmd) == MAX_COUNT) {
// That's the end of life for this pattern... Let's flush it
// so we'll start over with a single next time...
CHR(FlushPrevCmd());
}
goto Error;
} else {
// Nope, we don't fit into the previous pattern. Just
// make a single...
goto MakeSingle;
}
}
break;
default:
ASSERT(0);
CHR(E_FAIL);
}
}
MakeSingle:
CHR(FlushPrevCmd());
m_dwPrevCmd = RELOC_CMDTYPE_SINGLE << RELOC_CMD_SHIFT;
m_dwPrevCmdData = dwFixupLoc;
Error:
return hr;
} /* CSectionData::AddReloc()
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -