bebbo / binutils-gdb

Unofficial mirror of sourceware binutils-gdb repository. Updated daily.
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git
GNU General Public License v2.0
3 stars 3 forks source link

.data Section Overlaps with .text Section #29

Closed RetroRevivalGames closed 1 year ago

RetroRevivalGames commented 1 year ago

If you couldn't tell from my previous issues, I'm using the amiga-gcc tool-chain for a 68000 platform other than the Amiga. The SEGA Mega Drive. I'm running into issues with linker scripts so I apologize for the non-Amiga related issues.

What I'm trying to do is make a linker script that'll place the .data section after the .text section at the proper LMA and with a VMA of 0xFF0000. Here is my script,

ENTRY(__START)

MEMORY
{
    rom (rx)  : ORIGIN = 0x00000000, LENGTH = 0x00400000
    ram (rwx) : ORIGIN = 0x00FF0000, LENGTH = 0x00010000
}

SECTIONS
{
    .text 0x00000000 : SUBALIGN(2) {
        KEEP(*(.header))
        *(.boot)
        *(.main)
        *(.text*)
        *(.vdp)
        *(.rodata .rodata.*)
    } > rom
    __stext = SIZEOF(.text);

    .data 0x00FF0000 : AT( ADDR(.text) + SIZEOF(.text) ) {
        *(.data*)
        *(.asmdata)
        FILL(0x00)
        . = ALIGN(2);
    } > ram
    __sdata = SIZEOF(.data);

    .bss 0x00FF0000 + SIZEOF(.data) : {
        *(.bss) 
    } > ram
}

This script works when using the m68k-elf tool-chain, however, using amiga-gcc causes the .data section to restart at address 0.

image

When producing the Mega Drive ROM binary, it ends up overwriting address 0 - 24 with the .data section.

bebbo commented 1 year ago

That version for the Amiga can only output relocatable stuff - as needed by the AmigaOs...

RetroRevivalGames commented 1 year ago

Ah OK. I'll have to find a workaround. Thank you.

bentorkington commented 1 year ago

Ah OK. I'll have to find a workaround. Thank you.

Can you please share what it is? I'm looking into using this compiler to make binaries for the Capcom Play System, and will probably run into the same problem.

RetroRevivalGames commented 1 year ago

I will leave the solution here when I find it. Working on that.

For now, not sure if you've seen the m68k-elf toolchain? https://github.com/kentosama/m68k-elf-gcc

It works great, but it's code generation for the 68000 is inferior to Bebbo's Amiga GCC. For one, it uses the stack to pass parameters to functions which is slower than using registers. Plus, I've noticed it doesn't use the Post-Increment addressing mode as much as I'd like. It does a lot of indexing, dn(A0), instead of (A0)+, which is both slower and takes up more memory.

bentorkington commented 1 year ago

Sorry, it was early and I'd misread your post and thought it said you had already found a workaround.

For now I'm using the gcc-m68k-linux-gnu package available on Debian et al. I presume it's about the same thing.

Like you, I've found that gcc works, but is too hungry on the stack, and can't integrate with existing code that passes args in registers without writing a heap of asm stubs. Going to look at vbcc and llvm (which recently added an m68k backend) next. Good luck!

RetroRevivalGames commented 1 year ago

Sounds good. Only thing about vbcc is it has a commercial license. That goes for vasm and vlink too.

I will say there is one solution in the past that works like a charm. For what I'm working on I really want LTO to work which is proving to be the bottleneck here. However, if you don't care about LTO, you could use m68k-amigaos-gcc to generate the assembly.

m68k-amigaos-gcc -S main.c

Then, take the resulting assembly files and assemble / link them all together with the m68k-elf-gcc.

m68k-elf-gcc -o app.out main.s

LTO won't work here because that it done using GCC's intermediate language before assembly is ever generated. That is proving to be quite the challenge.

RetroRevivalGames commented 1 year ago

After many trials of various methods I don't think it's possible to mix m68k-elf and m68k-amigaos to achieve an LTO ROM binary. Ultimately the application has to get linked through m68k-amigaos that produces a hunk file which Bebbo already stated uses relocation.

@bebbo, I am not familiar with the GCC source code as it is so expansive. But is there a certain part of this project that contains source code for 68000 assembly generation which can be brought over to my own fork of GCC to provide the same code generation, but output in ELF format?

RetroRevivalGames commented 1 year ago

After browsing through the gcc repo I'm guessing a lot of the 68000 assembly generation is under gcc/config/m68k? I'm seeing amiga-gcc specific files like amigaos.c, amigaos.h and amigaos.opt.

Happy New Year.

bebbo commented 1 year ago

Now: If any section offset is given, all relocations are done against the given offsets, where 0 is also a valid offset then. Consider foo.c:

int x = 0;
int y;

int foo() {
  return x + y;
}

then using your lds file yields:

foo:     file format amiga

Disassembly of section .text:

00000000 00000000 _foo:
   0:   4e55 0000       link.w a5,#0
   4:   2239 00ff 0000  move.l ff0000 ff0000 _y+0xfefffc,d1
   a:   2039 00ff 0004  move.l ff0004 ff0004 _y+0xff0000,d0
  10:   d081            add.l d1,d0
  12:   4e5d            unlk a5
  14:   4e75            rts
  16:   0000            Address 0x0000000000000018 is out of bounds.
.short 0x0000

Disassembly of section .bss:

00000000 00000000 _x:
   0:   0000 0000       ori.b #0,d0

00000004 00000004 _y:
   4:   0000 0000       ori.b #0,d0

There are no relocs left, and the offset to .data/.bss is used in the .text section.

objectdump will still report the ofsset 00000000 for .data/.bss since this is not supported. Putting the .text to 00000000 and .data/.bss to 00ff0000 is your task.

RetroRevivalGames commented 1 year ago

Awesome. I've tested it out and it works as you have it above. You've done the hard part which is figuring out VMAs. Now I just have to append the three output sections, .text, .data, .bss, together to form the ROM image (LMAs).

Thank you for your efforts. You'll be credited in my project for whatever amiga-gcc tools we use.

Note: For anyone who finds this, as of January 3, 2023 you have to use binutils_BRANCH=devel1 when doing make update because the changes where made on that branch.

make update binutils_BRANCH=devel1

bebbo commented 1 year ago

that should be live soon