mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-28 21:49:33 +00:00
ConvertObj: use string ids internally
This commit is contained in:
parent
9e0f85dbde
commit
738a218417
@ -16,8 +16,10 @@ using std::string;
|
|||||||
using std::vector;
|
using std::vector;
|
||||||
using std::unordered_map;
|
using std::unordered_map;
|
||||||
|
|
||||||
unordered_map<string,string> sectionMap;
|
using stringid = int;
|
||||||
|
unordered_map<stringid,stringid> sectionMap;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
unordered_map<stringid,string> stringDictionary;
|
||||||
|
|
||||||
enum RecordType {
|
enum RecordType {
|
||||||
kPad = 0,
|
kPad = 0,
|
||||||
@ -49,68 +51,6 @@ enum ComputedReferenceFlags {
|
|||||||
kDifference = 0x80
|
kDifference = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Reloc
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
string name1;
|
|
||||||
string name2;
|
|
||||||
|
|
||||||
int write(std::ostream& out, uint8_t *p);
|
|
||||||
};
|
|
||||||
|
|
||||||
int Reloc::write(std::ostream& out, uint8_t *p)
|
|
||||||
{
|
|
||||||
if(size == 2)
|
|
||||||
{
|
|
||||||
out << "\t.short ";
|
|
||||||
int val = (int)p[0] * 256 + p[1];
|
|
||||||
|
|
||||||
out << name1;
|
|
||||||
if(name2.size())
|
|
||||||
out << " - " << name2;
|
|
||||||
if(val > 0)
|
|
||||||
out << " + " << val;
|
|
||||||
else if(val < 0)
|
|
||||||
out << " - " << -val;
|
|
||||||
if(name2.size() == 0)
|
|
||||||
out << "-.";
|
|
||||||
out << std::endl;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else if(size == 4)
|
|
||||||
{
|
|
||||||
out << "\t.long ";
|
|
||||||
int val = ((int)p[0] << 24) | ((int)p[1] << 16) | ((int)p[2] << 8) | p[3];
|
|
||||||
|
|
||||||
out << name1;
|
|
||||||
if(name2.size())
|
|
||||||
out << " - " << name2;
|
|
||||||
if(val > 0)
|
|
||||||
out << " + " << val;
|
|
||||||
else if(val < 0)
|
|
||||||
out << " - " << -val;
|
|
||||||
out << std::endl;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Module
|
|
||||||
{
|
|
||||||
string name;
|
|
||||||
string segment;
|
|
||||||
vector<uint8_t> bytes;
|
|
||||||
unordered_map<uint32_t, vector<string>> labels;
|
|
||||||
unordered_map<uint32_t, Reloc> relocs;
|
|
||||||
|
|
||||||
std::vector<std::weak_ptr<Module>> nearrefs;
|
|
||||||
|
|
||||||
void write(std::ostream& out);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool isValidIdentifier(const string& s)
|
bool isValidIdentifier(const string& s)
|
||||||
{
|
{
|
||||||
@ -150,10 +90,73 @@ string encodeIdentifier(const string& s)
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Reloc
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
stringid name1 = -1;
|
||||||
|
stringid name2 = -1;
|
||||||
|
|
||||||
|
int write(std::ostream& out, uint8_t *p);
|
||||||
|
};
|
||||||
|
|
||||||
|
int Reloc::write(std::ostream& out, uint8_t *p)
|
||||||
|
{
|
||||||
|
if(size == 2)
|
||||||
|
{
|
||||||
|
out << "\t.short ";
|
||||||
|
int val = (int)p[0] * 256 + p[1];
|
||||||
|
|
||||||
|
out << encodeIdentifier(stringDictionary[name1]);
|
||||||
|
if(name2 != -1)
|
||||||
|
out << " - " << encodeIdentifier(stringDictionary[name2]);
|
||||||
|
if(val > 0)
|
||||||
|
out << " + " << val;
|
||||||
|
else if(val < 0)
|
||||||
|
out << " - " << -val;
|
||||||
|
if(name2 == -1)
|
||||||
|
out << "-.";
|
||||||
|
out << std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else if(size == 4)
|
||||||
|
{
|
||||||
|
out << "\t.long ";
|
||||||
|
int val = ((int)p[0] << 24) | ((int)p[1] << 16) | ((int)p[2] << 8) | p[3];
|
||||||
|
|
||||||
|
out << encodeIdentifier(stringDictionary[name1]);
|
||||||
|
if(name2 != -1)
|
||||||
|
out << " - " << encodeIdentifier(stringDictionary[name2]);
|
||||||
|
if(val > 0)
|
||||||
|
out << " + " << val;
|
||||||
|
else if(val < 0)
|
||||||
|
out << " - " << -val;
|
||||||
|
out << std::endl;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module
|
||||||
|
{
|
||||||
|
stringid name;
|
||||||
|
stringid segment;
|
||||||
|
vector<uint8_t> bytes;
|
||||||
|
unordered_map<uint32_t, vector<stringid>> labels;
|
||||||
|
unordered_map<uint32_t, Reloc> relocs;
|
||||||
|
|
||||||
|
std::vector<std::weak_ptr<Module>> nearrefs;
|
||||||
|
|
||||||
|
void write(std::ostream& out);
|
||||||
|
};
|
||||||
|
|
||||||
void Module::write(std::ostream& out)
|
void Module::write(std::ostream& out)
|
||||||
{
|
{
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
string encodedName = encodeIdentifier(sectionMap[name]);
|
string encodedName = encodeIdentifier(stringDictionary[sectionMap[name]]);
|
||||||
|
|
||||||
out << "\t.section .text." << encodedName << ",\"ax\",@progbits\n";
|
out << "\t.section .text." << encodedName << ",\"ax\",@progbits\n";
|
||||||
|
|
||||||
@ -162,9 +165,9 @@ void Module::write(std::ostream& out)
|
|||||||
auto labelP = labels.find(offset);
|
auto labelP = labels.find(offset);
|
||||||
if(labelP != labels.end())
|
if(labelP != labels.end())
|
||||||
{
|
{
|
||||||
for(string rawLabel : labelP->second)
|
for(stringid rawLabel : labelP->second)
|
||||||
{
|
{
|
||||||
string label = encodeIdentifier(rawLabel);
|
string label = encodeIdentifier(stringDictionary[rawLabel]);
|
||||||
out << "\t.globl " << label << "\n";
|
out << "\t.globl " << label << "\n";
|
||||||
out << label << ":\n";
|
out << label << ":\n";
|
||||||
}
|
}
|
||||||
@ -195,11 +198,11 @@ void Module::write(std::ostream& out)
|
|||||||
|
|
||||||
void sortModules(std::vector<std::shared_ptr<Module>>& modules)
|
void sortModules(std::vector<std::shared_ptr<Module>>& modules)
|
||||||
{
|
{
|
||||||
std::set<std::string> unemitted;
|
std::set<stringid> unemitted;
|
||||||
for(auto& m : modules)
|
for(auto& m : modules)
|
||||||
unemitted.insert(m->name);
|
unemitted.insert(m->name);
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Module>> nameMap;
|
std::unordered_map<stringid, std::shared_ptr<Module>> nameMap;
|
||||||
for(auto& m : modules)
|
for(auto& m : modules)
|
||||||
for(auto& l : m->labels)
|
for(auto& l : m->labels)
|
||||||
for(auto& str : l.second)
|
for(auto& str : l.second)
|
||||||
@ -211,7 +214,7 @@ void sortModules(std::vector<std::shared_ptr<Module>>& modules)
|
|||||||
{
|
{
|
||||||
if(r.second.size != 2)
|
if(r.second.size != 2)
|
||||||
continue;
|
continue;
|
||||||
if(r.second.name2.empty())
|
if(r.second.name2 == -1)
|
||||||
{
|
{
|
||||||
if(auto p = nameMap.find(r.second.name1); p != nameMap.end())
|
if(auto p = nameMap.find(r.second.name1); p != nameMap.end())
|
||||||
{
|
{
|
||||||
@ -284,7 +287,6 @@ int main(int argc, char* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_map<int,string> stringDictionary;
|
|
||||||
|
|
||||||
bool shouldSortModules = true;
|
bool shouldSortModules = true;
|
||||||
|
|
||||||
@ -379,11 +381,11 @@ int main(int argc, char* argv[])
|
|||||||
case kModule:
|
case kModule:
|
||||||
{
|
{
|
||||||
int flags = byte(in);
|
int flags = byte(in);
|
||||||
string name = stringDictionary[word(in)];
|
stringid name = word(in);
|
||||||
sectionMap[name] = name;
|
sectionMap[name] = name;
|
||||||
string segment = stringDictionary[word(in)];
|
stringid segment = word(in);
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "Module " << name << "(" << segment << "), flags = " << flags << "\n";
|
std::cerr << "Module " << stringDictionary[name] << "(" << stringDictionary[segment] << "), flags = " << flags << "\n";
|
||||||
|
|
||||||
module.reset(new Module());
|
module.reset(new Module());
|
||||||
module->name = name;
|
module->name = name;
|
||||||
@ -424,12 +426,12 @@ int main(int argc, char* argv[])
|
|||||||
int flags = byte(in);
|
int flags = byte(in);
|
||||||
int sz = word(in);
|
int sz = word(in);
|
||||||
int end = (int)(in.tellg()) - 4 + sz;
|
int end = (int)(in.tellg()) - 4 + sz;
|
||||||
string name = stringDictionary[word(in)];
|
stringid name = word(in);
|
||||||
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "Reference to " << name << " at\n";
|
std::cerr << "Reference to " << stringDictionary[name] << " at\n";
|
||||||
Reloc reloc;
|
Reloc reloc;
|
||||||
reloc.name1 = encodeIdentifier(name);
|
reloc.name1 = name;
|
||||||
|
|
||||||
if(flags & kUnknownReferenceFlags)
|
if(flags & kUnknownReferenceFlags)
|
||||||
{
|
{
|
||||||
@ -462,10 +464,10 @@ int main(int argc, char* argv[])
|
|||||||
case kEntryPoint:
|
case kEntryPoint:
|
||||||
{
|
{
|
||||||
/*int flags =*/ byte(in);
|
/*int flags =*/ byte(in);
|
||||||
string name = stringDictionary[word(in)];
|
stringid name = word(in);
|
||||||
long offset = longword(in);
|
long offset = longword(in);
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "EntryPoint " << name << " at offset " << offset << "\n";
|
std::cerr << "EntryPoint " << stringDictionary[name] << " at offset " << offset << "\n";
|
||||||
assert(module);
|
assert(module);
|
||||||
module->labels[offset].push_back(name);
|
module->labels[offset].push_back(name);
|
||||||
}
|
}
|
||||||
@ -475,22 +477,22 @@ int main(int argc, char* argv[])
|
|||||||
int flags = byte(in);
|
int flags = byte(in);
|
||||||
int sz = word(in);
|
int sz = word(in);
|
||||||
int end = (int)(in.tellg()) - 4 + sz;
|
int end = (int)(in.tellg()) - 4 + sz;
|
||||||
string name1 = stringDictionary[word(in)];
|
stringid name1 = word(in);
|
||||||
string name2 = stringDictionary[word(in)];
|
stringid name2 = word(in);
|
||||||
|
|
||||||
Reloc reloc;
|
Reloc reloc;
|
||||||
reloc.name1 = encodeIdentifier(name1);
|
reloc.name1 = name1;
|
||||||
reloc.name2 = encodeIdentifier(name2);
|
reloc.name2 = name2;
|
||||||
reloc.size = 2;
|
reloc.size = 2;
|
||||||
|
|
||||||
assert(flags == 0x90);
|
assert(flags == 0x90);
|
||||||
assert(module);
|
assert(module);
|
||||||
|
|
||||||
string secName = sectionMap[name1];
|
if(auto p = sectionMap.find(name1); p != sectionMap.end())
|
||||||
if(secName != "")
|
sectionMap[module->name] = p->second;
|
||||||
sectionMap[module->name] = secName;
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "ComputedReference to " << name1 << " - " << name2 << " at\n";
|
std::cerr << "ComputedReference to "
|
||||||
|
<< stringDictionary[name1] << " - " << stringDictionary[name2] << " at\n";
|
||||||
while(in.tellg() < end)
|
while(in.tellg() < end)
|
||||||
{
|
{
|
||||||
int offset = word(in);
|
int offset = word(in);
|
||||||
|
Loading…
Reference in New Issue
Block a user