/usr/bin/ld: cannot find -lgcc_s - c

I have a problem I need help with.
I am currently trying to write a program to read out the address of a section I created.
add.c:
#include <stdio.h>
extern unsigned char arduino_handler_size[];
int main(){
printf("section `.arduino_handler` starts at %p and the 1st byte is %x\n",
arduino_handler_size, (unsigned int)arduino_handler_size[0]);
return 0;
}
arduino_handler.ld:
OUTPUT_FORMAT(elf64-x86-64)
ENTRY(main)
OUTPUT(Test)
SECTIONS
{
.text : { *(.text) }
. = ALIGN(0x1000);
.data : { *(.data) }
. = ALIGN(0x10000);
.bss : { *(.bss)}
. = ALIGN(0X10000);
.arduino_handler :
{
arduino_handler_size = 0x10;
arduino_handler_start = .;
. = . + arduino_handler_size;
arduino_handler_end = .;
}
}
When I run gcc -T arduino_handler.ld -N add.c I get the error:
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
I am working on:
Ubuntu 18.04.3 LTS
Kernel: 5.0.0-37-generic x86_64 bits: 64
I have tried changing the gcc version from 7 to 4.8 and back to 8. That sadly doesn't help.
The symbolic link for libgcc_s is not broken, but it still gives me an error.
How can I fix this?

Related

ARM cross compile for x86 error: relocation truncated to fit: R_x86_64_32 against '.rodata", how do I fix this?

I'm trying to cross compile a custom OS for x86 hardware on an ARM based system (Debian VM on M1 Mac). To compile I'm using "x86_64-linux-gnu-gcc" and for a linker I'm using "x86_64_linux-gnu-ld".
Note that this does build and compile normally when not on an ARM system. So an x86_64 system will compile and link correctly. I am trying to cross compile this because the ARM version of gcc does not like the x86 assembly boot code that we have (if you think this is the better approach and have tips for handling it this way please let me know).
The error I have comes up when trying to go through the linking process:
Linking for "kernel/kernel.bin"...
main/acpi.o: in function `__rsdp_search_range':
/home/project/kernel/main/acpi.c:63:(.text+0x13b): relocation truncated to fit: R_X86_64_32 against `.rodata'
main/acpi.o: in function `acpi_init':
/home/project/kernel/main/acpi.c:108:(.text+0x290): relocation truncated to fit: R_X86_64_32 against `.rodata'
/home/project/kernel/main/acpi.c:108:(.text+0x295): relocation truncated to fit: R_X86_64_32 against `.rodata'
/home/project/kernel/main/acpi.c:108:(.text+0x29a): relocation truncated to fit: R_X86_64_32 against `.rodata'
/home/project/kernel/main/acpi.c:108:(.text+0x2a4): relocation truncated to fit: R_X86_64_32 against `.rodata'
/home/project/kernel/main/acpi.c:114:(.text+0x327): additional relocation overflows omitted from the output
make[1]: *** [Makefile:34: kernel.bin] Error 1
make[1]: Leaving directory '/home/project/kernel'
make: *** [Makefile:6: all_kernel] Error 2
After trying to search for similar errors, I tried modifying the gcc flags. We already had -mcmodel=large, but i tested with the different variations. I also tested with -fPIC but none of these changes fixed the problem.
gcc flags:
cflags.x86-64 := -march=x86-64 -m64 -mno-red-zone -mcmodel=large -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-sse4a -mno-3dnow -mno-avx -mno-avx2
cflags.common := -fno-pie -ffreestanding -fno-builtin -nostdinc -std=c99 -g3 -gdwarf-3 -fno-stack-protector -fsigned-char -Iinclude
cflags.warnings := -Wall -Wredundant-decls -Wundef -Wpointer-arith -Wfloat-equal -Wnested-externs -Wvla -Winline -Wextra -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wno-attributes
linker code:
OUTPUT_FORMAT(elf64-x86-64)
KERNEL_LMA = 0x00100000;
KERNEL_VMA = 0xffff800000000000;
ENTRY(_start)
STARTUP(entry/entry.o)
SECTIONS {
. = KERNEL_VMA + KERNEL_LMA;
k_start = .;
.text : AT(ADDR(.text) - KERNEL_VMA) {
_code = .;
*(.multiboot)
*(.text)
. = ALIGN(0x1000);
}
csd_start = .;
.csd : AT(ADDR(.csd) - KERNEL_VMA) {
*(.csd)
. = ALIGN(0x1000);
}
csd_end = .;
.init : AT(ADDR(.init) - KERNEL_VMA) {
kernel_start_init = .;
*(.init)
. = ALIGN(0x1000);
kernel_end_init = .;
}
.rodata : AT(ADDR(.rodata) - KERNEL_VMA) {
_rodata = .;
*(.rodata)
. = ALIGN(0x1000);
}
.data : AT(ADDR(.data) - KERNEL_VMA) {
_data = .;
*(.data)
. = ALIGN(0x1000);
}
_edata = .;
.bss : AT(ADDR(.bss) - KERNEL_VMA) {
_bss = .;
*(.bss)
*(COMMON)
. = ALIGN(0x1000);
}
_end = .;
/DISCARD/ : {
*(.comment)
*(note.*)
}
kernel_phys_off = k_start - KERNEL_LMA;
kernel_phys_base = k_start - kernel_phys_off;
kernel_phys_end = _end - kernel_phys_off;
kernel_page_tables = ((_end - k_start) / 0x80000) + 1; /* XXX might be 0x200000 */
kernel_text_sectors = ((_end - k_start) / 512) + 1;
}
Edit
Below is the __rsdp_search_range function, I dont necessarily think it is the problem because if I comment out this file, for instance, the error pops up elsewhere.
static rsdp_20_t *__rsdp_search_range(uintptr_t start, uintptr_t end)
{
uintptr_t rsdp_candidate = start;
while (rsdp_candidate <= end - sizeof(struct rsdp))
{
if (memcmp((void *)rsdp_candidate, rsdp_sig, sizeof(rsdp_sig)) == 0 &&
__acpi_checksum((uint8_t *)rsdp_candidate, sizeof(rsdp_20_t)) ==
0)
{
return (rsdp_20_t *)rsdp_candidate;
}
rsdp_candidate += RSDP_ALIGN;
}
return NULL;
}
I did try and remove -fno-pie and got the following error instead: x86_64-linux-gnu-ld: failed to convert GOTPCREL relocation; relink with --no-relax"

How to run a linker script for GCC

I'm trying to run a simple linker script to understand how linking works and how i can implement function reordering with the linker script
Here is my C code
void A(){
printf("A\n");
}
void B(){
printf("B\n");
}
void main(){
B();
A();
}
Here is the linker script
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
When i try to compile with this external linker script it gives me this error
/usr/lib64/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x14): undefined reference to `__init_array_start'
/usr/lib64/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x1c): undefined reference to `__init_array_end'
/usr/bin/ld: cl: hidden symbol `__init_array_end' isn't defined
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
My compile command is this
gcc -Wl,-no-whole-archive -ffunction-sections -T simple.ld cache_ex.c -o cl
Can you tell me what i'm doing wrong?

