Page 1 of 1

Trouble with extern variable in 64 bit flat binary

Posted: Tue Nov 25, 2014 9:28 am
by jcmatias
Enviorment : Linux Fedora 20
gcc version 4.8.3 20140624 (Red Hat 4.8.3-1)

my makefile is mk
my linker srcipt is LinkerScript_02

I have declared a var x as extern in test.h

define x in test.c

use make -f mk test.bin flat binary

disasemble it with ndisasm -b 64 test.bin >> test.nds

file test.h:

extern unsigned long int x ;

------------------------------
file test.c:

#include "test.h"

__attribute__((section(".data"))) unsigned long int x = 0x123456789abcdef;


void *_start(void)
{
unsigned long y = 0x123456789ABCDEF;


x = (unsigned long)&y;

return((void*)x);

}

------------------
make file
file mk:

CC = gcc

SOURCES = test.c

OBJ = test.o

BIN = test.bin

#use this to intel syntax
CFLAGS = -masm=intel -m64 -fno-builtin -nodefaultlibs -nostdinc -nostdlib -nostartfiles -fno-exceptions -fno-stack-protector -s -O2

#liker options
LFLAGS = -fdce -fdse -free -pie -fpic -s -static -T LinkerScript_02 -nostartfiles -nostdlib -nostdinc -nodefaultlibs -Wl,--oformat,binary -Wl,-e0x0 -Wl,-N -Wl,-q

$(BIN): $(OBJ)
$(CC) $(LFLAGS) $(OBJ) -o $(BIN)


$(OBJ): $(SOURCES)
$(CC) $(CFLAGS) $(SOURCES) -o $(OBJ)

--------------
Linker script
file LinkerScript_02:

ENTRY(start)

start = 0x0;

OUTPUT_FORMAT(binary)

SECTIONS
{
. = 0x0;

.text . :
{

*(.text) ;

}


.data . :
{
*(.data) *(.rodata) *(.bss) *(COMMON)
}



/DISCARD/ : { *(.got.plt) *(.shstrtab) *(.note.gnu.build-id ) *(.xdata) *(.pdata) *(.comment) *(.note.GNU-stack) *(.eh_frame) *(.eh_frame_hdr) }
}

---------------------------------------------------
make -f mk procuces test.bin


ndisasm -b 64 test.bin >> test.nds
-------------------------------------
test.nds:
disasembled code:

00000000 488D4424F8 lea rax,[rsp-0x8]
00000005 488905740E2000 mov [rel 0x200e80],rax
0000000C C3 ret
0000000D 0000 add [rax],al
0000000F 00EF add bh,ch
00000011 CDAB int 0xab
00000013 896745 mov [rdi+0x45],esp
00000016 2301 and eax,[rcx]

note : x address is 0x200e80 +IP
x value is stored at 0x11

I expected x addess at 0x11

How I can set the address of x to 0x11 ??

Re: Trouble with extern variable in 64 bit flat binary

Posted: Tue Nov 25, 2014 10:33 am
by sortie
You are using a very weird, unsupported and heavily discouraged approach. In particular, you are not using a cross-compiler, you are using a flat binary (they are too simple), you are passing a lot of options (some of them are bad) to the compiler and linker, you are putting variables in the .data section even though that's the default, you are changing the assembler language the compiler emits, and a lot of things I have never seen before (and I've seen quite some stuff).

It might be possible to osdev with your approach, but if you have to ask, then you are not able to do it. I expect your approach to give a lot of trouble and fall apart very soon, even if you get it working. I'm curious, where did you get the instructions to do these things?

I recommend you discard your code and follow http://wiki.osdev.org/Bare_Bones instead, or any other community reviewed and recommended approach.

Re: Trouble with extern variable in 64 bit flat binary

Posted: Tue Nov 25, 2014 6:46 pm
by Brendan
Hi,
jcmatias wrote:LFLAGS = -fdce -fdse -free -pie -fpic -s -static -T LinkerScript_02 -nostartfiles -nostdlib -nostdinc -nodefaultlibs -Wl,--oformat,binary -Wl,-e0x0 -Wl,-N -Wl,-q
I don't think it makes sense to ask for a position independent executable that is flat binary and has no GOT. As far as I know, this combination would be impossible to support.

For a simple example, imagine these global variables:

Code: Select all

int foo = 123;
int *fooPtr = &foo;
In this case, the compiler/linker has to give "fooPtr" a value (and can't rely on RIP relative addressing), but that value can't be known (due to position independence), so the GOT is required.

I also don't think it makes sense to ask for both PIC and PIE. Either it's an executable and not a library (and therefore PIC doesn't make sense) or it's a library and not an executable (and therefore PIE doesn't make sense). Note that for PIC/libraries the sizes of sections aren't known until the resulting library is linked into an executable; which means that the relative offset in an instruction like "mov [rel 0x200e80],rax" can't be known for PIC - this relative offset would have to be fixed later (when the library becomes an executable, and when the sizes of sections can be known).


Cheers,

Brendan

Re: Trouble with extern variable in 64 bit flat binary

Posted: Wed Nov 26, 2014 3:22 am
by no92
Please use code-tags. It makes the code parts stand out and more readable.

As sortie pointed out, you are not using a cross-compiler and flat binaries. As Combuster said a while ago, "t tends to bite afterwards". Build one yourself using the wiki. After that, we'll be able to talk a little bit more.

Re: Trouble with extern variable in 64 bit flat binary

Posted: Wed Nov 26, 2014 4:43 am
by jcmatias
Mr Brendan:
I try by any meas avoid relocation, but I think that you confirm my worst scenario.

I'm working in a scheme interpreter that run in pure metal : PC boots, goto long mode,
run the loop eval. I implement r6rs grammar in bison that generate yyparse()
and a lexer, yylex() , with re2c. A smal nunber of i/o funcitons (get puts,printf,string funcions)
was implemented too.
The pareser yypareser(), runs OK, but i have trouble wthi O N L Y one variable: yylval
yylval is extern. The entire program works well.
I don't want rewrite all parser ( the grammar is easy), but I refuse to lost to ONLY ONE variable.
If I had succes I will document all precess and post here.( I cant put nothin now, the code is very messy)

I copy the linker script from my original project that works like "Natural Selecion":
If works and dont disrupts keep, otherwise write off, so same flags are useless.
This is a test of concept.


But, same results that I expected are achived only with this freak combination of flags:
For example: Without -O2 my printf don't work properly with const strings:
char *hello="Hello, World" , printf("%s",hello) works, but printf("Hello, world") don't.
(before I post the code I will solve this);

This line for example __attribute__((section(".data"))) unsigned long int x = 0x123456789abcdef; is
attempt to put the varable in data section, but only the value goto .data section as we see at end of
disassembled code.

Re: Trouble with extern variable in 64 bit flat binary

Posted: Thu Nov 27, 2014 5:19 am
by jcmatias
Solved :
As every people warned, the command line args to linker and compiler are wrong.
I will post a solution when I clean up the code.
Thanks for all !