Skip to content

[JITLink][AArch32] Run all error unittests through the main entrypoints applyFixup() and readAddend() #72091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,28 +226,30 @@ struct FixupInfo<Thumb_MovwAbsNC> : public FixupInfo<Thumb_MovtAbs> {
};

/// Helper function to read the initial addend for Data-class relocations.
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, const Edge &E);
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind);

/// Helper function to read the initial addend for Arm-class relocations.
Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, const Edge &E);
Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind);

/// Helper function to read the initial addend for Thumb-class relocations.
Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
const ArmConfig &ArmCfg);
Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind, const ArmConfig &ArmCfg);

/// Read the initial addend for a REL-type relocation. It's the value encoded
/// in the immediate field of the fixup location by the compiler.
inline Expected<int64_t> readAddend(LinkGraph &G, Block &B, const Edge &E,
inline Expected<int64_t> readAddend(LinkGraph &G, Block &B,
Edge::OffsetT Offset, Edge::Kind Kind,
const ArmConfig &ArmCfg) {
Edge::Kind Kind = E.getKind();
if (Kind <= LastDataRelocation)
return readAddendData(G, B, E);
return readAddendData(G, B, Offset, Kind);

if (Kind <= LastArmRelocation)
return readAddendArm(G, B, E);
return readAddendArm(G, B, Offset, Kind);

if (Kind <= LastThumbRelocation)
return readAddendThumb(G, B, E, ArmCfg);
return readAddendThumb(G, B, Offset, Kind, ArmCfg);

llvm_unreachable("Relocation must be of class Data, Arm or Thumb");
}
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,13 @@ class ELFLinkGraphBuilder_aarch32

auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
Edge E(*Kind, Offset, *GraphSymbol, 0);

Expected<int64_t> Addend =
aarch32::readAddend(*Base::G, BlockToFix, E, ArmCfg);
aarch32::readAddend(*Base::G, BlockToFix, Offset, *Kind, ArmCfg);
if (!Addend)
return Addend.takeError();

E.setAddend(*Addend);
Edge E(*Kind, Offset, *GraphSymbol, *Addend);
LLVM_DEBUG({
dbgs() << " ";
printEdge(dbgs(), BlockToFix, E, getELFAArch32EdgeKindName(*Kind));
Expand Down
26 changes: 12 additions & 14 deletions llvm/lib/ExecutionEngine/JITLink/aarch32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,11 @@ void writeImmediate(WritableArmRelocation &R, uint32_t Imm) {
R.Wd = (R.Wd & ~Mask) | Imm;
}

Expected<int64_t> readAddendData(LinkGraph &G, Block &B, const Edge &E) {
Expected<int64_t> readAddendData(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind) {
llvm::endianness Endian = G.getEndianness();

Edge::Kind Kind = E.getKind();
const char *BlockWorkingMem = B.getContent().data();
const char *FixupPtr = BlockWorkingMem + E.getOffset();
const char *FixupPtr = BlockWorkingMem + Offset;

switch (Kind) {
case Data_Delta32:
Expand All @@ -319,13 +318,13 @@ Expected<int64_t> readAddendData(LinkGraph &G, Block &B, const Edge &E) {
return make_error<JITLinkError>(
"In graph " + G.getName() + ", section " + B.getSection().getName() +
" can not read implicit addend for aarch32 edge kind " +
G.getEdgeKindName(E.getKind()));
G.getEdgeKindName(Kind));
}
}

Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, const Edge &E) {
ArmRelocation R(B.getContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind) {
ArmRelocation R(B.getContent().data() + Offset);

switch (Kind) {
case Arm_Call:
Expand All @@ -352,14 +351,13 @@ Expected<int64_t> readAddendArm(LinkGraph &G, Block &B, const Edge &E) {
return make_error<JITLinkError>(
"In graph " + G.getName() + ", section " + B.getSection().getName() +
" can not read implicit addend for aarch32 edge kind " +
G.getEdgeKindName(E.getKind()));
G.getEdgeKindName(Kind));
}
}

Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
const ArmConfig &ArmCfg) {
ThumbRelocation R(B.getContent().data() + E.getOffset());
Edge::Kind Kind = E.getKind();
Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, Edge::OffsetT Offset,
Edge::Kind Kind, const ArmConfig &ArmCfg) {
ThumbRelocation R(B.getContent().data() + Offset);

switch (Kind) {
case Thumb_Call:
Expand Down Expand Up @@ -394,7 +392,7 @@ Expected<int64_t> readAddendThumb(LinkGraph &G, Block &B, const Edge &E,
return make_error<JITLinkError>(
"In graph " + G.getName() + ", section " + B.getSection().getName() +
" can not read implicit addend for aarch32 edge kind " +
G.getEdgeKindName(E.getKind()));
G.getEdgeKindName(Kind));
}
}

Expand Down
45 changes: 7 additions & 38 deletions llvm/unittests/ExecutionEngine/JITLink/AArch32ErrorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,32 +44,16 @@ TEST(AArch32_ELF, readAddendArmErrors) {
sizeof(ArmWord));
auto &BArm = G->createContentBlock(Sec, ArmContent, B1DummyAddr, ArmAlignment,
AlignmentOffset);
Symbol &TargetSymbol =
G->addAnonymousSymbol(BArm, SymbolOffset, SymbolSize, false, false);
Edge InvalidEdge(Edge::GenericEdgeKind::Invalid, 0 /*Offset*/, TargetSymbol,
0 /*Addend*/);

// Edge kind is tested, block itself is not significant here. So it is tested
// once in Arm
EXPECT_THAT_EXPECTED(readAddendData(*G, BArm, InvalidEdge),
FailedWithMessage(testing::HasSubstr(
"can not read implicit addend for aarch32 edge kind "
"INVALID RELOCATION")));

EXPECT_THAT_EXPECTED(readAddendArm(*G, BArm, InvalidEdge),
FailedWithMessage(testing::HasSubstr(
"can not read implicit addend for aarch32 edge kind "
"INVALID RELOCATION")));
Edge::Kind Invalid = Edge::GenericEdgeKind::Invalid;

EXPECT_THAT_EXPECTED(readAddendThumb(*G, BArm, InvalidEdge, ArmCfg),
EXPECT_THAT_EXPECTED(readAddend(*G, BArm, SymbolOffset, Invalid, ArmCfg),
FailedWithMessage(testing::HasSubstr(
"can not read implicit addend for aarch32 edge kind "
"INVALID RELOCATION")));

for (Edge::Kind K = FirstArmRelocation; K < LastArmRelocation; K += 1) {
Edge E(K, 0, TargetSymbol, 0);
EXPECT_THAT_EXPECTED(
readAddendArm(*G, BArm, E),
readAddend(*G, BArm, SymbolOffset, K, ArmCfg),
FailedWithMessage(testing::StartsWith("Invalid opcode")));
}
}
Expand All @@ -90,15 +74,10 @@ TEST(AArch32_ELF, readAddendThumbErrors) {
sizeof(ThumbHalfWords));
auto &BThumb = G->createContentBlock(Sec, ThumbContent, B2DummyAddr,
ThumbAlignment, AlignmentOffset);
Symbol &TargetSymbol =
G->addAnonymousSymbol(BThumb, SymbolOffset, SymbolSize, false, false);
Edge InvalidEdge(Edge::GenericEdgeKind::Invalid, 0 /*Offset*/, TargetSymbol,
0 /*Addend*/);

for (Edge::Kind K = FirstThumbRelocation; K < LastThumbRelocation; K += 1) {
Edge E(K, 0, TargetSymbol, 0);
EXPECT_THAT_EXPECTED(
readAddendThumb(*G, BThumb, E, ArmCfg),
readAddend(*G, BThumb, SymbolOffset, K, ArmCfg),
FailedWithMessage(testing::StartsWith("Invalid opcode")));
}
}
Expand All @@ -119,24 +98,14 @@ TEST(AArch32_ELF, applyFixupArmErrors) {
Edge InvalidEdge(Edge::GenericEdgeKind::Invalid, 0 /*Offset*/, TargetSymbol,
0 /*Addend*/);

// Edge kind is tested, block itself is not significant here. So it is tested
// once in Arm
EXPECT_THAT_ERROR(
applyFixupData(*G, BArm, InvalidEdge),
FailedWithMessage(testing::HasSubstr(
"encountered unfixable aarch32 edge kind INVALID RELOCATION")));
EXPECT_THAT_ERROR(
applyFixupArm(*G, BArm, InvalidEdge),
FailedWithMessage(testing::HasSubstr(
"encountered unfixable aarch32 edge kind INVALID RELOCATION")));
EXPECT_THAT_ERROR(
applyFixupThumb(*G, BArm, InvalidEdge, ArmCfg),
applyFixup(*G, BArm, InvalidEdge, ArmCfg),
FailedWithMessage(testing::HasSubstr(
"encountered unfixable aarch32 edge kind INVALID RELOCATION")));

for (Edge::Kind K = FirstArmRelocation; K < LastArmRelocation; K += 1) {
Edge E(K, 0, TargetSymbol, 0);
EXPECT_THAT_ERROR(applyFixupArm(*G, BArm, E),
EXPECT_THAT_ERROR(applyFixup(*G, BArm, E, ArmCfg),
FailedWithMessage(testing::AllOf(
testing::StartsWith("Invalid opcode"),
testing::EndsWith(G->getEdgeKindName(K)))));
Expand Down Expand Up @@ -177,7 +146,7 @@ TEST(AArch32_ELF, applyFixupThumbErrors) {

for (Edge::Kind K = FirstThumbRelocation; K < LastThumbRelocation; K += 1) {
Edge E(K, 0, TargetSymbol, 0);
EXPECT_THAT_ERROR(applyFixupThumb(*G, BThumb, E, ArmCfg),
EXPECT_THAT_ERROR(applyFixup(*G, BThumb, E, ArmCfg),
FailedWithMessage(testing::AllOf(
testing::StartsWith("Invalid opcode"),
testing::EndsWith(G->getEdgeKindName(K)))));
Expand Down