mirror of
https://github.com/autc04/Retro68.git
synced 2025-01-10 10:31:09 +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 "Section.h"
|
||||
#include "SegmentMap.h"
|
||||
#include "Reloc.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
@ -135,10 +136,17 @@ void Object::FlatCode(std::ostream& out)
|
||||
|
||||
out << dataSection->GetData();
|
||||
|
||||
std::vector<RuntimeReloc> relocs;
|
||||
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)
|
||||
@ -364,11 +372,11 @@ void Object::MultiSegmentApp(string output, SegmentMap& segmentMap)
|
||||
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("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";
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include "Reloc.h"
|
||||
#include <sstream>
|
||||
#include "BinaryIO.h"
|
||||
|
||||
Reloc::Reloc()
|
||||
{
|
||||
@ -27,3 +29,41 @@ Reloc::Reloc(const GElf_Rela &rela)
|
||||
: 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
|
||||
|
||||
#include <gelf.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum class RelocBase
|
||||
{
|
||||
@ -40,4 +44,17 @@ public:
|
||||
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
|
||||
|
@ -85,9 +85,9 @@ string Section::GetData()
|
||||
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)
|
||||
{
|
||||
@ -112,12 +112,12 @@ string Section::GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry
|
||||
if(useOffsets)
|
||||
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 out.str();
|
||||
|
||||
return outRelocs;
|
||||
}
|
||||
|
||||
void Section::ScanRelocs()
|
||||
|
@ -29,6 +29,7 @@
|
||||
class Object;
|
||||
class Reloc;
|
||||
class Symbol;
|
||||
class RuntimeReloc;
|
||||
|
||||
enum class SectionKind
|
||||
{
|
||||
@ -63,7 +64,7 @@ public:
|
||||
|
||||
uint32_t GetSize();
|
||||
std::string GetData();
|
||||
std::string GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry = false);
|
||||
std::vector<RuntimeReloc> GetRelocations(bool useOffsets);
|
||||
|
||||
void ScanRelocs();
|
||||
void FixRelocs();
|
||||
|
@ -87,7 +87,7 @@ Retro68RelocState relocState __attribute__ ((section(".relocvars"))) = {
|
||||
_ptr[0] = (_a >>= 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#if 0
|
||||
void Retro68ApplyRelocations(uint8_t *base, uint32_t size, void *relocations, uint32_t displacements[])
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user