Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux在ELF上迭代;第「;运行时的标题_C_Linux_Elf - Fatal编程技术网

C Linux在ELF上迭代;第「;运行时的标题

C Linux在ELF上迭代;第「;运行时的标题,c,linux,elf,C,Linux,Elf,简短版本: 可以在运行时检查所有ELF“section”头,并为每个加载的共享库获取每个“section”头的重新定位地址 长版本: 我试图在用户空间中实现与内核中存在的相同的动态调试机制(dyn_debug)。每个日志宏实例在程序的特定“部分”中创建静态变量的工作方式 \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 这迫使编译器将变量不放在“.data”节中,而是放在“\uu ver

简短版本: 可以在运行时检查所有ELF“section”头,并为每个加载的共享库获取每个“section”头的重新定位地址

长版本: 我试图在用户空间中实现与内核中存在的相同的动态调试机制(dyn_debug)。每个日志宏实例在程序的特定“部分”中创建静态变量的工作方式
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
这迫使编译器将变量不放在“.data”节中,而是放在“\uu verbose”节中。本节稍后的开始和停止地址可以通过变量访问
__开始详细,停止详细。通过这种方式,一些中心例程可以检查所有注册的“日志”条目,并根据需要更改属性。
这适用于静态链接的可执行文件,但在使用共享库时,有几个“\uuu verbose”部分(每个共享库一个)和可执行文件本身一个。(我使用-fPIC标志当然是为了被纳入图书馆)
此外,所有符号都与“-导出动态”链接,以确保导出所有符号

每个共享库和主可执行文件都有 属性(构造函数)初始化方法

我在两个病例中观察到两种不同的行为

案例1:对于第一个案例,库不是由ldopen加载的,而是由“libc加载程序”加载的

  • 引用\uuuu start\uuuuu verbose始终返回相同的地址(主可执行文件的地址),其中仅存在“主”可执行文件日志记录项

  • dlsym(RTLD\u NEXT,\uuuu start\uuuu verbose)返回“NEXT”可解析库的符号地址,因此实际上我得到了所有地址

  • 案例2:使用ldopen加载库

  • 引用\uuuu start\uuuuu verbose始终返回相同的地址(主可执行文件的地址)
  • dlsym(RTLD\u NEXT,\uuuu start\uuuu verbose)返回NULL
  • dlsym(RTLD_默认值,_开始__详细)返回“主”进程表
  • dlsym(句柄,开始详细)-返回正确的节地址
  • 问题:对于使用ldopen打开的库,除了4之外,还有什么方法可以获得该符号,因为4需要从“加载器”显式调用

    代码:


    您不应该在运行时访问节信息。节不应该在运行时使用,并且可能会从可执行文件中删除(剥离)

    我可能会将自定义链接器脚本用于:

    .__verbose:
    {
      PROVIDE_HIDDEN (__verbose_start = .);
      *(.__verbose)
      PROVIDE_HIDDEN (__verbose_end = .);
    }
    
    这将定义节的隐藏符号,以便每个ELF文件都有自己的符号版本

    ELF文件中的构造函数(或某些其他代码)可以使用它们:

    struct foo*;
    extern struct foo* __verbose_start __attribute__((visibility("hidden")));
    extern struct foo* __verbose_stop __attribute__((visibility("hidden")));
    
    void __attribute__((constructor)) initializer()
    {
       initialize_logging(__verbose_start,__verbose_stop);  
    }
    

    由于我没有
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu verbose
    变量,您是否做了什么特别的工作。您不想在ELF文件的(高优先级)?否则,在执行构造函数的代码时将不会初始化它们。
    struct foo*;
    extern struct foo* __verbose_start __attribute__((visibility("hidden")));
    extern struct foo* __verbose_stop __attribute__((visibility("hidden")));
    
    void __attribute__((constructor)) initializer()
    {
       initialize_logging(__verbose_start,__verbose_stop);  
    }