output of elf2mac is now a piece of code with no headers with its entry point at the start. No more FLT file format.

This commit is contained in:
Wolfgang Thaller 2017-09-24 00:32:13 +02:00
parent 6c1e76280e
commit 0e3a0a5d18
4 changed files with 32 additions and 42 deletions

View File

@ -141,39 +141,23 @@ void ElfToFlt(string input, string output)
std::sort(relocs.begin(), relocs.end());
ofstream out(output);
byte(out, 'b');
byte(out, 'F');
byte(out, 'L');
byte(out, 'T');
longword(out, 4);
longword(out, 0x40 + ehdr.e_entry); // entry point
GElf_Shdr text_shdr, data_shdr, bss_shdr;
gelf_getshdr(codeSections[".text"], &text_shdr);
gelf_getshdr(codeSections[".data"], &data_shdr);
gelf_getshdr(bssSection, &bss_shdr);
longword(out, 0x40 + data_shdr.sh_addr); // data start
longword(out, 0x40 + bss_shdr.sh_addr); // data end
longword(out, 0x40 + bss_shdr.sh_addr + bss_shdr.sh_size); // bss end
longword(out, 4096); // stack size, ignored
longword(out, 0x40 + bss_shdr.sh_addr); // relocStart);
longword(out, relocs.size());
longword(out, 0); // flags
for(int i = 0; i < 6; i++)
longword(out, 0); // filler
ofstream out(output);
Elf_Data *data = elf_getdata(codeSections[".text"], NULL);
out << string((char*)data->d_buf, (char*)data->d_buf + data->d_size);
while(out.tellp() < 0x40 + data_shdr.sh_addr)
while(out.tellp() < /*0x40 + */data_shdr.sh_addr)
byte(out, 0x00);
data = elf_getdata(codeSections[".data"], NULL);
out << string((char*)data->d_buf, (char*)data->d_buf + data->d_size);
while(out.tellp() < 0x40 + bss_shdr.sh_addr)
while(out.tellp() < /*0x40 +*/ bss_shdr.sh_addr)
byte(out, 0x00);
for(int reloc : relocs)
longword(out, reloc);

View File

@ -28,6 +28,19 @@ SECTIONS
.text : {
_stext = . ;
PROVIDE(_rsrc_start = .);
*(.rsrcheader)
. = ALIGN (2);
_entry_trampoline = .;
SHORT(DEFINED(__break_on_entry) ? 0xA9FF : 0x4e71);
LONG(0x61000002); /* bsr *+2 */
SHORT(0x0697); /* addi.l #_, (a7) */
LONG(_start - _entry_trampoline - 6);
SHORT(0x4e75); /* rts */
*(.relocvars)
*/libretrocrt.a:start.c.obj(.text*)
*/libretrocrt.a:relocate.c.obj(.text*)
*/libretrocrt.a:*(.text*)
*(.text*)

View File

@ -16,17 +16,8 @@ jtend:
#define RETRO68_CODE_TYPE \
hex string dontBreakAtEntry = $"", breakAtEntry = $"A9FF"; \
longint = 0x61000002; /* bsr *+2 */ \
relativeTo: \
integer = 0x0697; /* addi.l #_, (a7) */ \
longint = $$long(fltfile + 8*8) + (fltfile-relativeTo)/8; \
integer = 0x4e75; /* rts */ \
longint = fltfile/8; \
fltfile: \
hex string;
type 'CODE' (1) {
integer = 0;
integer = 1;

View File

@ -40,9 +40,16 @@ typedef void (*voidFunction)(void);
/*
Linker-defined addresses in the binary;
*/
// section boundaries
extern uint8_t _stext, _etext, _sdata, _edata, _sbss, _ebss;
// constructor list:
extern uint8_t __init_section, __init_section_end;
// destructor list:
extern uint8_t __fini_section, __fini_section_end;
// address of start of code reource.
// usually equal to _stext, but can be overridden.
extern uint8_t _rsrc_start;
typedef struct Retro68RelocState
{
@ -50,7 +57,7 @@ typedef struct Retro68RelocState
Handle codeHandle;
} Retro68RelocState;
static Retro68RelocState relocState __attribute__ ((nocommon, section(".text"))) = {
static Retro68RelocState relocState __attribute__ ((section(".relocvars"))) = {
NULL, NULL
};
@ -149,18 +156,15 @@ void Retro68Relocate()
log(orig_ebss);
uint8_t *base = orig_stext + displacement;
// Recover the handle to the code resource by looking at the
// longword before the FLT header. The resource templates in Retro68.r store the offset
// from the beginning of the code resource there.
uint32_t offsetInResource = *(uint32_t*)(base - 0x44) + 0x40;
if(offsetInResource < 4096)
// Arbitrary magic number. We expect the offset to be small, just a few header bytes before it.
// if it's out of range, assume the longword before the header is not the offset we're looking for.
{
Handle h = RecoverHandle((Ptr) base - offsetInResource);
{
uint8_t *orig_rsrc_start;
GET_VIRTUAL_ADDRESS(orig_rsrc_start, _rsrc_start);
uint8_t *rsrc_start = orig_rsrc_start + displacement;
Handle h = RecoverHandle((Ptr) rsrc_start);
if(MemError() == noErr && h)
{
{
// Make sure the code is locked. Only relevant for some code resources.
HLock(h);
rState->codeHandle = h;
@ -185,9 +189,7 @@ void Retro68Relocate()
bss_displacement = (uint8_t*)rState->bssPtr - orig_sbss;
}
long i;
// Process relocation records
for(long *reloc = (long*)( base + text_and_data_size );
*reloc != -1;
++reloc)
@ -215,7 +217,7 @@ void Retro68Relocate()
WRITE_UNALIGNED_LONGWORD(addrPtr, (uint32_t) addr);
}
// We're basically done.
// Now check whether we're on 68040 or later and need to flush the cache.
// only do this if SysEnvirons is available.