I noticed (the hard way sadly) that -Wl,--nmagic aka the linker -n option makes my app segfault when I use global variables. Reading the man page doesn't really answer why. I was using it because it brought my binary from 14K to 1K (and less than 1K if I use a few more commands). Is there anything I can do to restore proper behavior? I thread thread local but Ican't figure out how to set thread local memory. c compilers say FS isn't a valid register and mov fs, rax creates an invalid instruction (or something)
Things I noticed:
const int test=6 it works (you'll have to delete the if)Source:
//clang or gcc -static -Wl,--nmagic -nostdlib test.c
typedef unsigned long long int size_t;
typedef long long int ssize_t;
typedef long long int int64_t;
ssize_t my_write(int fd, const void *buf, size_t size) {
register int64_t rax __asm__ ("rax") = 1;
register int rdi __asm__ ("rdi") = fd;
register const void *rsi __asm__ ("rsi") = buf;
register size_t rdx __asm__ ("rdx") = size;
__asm__ __volatile__ (
"syscall"
: "+r" (rax)
: "r" (rdi), "r" (rsi), "r" (rdx)
: "cc", "rcx", "r11", "memory"
);
return rax;
}
void my_exit(int exit_status) {
register int64_t rax __asm__ ("rax") = 60;
register int rdi __asm__ ("rdi") = exit_status;
__asm__ __volatile__ (
"syscall"
: "+r" (rax)
: "r" (rdi)
: "cc", "rcx", "r11", "memory"
);
}
int test=6; //if this isn't assigned it works fine
int _start(){
if (test == 0)
test=6;
my_write(1, "Hello\n", test);
my_exit(0);
return 0;
}
size -A ./a.out
section size addr
.note.gnu.property 48 4194816
.note.gnu.build-id 36 4194864
.text 127 4198400
.rodata 7 4202496
.eh_frame 120 4202504
.data 4 4210688
.comment 18 0
Total 360