Articles of gcc

为什么编译器版本出现在我的ELF可执行文件中?

我最近使用gcc在Debian Linux下编译了一个简单的hello world C程序: gcc -mtune=native -march=native -m32 -s -Wunused -O2 -o hello hello.c 文件大小是2980字节。 我在一个hex编辑器中打开它,我看到以下几行: GCC: (Debian 4.4.5-8) 4.4.5 GCC: (Debian 4.4.5-10) 4.4.5 .shstrtab .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .text .fini .rodata .eh_frame .ctors .dtors .jcr .dynamic .got .got.plt data.data .bss .comment 他们真的需要吗? 没办法减less可执行文件的大小?

为什么在缓冲区的末尾和保存的帧指针之间有8个字节?

我正在为作业做一个堆叠砸练习,而且我已经完成了作业,但是有一个方面我不明白。 这是目标程序: #include <stdio.h> #include <stdlib.h> #include <string.h> int bar(char *arg, char *out) { strcpy(out, arg); return 0; } void foo(char *argv[]) { char buf[256]; bar(argv[1], buf); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "target1: argc != 2\n"); exit(EXIT_FAILURE); } foo(argv); return 0; } 以下是在运行Ubuntu 12.04的x86虚拟机上禁用ASLR编译命令。 gcc -ggdb -m32 […]

为什么gcc 4.x默认在调用方法时为linux上的堆栈保留8个字节?

作为asm的初学者,我正在检查gcc -S生成的asm代码来学习。 为什么gcc 4.x默认为调用方法时保留8个字节的堆栈? func18是空函数,没有返回没有参数没有本地variables定义。 我不知道为什么8字节保留在这里(没有任何论坛/网站提到的理由,脂肪酶似乎是理所当然的)是%ebp只是推? 还是返回types? 很多thx! .globl _func18 _func18: pushl %ebp movl %esp, %ebp subl $8, %esp .text

argv:消毒通配符

我正在做一个K&R C书中的例子,它要求你基本上build立一个RPN计算器,它通过命令行参数来input。 我的解决scheme基本上遍历给定的参数,并吐出答案,但我注意到了一些事情: 如果我给乘法字符(星号) '*'没有单引号,gcc认为是一个通配符input,所以我的input $./rpn 5 10 * 给我一个输出 read 5 read 10 read rpn read rpn.c = 0 用单引号包裹星号可以解决问题 $./rpn 5 10 '*' read 5 read 10 read * = 50 我的问题是有没有办法消毒input,以便我的程序不需要用单引号包裹星号,或者是由更基本的东西(例如Linux / POSIX / UNIX二进制执行和参数处理)引起的这种行为?

无法使用静态TLS加载更多对象

我有一个应用程序使用dlopen()来加载额外的模块。 应用程序和模块是在Ubuntu 12.04 x86_64上使用gcc 4.6而构build的,但是为了i386 arch。 然后将二进制文件复制到具有完全相同的操作系统的另一台机器,并正常工作 但是,如果它们被复制到Ubuntu 12.04 i386,则一些(但不是全部)模块将无法加载以下消息: dlopen: cannot load any more object with static TLS 我怀疑这是由__threadvariables的使用引起的。 但是,这些variables不会在加载的模块中使用 – 只能在加载器模块本身中使用。 有人可以提供任何额外的信息,可以是什么原因? 我正在减less__threadvariables的数量并优化它们(使用-ftls-model等),我只是好奇它为什么不能在几乎相同的系统上工作。

GCC存储的string常量以及这些指针映射的位置在哪里?

当我编译并运行我的Linux x86_64机器上的C程序时,由GCC编译: #include <stdio.h> int main(void) { char *p1 = "hello"; // Pointers to strings char *p2 = "hello"; // Pointers to strings if (p1 == p2) { // They are equal printf("equal %p %p\n", p1, p2); // equal 0x40064c 0x40064c // This is always the output on my machine } else { printf("NotEqual %p […]

