x86的库和arm的.o文件能链接吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了x86的库和arm的.o文件能链接吗相关的知识,希望对你有一定的参考价值。

不行。x86的库是建立在x86架构上的,而.o文件是建立在ARM架构上的,二者不兼容,因此无法直接链接。你需要先将x86的库编译成ARM架构下的可执行文件,然后再和.o文件相链接,这样就可以执行ARM架构下的可执行文件了。 参考技术A arm64-v8a是可以向下兼容的,但前提是你的项目里面没有arm64-v8a的文件夹,如果你有两个文件夹armeabi和arm64-v8a,两个文件夹,armeabi里面有a.so 和 b.so,arm64-v8a里面只有a.so,那么arm64-v8a的手机在用到b的时候发现有arm64-v8a的文件夹,发现里面没有b.so,就报错了,所以这个时候删掉arm64-v8a文件夹,这个时候手机发现没有适配arm64-v8a,就会直接去找armeabi的so库,所以要么你别加arm64-v8a,要么armeabi里面有的so库,arm64-v8a里面也必须有

编译原理-链接实例分析

gcc-arm-none-eabi 工具链功能

1.arm-none-eabi-gcc :c语言编译器,可以将.c文件编译为.o的执行文件

2.arm-none-eabi-g++ :c++编译器,可以将.cpp文件编译成.o的执行文件

3.arm-none-eabi-ld : 链接器,链接所有的.o文件生成可执行文件

4.arm-none-eabi-objcopy :将链接器生成的文件转换为bin/hex等可烧写的格式

5.arm-none-eabi-gdb :调试器,将gdb连接到硬件产生的网络端口就可以实现硬件和代码的调试。

https://sourceware.org/binutils/docs/binutils/objcopy.html

objcopy can be used to generate a raw binary file by using an output target of ‘binary’ (e.g., use -O binary). When objcopy generates a raw binary file, it will essentially produce a memory dump of the contents of the input object file. All symbols and relocation information will be discarded. The memory dump will start at the load address of the lowest section copied into the output file.

https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html

Every section has a virtual address (VMA) and a load address (LMA);

The load address is specified by the AT or AT> keywords. Specifying a load address is optional.

If neither AT nor AT> is specified for an allocatable section, the linker will use the following heuristic to determine the load address:

  • If the section has a specific VMA address, then this is used as the LMA address as well.

  • If the section is not allocatable then its LMA is set to its VMA.

  • Otherwise if a memory region can be found that is compatible with the current section, and this region contains at least one section, then the LMA is set so the difference between the VMA and LMA is the same as the difference between the VMA and LMA of the last section in the located region.

  • If no memory regions have been declared then a default region that covers the entire address space is used in the previous step.

  • If no suitable region could be found, or there was no previous section then the LMA is set equal to the VMA.

This feature is designed to make it easy to build a ROM image. For example, the following linker script creates three output sections: one called ‘.text’, which starts at 0x1000, one called ‘.mdata’, which is loaded at the end of the ‘.text’ section even though its VMA is 0x2000, and one called ‘.bss’ to hold uninitialized data at address 0x3000. The symbol _data is defined with the value 0x2000, which shows that the location counter holds the VMA value, not the LMA value.

SECTIONS .text 0x1000 : *(.text) _etext = . ; .mdata 0x2000 : AT ( ADDR (.text) + SIZEOF (.text) ) _data = . ; *(.data); _edata = . ; .bss 0x3000 : _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;

The run-time initialization code for use with a program generated with this linker script would include something like the following, to copy the initialized data from the ROM image to its runtime address. Notice how this code takes advantage of the symbols defined by the linker script.

extern char _etext, _data, _edata, _bstart, _bend;char *src = &_etext;char *dst = &_data;/* ROM has data at end of text; copy it. */while (dst < &_edata) *dst++ = *src++;/* Zero bss. */for (dst = &_bstart; dst< &_bend; dst++) *dst = 0;

案例:

编码

main.c

int i = 10 ;
int f ;

int main(void)
        
        int k = 0 ; int m = 10; 
        
        k = m+i+f;
        
        return k ;
        

编译

$System/Tools/GNUArmToolchain/windows/bin/arm-none-eabi-gcc.exe -c main.c

生成main.o ,查看main.o的sections状态:

$System/Tools/GNUArmToolchain/windows/bin/arm-none-eabi-readelf.exe -S main.o

重点关注text.data.bass段的大小。

There are 10 section headers, starting at offset 0x260:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000058 00  AX  0   0  4  [ 2] .rel.text         REL             00000000 0001fc 000018 08   I  7   1  4  [ 3] .data             PROGBITS        00000000 00008c 000004 00  WA  0   0  4  [ 4] .bss              NOBITS          00000000 000090 000004 00  WA  0   0  4
  [ 5] .comment          PROGBITS        00000000 000090 00004a 01  MS  0   0  1
  [ 6] .ARM.attributes   ARM_ATTRIBUTES  00000000 0000da 00002a 00      0   0  1
  [ 7] .symtab           SYMTAB          00000000 000104 0000e0 10      8  11  4
  [ 8] .strtab           STRTAB          00000000 0001e4 000017 00      0   0  1
  [ 9] .shstrtab         STRTAB          00000000 000214 000049 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

