Search code examples
cassemblyamiga

How can I avoid vlink to combine BSS and CODE sections when linking C and ASM code?


I am trying to link this C file (hello.c):

#include <stdio.h>

#include <proto/intuition.h>
#include <proto/exec.h>
#include <proto/dos.h>

struct gdata_t {
  void* level_1_interrupt_autovector;
} gdata;

ULONG start_get_level_1_interrupt_autovector();

int main(void) {
  printf("Hello World!\n");
  Supervisor(start_get_level_1_interrupt_autovector);
  printf("%p\n", gdata.level_1_interrupt_autovector);
  return 0;
}

To this asm file (level_1_interrupt_autovector.asm):

gdata_level_1_interrupt_autovector = 0

_start_get_level_1_interrupt_autovector:
  movec    VBR,D0
  addi.l   #100,D0
  lea      (_gdata,PC),A5
  move.l   D0,(gdata_level_1_interrupt_autovector,A5)
  rte

  public _gdata
  public _start_get_level_1_interrupt_autovector

The compiler tools are vc / vbcc / vasm / vlink.

My build script looks like this:

#!/bin/sh
vc -v -c level_1_interrupt_autovector.asm -o level_1_interrupt_autovector.o
#vc -v -S hello.c -o hello.asm
vc -v -c hello.c -o hello.o
vc -v hello.o level_1_interrupt_autovector.o -o s1c -lamiga
cp s1c ../amiga/hdd

The program links and works in fs-uae, but I get these warnings during the linker stage:

Warning 58: Relative references between code section "CODE" and bss section "BSS" (hello.o) force a combination of the two.
Warning 22: Attributes of section CODE were changed from r-x- to rwx- in hello.o.

How can I avoid the CODE and BSS sections to be combined?

Is the problem related to the lea (_gdata,PC),A5 instruction?


Solution

  • The problem is indeed the lea (_gdata,PC),A5 instruction. The PC relative adressing means that the _gdata reference must be moved from the .BSS section to the .CODE section by the linker for the program to work.

    I can just use _gdata without the relative PC location:

    gdata_level_1_interrupt_autovector = 0
    
    _start_get_level_1_interrupt_autovector:
      movec    VBR,D0
      addi.l   #100,D0
      lea      (_gdata),A5 ; The linker should add a relocation here
      move.l   D0,(gdata_level_1_interrupt_autovector,A5)
      rte
    
      public _gdata
      public _start_get_level_1_interrupt_autovector
    

    This seems to work fine.