Page 1 of 1

relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 12:02 pm
by 22OsC
Hello OSDev forum!
I got a problem about GDT table when I am trying to compile.

Code: Select all

gdt.o: relocation R_X86_64_32S against `.text' can not be used when making a PIE object; recompile with -fPIE
My makefile code:

Code: Select all

INTERNALLDFLAGS := \
	-fno-pic -fPIE \
	-Wl,-static,-pie,--no-dynamic-linker,-ztext \
	-static-pie    \
	-nostdlib      \
	-Tlinker.ld    \
	-z max-page-size=0x1000

INTERNALCFLAGS  :=       \
	-I${INCLUDE_DIR}     \
	-std=gnu11           \
	-ffreestanding       \
	-fno-stack-protector \
	-fno-pic -fPIE       \
	-mno-80387           \
	-mno-mmx             \
	-mno-3dnow           \
	-mno-red-zone

build: $(KERNEL)

$(KERNEL): $(OBJ)
	$(CC) $(INTERNALLDFLAGS) $(OBJ) -o $@

%.o: %.c ${C_HEADERS}
	$(CC) $(CFLAGS) $(INTERNALCFLAGS) -c $< -o $@

%.o: %.asm
	${NASM} $< -f elf64 -o $@
Code that is causing relocation error

Code: Select all

void init_gdt()
{
    __lgdt(&g_gdt);

    asm volatile(
        "movq %%rsp, %%rax\n"
        "pushq $16\n"
        "pushq %%rax\n"
        "pushfq\n"
        "pushq $8\n"
        "pushq $1f\n"
        "iretq\n"
        "1:\n"
        "movw $16, %%ax\n"
        "movw %%ax, %%ds\n"
        "movw %%ax, %%es\n"
        "movw %%ax, %%fs\n"
        "movw %%ax, %%gs\n" ::
            : "memory", "rax");
}
I am using gcc cross compiler like in GCC_Cross-Compiler tutorial
Do anyone knows what's wrong?

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 2:57 pm
by nexos
What does linker.ld look like

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 3:18 pm
by Octocontrabass
22OsC wrote:

Code: Select all

        "pushq $1f\n"
This instruction requires the R_X86_64_32S relocation. You need to either choose a position-independent way of getting that address or stop trying to make your kernel position-independent.

Why are you trying to make your kernel position-independent?

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 6:07 pm
by 22OsC
nexos wrote:What does linker.ld look like
Oops i forgot

Code: Select all

ENTRY(kernel_main)

OUTPUT_FORMAT(elf64-x86-64)

SECTIONS
{
    /**************** KERNEL SECTIONS ****************/
    . = 0xffffffff80000000 + 200000;
    _kernel_start =.;

    /**************** STIVALE2 HEADER ****************/
    .stivale2hdr :
    {
        KEEP(*(.stivale2hdr))
    }

    .text :
    {
        *(.text*)
    }

    .rodata :
    {
        *(.rodata*)
    }

    .data :
    {
        *(.data*)
    }

    .bss :
    {
        *(COMMON)
        *(.bss*)
    }
    _kernel_end = .;
}

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 6:26 pm
by 22OsC
Octocontrabass wrote:
22OsC wrote:

Code: Select all

        "pushq $1f\n"
This instruction requires the R_X86_64_32S relocation. You need to either choose a position-independent way of getting that address or stop trying to make your kernel position-independent.

Why are you trying to make your kernel position-independent?
I tried to compile with -fno-pic but I am getting

Code: Select all

stivale.c:16:(.text+0x1): relocation truncated to fit: R_X86_64_32 against `.rodata'
string.c:16:(.text+0x269): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
stivale2.c:72:(.text+0x179): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
and many, many more errors
I don't know why is doing this, I mean, nothing here it's wrong

Code: Select all

        void (*term_write)(const char *string, size_t length) = (void *)term_str_tag->term_write;
        term_write("Unable to get memory map!", 25); <----- line 72 in stivale2.c

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 6:40 pm
by Octocontrabass
22OsC wrote:

Code: Select all

relocation truncated to fit: R_X86_64_32
The default "small" memory model requires all symbols to have addresses in the 0-0x7FFFFFFF range.
22OsC wrote:

Code: Select all

    . = 0xffffffff80000000 + 200000;
All of your symbols have addresses above 0xFFFFFFFF80000000. You probably want to use the "kernel" memory model instead.

Pass "-mcmodel=kernel" to the compiler. There's more information on the wiki. There's even more information in the GCC manual.

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 7:55 pm
by 22OsC
Octocontrabass wrote:
22OsC wrote:

Code: Select all

relocation truncated to fit: R_X86_64_32
The default "small" memory model requires all symbols to have addresses in the 0-0x7FFFFFFF range.
22OsC wrote:

Code: Select all

    . = 0xffffffff80000000 + 200000;
All of your symbols have addresses above 0xFFFFFFFF80000000. You probably want to use the "kernel" memory model instead.

Pass "-mcmodel=kernel" to the compiler. There's more information on the wiki. There's even more information in the GCC manual.
Oh thanks, I didn't knew that #-o

Re: relocation R_X86_64_32S against '.text' can not be used

Posted: Fri Jul 16, 2021 9:58 pm
by nullplan
22OsC wrote:

Code: Select all

void init_gdt()
{
    __lgdt(&g_gdt);

    asm volatile(
        "movq %%rsp, %%rax\n"
        "pushq $16\n"
        "pushq %%rax\n"
        "pushfq\n"
        "pushq $8\n"
        "pushq $1f\n"
        "iretq\n"
        "1:\n"
        "movw $16, %%ax\n"
        "movw %%ax, %%ds\n"
        "movw %%ax, %%es\n"
        "movw %%ax, %%fs\n"
        "movw %%ax, %%gs\n" ::
            : "memory", "rax");
}
You know, this can be done easier and position independent in a separate function:

Code: Select all

/* void load_desc(uint16_t cs, uint16_t ds); */
.global load_desc
.type load_desc,@function
load_desc:
  movw %si, %ds
  movw %si, %es
  movw %si, %fs
  movw %si, %gs
  movw %si, %ss
  movq (%rsp), %rax
  andl $0xffff, %edi
  pushq %rdi
  pushq %rax
  lretq $8
.size load_desc, .-load_desc
You must put that into a separate function rather than inline assembler, because you need to get at the return address. There is no need to load CS before the other segments, so you can do it last, and as code address you can just use the return address.