mirror of
https://github.com/ksherlock/x65.git
synced 2025-02-12 16:30:39 +00:00
Fixes
- Sections got overwritten (reference vs pointer mistake) - Check that relocs and late evals apply the adjustments within the existing binary
This commit is contained in:
parent
ca604ad81c
commit
12cfe830f9
95
x65.cpp
95
x65.cpp
@ -117,6 +117,7 @@ enum StatusCode {
|
|||||||
ERROR_LINKER_MUST_BE_IN_FIXED_ADDRESS_SECTION,
|
ERROR_LINKER_MUST_BE_IN_FIXED_ADDRESS_SECTION,
|
||||||
ERROR_LINKER_CANT_LINK_TO_DUMMY_SECTION,
|
ERROR_LINKER_CANT_LINK_TO_DUMMY_SECTION,
|
||||||
ERROR_UNABLE_TO_PROCESS,
|
ERROR_UNABLE_TO_PROCESS,
|
||||||
|
ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE,
|
||||||
|
|
||||||
STATUSCODE_COUNT
|
STATUSCODE_COUNT
|
||||||
};
|
};
|
||||||
@ -173,6 +174,7 @@ const char *aStatusStrings[STATUSCODE_COUNT] = {
|
|||||||
"Link can only be used in a fixed address section",
|
"Link can only be used in a fixed address section",
|
||||||
"Link can not be used in dummy sections",
|
"Link can not be used in dummy sections",
|
||||||
"Can not process this line",
|
"Can not process this line",
|
||||||
|
"Unexpected target offset for reloc or late evaluation",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assembler directives
|
// Assembler directives
|
||||||
@ -728,6 +730,7 @@ public:
|
|||||||
void SetSection(strref name); // relative address section
|
void SetSection(strref name); // relative address section
|
||||||
StatusCode LinkSections(strref name); // link relative address sections with this name here
|
StatusCode LinkSections(strref name); // link relative address sections with this name here
|
||||||
void LinkLabelsToAddress(int section_id, int section_address);
|
void LinkLabelsToAddress(int section_id, int section_address);
|
||||||
|
StatusCode LinkRelocs(int section_id, int section_address);
|
||||||
void DummySection(int address);
|
void DummySection(int address);
|
||||||
void DummySection();
|
void DummySection();
|
||||||
void EndSection();
|
void EndSection();
|
||||||
@ -1005,6 +1008,54 @@ void Asm::LinkLabelsToAddress(int section_id, int section_address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// go through relocs in all sections to see if any targets this section
|
||||||
|
// relocate section to address!
|
||||||
|
StatusCode Asm::LinkRelocs(int section_id, int section_address)
|
||||||
|
{
|
||||||
|
for (std::vector<Section>::iterator j = allSections.begin(); j != allSections.end(); ++j) {
|
||||||
|
Section &s2 = *j;
|
||||||
|
if (s2.pRelocs) {
|
||||||
|
relocList *pList = s2.pRelocs;
|
||||||
|
relocList::iterator i = pList->end();
|
||||||
|
while (i != pList->begin()) {
|
||||||
|
--i;
|
||||||
|
if (i->target_section == section_id) {
|
||||||
|
Section *trg_sect = &s2;
|
||||||
|
size_t output_offs = 0;
|
||||||
|
while (trg_sect->merged_offset>=0) {
|
||||||
|
output_offs += trg_sect->merged_offset;
|
||||||
|
trg_sect = &allSections[trg_sect->merged_section];
|
||||||
|
}
|
||||||
|
unsigned char *trg = trg_sect->output + output_offs + i->section_offset;
|
||||||
|
int value = i->base_value + section_address;
|
||||||
|
if (i->value_type == Reloc::WORD) {
|
||||||
|
if ((trg+1) >= (trg_sect->output + trg_sect->size()))
|
||||||
|
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||||
|
*trg++ = (unsigned char)value;
|
||||||
|
*trg = (unsigned char)(value >> 8);
|
||||||
|
} else if (i->value_type == Reloc::LO_BYTE) {
|
||||||
|
if (trg >= (trg_sect->output + trg_sect->size()))
|
||||||
|
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||||
|
*trg = (unsigned char)value;
|
||||||
|
} else if (i->value_type == Reloc::HI_BYTE) {
|
||||||
|
if (trg >= (trg_sect->output + trg_sect->size()))
|
||||||
|
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||||
|
*trg = (unsigned char)(value >> 8);
|
||||||
|
}
|
||||||
|
i = pList->erase(i);
|
||||||
|
if (i != pList->end())
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pList->empty()) {
|
||||||
|
free(pList);
|
||||||
|
s2.pRelocs = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
StatusCode Asm::LinkSections(strref name) {
|
StatusCode Asm::LinkSections(strref name) {
|
||||||
if (CurrSection().IsRelativeSection())
|
if (CurrSection().IsRelativeSection())
|
||||||
return ERROR_LINKER_MUST_BE_IN_FIXED_ADDRESS_SECTION;
|
return ERROR_LINKER_MUST_BE_IN_FIXED_ADDRESS_SECTION;
|
||||||
@ -1040,34 +1091,9 @@ StatusCode Asm::LinkSections(strref name) {
|
|||||||
// All labels in this section can now be assigned
|
// All labels in this section can now be assigned
|
||||||
LinkLabelsToAddress(section_id, section_address);
|
LinkLabelsToAddress(section_id, section_address);
|
||||||
|
|
||||||
// go through relocs in all sections to see if any targets this section
|
StatusCode status = LinkRelocs(section_id, section_address);
|
||||||
// relocate section to address!
|
if (status != STATUS_OK)
|
||||||
for (std::vector<Section>::iterator j = allSections.begin(); j != allSections.end(); ++j) {
|
return status;
|
||||||
Section &s2 = *j;
|
|
||||||
if (s2.pRelocs) {
|
|
||||||
relocList *pList = s2.pRelocs;
|
|
||||||
relocList::iterator i = pList->end();
|
|
||||||
while (i != pList->begin()) {
|
|
||||||
--i;
|
|
||||||
if (i->target_section == section_id) {
|
|
||||||
unsigned char *trg = s2.merged_offset < 0 ? s2.output :
|
|
||||||
(allSections[s2.merged_section].output + s2.merged_offset);
|
|
||||||
trg += i->section_offset;
|
|
||||||
int value = i->base_value + section_address;
|
|
||||||
if (i->value_type == Reloc::WORD) {
|
|
||||||
*trg++ = (unsigned char)value;
|
|
||||||
*trg = (unsigned char)(value >> 8);
|
|
||||||
} else if (i->value_type == Reloc::LO_BYTE)
|
|
||||||
*trg = (unsigned char)value;
|
|
||||||
else if (i->value_type == Reloc::HI_BYTE)
|
|
||||||
*trg = (unsigned char)(value >> 8);
|
|
||||||
i = pList->erase(i);
|
|
||||||
if (i != pList->end())
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
++section_id;
|
++section_id;
|
||||||
}
|
}
|
||||||
@ -1124,9 +1150,6 @@ void Section::AddReloc(int base, int offset, int section, Reloc::Type type)
|
|||||||
pRelocs = new relocList;
|
pRelocs = new relocList;
|
||||||
if (pRelocs->size() == pRelocs->capacity())
|
if (pRelocs->size() == pRelocs->capacity())
|
||||||
pRelocs->reserve(pRelocs->size() + 32);
|
pRelocs->reserve(pRelocs->size() + 32);
|
||||||
|
|
||||||
printf("Add reloc base = $0x%04x offs=$0x%04x section=$0x%04x type = %d\n", base, offset, section, type);
|
|
||||||
|
|
||||||
pRelocs->push_back(Reloc(base, offset, section, type));
|
pRelocs->push_back(Reloc(base, offset, section, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1803,6 +1826,8 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
|||||||
value -= i->address+1;
|
value -= i->address+1;
|
||||||
if (value<-128 || value>127)
|
if (value<-128 || value>127)
|
||||||
return ERROR_BRANCH_OUT_OF_RANGE;
|
return ERROR_BRANCH_OUT_OF_RANGE;
|
||||||
|
if (trg >= allSections[sec].size())
|
||||||
|
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||||
allSections[sec].SetByte(trg, value);
|
allSections[sec].SetByte(trg, value);
|
||||||
break;
|
break;
|
||||||
case LateEval::LET_BYTE:
|
case LateEval::LET_BYTE:
|
||||||
@ -1815,6 +1840,8 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
|||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (trg >= allSections[sec].size())
|
||||||
|
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||||
allSections[sec].SetByte(trg, value);
|
allSections[sec].SetByte(trg, value);
|
||||||
break;
|
break;
|
||||||
case LateEval::LET_ABS_REF:
|
case LateEval::LET_ABS_REF:
|
||||||
@ -1826,6 +1853,8 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end)
|
|||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((trg+1) >= allSections[sec].size())
|
||||||
|
return ERROR_SECTION_TARGET_OFFSET_OUT_OF_RANGE;
|
||||||
allSections[sec].SetWord(trg, value);
|
allSections[sec].SetWord(trg, value);
|
||||||
break;
|
break;
|
||||||
case LateEval::LET_LABEL: {
|
case LateEval::LET_LABEL: {
|
||||||
@ -3150,8 +3179,6 @@ StatusCode Asm::AddOpcode(strref line, int group, int index, strref source_file)
|
|||||||
if (evalLater)
|
if (evalLater)
|
||||||
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_ABS_REF);
|
AddLateEval(CurrSection().DataOffset(), CurrSection().GetPC(), scope_address[scope_depth], expression, source_file, LateEval::LET_ABS_REF);
|
||||||
else if (error == STATUS_RELATIVE_SECTION) {
|
else if (error == STATUS_RELATIVE_SECTION) {
|
||||||
printf("Reloc two byte op: ");
|
|
||||||
|
|
||||||
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(),
|
CurrSection().AddReloc(target_section_offs, CurrSection().DataOffset(),
|
||||||
target_section, target_section_type);
|
target_section, target_section_type);
|
||||||
value = 0;
|
value = 0;
|
||||||
@ -3675,7 +3702,7 @@ StatusCode Asm::ReadObjectFile(strref filename)
|
|||||||
else
|
else
|
||||||
SetSection(aSect[si].name.offs >= 0 ? strref(str_pool + aSect[si].name.offs) : strref());
|
SetSection(aSect[si].name.offs >= 0 ? strref(str_pool + aSect[si].name.offs) : strref());
|
||||||
if (aSect[si].output_size) {
|
if (aSect[si].output_size) {
|
||||||
CurrSection().output = (unsigned char*)malloc(aSect[si].output_size+64);
|
CurrSection().output = (unsigned char*)malloc(aSect[si].output_size);
|
||||||
memcpy(CurrSection().output, bin_data, aSect[si].output_size);
|
memcpy(CurrSection().output, bin_data, aSect[si].output_size);
|
||||||
CurrSection().curr = CurrSection().output + aSect[si].output_size;
|
CurrSection().curr = CurrSection().output + aSect[si].output_size;
|
||||||
CurrSection().output_capacity = aSect[si].output_size;
|
CurrSection().output_capacity = aSect[si].output_size;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user