What happens during a “relocation has invalid symbol index” error?

后端 未结 3 1520
孤独总比滥情好
孤独总比滥情好 2021-02-13 18:57

Here is a test reproducing the problem:

$ echo \"void whatever() {}\" > prog.c
$ gcc prog.c

This produces the following error on GCC 4.8.4:<

3条回答
  •  抹茶落季
    2021-02-13 19:17

    C Program Features (Unix-like)

    • every program is compiled separately into elf format
    • c program can use external variable/function reference, which is linked later
    • main is not the start of program as you originally thought, c lib has a starter program (crt1.o) which has a _start program which will invoke our main and do cleaning job after main
    • concludes above statement, we can know that even a very simple program as OP showed need to be linked

    ELF Format

    ELF has two headers, as following shows:

    • section header -- used to link multiple elf to make process image
    • program header -- used to load process image

    Here we only focus on section header structure:

        mapping
        // and special cases
        mapping
    

    Every program is compiled separately, which means address allocation is similar (In the early version of linux, every compiled program start with same virtual address -- 0x08000000, and many attacks can make use of this, so it changes to adding some random delta to address to alleviate the problem), so there may exists some overlay area. This is why address relocation needed.

    Relocation

    The relocation info (offset, value etc) is stored in .rel.* section:

        Relocation section '.rel.text' at offset 0x7a4 contains 2 entries:
         Offset     Info    Type            Sym.Value  Sym. Name
        0000000d  00000e02 R_386_PC32        00000000   main
        00000015  00000f02 R_386_PC32        00000000   exit
    
        Relocation section '.rel.debug_info' at offset 0x7b4 contains 43 entries:
         Offset     Info    Type            Sym.Value  Sym. Name
        00000006  00000601 R_386_32          00000000   .debug_abbrev
        0000000c  00000901 R_386_32          00000000   .debug_str
    

    When the linker want to set the address of main in the process of relocation, it can't find a symbol in your compiled elf file, so it complains that and stop the linking process.

    Example

    Here is the simplified version of os implementations, start.c corresponds to crt1.o's source code:

        int entry(char *); // corresponds to main
    
        void _start(char *args) {
            entry(args);
            exit();
        }
    

    Ref

    • ELF
    • Relocation

提交回复
热议问题