mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-28 11:30:19 +00:00
ConvertObj: handle "repeat" flag for data modules
This commit is contained in:
parent
94c4bbabae
commit
a3c8783a88
|
@ -17,9 +17,15 @@ using std::vector;
|
||||||
using std::unordered_map;
|
using std::unordered_map;
|
||||||
using std::unordered_set;
|
using std::unordered_set;
|
||||||
|
|
||||||
|
bool verbose = false;
|
||||||
|
bool shouldSortModules = true;
|
||||||
|
bool addMacsbugNames = true;
|
||||||
|
bool functionSections = true;
|
||||||
|
bool dataSections = true;
|
||||||
|
bool dataInText = false;
|
||||||
|
|
||||||
using stringid = int;
|
using stringid = int;
|
||||||
unordered_map<stringid,stringid> sectionMap;
|
unordered_map<stringid,stringid> sectionMap;
|
||||||
bool verbose = false;
|
|
||||||
unordered_map<stringid,string> stringDictionary;
|
unordered_map<stringid,string> stringDictionary;
|
||||||
unordered_set<stringid> localLabels;
|
unordered_set<stringid> localLabels;
|
||||||
|
|
||||||
|
@ -58,6 +64,11 @@ enum ComputedReferenceFlags {
|
||||||
kDifference = 0x80
|
kDifference = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ContentFlags {
|
||||||
|
// kData = 0x01 // ?
|
||||||
|
kContentOffset = 0x08,
|
||||||
|
kContentRepeat = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
string encodeIdentifier(stringid id)
|
string encodeIdentifier(stringid id)
|
||||||
{
|
{
|
||||||
|
@ -137,6 +148,7 @@ struct Module
|
||||||
{
|
{
|
||||||
stringid name;
|
stringid name;
|
||||||
stringid segment;
|
stringid segment;
|
||||||
|
bool isData;
|
||||||
vector<uint8_t> bytes;
|
vector<uint8_t> bytes;
|
||||||
unordered_map<uint32_t, vector<stringid>> labels;
|
unordered_map<uint32_t, vector<stringid>> labels;
|
||||||
unordered_map<uint32_t, Reloc> relocs;
|
unordered_map<uint32_t, Reloc> relocs;
|
||||||
|
@ -148,12 +160,28 @@ struct Module
|
||||||
|
|
||||||
void Module::write(std::ostream& out)
|
void Module::write(std::ostream& out)
|
||||||
{
|
{
|
||||||
uint32_t offset = 0;
|
|
||||||
string encodedName = encodeIdentifier(sectionMap[name]);
|
string encodedName = encodeIdentifier(sectionMap[name]);
|
||||||
|
|
||||||
|
if(isData && !dataInText)
|
||||||
|
{
|
||||||
|
if(dataSections)
|
||||||
|
out << "\t.section .data." << encodedName << ",\"aw\"\n";
|
||||||
|
else
|
||||||
|
out << "\t.data\n";
|
||||||
|
if(bytes.size() >= 2)
|
||||||
|
out << "\t.align 2,0\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(functionSections)
|
||||||
out << "\t.section .text." << encodedName << ",\"ax\",@progbits\n";
|
out << "\t.section .text." << encodedName << ",\"ax\",@progbits\n";
|
||||||
|
else
|
||||||
|
out << "\t.section .text,\"ax\",@progbits\n";
|
||||||
|
out << "\t.align 2,0\n";
|
||||||
|
}
|
||||||
|
|
||||||
while(offset < bytes.size())
|
for(uint32_t offset = 0; offset < bytes.size();)
|
||||||
{
|
{
|
||||||
auto labelP = labels.find(offset);
|
auto labelP = labels.find(offset);
|
||||||
if(labelP != labels.end())
|
if(labelP != labels.end())
|
||||||
|
@ -178,6 +206,9 @@ void Module::write(std::ostream& out)
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(addMacsbugNames && !isData)
|
||||||
|
{
|
||||||
|
if(functionSections)
|
||||||
out << "\t.section .text." << encodedName << ".macsbug,\"ax\",@progbits\n";
|
out << "\t.section .text." << encodedName << ".macsbug,\"ax\",@progbits\n";
|
||||||
if(encodedName.size() < 32)
|
if(encodedName.size() < 32)
|
||||||
out << "\t.byte " << (encodedName.size() | 0x80) << "\n";
|
out << "\t.byte " << (encodedName.size() | 0x80) << "\n";
|
||||||
|
@ -186,7 +217,7 @@ void Module::write(std::ostream& out)
|
||||||
<< "\t.byte " << encodedName.size() << "\n";
|
<< "\t.byte " << encodedName.size() << "\n";
|
||||||
out << "\t.ascii \"" << encodedName << "\"\n";
|
out << "\t.ascii \"" << encodedName << "\"\n";
|
||||||
out << "\t.align 2,0\n\t.short 0\n";
|
out << "\t.align 2,0\n\t.short 0\n";
|
||||||
|
}
|
||||||
out << "# ######\n\n";
|
out << "# ######\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,9 +312,6 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool shouldSortModules = true;
|
|
||||||
|
|
||||||
std::shared_ptr<Module> module;
|
std::shared_ptr<Module> module;
|
||||||
std::vector<std::shared_ptr<Module>> modules;
|
std::vector<std::shared_ptr<Module>> modules;
|
||||||
|
|
||||||
|
@ -378,6 +406,7 @@ int main(int argc, char* argv[])
|
||||||
stringid name = word(in);
|
stringid name = word(in);
|
||||||
sectionMap[name] = name;
|
sectionMap[name] = name;
|
||||||
stringid segment = word(in);
|
stringid segment = word(in);
|
||||||
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "Module " << stringDictionary[name] << "(" << stringDictionary[segment] << "), flags = " << flags << "\n";
|
std::cerr << "Module " << stringDictionary[name] << "(" << stringDictionary[segment] << "), flags = " << flags << "\n";
|
||||||
|
|
||||||
|
@ -386,6 +415,8 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
module.reset(new Module());
|
module.reset(new Module());
|
||||||
module->name = name;
|
module->name = name;
|
||||||
|
module->segment = segment;
|
||||||
|
module->isData = (flags & kData) != 0;
|
||||||
module->labels[0].push_back(name);
|
module->labels[0].push_back(name);
|
||||||
modules.push_back(module);
|
modules.push_back(module);
|
||||||
}
|
}
|
||||||
|
@ -395,17 +426,30 @@ int main(int argc, char* argv[])
|
||||||
int flags = byte(in);
|
int flags = byte(in);
|
||||||
int sz = word(in) - 4;
|
int sz = word(in) - 4;
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
if(flags & 0x08)
|
if(flags & kContentOffset)
|
||||||
{
|
{
|
||||||
offset = longword(in);
|
offset = longword(in);
|
||||||
sz -= 4;
|
sz -= 4;
|
||||||
}
|
}
|
||||||
assert(module.get());
|
int repeat = 1;
|
||||||
if(module->bytes.size() < offset + sz)
|
if(flags & kContentRepeat)
|
||||||
module->bytes.resize(offset + sz);
|
{
|
||||||
in.read((char*) &module->bytes[offset], sz);
|
repeat = word(in);
|
||||||
|
sz -= 2;
|
||||||
|
}
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "Content (offset = " << offset << ", size = " << sz << ")\n";
|
std::cerr << "Content (offset = " << offset << ", size = " << sz << ", repeat = " << repeat << ")\n";
|
||||||
|
|
||||||
|
assert(module.get());
|
||||||
|
if(module->bytes.size() < offset + sz * repeat)
|
||||||
|
module->bytes.resize(offset + sz * repeat);
|
||||||
|
in.read((char*) &module->bytes[offset], sz);
|
||||||
|
while(--repeat > 0)
|
||||||
|
{
|
||||||
|
std::copy(module->bytes.begin() + offset, module->bytes.begin() + offset + sz,
|
||||||
|
module->bytes.begin() + offset + sz);
|
||||||
|
offset += sz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kSize:
|
case kSize:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user