ConvertObj: handle some corner cases, silence overly verbose output

This commit is contained in:
Wolfgang Thaller 2017-04-22 12:26:53 +02:00
parent 4d0f9e202c
commit b54493c18a

View File

@ -8,11 +8,15 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <sstream> #include <sstream>
#include <memory>
using std::string; using std::string;
using std::vector; using std::vector;
using std::unordered_map; using std::unordered_map;
unordered_map<string,string> sectionMap;
bool verbose = false;
enum RecordType { enum RecordType {
kPad = 0, kPad = 0,
kFirst = 1, kFirst = 1,
@ -59,7 +63,7 @@ struct Module
string name; string name;
string segment; string segment;
vector<uint8_t> bytes; vector<uint8_t> bytes;
unordered_map<uint32_t, string> labels; unordered_map<uint32_t, vector<string>> labels;
unordered_map<uint32_t, Reloc> relocs; unordered_map<uint32_t, Reloc> relocs;
void write(std::ostream& out); void write(std::ostream& out);
@ -102,19 +106,21 @@ string encodeIdentifier(const string& s)
void Module::write(std::ostream& out) void Module::write(std::ostream& out)
{ {
int offset = 0; uint32_t offset = 0;
out << "\t.section .text." << encodeIdentifier(name) << ",\"ax\",@progbits\n"; out << "\t.section .text." << encodeIdentifier(sectionMap[name]) << ",\"ax\",@progbits\n";
while(offset < bytes.size()) while(offset < bytes.size())
{ {
auto labelP = labels.find(offset); auto labelP = labels.find(offset);
if(labelP != labels.end()) if(labelP != labels.end())
{ {
string label = encodeIdentifier(labelP->second); for(string rawLabel : labelP->second)
out << "\t.globl " << label << "\n"; {
out << label << ":\n"; string label = encodeIdentifier(rawLabel);
out << "\t.globl " << label << "\n";
out << label << ":\n";
}
} }
auto relocP = relocs.find(offset); auto relocP = relocs.find(offset);
@ -141,7 +147,8 @@ int main(int argc, char* argv[])
std::cout << "\t.text\n\t.align 2\n"; std::cout << "\t.text\n\t.align 2\n";
for(bool endOfObject = false; !endOfObject;) { for(bool endOfObject = false; !endOfObject;) {
std::cerr << std::hex << in.tellg() << ": "; if(verbose)
std::cerr << std::hex << in.tellg() << ": ";
int recordType = byte(in); int recordType = byte(in);
if(!in) if(!in)
{ {
@ -149,25 +156,32 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
std::cerr << "Record: " << recordType << std::endl; if(verbose)
std::cerr << "Record: " << recordType << std::endl;
switch(recordType) switch(recordType)
{ {
case kPad: case kPad:
std::cerr << "Pad\n"; if(verbose)
std::cerr << "Pad\n";
break; break;
case kFirst: case kFirst:
{ {
int flags = byte(in); /*int flags =*/ byte(in);
std::cerr << "First\n"; int version = word(in);
std::cerr << "Version: " << word(in) << std::endl; if(verbose)
{
std::cerr << "First\n";
std::cerr << "Version: " << version << std::endl;
}
} }
break; break;
case kDictionary: case kDictionary:
{ {
int flags = byte(in); /*int flags =*/ byte(in);
std::cerr << "Dictionary\n"; if(verbose)
std::cerr << "Dictionary\n";
int sz = word(in); int sz = word(in);
int stringId = word(in); int stringId = word(in);
int end = (int)(in.tellg()) - 6 + sz; int end = (int)(in.tellg()) - 6 + sz;
@ -177,7 +191,8 @@ int main(int argc, char* argv[])
string s; string s;
for(int i = 0; i < n; i++) for(int i = 0; i < n; i++)
s += (char) byte(in); s += (char) byte(in);
std::cerr << s << std::endl; if(verbose)
std::cerr << s << std::endl;
stringDictionary[stringId++] = s; stringDictionary[stringId++] = s;
} }
} }
@ -186,36 +201,43 @@ int main(int argc, char* argv[])
{ {
int flags = byte(in); int flags = byte(in);
string name = stringDictionary[word(in)]; string name = stringDictionary[word(in)];
sectionMap[name] = name;
string segment = stringDictionary[word(in)]; string segment = stringDictionary[word(in)];
std::cerr << "Module " << name << "(" << segment << "), flags = " << flags << "\n"; if(verbose)
std::cerr << "Module " << name << "(" << segment << "), flags = " << flags << "\n";
if(module) if(module)
module->write(std::cout); module->write(std::cout);
module.reset(new Module()); module.reset(new Module());
module->name = name; module->name = name;
module->labels[0] = name; module->labels[0].push_back(name);
} }
break; break;
case kContent: case kContent:
{ {
int flags = byte(in); int flags = byte(in);
int sz = word(in); int sz = word(in) - 4;
int end = (int)(in.tellg()) - 4 + sz; uint32_t offset = 0;
long offset = longword(in); if(flags & 0x08)
{
offset = longword(in);
sz -= 4;
}
assert(module.get()); assert(module.get());
if(module->bytes.size() < offset + sz) if(module->bytes.size() < offset + sz)
module->bytes.resize(offset + sz); module->bytes.resize(offset + sz);
in.read((char*) &module->bytes[offset], sz-8); in.read((char*) &module->bytes[offset], sz);
//in.seekg(end); if(verbose)
std::cerr << "Content\n"; std::cerr << "Content (offset = " << offset << ", size = " << sz << ")\n";
} }
break; break;
case kSize: case kSize:
{ {
int flags = byte(in); /*int flags =*/ byte(in);
long size = longword(in); long size = longword(in);
std::cerr << "Size\n"; if(verbose)
std::cerr << "Size " << size << "\n";
assert(module.get()); assert(module.get());
module->bytes.resize(size); module->bytes.resize(size);
} }
@ -227,7 +249,8 @@ int main(int argc, char* argv[])
int end = (int)(in.tellg()) - 4 + sz; int end = (int)(in.tellg()) - 4 + sz;
string name = stringDictionary[word(in)]; string name = stringDictionary[word(in)];
std::cerr << "Reference to " << name << " at\n"; if(verbose)
std::cerr << "Reference to " << name << " at\n";
Reloc reloc; Reloc reloc;
reloc.name1 = name; reloc.name1 = name;
reloc.size = 2; reloc.size = 2;
@ -238,19 +261,21 @@ int main(int argc, char* argv[])
while(in.tellg() < end) while(in.tellg() < end)
{ {
int offset = word(in); int offset = word(in);
std::cerr << " " << offset << std::endl; if(verbose)
std::cerr << " " << offset << std::endl;
module->relocs[offset] = reloc; module->relocs[offset] = reloc;
} }
} }
break; break;
case kEntryPoint: case kEntryPoint:
{ {
int flags = byte(in); /*int flags =*/ byte(in);
string name = stringDictionary[word(in)]; string name = stringDictionary[word(in)];
long offset = longword(in); long offset = longword(in);
std::cerr << "EntryPoint " << name << " at offset " << offset << "\n"; if(verbose)
std::cerr << "EntryPoint " << name << " at offset " << offset << "\n";
assert(module); assert(module);
module->labels[offset] = name; module->labels[offset].push_back(name);
} }
break; break;
case kComputedRef: case kComputedRef:
@ -269,11 +294,16 @@ int main(int argc, char* argv[])
assert(flags == 0x90); assert(flags == 0x90);
assert(module); assert(module);
std::cerr << "ComputedReference to " << name1 << " - " << name2 << " at\n"; string secName = sectionMap[name1];
if(secName != "")
sectionMap[module->name] = secName;
if(verbose)
std::cerr << "ComputedReference to " << name1 << " - " << name2 << " at\n";
while(in.tellg() < end) while(in.tellg() < end)
{ {
int offset = word(in); int offset = word(in);
std::cerr << " " << offset << std::endl; if(verbose)
std::cerr << " " << offset << std::endl;
module->relocs[offset] = reloc; module->relocs[offset] = reloc;
} }
} }
@ -285,7 +315,7 @@ int main(int argc, char* argv[])
module->write(std::cout); module->write(std::cout);
break; break;
default: default:
std::cerr << "Unknown record at " << std::hex << in.tellg() << std::endl; std::cerr << "Unknown record (type " << recordType << ") at " << std::hex << in.tellg() << std::endl;
return 1; return 1;
} }
} }