OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Apr 24, 2024 4:29 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: gcc produces unexpected ip-relative code for static variable
PostPosted: Sun Jan 28, 2018 12:53 am 
Offline

Joined: Tue Jan 09, 2018 9:25 pm
Posts: 2
Hi,

I want to load small 64-bit ELF images using BIOS in boot loader for testing purposes. Obviously the image must be small enough to fit into the first 640K due to BIOS limitation.

I was able to load and run a few testing code, except any code that references static/global variables. The problem is gcc produces ip-relative code with a very large/random offset to reference the global/static data (i.e. variable i). Somehow gcc decides to place variable i at 0x208018 regardless the section addresses specified for ld.

This is a very small image starting at address 0x8000. Ideally variable "i" should be located in .data section near 0xf400 (--section-start .data=0xf400). I don't know how gcc comes up with this 0x208018 address. I cannot create a page mapping ahead of time. This leads to crash.

I don't think this is PIC related, but how to make gcc not to produce this ip-relative code and place the global data at specified location?

In the following example, I'd be able to load and run the ELF image if I remove the "static" keyword. If it's "int i" (instead of "static int i"), gcc references it with standard %rbp notation (e.g. -0x4(%rbp)).

Code:
my: my.o
  ld -s --section-start .text=0x8000 --section-start .rodata=0xf000 --section-start .bss=0xf200 --section-start .data=0xf400 --section-start .note.gnu.build-id=0xf800 -o $@ $<

my.o: my.c
  gcc -o $@ -fpie -nostdlib -fno-asynchronous-unwind-tables $<

Code:
void _start()
{
  static int i;
  i++;
}

Code:
> objdump -d my

Disassembly of section .text:

0000000000008000 <.text>:
    8000:   55                      push   %rbp
    8001:   48 89 e5                mov    %rsp,%rbp
    8004:   8b 05 0e 00 20 00       mov    0x20000e(%rip),%eax        # 0x208018
    800a:   83 c0 01                add    $0x1,%eax
    800d:   89 05 05 00 20 00       mov    %eax,0x200005(%rip)        # 0x208018
    8013:   90                      nop
    8014:   5d                      pop    %rbp
    8015:   c3                      retq

Code:
> readelf -S my
There are 6 section headers, starting at offset 0xf890:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000008000  00008000
       0000000000000016  0000000000000000  AX       0     0     1
  [ 2] .bss              NOBITS           000000000000f200  00008016
       0000000000000008  0000000000000000  WA       0     0     4
  [ 3] .note.gnu.build-i NOTE             000000000000f800  0000f800
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .comment          PROGBITS         0000000000000000  0000f824
       0000000000000034  0000000000000001  MS       0     0     1
  [ 5] .shstrtab         STRTAB           0000000000000000  0000f858
       0000000000000032  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)


Top
 Profile  
 
 Post subject: Re: gcc produces unexpected ip-relative code for static vari
PostPosted: Sun Jan 28, 2018 1:17 am 
Offline
Member
Member
User avatar

Joined: Wed Dec 01, 2010 3:41 am
Posts: 1761
Location: Hong Kong
gtq wrote:
I want to load small 64-bit ELF images using BIOS in boot loader for testing purposes. Obviously the image must be small enough to fit into the first 640K due to BIOS limitation.

No. most of us use the so called unreal mode (or BIOS extended function, which I don't recommend) to copy image to 1MB mark (or any position you wish), and there is more room you can use there.
(It should be safe to use 1~2MB range, for pedantic implementation you may walk the memory map)

gtq wrote:
I don't think this is PIC related, but how to make gcc not to produce this ip-relative code and place the global data at specified location?

You have -fpie in your compiler flag, it means generate position independent code, thus you cannot access variable with absolute address.
Try remove the -fpie, (why you want it for kernel anyway), and see if it emit GOT instead.


Top
 Profile  
 
 Post subject: Re: gcc produces unexpected ip-relative code for static vari
PostPosted: Sun Jan 28, 2018 1:55 am 
Offline

Joined: Tue Jan 09, 2018 9:25 pm
Posts: 2
I forgot to remove the -fpie option. I was playing with the option to disable PIC. This option doesn’t seem matter. I can try again.

I can try unreal mode too. Thank you


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 137 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group