链接生成elf

写一个链接脚本linktest.ld

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(main)
MEMORY

    IRAM1_CODE (r) : ORIGIN = 0x410000,  LENGTH = 0xEFFFF        
    TCM   (rw) : ORIGIN = 0x40,   LENGTH = 0x1ffc0


SECTIONS

    /*vector start_1 VMA在TCM,LMA在IRAM1_CODE*/
    .start_1 : 
        *(.text*)
     > TCM AT >IRAM1_CODE

    .start_2 : ALIGN(32) 
        __bss_start__ = . ;
        *(.bss .bss.*)
        __bss_end__ = . ;
     > IRAM1_CODE 
        
        .start_3 : ALIGN(32) 
        *(.data .data.*)
     > IRAM1_CODE 
        _exit = . ;

$System/Tools/GNUArmToolchain/windows/bin/arm-none-eabi-gcc.exe -o main.elf main.o -T ../linktest.ld

链接生成elf文件。

$System/Tools/GNUArmToolchain/windows/bin/arm-none-eabi-readelf.exe -S main.elf

There are 19 section headers, starting at offset 0x21c5c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .start_1          PROGBITS        00000040 010040 000688 00  AX  0   0  4
  [ 2] .init             PROGBITS        000006c8 0106c8 000018 00  AX  0   0  4
  [ 3] .fini             PROGBITS        000006e0 0106e0 000018 00  AX  0   0  4
  [ 4] .rodata           PROGBITS        000006f8 0106f8 000048 00   A  0   0  4
  [ 5] .eh_frame         PROGBITS        00000740 010740 000004 00   A  0   0  4
  [ 6] .ARM.exidx        ARM_EXIDX       00000744 010744 000008 00  AL  1   0  4
  [ 7] .rodata._glo[...] PROGBITS        0000074c 01074c 000004 00   A  0   0  4
  [ 8] .start_2          NOBITS          00410720 020720 000041 00  WA  0   0 32  
  [ 9] .start_3          PROGBITS        00410780 020780 00043c 00  WA  0   0 32
  [10] .init_array       INIT_ARRAY      00410bbc 020bbc 000004 04  WA  0   0  4
  [11] .fini_array       FINI_ARRAY      00410bc0 020bc0 000004 04  WA  0   0  4
  [12] .init_array.00000 INIT_ARRAY      00410bc4 020bc4 000004 04  WA  0   0  4
  [13] .ARM.attributes   ARM_ATTRIBUTES  00000000 020bc8 000026 00      0   0  1
  [14] .comment          PROGBITS        00000000 020bee 000049 01  MS  0   0  1
  [15] .debug_frame      PROGBITS        00000000 020c38 000258 00      0   0  4
  [16] .symtab           SYMTAB          00000000 020e90 000900 10     17 103  4
  [17] .strtab           STRTAB          00000000 021790 000401 00      0   0  1
  [18] .shstrtab         STRTAB          00000000 021b91 0000ca 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

objcopy生成bin

$System/Tools/GNUArmToolchain/windows/bin/arm-none-eabi-objcopy.exe -O binary main.elf main.bin

objcopy can be used to generate a raw binary file by using an output target of ‘binary’ (e.g., use -O binary). When objcopy generates a raw binary file, it will essentially produce a memory dump of the contents of the input object file. All symbols and relocation information will be discarded. The memory dump will start at the load address of the lowest section copied into the output file.

elf文件包含各个sections的信息,地址信息,调试信息等。

bin文件时剔除了elf文件中的各种信息,只保留二进制汇编指令,按照LMA的顺序进行排序存储。

比如start_1 ,start_2 ,start_3的LMA,都指向IRAM1_CODE 中,按照顺序排列后生成bin。

如果

.start_1 : *(.text*) > TCM

去除AT >IRAM1_CODE,则.start_1的LMA,则指向了TCM,0x40。那么生成的bin文件将会很大,因为空洞的产生。

分析LMA VMA地址关系

总结:

1,BIN文件时按照LMA地址顺序存储,使用objcopy工具。

2,ELF文件按照VMA地址顺序存储,相当于内存映像,多用于调试。

3,If neither AT nor AT> is specified for an allocatable section,the linker will likely use VMA to determine the load address(LMA)。

以上是关于x86的库和arm的.o文件能链接吗的主要内容,如果未能解决你的问题,请参考以下文章

VS2008如何设置才能使库函数静态链接

动态链接库和静态链接库的区别

arm开发板上的linux如何通过网口和windows的网口通信,linux中的socket和windows下的socket能通用吗?

汇编语言交叉编译&Makefile文件

我可以在 x86 C 程序中模拟 ARM NEON 吗?

androidX86的应用在ARM上能用吗