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 ??
Trouble with extern variable in 64 bit flat binary
Re: Trouble with extern variable in 64 bit flat binary
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.
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
Hi,
For a simple example, imagine these global variables:
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
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.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
For a simple example, imagine these global variables:
Code: Select all
int foo = 123;
int *fooPtr = &foo;
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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
-
- Member
- Posts: 307
- Joined: Wed Oct 30, 2013 1:57 pm
- Libera.chat IRC: no92
- Location: Germany
- Contact:
Re: Trouble with extern variable in 64 bit flat binary
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.
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
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.
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
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 !
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 !