mirror of
https://github.com/autc04/Retro68.git
synced 2024-05-29 10:41:39 +00:00
Exceptions now work in multiseg
This commit is contained in:
parent
d08331584e
commit
8a2038601a
|
@ -40,6 +40,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::unordered_map;
|
using std::unordered_map;
|
||||||
|
@ -107,11 +108,13 @@ public:
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
vector<Symbol> symbols;
|
vector<Symbol> symbols;
|
||||||
map<pair<int,uint32_t>, int> symbolsByAddress;
|
map<pair<int,uint32_t>, int> symbolsByAddress;
|
||||||
|
unordered_map<string, int> symbolsByName;
|
||||||
|
|
||||||
Symtab(Elf_Scn *elfsec);
|
Symtab(Elf_Scn *elfsec);
|
||||||
|
|
||||||
Symbol& GetSym(int idx);
|
Symbol& GetSym(int idx);
|
||||||
int FindSym(int secidx, uint32_t addr);
|
int FindSym(int secidx, uint32_t addr);
|
||||||
|
int FindSym(string name);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Reloc : public GElf_Rela
|
class Reloc : public GElf_Rela
|
||||||
|
@ -133,6 +136,7 @@ public:
|
||||||
Elf_Data *data;
|
Elf_Data *data;
|
||||||
GElf_Shdr shdr;
|
GElf_Shdr shdr;
|
||||||
uint32_t outputBase;
|
uint32_t outputBase;
|
||||||
|
uint32_t exceptionInfoStart;
|
||||||
|
|
||||||
int codeID;
|
int codeID;
|
||||||
|
|
||||||
|
@ -212,18 +216,36 @@ int Symtab::FindSym(int secidx, uint32_t addr)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Symtab::FindSym(string name)
|
||||||
|
{
|
||||||
|
if(symbolsByName.empty())
|
||||||
|
{
|
||||||
|
for(auto& sym : symbols)
|
||||||
|
if(sym.st_name)
|
||||||
|
{
|
||||||
|
symbolsByName[sym.GetName()] = &sym - symbols.data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto p = symbolsByName.find(name);
|
||||||
|
if(p != symbolsByName.end())
|
||||||
|
return p->second;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reloc::Reloc()
|
Reloc::Reloc()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Reloc::Reloc(const GElf_Rela &rela)
|
Reloc::Reloc(const GElf_Rela &rela)
|
||||||
: GElf_Rela(rela)
|
: GElf_Rela(rela), relocBase(RelocBase::code)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Section::Section(string name, int idx, SectionKind kind, Elf_Scn *elfsec)
|
Section::Section(string name, int idx, SectionKind kind, Elf_Scn *elfsec)
|
||||||
: name(name), idx(idx), kind(kind), elfsec(elfsec), relasec(NULL),
|
: name(name), idx(idx), kind(kind), elfsec(elfsec), relasec(NULL),
|
||||||
|
exceptionInfoStart(0),
|
||||||
codeID(-1), firstJTEntryIndex(0)
|
codeID(-1), firstJTEntryIndex(0)
|
||||||
{
|
{
|
||||||
data = elf_getdata(elfsec, NULL);
|
data = elf_getdata(elfsec, NULL);
|
||||||
|
@ -288,7 +310,7 @@ string Section::GetAbsRelocations(bool useOffsets, bool suppressTerminatingEntry
|
||||||
if(useOffsets)
|
if(useOffsets)
|
||||||
offset -= shdr.sh_addr;
|
offset -= shdr.sh_addr;
|
||||||
|
|
||||||
std::cout << "RELA: " << std::hex << offset << " " << (int)rela.relocBase << std::dec << std::endl;
|
//std::cout << "RELA: " << std::hex << offset << " " << (int)rela.relocBase << std::dec << std::endl;
|
||||||
longword(out, offset | ((int)rela.relocBase << 24));
|
longword(out, offset | ((int)rela.relocBase << 24));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,7 +370,7 @@ void Section::FixRelocs()
|
||||||
{
|
{
|
||||||
case SectionKind::code:
|
case SectionKind::code:
|
||||||
relocBase = RelocBase::code;
|
relocBase = RelocBase::code;
|
||||||
if(sym.needsJT)
|
if(sym.needsJT && (exceptionInfoStart == 0 || rela.r_offset < exceptionInfoStart))
|
||||||
{
|
{
|
||||||
if(rela.r_addend == 0)
|
if(rela.r_addend == 0)
|
||||||
{
|
{
|
||||||
|
@ -644,6 +666,24 @@ void MultiSegmentApp(string output)
|
||||||
sec->outputBase = 4; // standard 'CODE' header
|
sec->outputBase = 4; // standard 'CODE' header
|
||||||
else
|
else
|
||||||
sec->outputBase = 40; // far-model 'CODE' header
|
sec->outputBase = 40; // far-model 'CODE' header
|
||||||
|
|
||||||
|
string exceptionInfoMarker = "__EH_FRAME_BEGIN__";
|
||||||
|
if(id != 1)
|
||||||
|
exceptionInfoMarker += boost::lexical_cast<string>(id);
|
||||||
|
int exceptionInfoSym = symtab->FindSym(exceptionInfoMarker);
|
||||||
|
if(exceptionInfoSym != -1)
|
||||||
|
{
|
||||||
|
Symbol& s = symtab->GetSym(exceptionInfoSym);
|
||||||
|
sec->exceptionInfoStart = s.st_value;
|
||||||
|
|
||||||
|
int codeSize = sec->shdr.sh_size;
|
||||||
|
int exceptionSize = sec->shdr.sh_addr + codeSize - sec->exceptionInfoStart;
|
||||||
|
double percent = 100.0 * exceptionSize / codeSize;
|
||||||
|
|
||||||
|
std::cout << "CODE " << id << " has " << exceptionSize << " bytes of exception info (" << percent << "%)\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
std::cout << "exception info marker not found: " << exceptionInfoMarker << std::endl;
|
||||||
}
|
}
|
||||||
dataSection->outputBase = -data_and_bss_size;
|
dataSection->outputBase = -data_and_bss_size;
|
||||||
bssSection->outputBase = -bssSection->shdr.sh_size;
|
bssSection->outputBase = -bssSection->shdr.sh_size;
|
||||||
|
|
|
@ -146,7 +146,6 @@ const char * codeSectionTemplate = R"ld(/* ld script for Elf2Mac */
|
||||||
KEEP(@FILTER@(.gcc_except_table.*))
|
KEEP(@FILTER@(.gcc_except_table.*))
|
||||||
|
|
||||||
. = ALIGN(0x4);
|
. = ALIGN(0x4);
|
||||||
LONG(0xDEADBEEF);
|
|
||||||
. += 32;
|
. += 32;
|
||||||
LONG(__EH_FRAME_BEGIN__@N@ - .);
|
LONG(__EH_FRAME_BEGIN__@N@ - .);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ pascal void* Retro68LoadSegment(uint8_t *p)
|
||||||
if (__register_frame_info)
|
if (__register_frame_info)
|
||||||
{
|
{
|
||||||
int32_t offset = ((int32_t*) (base + codeSize))[-1];
|
int32_t offset = ((int32_t*) (base + codeSize))[-1];
|
||||||
void *eh_frame_info = *(void**) (base + codeSize + offset);
|
void *eh_frame_info = base + codeSize - 4 + offset;
|
||||||
struct object *object = (struct object*) (base + codeSize - 36);
|
struct object *object = (struct object*) (base + codeSize - 36);
|
||||||
__register_frame_info(eh_frame_info, object);
|
__register_frame_info(eh_frame_info, object);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user