Skip to content

Commit

Permalink
Assert that labels are defined when applying label relocations
Browse files Browse the repository at this point in the history
A label has a null address until its location is determined when it is
encountered in the instruction stream during binary encoding. When the
compiler generates a jump to a label whose address has not yet been
determined, it also generates a label relocation to correct the jump
target once the label's address is known after binary encoding. But if
for some reason the label's address is never updated, the relocation
would silently continue using zero and generate an incorrect jump.

Because such jumps can be hard to debug, this commit adds assertions
that verify that the label has at least had some address set, otherwise
failing fast. Note that zero cannot be the true address of a label,
since we never generate instructions there.
  • Loading branch information
jdmpapin committed Jul 12, 2021
1 parent 07e7658 commit 43323d2
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
20 changes: 18 additions & 2 deletions compiler/codegen/Relocation.cpp
Expand Up @@ -58,21 +58,34 @@ TR::RelocationDebugInfo* TR::Relocation::getDebugInfo()
{
return this->_genData;
}

void TR::LabelRelocation::assertLabelDefined()
{
TR_ASSERT_FATAL(
_label->getCodeLocation() != NULL,
"cannot relocate reference to undefined label: %s (%p)\n",
_label->getName(TR::comp()->getDebug()),
_label);
}

void TR::LabelRelative8BitRelocation::apply(TR::CodeGenerator *codeGen)
{
AOTcgDiag2(codeGen->comp(), "TR::LabelRelative8BitRelocation::apply cursor=" POINTER_PRINTF_FORMAT " label=" POINTER_PRINTF_FORMAT "\n", getUpdateLocation(), getLabel());
assertLabelDefined();
codeGen->apply8BitLabelRelativeRelocation((int32_t *)getUpdateLocation(), getLabel());
}

void TR::LabelRelative12BitRelocation::apply(TR::CodeGenerator *codeGen)
{
AOTcgDiag2(codeGen->comp(), "TR::LabelRelative12BitRelocation::apply cursor=" POINTER_PRINTF_FORMAT " label=" POINTER_PRINTF_FORMAT "\n", getUpdateLocation(), getLabel());
assertLabelDefined();
codeGen->apply12BitLabelRelativeRelocation((int32_t *)getUpdateLocation(), getLabel(), isCheckDisp());
}

void TR::LabelRelative16BitRelocation::apply(TR::CodeGenerator *codeGen)
{
AOTcgDiag2(codeGen->comp(), "TR::LabelRelative16BitRelocation::apply cursor=" POINTER_PRINTF_FORMAT " label=" POINTER_PRINTF_FORMAT "\n", getUpdateLocation(), getLabel());
assertLabelDefined();
if(getAddressDifferenceDivisor() == 1)
codeGen->apply16BitLabelRelativeRelocation((int32_t *)getUpdateLocation(), getLabel());
else
Expand All @@ -82,19 +95,22 @@ void TR::LabelRelative16BitRelocation::apply(TR::CodeGenerator *codeGen)
void TR::LabelRelative24BitRelocation::apply(TR::CodeGenerator *codeGen)
{
AOTcgDiag2(codeGen->comp(), "TR::LabelRelative24BitRelocation::apply cursor=" POINTER_PRINTF_FORMAT " label=" POINTER_PRINTF_FORMAT "\n", getUpdateLocation(), getLabel());
assertLabelDefined();
codeGen->apply24BitLabelRelativeRelocation((int32_t *)getUpdateLocation(), getLabel());
}

void TR::LabelRelative32BitRelocation::apply(TR::CodeGenerator *codeGen)
{
AOTcgDiag2(codeGen->comp(), "TR::LabelRelative32BitRelocation::apply cursor=" POINTER_PRINTF_FORMAT " label=" POINTER_PRINTF_FORMAT "\n", getUpdateLocation(), getLabel());
assertLabelDefined();
codeGen->apply32BitLabelRelativeRelocation((int32_t *)getUpdateLocation(), getLabel());
}

void TR::LabelAbsoluteRelocation::apply(TR::CodeGenerator *codeGen)
{
intptr_t *cursor = (intptr_t *)getUpdateLocation();
AOTcgDiag2(codeGen->comp(), "TR::LabelAbsoluteRelocation::apply cursor=" POINTER_PRINTF_FORMAT " label=" POINTER_PRINTF_FORMAT "\n", cursor, getLabel());
assertLabelDefined();
*cursor = (intptr_t)getLabel()->getCodeLocation();
}

Expand Down Expand Up @@ -124,7 +140,7 @@ void
TR::InstructionLabelRelative16BitRelocation::apply(TR::CodeGenerator* cg)
{
uint8_t* p = getUpdateLocation();

assertLabelDefined();
*reinterpret_cast<int16_t*>(p) = static_cast<int16_t>(getLabel()->getCodeLocation() - p) / _divisor;
}

Expand Down Expand Up @@ -154,7 +170,7 @@ void
TR::InstructionLabelRelative32BitRelocation::apply(TR::CodeGenerator* cg)
{
uint8_t* p = getUpdateLocation();

assertLabelDefined();
*reinterpret_cast<int32_t*>(p) = static_cast<int32_t>(getLabel()->getCodeLocation() - p) / _divisor;
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/codegen/Relocation.hpp
Expand Up @@ -119,6 +119,8 @@ class LabelRelocation : public TR::Relocation
TR::LabelSymbol *getLabel() {return _label;}
TR::LabelSymbol *setLabel(TR::LabelSymbol *l) {return (_label = l);}

protected:
void assertLabelDefined();
};

class LabelRelative8BitRelocation : public TR::LabelRelocation
Expand Down

0 comments on commit 43323d2

Please sign in to comment.