Electronic Joint Business

Solution for E-Business

elf

ELF 对线程局部储存的处理 (一)

线程使用的增加使得开发者期望有更好的方式来处理线程局部数据 (read-local data)。 POSIX 线程接口的有关定义允许在每个线程中独立存储 void * 对象。不过使用该接口很麻烦。你需要在运行时为对象分配一个键(key),如果这个键不再使用就需要释放它。这项工作繁琐而且易出错。如果和动态加载代码(dynamically loaded code)一起使用,就真的成了个大麻烦。

应对这些问题的方法是扩展编程语言,让编译器接手这些工作。以 C/C++ 来说,可以在定义与声明变量时使用新关键字 __thread。这虽然不是个官方扩展,编译器开发者被鼓励实现它以支持新 ABI。用这个关键字定义及声明的变量会自动地局部分配到每个线程。

__thread int i;
__thread struct states;
extern __thread char *p;

不仅一般用户程序可以受益,运行时环境(runtime)亦能从中获得好处 (如全局变量 errno 必须是线程局部的),而且编译器可以执行构建非自动变量( non-autimatic variable)的优化。注意:用 __thread 来定义自动变量毫无意义也不被允许,这是因为自动变量总是线程局部的。而且,函数作用域中的静态变量应是首选。

 

, ,

Linux可执行文件格式分析

可执行文件格式综述

可执行文件是操作系统中最重要的文件类型。可执行文件中包含代码和数据,此外文件可能需要引用外部文件定义的符号(变量和函数),因此重定位信息和符号信息也是需要的。其他一些辅助信息是可选的,如调试信息、硬件信息等。基本上任意一种可执行文件格式都是按区间保存上述信息,称为段(Segment)或节(Section)。不同的文件格式中段和节的含义可能有细微区别。最后,可执行文件通常都有一个文件头部以描述本文件的总体结构。

获得可执行文件有三个重要的步骤:编译(compile)、连接(link,也可称为链接、联接)、加载(load)。源程序文件被编译成目标文件,多个目标文件被连接成一个最终的可执行文件,可执行文件被加载到内存中运行。

下面我们来看一下LINUX平台下ELF文件加载过程的一个简单描述。

1:内核首先读ELF文件的头部,然后根据头部的数据指示分别读入各种数据结构,找到标记为可加载(loadable)的段,并调用函数 mmap()把段内容加载到内存中。在加载之前,内核把段的标记直接传递给 mmap(),段的标记指示该段在内存中是否可读、可写,可执行。显然,文本段是只读可执行,而数据段是可读可写。这种方式是利用了现代操作系统和处理器对内存的保护功能。

>>> 阅读全文

 

,