使用arm-none-eabi-gcc编译和链接库liba.a错误

我在64位Linux机器上用C语言编译hello world程序。 我正在使用一个GCC ARMembedded式工具链,用一个ATMEL AT91SAM9G20处理器在FOX G20 V板上交叉编译我的程序。 在第一次,我编译时有一些错误,因为程序没有识别printf,return等函数(标准的C函数)。 所以我决定在函数之间build立链接,我相信这些函数是在libc.a库中定义的(纠正我,如果我错了),通过执​​行arm-none-eabi-gcc -o hello hello.c libc.a但结果仍然导致错误: libc.a(lib_a-exit.o): In function `exit': exit.c:(.text.exit+0x16): undefined reference to `_exit' libc.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk' libc.a(lib_a-writer.o): In function `_write_r': writer.c:(.text._write_r+0x10): undefined reference to `_write' libc.a(lib_a-closer.o): In function `_close_r': closer.c:(.text._close_r+0xc): undefined reference to `_close' libc.a(lib_a-fstatr.o): In function `_fstat_r': fstatr.c:(.text._fstat_r+0xe): undefined […]

如何从stdin编译代码?

代码很简单: test$ cat test.cpp int main() { } 有没有办法编译来自标准输出的代码? 我试过这个: cat test.cpp | g++ – 和一些变化,但没有产生可执行文件。 只是一些澄清。 我有一个程序预处理一个文件,并产生我想要编译的另一个文件。 我想过不要创build这个中间文件,而是直接生成目标文件。

使链接时,gcc偏好静态库共享对象?

当使用-l选项(比如说-lfoo )链接到库时,如果两者都find了(比较喜欢libfoo.so到libfoo.a ),gcc会select共享对象到静态库。 有没有办法让gcc更喜欢静态库,如果两者都find了? 我试图解决的问题如下:我创build一个应用程序(飞行模拟器称为X平面)插件,具有以下限制: 即使在64位系统上运行,插件也应该是32位共享对象的forms 运行环境不提供加载不在“正常”位置(例如/usr/lib或/usr/lib32共享对象的简便方法: 不能指望用户设置LD_PRELOAD或LD_LIBRARY_PATH来查找我的插件附带的共享对象 在dynamic加载插件共享对象之前,X-Plane运行环境不会将我的插件目录添加到“LD_LIBRARY_PATH”,这将允许我将所有需要的共享对象与我的插件共享对象 不能指望64位用户安装非平凡的32位共享对象(比如,不包含在ubuntu的ia32-libs包中) 为了解决上面的约束,一个可能的解决scheme是将生成的共享对象与所使用的所有非平凡库的静态32位版本链接起来。 但是,在安装这样的库时,通常会安装静态和dynamic版本,因此gcc将始终链接到共享对象而不是静态库。 当然,移动/删除/删除有问题的共享对象,只是把静态库放在/usr/lib32 ,是一个解决方法,但这不是一个好的方法 注意: 是的,我读了关于如何链接共享对象和库,我并没有试图创造一个“完全静态链接的共享对象” 是的,我试过了-Wl,-static -lfoo -Wl,-Bdynamic,但没有带来预期的结果 是的,我也尝试了-l:libfoo.a ,但是这也没有带来预期的结果

为什么我能够在Linux内核模块中执行浮点运算?

我正在x86 CentOS 6.3(内核v2.6.32)系统上运行。 我将下面的函数编译成一个简单的字符驱动模块,作为一个实验,看看Linux内核如何对浮点操作做出反应。 static unsigned floatstuff(void){ float x = 3.14; x *= 2.5; return x; } … printk(KERN_INFO "x: %u", x); 代码编译(这是不期望),所以我插入模块,并与dmesg检查日志。 日志显示: x: 7 。 这似乎很奇怪, 我以为你不能在Linux内核中执行浮点操作 – 保存一些exception,比如kernel_fpu_begin() 。 模块是如何执行浮点运算的? 这是因为我在x86处理器上吗?