So I am following a textbook example. There is a simple C program writing stuff. It is not using the standard library, the sys calls are written in assembly, the _start subprogram, preparing the main args and exiting is also written in assembly.
When I create a singular variable as the first line of main
in hello.c
it works fine.
When I create an array, like char arr[20]
, I get the following linker error: Undefined reference to __stack_chk_fail_local
,
hidden symbol __stack_chk_fail_local ins't defined
, final link failed: bad value
.
Does anyone have an idea why?
hello.c
:
#include "calls.h"
static const char dunno[] = "I don't know how to greet you\n";
static const char hello[] = "Hello, dear ";
static int string_length(const char *str)
{
int i = 0;
while(str[i])
i++;
return i;
}
int main(int argc, char **argv)
{
char arr[20];
if (argc < 2)
{
sys_write(1, dunno, sizeof(dunno)-1);
return 1;
}
sys_write(1, hello, sizeof(hello)-1);
sys_write(1, argv[1], string_length(argv[1]));
sys_write(1, "\n", 1);
return 0;
}
calls.h
:
#ifndef CALLS_H_SENTRY
#define CALLS_H_SENTRY
int sys_read(int fd, void *buf, int size);
int sys_write(int fd, const void *buf, int size);
extern int sys_errno;
#endif
start.asm
:
global _start ; no_std_lib/start.asm
extern main
section .text
_start :
mov ecx, [esp]
mov eax, esp
add eax, 4
push eax
push ecx
call main
add esp, 8
mov ebx, eax ; main's return result
mov eax, 1 ; syscall exit
int 80h
calls.asm
:
global sys_read ; no_std_lib/calls.asm
global sys_write
global sys_errno
section .bss
sys_errno resd 1
section .text
generic_syscall_3:
push ebp
mov ebp, esp
push ebx
mov ebx, [ebp+8] ; descriptor
mov ecx, [ebp+12] ; ptr to str start
mov edx, [ebp+16] ; size of str
int 80h
mov edx, eax
and edx, 0fffff000h
cmp edx, 0fffff000h
jnz .okay
mov [sys_errno], eax
mov eax, -1
.okay: pop ebx
mov esp, ebp
pop ebp
ret
sys_read: mov eax, 3
jmp generic_syscall_3
sys_write: mov eax, 4
jmp generic_syscall_3