Question on gcc of local array variable and inline functions when linking with own .ids files

I'm using gcc to compile a printing function. But met the following 2 problems:
Whenever I apply a local array type variable, the linker would report and error of "undefined reference to `__stack_chk_fail'"
When I'm using "inline" to define a function, it report an error of "undefined reference to `strlen'"
My platform is Ubuntu 18.04, and gcc version is 7.3.0.
I present some of the problem codes:
In function "number()" I applied an "char" type array variable, which actually cause the 1st error:
char* number(char *str, long num, int base, int field_width, int precision, int type)
{
char *TempDgt = DigitsCptl, c, sign;
int i;
char TempStr[50];
....
return str;
}
The problem lies on "char TempStr[50];" and with the removal of it, the link succeed. Similar problem appears on "va_list args;" of the following code:
int color_printk(unsigned int FRcolor, unsigned int BKcolor, char * fmt, ...)
{
int count, i, line;
va_list args;
...
return i;
}
Second problem lies on function "strlen" as follow:
inline int strlen(char * String)
{
...
return __res;
}
This time the "inline" descriptor caused the problem.
Both of the problems occur at "ld" instruction, the following is my makefile:
Kernel:
# Clear previous files
- rm head.s head.o main.o system kernel.bin printk.o
# Compile head.S
gcc -E ./OSFiles/Codes/head.S > head.s
as --64 -o head.o head.s
# Compile main function
gcc -mcmodel=large -fno-builtin -m64 -c ./OSFiles/Codes/main.c
gcc -mcmodel=large -fno-builtin -m64 -c ./OSFiles/Codes/printk.c
# Link compiled files
ld -b elf64-x86-64 -z muldefs -o system head.o main.o printk.o -T ./OSFiles/Codes/Kernel.lds
# Dump out Kernel.bin
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system Kernel.bin
And the .ids file:
OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
. = 0xffff800000000000 + 0x100000;
.text :
{
_text = .;
*(.text)
_etext = .;
}
.data :
{
_data = .;
*(.data)
_edata = .;
}
.bss :
{
_bss = .;
*(.bss)
_ebss = .;
}
_end = .;
}

Linker script not working?

I have a very simple program (simple.c):
#include <stdio.h>
int main(){
int a = 4;
return 0;
}
I am trying to use a the following linker script (MEMORY):
MEMORY
{
m_text : ORIGIN = 0x0000000000400000, LENGTH = 0x0001FBF0
m_data : ORIGIN = 0x0000000000600000, LENGTH = 0x00004000
}
SECTIONS
{
.text :
{
*(.text) /* Program Code */
} > m_text
.data : { *(.data) } > m_data
.bss : { *(.bss) } > m_data
}
I am using following commands to compile and link:
gcc -c simple.c
ld -T MEMORY -o simple -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o simple.o
I am getting the following ERROR:
ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
.
.
.
ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x12): undefined reference to `__libc_csu_fini'
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x19): undefined reference to `__libc_csu_init'
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x25): undefined reference to `__libc_start_main'
simple.o: In function `main':
simple.c:(.text+0xa): undefined reference to `puts'
If I try to use :
ld -T MEMORY4 -o simple -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o simple.o -lc
It gives the ERROR
ld: cannot find -lc
Any suggestions? All I want to do is place my simple.c into some different memory region then default.
There are a couple of problems, but the main one is with your linker script doesn't have a .debug_info or .debug_line section.

Using simple linker script gives "relocation truncated to fit: R_X86_64_32S"

I'm trying to compile this simple program with a custom linker script on an amd-64 linux machine
// main.c
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("Hello World!\n");
int* x = malloc(sizeof(int));
while(1) {}
return 0;
}
and
// script.ld
SECTIONS
{
. = 0x100000000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
but if I do gcc -T script.ld main.c -o main, I get
a lot of errors like
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x12): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_fini' defined in .text section in /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
You are trying to link main at 0x100000000, which is above 4GB boundary, but GCC (and your libc) are not set up for -mcmodel=large.
The default is -mcmodel=medium, which implies that the program is linked into the lower 2GBs of address space.
You would need to build both main.c and crt1.o with -mcmodel=large in order to link your executable at 0x100000000.
Or just use -fPIE and -pie and your executable will load at arbitrary (but usually well above 4GB boundary) address.

Resources