用glibc静态链接,而无需调用主 [英] Static linkage with glibc without calling main

查看:835
本文介绍了用glibc静态链接,而无需调用主的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用NASM这就要求的printf _exit 从libc中,但并没有采用简单的Hello World

I have created a simple hello world using NASM which calls printf and _exit from libc but does not use main.

extern printf
extern _exit

section .data
    hello:     db 'Hello world!',10

section .text
    global _start   
_start:
    xor eax, eax
    mov edi, hello
    call printf
    mov rax, 0    
    jmp _exit

我创建这样的对象文件

I create the object file like this

nasm -felf64 hello.asm

然后我就可以像这样的glibc使用动态链接将其链接

Then I can link it using dynamic linkage with glibc like this

ld hello.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64

这没有错误正常运行。但现在我想静态地做到这一点。我

This runs correctly with no errors. But now I want to do it statically. I do

ln -s `gcc -print-file-name=libc.a`
ln -s `gcc -print-file-name=libgcc_eh.a`
ld hello.o -static libc.a libgcc_eh.a libc.a -melf_x86_64

这个链接,但是当我运行code我得到一个分段错误。使用 GDB 我看到它给

This links but when I run the code I get a segmentation fault. Using gdb I see it gives

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401004 in vfprintf ()

如果我用C写一个简单的Hello World和运行静态编译精做显然是可能的静态链接到glibc的我的系统上。 如何,我可以使用静态链接用glibc与我组装code?

If I write a simple hello world in C and compile with static in runs fine so apparently it's possible to link statically to glibc on my system. How can I use static linkage with glibc with my assembly code?

如果我链接到一个替代glibc的,如 MUSL-libc的正常工作

If I link to an alternative to glibc such as musl-libc it works fine

ld hello.o -static /usr/local/musl/lib/libc.a -melf_x86_64

我在使用Ubuntu 14.04,eglibc 2.19,和GCC 4.9.1

I'm using Ubuntu 14.04, eglibc 2.19, and GCC 4.9.1

推荐答案

Glibc上有一个巨大的初始化序列,因为它具有很强的意愿在做多线程系统协同工作。此外GLIBC妥善处理一些GNU扩展像构造属性。在启动时,它缓存里面很多TLS,包括区域设置信息,它初始化同步对象等。

Glibc have a huge initialization sequence, because it is done with strong intention to work in multithreading systems. Also GLIBC properly handles some GNU extensions like constructor attributes. On startup, it caching a lot inside TLS, including locale information, it initializes synchronization objects and so on.

你vprintf确切的问题是未初始化的区域设置访问权限。

Exact problem with your vprintf is uninitialized locale access.

在动态链接到它,这一切工作的完成加载和一切正常。

When you are linking to it dynamically, all this work is done on loading and everything works.

静态链接glibc的要求 __ libc_init_first 来调用初始化所有需要它。在此之前,叫你需要 __ dl_tls_setup 来正确设置TLS并在此之后叫你将需要 __ libc_csu_init 正确地调用所有全局构造

Statically linked glibc requires __libc_init_first to be called to initialize all it need. Before this call you need __dl_tls_setup to properly setup TLS and after this call you will need __libc_csu_init to properly call all global constructors.

所有这些东西是高度依赖于版本的和实际无证。严格说,没有安全静态链接到glibc的,跳过或修改其正常 _start 顺序的方式。

All this stuff is highly version-dependent and practically undocumented. Strictly saying, there is no safe way to link statically to glibc, skipping or modifying its normal _start sequence.

在另一方面,像MUSL或newlib嵌入的函数库都没有等限制性有关的初始化和多线程和地点。

On the other hand, embedded-oriented libraries like musl or newlib are not so restrictive about initialization and multithreading and locales.

这篇关于用glibc静态链接,而无需调用主的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