mirror of https://github.com/stella-emu/stella.git
Add R_ARM_REL32 .
This commit is contained in:
parent
91044b3b4f
commit
8a3cf489ec
|
@ -96,6 +96,7 @@ class ElfFile {
|
||||||
static constexpr uInt32 STT_NOTYPE = 0x00;
|
static constexpr uInt32 STT_NOTYPE = 0x00;
|
||||||
|
|
||||||
static constexpr uInt32 R_ARM_ABS32 = 0x02;
|
static constexpr uInt32 R_ARM_ABS32 = 0x02;
|
||||||
|
static constexpr uInt32 R_ARM_REL32 = 0x03;
|
||||||
static constexpr uInt32 R_ARM_THM_CALL = 0x0a;
|
static constexpr uInt32 R_ARM_THM_CALL = 0x0a;
|
||||||
static constexpr uInt32 R_ARM_THM_JUMP24 = 0x1e;
|
static constexpr uInt32 R_ARM_THM_JUMP24 = 0x1e;
|
||||||
static constexpr uInt32 R_ARM_TARGET1 = 0x26;
|
static constexpr uInt32 R_ARM_TARGET1 = 0x26;
|
||||||
|
|
|
@ -438,7 +438,12 @@ void ElfLinker::applyRelocationToSection(const ElfFile::Relocation& relocation,
|
||||||
"unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range"
|
"unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range"
|
||||||
);
|
);
|
||||||
|
|
||||||
uInt8* target =
|
const uInt32 targetAddress =
|
||||||
|
getSegmentBase(targetSectionRelocated.segment) +
|
||||||
|
targetSectionRelocated.offset +
|
||||||
|
relocation.offset;
|
||||||
|
|
||||||
|
uInt8* const target =
|
||||||
getSegmentDataRef(targetSectionRelocated.segment).get() +
|
getSegmentDataRef(targetSectionRelocated.segment).get() +
|
||||||
targetSectionRelocated.offset +
|
targetSectionRelocated.offset +
|
||||||
relocation.offset;
|
relocation.offset;
|
||||||
|
@ -453,6 +458,16 @@ void ElfLinker::applyRelocationToSection(const ElfFile::Relocation& relocation,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ElfFile::R_ARM_REL32:
|
||||||
|
{
|
||||||
|
uInt32 value = relocatedSymbol->value + relocation.addend.value_or(read32(target));
|
||||||
|
value |= (symbol.type == ElfFile::STT_FUNC ? 0x01 : 0);
|
||||||
|
|
||||||
|
write32(target, value - targetAddress);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ElfFile::R_ARM_THM_CALL:
|
case ElfFile::R_ARM_THM_CALL:
|
||||||
case ElfFile::R_ARM_THM_JUMP24:
|
case ElfFile::R_ARM_THM_JUMP24:
|
||||||
{
|
{
|
||||||
|
|
|
@ -688,6 +688,102 @@ TEST(ElfLinker, RodataSectionsGoToRodata) {
|
||||||
EXPECT_EQ(segmentRead32(linker, SegmentType::rodata, 0x14), static_cast<uInt32>(0x12345679));
|
EXPECT_EQ(segmentRead32(linker, SegmentType::rodata, 0x14), static_cast<uInt32>(0x12345679));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(ElfLinker, R_ARM_REL32_InsertsTheValueRelativeToTheTargetPosition_text) {
|
||||||
|
ElfFixture fixture(1000);
|
||||||
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
|
||||||
|
fixture
|
||||||
|
.addSection(".text.1", ElfFile::SHT_PROGBITS, 0, 0x10)
|
||||||
|
.addSection(".text.2", ElfFile::SHT_PROGBITS, 0x10, 0x10)
|
||||||
|
.addSymbol("foo", 0x12345678, ElfFile::SHN_ABS)
|
||||||
|
.addRelocation(2, 0, 0x04, ElfFile::R_ARM_REL32);
|
||||||
|
|
||||||
|
linker.link({});
|
||||||
|
|
||||||
|
EXPECT_EQ(segmentRead32(linker, SegmentType::text, 0x14), static_cast<uInt32>(0x12345678 - 0x00100014));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfLinker, R_ARM_REL32_InsertsTheValueRelativeToTheTargetPosition_data) {
|
||||||
|
ElfFixture fixture(1000);
|
||||||
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
|
||||||
|
fixture
|
||||||
|
.addSection(".data.1", ElfFile::SHT_PROGBITS, 0, 0x10)
|
||||||
|
.addSection(".data.2", ElfFile::SHT_PROGBITS, 0x10, 0x10)
|
||||||
|
.addSymbol("foo", 0x12345678, ElfFile::SHN_ABS)
|
||||||
|
.addRelocation(2, 0, 0x04, ElfFile::R_ARM_REL32);
|
||||||
|
|
||||||
|
linker.link({});
|
||||||
|
|
||||||
|
EXPECT_EQ(segmentRead32(linker, SegmentType::data, 0x14), static_cast<uInt32>(0x12345678 - 0x00200014));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfLinker, R_ARM_REL32_InsertsTheValueRelativeToTheTargetPosition_rodata) {
|
||||||
|
ElfFixture fixture(1000);
|
||||||
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
|
||||||
|
fixture
|
||||||
|
.addSection(".rodata.1", ElfFile::SHT_PROGBITS, 0, 0x10)
|
||||||
|
.addSection(".rodata.2", ElfFile::SHT_PROGBITS, 0x10, 0x10)
|
||||||
|
.addSymbol("foo", 0x12345678, ElfFile::SHN_ABS)
|
||||||
|
.addRelocation(2, 0, 0x04, ElfFile::R_ARM_REL32);
|
||||||
|
|
||||||
|
linker.link({});
|
||||||
|
|
||||||
|
EXPECT_EQ(segmentRead32(linker, SegmentType::rodata, 0x14), static_cast<uInt32>(0x12345678 - 0x00300014));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfLinker, R_ARM_REL32_AddsAddendToTarget) {
|
||||||
|
ElfFixture fixture(1000);
|
||||||
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
|
||||||
|
fixture
|
||||||
|
.addSection(".rodata.1", ElfFile::SHT_PROGBITS, 0, 0x10)
|
||||||
|
.addSection(".rodata.2", ElfFile::SHT_PROGBITS, 0x10, 0x10)
|
||||||
|
.addSymbol("foo", 0x12345678, ElfFile::SHN_ABS)
|
||||||
|
.addRelocation(2, 0, 0x04, ElfFile::R_ARM_REL32, -4);
|
||||||
|
|
||||||
|
|
||||||
|
linker.link({});
|
||||||
|
|
||||||
|
EXPECT_EQ(segmentRead32(linker, SegmentType::rodata, 0x14), static_cast<uInt32>(0x12345674 - 0x00300014));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfLinker, R_ARM_REL32_UsesExistingValueAsAddend) {
|
||||||
|
ElfFixture fixture(1000);
|
||||||
|
|
||||||
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
|
||||||
|
fixture
|
||||||
|
.addSection(".rodata.1", ElfFile::SHT_PROGBITS, 0, 0x10)
|
||||||
|
.addSection(".rodata.2", ElfFile::SHT_PROGBITS, 0x10, 0x10)
|
||||||
|
.addSymbol("foo", 0x12345678, ElfFile::SHN_ABS)
|
||||||
|
.addRelocation(2, 0, 0x04, ElfFile::R_ARM_REL32)
|
||||||
|
.write32(0x14, -4);
|
||||||
|
|
||||||
|
|
||||||
|
linker.link({});
|
||||||
|
|
||||||
|
EXPECT_EQ(segmentRead32(linker, SegmentType::rodata, 0x14), static_cast<uInt32>(0x12345674 - 0x00300014));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfLinker, R_ARM_REL32_SetsBit0IfTargetIsFunction) {
|
||||||
|
ElfFixture fixture(1000);
|
||||||
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
|
||||||
|
fixture
|
||||||
|
.addSection(".rodata.1", ElfFile::SHT_PROGBITS, 0, 0x10)
|
||||||
|
.addSection(".rodata.2", ElfFile::SHT_PROGBITS, 0x10, 0x10)
|
||||||
|
.addSymbol("foo", 0x12345678, ElfFile::SHN_ABS, ElfFile::STT_FUNC)
|
||||||
|
.addRelocation(2, 0, 0x04, ElfFile::R_ARM_REL32);
|
||||||
|
|
||||||
|
|
||||||
|
linker.link({});
|
||||||
|
|
||||||
|
EXPECT_EQ(segmentRead32(linker, SegmentType::rodata, 0x14), static_cast<uInt32>(0x12345679 - 0x00300014));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ElfLinker, R_ARM_THM_CALL_PatchesOffset) {
|
TEST(ElfLinker, R_ARM_THM_CALL_PatchesOffset) {
|
||||||
ElfFixture fixture(1000);
|
ElfFixture fixture(1000);
|
||||||
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
ElfLinker linker(0x00100000, 0x00200000, 0x00300000, fixture);
|
||||||
|
@ -854,7 +950,7 @@ TEST(ElfLinker, RodataSectionsGoToRodata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(RelocationExceptionSuite, RelocationExceptionTest, testing::Values(
|
INSTANTIATE_TEST_SUITE_P(RelocationExceptionSuite, RelocationExceptionTest, testing::Values(
|
||||||
ElfFile::R_ARM_ABS32, ElfFile::R_ARM_TARGET1,
|
ElfFile::R_ARM_ABS32, ElfFile::R_ARM_TARGET1, ElfFile::R_ARM_REL32,
|
||||||
ElfFile::R_ARM_THM_CALL, ElfFile::R_ARM_THM_JUMP24
|
ElfFile::R_ARM_THM_CALL, ElfFile::R_ARM_THM_JUMP24
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue