mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-12 16:29:39 +00:00
add support for R_68K_PC32 relocations
This commit is contained in:
parent
522a96e6ff
commit
4c7b83bb75
|
@ -44,9 +44,14 @@ std::string SerializeRelocsUncompressed(std::vector<RuntimeReloc> relocs)
|
||||||
std::string SerializeRelocs(std::vector<RuntimeReloc> relocs)
|
std::string SerializeRelocs(std::vector<RuntimeReloc> relocs)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
|
for(int relative = 0; relative <= 1; relative++)
|
||||||
|
{
|
||||||
uint32_t offset = -1;
|
uint32_t offset = -1;
|
||||||
|
|
||||||
for(const auto& r : relocs)
|
for(const auto& r : relocs)
|
||||||
|
{
|
||||||
|
if(r.relative == (bool)relative)
|
||||||
{
|
{
|
||||||
uint32_t delta = r.offset - offset;
|
uint32_t delta = r.offset - offset;
|
||||||
offset = r.offset;
|
offset = r.offset;
|
||||||
|
@ -62,8 +67,10 @@ std::string SerializeRelocs(std::vector<RuntimeReloc> relocs)
|
||||||
}
|
}
|
||||||
byte(out, encoded);
|
byte(out, encoded);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
byte(out, 0);
|
byte(out, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,11 @@ public:
|
||||||
class RuntimeReloc
|
class RuntimeReloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RelocBase base;
|
RelocBase base = RelocBase::code;
|
||||||
uint32_t offset;
|
uint32_t offset = 0;
|
||||||
|
bool relative = false;
|
||||||
|
|
||||||
RuntimeReloc() : base(RelocBase::code), offset(0) {}
|
RuntimeReloc(RelocBase b = RelocBase::code, uint32_t o = 0, bool r = false) : base(b), offset(o), relative(r) {}
|
||||||
RuntimeReloc(RelocBase b, uint32_t o) : base(b), offset(o) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string SerializeRelocsUncompressed(std::vector<RuntimeReloc> relocs);
|
std::string SerializeRelocsUncompressed(std::vector<RuntimeReloc> relocs);
|
||||||
|
|
|
@ -104,17 +104,20 @@ std::vector<RuntimeReloc> Section::GetRelocations(bool useOffsets)
|
||||||
if(sym.sectionKind == SectionKind::undefined)
|
if(sym.sectionKind == SectionKind::undefined)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(GELF_R_TYPE(rela.r_info) == R_68K_32)
|
|
||||||
{
|
|
||||||
assert(sym.sectionKind != SectionKind::undefined);
|
|
||||||
|
|
||||||
uint32_t offset = rela.r_offset;
|
uint32_t offset = rela.r_offset;
|
||||||
if(useOffsets)
|
if(useOffsets)
|
||||||
offset -= shdr.sh_addr;
|
offset -= shdr.sh_addr;
|
||||||
|
|
||||||
//longword(out, offset | ((int)rela.relocBase << 24));
|
if(GELF_R_TYPE(rela.r_info) == R_68K_32)
|
||||||
|
{
|
||||||
outRelocs.emplace_back(rela.relocBase, offset);
|
outRelocs.emplace_back(rela.relocBase, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(GELF_R_TYPE(rela.r_info) == R_68K_PC32
|
||||||
|
&& sym.st_shndx != idx)
|
||||||
|
{
|
||||||
|
outRelocs.emplace_back(rela.relocBase, offset, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return outRelocs;
|
return outRelocs;
|
||||||
|
@ -154,7 +157,7 @@ void Section::FixRelocs(bool allowDirectCodeRefs)
|
||||||
{
|
{
|
||||||
for(Reloc& rela : relocs)
|
for(Reloc& rela : relocs)
|
||||||
{
|
{
|
||||||
if(GELF_R_TYPE(rela.r_info) != R_68K_32)
|
if(GELF_R_TYPE(rela.r_info) != R_68K_32 && GELF_R_TYPE(rela.r_info) != R_68K_PC32)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int symidx = GELF_R_SYM(rela.r_info);
|
int symidx = GELF_R_SYM(rela.r_info);
|
||||||
|
@ -165,6 +168,9 @@ void Section::FixRelocs(bool allowDirectCodeRefs)
|
||||||
if(sym.sectionKind == SectionKind::undefined)
|
if(sym.sectionKind == SectionKind::undefined)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(GELF_R_TYPE(rela.r_info) == R_68K_PC32 && sym.st_shndx == idx)
|
||||||
|
continue;
|
||||||
|
|
||||||
RelocBase relocBase;
|
RelocBase relocBase;
|
||||||
switch(sym.sectionKind)
|
switch(sym.sectionKind)
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,6 +111,8 @@ void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, ui
|
||||||
void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, uint32_t displacements[])
|
void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, uint32_t displacements[])
|
||||||
{
|
{
|
||||||
uint8_t *reloc = (uint8_t*) relocations;
|
uint8_t *reloc = (uint8_t*) relocations;
|
||||||
|
for(int relative = 0; relative <= 1; relative++)
|
||||||
|
{
|
||||||
uint8_t *addrPtr = base - 1;
|
uint8_t *addrPtr = base - 1;
|
||||||
while(*reloc)
|
while(*reloc)
|
||||||
{
|
{
|
||||||
|
@ -135,8 +137,14 @@ void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, ui
|
||||||
|
|
||||||
uint8_t *addr = (uint8_t*) READ_UNALIGNED_LONGWORD(addrPtr);
|
uint8_t *addr = (uint8_t*) READ_UNALIGNED_LONGWORD(addrPtr);
|
||||||
addr += displacements[kind];
|
addr += displacements[kind];
|
||||||
|
if(relative)
|
||||||
|
addr -= (uint32_t) addrPtr;
|
||||||
|
|
||||||
WRITE_UNALIGNED_LONGWORD(addrPtr, (uint32_t) addr);
|
WRITE_UNALIGNED_LONGWORD(addrPtr, (uint32_t) addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reloc++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user