mirror of https://github.com/stella-emu/stella.git
Logging.
This commit is contained in:
parent
135349ed6b
commit
5a7a72c745
|
@ -82,16 +82,17 @@ namespace {
|
|||
};
|
||||
|
||||
#ifdef DUMP_ELF
|
||||
void dumpElf(const ElfParser& elfParser) {
|
||||
void dumpElf(const ElfParser& parser)
|
||||
{
|
||||
cout << "ELF sections:" << std::endl << std::endl;
|
||||
|
||||
size_t i = 0;
|
||||
for (auto& section: elfParser.getSections()) {
|
||||
for (auto& section: parser.getSections()) {
|
||||
if (section.type != 0x00) cout << i << " " << section << std::endl;
|
||||
i++;
|
||||
}
|
||||
|
||||
auto symbols = elfParser.getSymbols();
|
||||
auto symbols = parser.getSymbols();
|
||||
cout << std::endl << "ELF symbols:" << std::endl << std::endl;
|
||||
if (symbols.size() > 0) {
|
||||
i = 0;
|
||||
|
@ -100,8 +101,8 @@ namespace {
|
|||
}
|
||||
|
||||
i = 0;
|
||||
for (auto& section: elfParser.getSections()) {
|
||||
auto rels = elfParser.getRelocations(i++);
|
||||
for (auto& section: parser.getSections()) {
|
||||
auto rels = parser.getRelocations(i++);
|
||||
if (!rels) continue;
|
||||
|
||||
cout
|
||||
|
@ -111,6 +112,49 @@ namespace {
|
|||
for (auto& rel: *rels) cout << rel << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void dumpLinkage(const ElfParser& parser, const ElfLinker& linker)
|
||||
{
|
||||
cout << std::endl << "relocated sections:" << std::endl << std::endl;
|
||||
cout << std::hex << std::setfill('0');
|
||||
|
||||
const auto& sections = parser.getSections();
|
||||
const auto& relocatedSections = linker.getRelocatedSections();
|
||||
|
||||
for (size_t i = 0; i < sections.size(); i++) {
|
||||
if (!relocatedSections[i]) continue;
|
||||
|
||||
cout
|
||||
<< sections[i].name
|
||||
<< " @ 0x"<< std::setw(8) << (relocatedSections[i]->offset +
|
||||
(relocatedSections[i]->type == ElfLinker::SectionType::text ? ADDR_TEXT_BASE : ADDR_DATA_BASE)
|
||||
)
|
||||
<< " size 0x" << std::setw(8) << sections[i].size << std::endl;
|
||||
}
|
||||
|
||||
cout << std::endl << "relocated symbols:" << std::endl << std::endl;
|
||||
|
||||
const auto& symbols = parser.getSymbols();
|
||||
const auto& relocatedSymbols = linker.getRelocatedSymbols();
|
||||
|
||||
for (size_t i = 0; i < symbols.size(); i++) {
|
||||
if (!relocatedSymbols[i]) continue;
|
||||
|
||||
cout
|
||||
<< symbols[i].name
|
||||
<< " = 0x" << std::setw(8) << relocatedSymbols[i]->value;
|
||||
|
||||
if (relocatedSymbols[i]->section) {
|
||||
cout << (*relocatedSymbols[i]->section == ElfLinker::SectionType::text ? " (text)" : " (data)");
|
||||
} else {
|
||||
cout << " (abs)";
|
||||
}
|
||||
|
||||
cout << std::endl;
|
||||
}
|
||||
|
||||
cout << std::dec;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -153,6 +197,8 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5
|
|||
}
|
||||
|
||||
#ifdef DUMP_ELF
|
||||
dumpLinkage(elfParser, elfLinker);
|
||||
|
||||
cout
|
||||
<< std::endl
|
||||
<< "ARM entrypoint: 0x"
|
||||
|
|
|
@ -78,7 +78,7 @@ void ElfLinker::link(const vector<ExternalSymbol>& externalSymbols)
|
|||
|
||||
for (size_t i = 0; i < sections.size(); i++) {
|
||||
const auto& relocatedSection = myRelocatedSections[i];
|
||||
if (!relocatedSection.has_value()) continue;
|
||||
if (!relocatedSection) continue;
|
||||
|
||||
const auto& section = sections[i];
|
||||
if (section.type != ElfParser::SHT_PROGBITS) continue;
|
||||
|
@ -192,6 +192,16 @@ ElfLinker::RelocatedSymbol ElfLinker::findRelocatedSymbol(string_view name) cons
|
|||
ElfSymbolResolutionError::raise("symbol not found");
|
||||
}
|
||||
|
||||
const vector<std::optional<ElfLinker::RelocatedSection>>& ElfLinker::getRelocatedSections() const
|
||||
{
|
||||
return myRelocatedSections;
|
||||
}
|
||||
|
||||
const vector<std::optional<ElfLinker::RelocatedSymbol>>& ElfLinker::getRelocatedSymbols() const
|
||||
{
|
||||
return myRelocatedSymbols;
|
||||
}
|
||||
|
||||
void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t iSection)
|
||||
{
|
||||
const auto& targetSection = myParser.getSections()[iSection];
|
||||
|
@ -204,6 +214,11 @@ void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t
|
|||
"unable to relocate " + symbol.name + " in " + targetSection.name + ": symbol could not be relocated"
|
||||
);
|
||||
|
||||
if (relocation.offset + 4 > targetSection.size)
|
||||
ElfLinkError::raise(
|
||||
"unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range"
|
||||
);
|
||||
|
||||
uInt8* target =
|
||||
(targetSectionRelocated.type == SectionType::text ? myTextData : myDataData).get() +
|
||||
targetSectionRelocated.offset + relocation.offset;
|
||||
|
@ -212,11 +227,6 @@ void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t
|
|||
case ElfParser::R_ARM_ABS32:
|
||||
case ElfParser::R_ARM_TARGET1:
|
||||
{
|
||||
if (relocation.offset + 4 > targetSection.size)
|
||||
ElfLinkError::raise(
|
||||
"unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range"
|
||||
);
|
||||
|
||||
const uInt32 value = relocatedSymbol->value + relocation.addend.value_or(read32(target));
|
||||
write32(target, value | (symbol.type == ElfParser::STT_FUNC ? 0x01 : 0));
|
||||
|
||||
|
@ -226,18 +236,13 @@ void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t
|
|||
case ElfParser::R_ARM_THM_CALL:
|
||||
case ElfParser::R_ARM_THM_JUMP24:
|
||||
{
|
||||
if (relocation.offset + 4 > targetSection.size)
|
||||
ElfLinkError::raise(
|
||||
"unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range"
|
||||
);
|
||||
|
||||
const uInt32 op = read32(target);
|
||||
|
||||
Int32 offset = relocatedSymbol->value + relocation.addend.value_or(elfUtil::decode_B_BL(op)) -
|
||||
(targetSectionRelocated.type == SectionType::text ? myTextBase : myDataBase) -
|
||||
targetSectionRelocated.offset - relocation.offset - 4;
|
||||
|
||||
if ((offset >> 25) != -1 && (offset >> 25) != 0)
|
||||
if ((offset >> 24) != -1 && (offset >> 24) != 0)
|
||||
ElfLinkError::raise("unable to relocate jump: offset out of bounds");
|
||||
|
||||
write32(target, elfUtil::encode_B_BL(offset, relocation.type == ElfParser::R_ARM_THM_CALL));
|
||||
|
|
|
@ -59,6 +59,11 @@ class ElfLinker {
|
|||
|
||||
enum class SectionType: uInt8 { text, data };
|
||||
|
||||
struct RelocatedSection {
|
||||
SectionType type;
|
||||
uInt32 offset;
|
||||
};
|
||||
|
||||
struct RelocatedSymbol {
|
||||
optional<SectionType> section;
|
||||
uInt32 value;
|
||||
|
@ -87,11 +92,8 @@ class ElfLinker {
|
|||
|
||||
RelocatedSymbol findRelocatedSymbol(string_view name) const;
|
||||
|
||||
private:
|
||||
struct RelocatedSection {
|
||||
SectionType type;
|
||||
uInt32 offset;
|
||||
};
|
||||
const vector<std::optional<RelocatedSection>>& getRelocatedSections() const;
|
||||
const vector<std::optional<RelocatedSymbol>>& getRelocatedSymbols() const;
|
||||
|
||||
private:
|
||||
void applyRelocation(const ElfParser::Relocation& relocation, size_t iSection);
|
||||
|
|
|
@ -329,12 +329,12 @@ ostream& operator<<(ostream& os, const ElfParser::Symbol symbol)
|
|||
os
|
||||
<< symbol.nameOffset << " "
|
||||
<< symbol.name
|
||||
<< std::hex << std::setw(4) << std::setfill('0')
|
||||
<< " value=0x" << symbol.value
|
||||
<< " size=0x" << symbol.size
|
||||
<< std::hex << std::setfill('0')
|
||||
<< " value=0x" << std::setw(8) << symbol.value
|
||||
<< " size=0x" << std::setw(8) << symbol.size
|
||||
<< std::setw(1)
|
||||
<< " bind=0x" << (int)symbol.bind
|
||||
<< " type=0x" << (int)symbol.type;
|
||||
<< " bind=0x" << std::setw(2) << (int)symbol.bind
|
||||
<< " type=0x" << std::setw(2) << (int)symbol.type;
|
||||
|
||||
os.copyfmt(reset);
|
||||
|
||||
|
@ -351,13 +351,13 @@ ostream& operator<<(ostream& os, const ElfParser::Relocation rel)
|
|||
|
||||
os
|
||||
<< rel.symbolName << " :"
|
||||
<< std::hex << std::setw(4) << std::setfill('0')
|
||||
<< " offset=0x" << rel.offset
|
||||
<< " info=0x" << rel.info
|
||||
<< " type=0x" << (int)rel.type;
|
||||
<< std::hex << std::setfill('0')
|
||||
<< " offset=0x" << std::setw(8) << rel.offset
|
||||
<< " info=0x" << std::setw(8) << rel.info
|
||||
<< " type=0x" << std::setw(2) << (int)rel.type;
|
||||
|
||||
if (rel.addend.has_value())
|
||||
os << " addend=0x" << *rel.addend;
|
||||
os << " addend=0x" << std::setw(8) << *rel.addend;
|
||||
|
||||
os.copyfmt(reset);
|
||||
|
||||
|
|
Loading…
Reference in New Issue