mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-27 23:31:44 +00:00
ConvertObj: deal with 32-bit patches. Can now convert OpenTransport.o (see #35)
This commit is contained in:
parent
3ecff9bcc6
commit
d7e89e2fd5
@ -31,6 +31,21 @@ enum RecordType {
|
|||||||
kComputedRef = 10
|
kComputedRef = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ReferenceFlags { // flags field of kReference
|
||||||
|
k16BitPatch = 0x10, // default 32Bit
|
||||||
|
kFromData = 0x01, // default fromCode
|
||||||
|
kA5Relative = 0x80, // default absolute
|
||||||
|
|
||||||
|
kUnknownReferenceFlags = 0x6E // rather a lot, isn't it?
|
||||||
|
// The following flags are known to exist from DumpOBJ,
|
||||||
|
// but their value is unkown as I haven't actually seen them yet:
|
||||||
|
// k32BitOffsets (default k16BitOffsets)
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ComputedReferenceFlags {
|
||||||
|
kDifference = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
struct Reloc
|
struct Reloc
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
@ -42,21 +57,45 @@ struct Reloc
|
|||||||
|
|
||||||
int Reloc::write(std::ostream& out, uint8_t *p)
|
int Reloc::write(std::ostream& out, uint8_t *p)
|
||||||
{
|
{
|
||||||
assert(size == 2);
|
if(size == 2)
|
||||||
out << "\t.short ";
|
{
|
||||||
int val = (int)p[0] * 256 + p[1];
|
out << "\t.short ";
|
||||||
|
int val = (int)p[0] * 256 + p[1];
|
||||||
|
|
||||||
out << name1;
|
out << name1;
|
||||||
if(name2.size())
|
if(name2.size())
|
||||||
out << " - " << name2;
|
out << " - " << name2;
|
||||||
if(val > 0)
|
if(val > 0)
|
||||||
out << " + " << val;
|
out << " + " << val;
|
||||||
else if(val < 0)
|
else if(val < 0)
|
||||||
out << " - " << -val;
|
out << " - " << -val;
|
||||||
if(name2.size() == 0)
|
if(name2.size() == 0)
|
||||||
out << "-.";
|
out << "-.";
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
return 2;
|
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;
|
||||||
|
if(name2.size() == 0)
|
||||||
|
out << "-.";
|
||||||
|
out << std::endl;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Module
|
struct Module
|
||||||
@ -346,9 +385,24 @@ int main(int argc, char* argv[])
|
|||||||
std::cerr << "Reference to " << name << " at\n";
|
std::cerr << "Reference to " << name << " at\n";
|
||||||
Reloc reloc;
|
Reloc reloc;
|
||||||
reloc.name1 = name;
|
reloc.name1 = name;
|
||||||
reloc.size = 2;
|
|
||||||
|
|
||||||
assert(flags == 0x10);
|
if(flags & kUnknownReferenceFlags)
|
||||||
|
{
|
||||||
|
std::cerr << "Unknown relocation flags: 0x" << std::hex << flags << std::endl;
|
||||||
|
std::cerr << "Cannot convert this file.\n";
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
if(flags & kA5Relative)
|
||||||
|
{
|
||||||
|
std::cerr << "Unsupported relocation flags: 0x" << std::hex << flags << std::endl;
|
||||||
|
std::cerr << "MPW .o files with near-model global variables or calls to imported functions will not work.\n";
|
||||||
|
std::cerr << "Cannot convert this file.\n";
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
flags &= ~kFromData; // FIXME: sticking data bits in the text section, not nice, but might sometimes work
|
||||||
|
|
||||||
|
reloc.size = (flags & k16BitPatch ? 2 : 4);
|
||||||
|
|
||||||
assert(module);
|
assert(module);
|
||||||
|
|
||||||
while(in.tellg() < end)
|
while(in.tellg() < end)
|
||||||
|
Loading…
Reference in New Issue
Block a user