mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-04 07:29:59 +00:00
New, more compact format for relocations
This commit is contained in:
parent
a68112b08d
commit
32a2da9547
|
@ -22,6 +22,7 @@
|
||||||
#include "Symtab.h"
|
#include "Symtab.h"
|
||||||
#include "Section.h"
|
#include "Section.h"
|
||||||
#include "SegmentMap.h"
|
#include "SegmentMap.h"
|
||||||
|
#include "Reloc.h"
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -135,10 +136,17 @@ void Object::FlatCode(std::ostream& out)
|
||||||
|
|
||||||
out << dataSection->GetData();
|
out << dataSection->GetData();
|
||||||
|
|
||||||
|
std::vector<RuntimeReloc> relocs;
|
||||||
for(auto sec : codeSections)
|
for(auto sec : codeSections)
|
||||||
out << sec->GetAbsRelocations(false, true);
|
{
|
||||||
out << dataSection->GetAbsRelocations(false);
|
auto tmp = sec->GetRelocations(false);
|
||||||
|
relocs.insert(relocs.end(), tmp.begin(), tmp.end());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto tmp = dataSection->GetRelocations(false);
|
||||||
|
relocs.insert(relocs.end(), tmp.begin(), tmp.end());
|
||||||
|
}
|
||||||
|
out << SerializeRelocs(relocs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::FlatCode(string fn)
|
void Object::FlatCode(string fn)
|
||||||
|
@ -364,11 +372,11 @@ void Object::MultiSegmentApp(string output, SegmentMap& segmentMap)
|
||||||
segmentName));
|
segmentName));
|
||||||
|
|
||||||
|
|
||||||
rsrc.addResource(Resource(ResType("RELA"),id, sec->GetAbsRelocations(true)));
|
rsrc.addResource(Resource(ResType("RELA"),id, SerializeRelocs(sec->GetRelocations(true))));
|
||||||
}
|
}
|
||||||
|
|
||||||
rsrc.addResource(Resource(ResType("DATA"),0, dataSection->GetData()));
|
rsrc.addResource(Resource(ResType("DATA"),0, dataSection->GetData()));
|
||||||
rsrc.addResource(Resource(ResType("RELA"),0, dataSection->GetAbsRelocations(true)));
|
rsrc.addResource(Resource(ResType("RELA"),0, SerializeRelocs(dataSection->GetRelocations(true))));
|
||||||
|
|
||||||
std::cout << "DATA 0: " << dataSection->shdr.sh_size << " bytes\n";
|
std::cout << "DATA 0: " << dataSection->shdr.sh_size << " bytes\n";
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Reloc.h"
|
#include "Reloc.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include "BinaryIO.h"
|
||||||
|
|
||||||
Reloc::Reloc()
|
Reloc::Reloc()
|
||||||
{
|
{
|
||||||
|
@ -27,3 +29,41 @@ Reloc::Reloc(const GElf_Rela &rela)
|
||||||
: GElf_Rela(rela), relocBase(RelocBase::code)
|
: GElf_Rela(rela), relocBase(RelocBase::code)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SerializeRelocsUncompressed(std::vector<RuntimeReloc> relocs)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
for(const auto& r : relocs)
|
||||||
|
{
|
||||||
|
longword(out, r.offset | ((int)r.base << 24));
|
||||||
|
}
|
||||||
|
longword(out, -1);
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SerializeRelocs(std::vector<RuntimeReloc> relocs)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
uint32_t offset = -1;
|
||||||
|
|
||||||
|
for(const auto& r : relocs)
|
||||||
|
{
|
||||||
|
uint32_t delta = r.offset - offset;
|
||||||
|
offset = r.offset;
|
||||||
|
|
||||||
|
uint32_t base = (uint32_t) r.base;
|
||||||
|
|
||||||
|
uint32_t encoded = (delta << 2) | base;
|
||||||
|
|
||||||
|
while(encoded >= 128)
|
||||||
|
{
|
||||||
|
byte(out, (encoded & 0x7F) | 0x80);
|
||||||
|
encoded >>= 7;
|
||||||
|
}
|
||||||
|
byte(out, encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte(out, 0);
|
||||||
|
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
#define RELOC_H
|
#define RELOC_H
|
||||||
|
|
||||||
#include <gelf.h>
|
#include <gelf.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
enum class RelocBase
|
enum class RelocBase
|
||||||
{
|
{
|
||||||
|
@ -40,4 +44,17 @@ public:
|
||||||
Reloc(const GElf_Rela& rela);
|
Reloc(const GElf_Rela& rela);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RuntimeReloc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RelocBase base;
|
||||||
|
uint32_t offset;
|
||||||
|
|
||||||
|
RuntimeReloc() : base(RelocBase::code), offset(0) {}
|
||||||
|
RuntimeReloc(RelocBase b, uint32_t o) : base(b), offset(o) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string SerializeRelocsUncompressed(std::vector<RuntimeReloc> relocs);
|
||||||
|
std::string SerializeRelocs(std::vector<RuntimeReloc> relocs);
|
||||||
|
|
||||||
#endif // RELOC_H
|
#endif // RELOC_H
|
||||||
|
|
|
@ -85,9 +85,9 @@ string Section::GetData()
|
||||||
return string((char*)data->d_buf, (char*)data->d_buf + data->d_size);
|
return string((char*)data->d_buf, (char*)data->d_buf + data->d_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Section::GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry)
|
std::vector<RuntimeReloc> Section::GetRelocations(bool useOffsets)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::vector<RuntimeReloc> outRelocs;
|
||||||
|
|
||||||
for(auto& rela : relocs)
|
for(auto& rela : relocs)
|
||||||
{
|
{
|
||||||
|
@ -112,12 +112,12 @@ string Section::GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry
|
||||||
if(useOffsets)
|
if(useOffsets)
|
||||||
offset -= shdr.sh_addr;
|
offset -= shdr.sh_addr;
|
||||||
|
|
||||||
longword(out, offset | ((int)rela.relocBase << 24));
|
//longword(out, offset | ((int)rela.relocBase << 24));
|
||||||
|
outRelocs.emplace_back(rela.relocBase, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!suppressTerminatingEntry)
|
|
||||||
longword(out, -1);
|
return outRelocs;
|
||||||
return out.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Section::ScanRelocs()
|
void Section::ScanRelocs()
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
class Object;
|
class Object;
|
||||||
class Reloc;
|
class Reloc;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
|
class RuntimeReloc;
|
||||||
|
|
||||||
enum class SectionKind
|
enum class SectionKind
|
||||||
{
|
{
|
||||||
|
@ -63,7 +64,7 @@ public:
|
||||||
|
|
||||||
uint32_t GetSize();
|
uint32_t GetSize();
|
||||||
std::string GetData();
|
std::string GetData();
|
||||||
std::string GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry = false);
|
std::vector<RuntimeReloc> GetRelocations(bool useOffsets);
|
||||||
|
|
||||||
void ScanRelocs();
|
void ScanRelocs();
|
||||||
void FixRelocs();
|
void FixRelocs();
|
||||||
|
|
|
@ -87,7 +87,7 @@ Retro68RelocState relocState __attribute__ ((section(".relocvars"))) = {
|
||||||
_ptr[0] = (_a >>= 8); \
|
_ptr[0] = (_a >>= 8); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#if 0
|
||||||
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[])
|
||||||
{
|
{
|
||||||
uint32_t *reloc = (uint32_t*) relocations;
|
uint32_t *reloc = (uint32_t*) relocations;
|
||||||
|
@ -107,6 +107,38 @@ void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, ui
|
||||||
WRITE_UNALIGNED_LONGWORD(addrPtr, (uint32_t) addr);
|
WRITE_UNALIGNED_LONGWORD(addrPtr, (uint32_t) addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, uint32_t displacements[])
|
||||||
|
{
|
||||||
|
uint8_t *reloc = (uint8_t*) relocations;
|
||||||
|
uint8_t *addrPtr = base - 1;
|
||||||
|
while(*reloc)
|
||||||
|
{
|
||||||
|
// read an uleb128 value
|
||||||
|
uint32_t val = 0;
|
||||||
|
uint8_t b;
|
||||||
|
int i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
b = *reloc++;
|
||||||
|
val |= (b & 0x7F) << i;
|
||||||
|
i += 7;
|
||||||
|
} while(b & 0x80);
|
||||||
|
|
||||||
|
// ... which consists of an offset and the displacement base index
|
||||||
|
// the offset is relative to the previous relocation, or to base-1
|
||||||
|
addrPtr += val >> 2;
|
||||||
|
uint8_t kind = val & 0x3;
|
||||||
|
|
||||||
|
assert(addrPtr >= base);
|
||||||
|
assert(addrPtr < base + size);
|
||||||
|
|
||||||
|
uint8_t *addr = (uint8_t*) READ_UNALIGNED_LONGWORD(addrPtr);
|
||||||
|
addr += displacements[kind];
|
||||||
|
WRITE_UNALIGNED_LONGWORD(addrPtr, (uint32_t) addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Retro68Relocate()
|
void Retro68Relocate()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user