Análisis de segmento de programa/sección ELF

En el análisis de la implementación de la función de análisis elf en el controlador linux remoteproc, se presentan la función y la definición correspondiente de diferentes tipos de análisis de encabezado para archivos elf en el controlador linux remoteproc.
En este artículo, nos enfocamos en explicar el significado del segmento de programa y el procesamiento de datos correspondiente.

1 segmento de programa elfo

1.1 encabezado del programa elfo

/* These constants define the permissions on sections in the program
   header, p_flags. */
#define PF_R            0x4
#define PF_W            0x2
#define PF_X            0x1

typedef struct elf32_phdr{
    
    
  Elf32_Word    p_type;
  Elf32_Off     p_offset;
  Elf32_Addr    p_vaddr;
  Elf32_Addr    p_paddr;
  Elf32_Word    p_filesz;
  Elf32_Word    p_memsz;
  Elf32_Word    p_flags;
  Elf32_Word    p_align;
} Elf32_Phdr;
                                                                                                       
typedef struct elf64_phdr {
    
    
  Elf64_Word p_type;
  Elf64_Word p_flags;
  Elf64_Off p_offset;           /* Segment file offset */
  Elf64_Addr p_vaddr;           /* Segment virtual address */
  Elf64_Addr p_paddr;           /* Segment physical address */
  Elf64_Xword p_filesz;         /* Segment size in file */
  Elf64_Xword p_memsz;          /* Segment size in memory */
  Elf64_Xword p_align;          /* Segment alignment, file & memory */
} Elf64_Phdr;

1.2 Ejemplos de ELF32 y ELF64

1.2.1 Segmento de programa ELF32

Tome test.elf como ejemplo para analizar

  • OffsetIndica la dirección de desplazamiento de los datos del segmento de programa correspondiente en el archivo elf
  • PhysAddrIndica la dirección física a la que se copiarán los datos del segmento de programa
  • FileSizIndica el tamaño del segmento de programa actual en el archivo elf
  • MemSizIndica el tamaño del segmento de programa actual en el archivo bin correspondiente
  • FlgRepresenta los atributos del segmento de programa actual
  • AlignIndica el tamaño de alineación del segmento de programa actual
$ readelf -lW test.elf 



Elf file type is EXEC (Executable file)

Entry point 0x0

There are 6 program headers, starting at offset 52



Program Headers:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align

  EXIDX          0x09262c 0x1016262c 0x1016262c 0x00008 0x00008 R   0x4

  LOAD           0x010000 0x00000000 0x00000000 0x00440 0x00440 RW  0x10000

  LOAD           0x020000 0x10000000 0x10000000 0x00800 0x00800 R E 0x10000

  LOAD           0x030000 0x10100000 0x10100000 0x62638 0x62638 R E 0x10000

  LOAD           0x092740 0x10172740 0x10172740 0x0900c 0x5d158a0 RW  0x10000

  LOAD           0x000000 0xa0000000 0xa0000000 0x00000 0x04100 RW  0x10000



 Section to Segment mapping:

  Segment Sections...

   00     .ARM.exidx 

   01     .reset .rom 

   02     .cpu_vectors 

   03     .init .text .fini .rodata .ARM.exidx .eh_frame 

   04     shell_cmd .data .init_array .fini_array .init_array.00000 .datasafe .bss .stack .heap 

   05     .ram_mpu 

$

1.2.2 Segmento de programa ELF64

Tome el vmlinux generado por la compilación de linux como ejemplo: contiene 5 segmentos de programa en total;

  • OffsetIndica la dirección de desplazamiento de los datos del segmento de programa correspondiente en el archivo elf
  • PhysAddrIndica la dirección física a la que se copiarán los datos del segmento de programa
  • FileSizIndica el tamaño del segmento de programa actual en el archivo elf
  • MemSizIndica el tamaño del segmento de programa actual en el archivo bin correspondiente
  • FlgRepresenta los atributos del segmento de programa actual
  • AlignIndica el tamaño de alineación del segmento de programa actual
$ readelf -lW vmlinux 

Elf file type is DYN (Shared object file)
Entry point 0xffff800008000000
There are 5 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x010000 0xffff800008000000 0xffff800008000000 0xd2c000 0xd2c000 RWE 0x10000
  LOAD           0xd40000 0xffff800008d40000 0xffff800008d40000 0x0588dc 0x0588dc R E 0x10000
  LOAD           0xda0000 0xffff800008da0000 0xffff800008da0000 0x397808 0x43ea24 RW  0x10000
  NOTE           0xd3aa50 0xffff800008d2aa50 0xffff800008d2aa50 0x000054 0x000054 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10

 Section to Segment mapping:
  Segment Sections...
   00     .head.text .text .got.plt .rodata __ksymtab __ksymtab_gpl __ksymtab_strings __param __modver __ex_table .notes .hyp.rodata 
   01     .init.text .exit.text .altinstructions 
   02     .init.data .data..percpu .hyp.data..percpu .hyp.reloc .rela.dyn .data __bug_table .mmuoff.data.write .mmuoff.data.read .bss 
   03     .notes 
   04     
$

1.3 Diagrama de flujo de datos del segmento de programa elf

inserte la descripción de la imagen aquí

2 sección de elfos

2.1 encabezado de sección de campo

typedef struct elf32_shdr {
    
    
  Elf32_Word    sh_name;
  Elf32_Word    sh_type;
  Elf32_Word    sh_flags;
  Elf32_Addr    sh_addr;
  Elf32_Off     sh_offset;
  Elf32_Word    sh_size;
  Elf32_Word    sh_link;
  Elf32_Word    sh_info;
  Elf32_Word    sh_addralign;                                                                          
  Elf32_Word    sh_entsize;
} Elf32_Shdr;

typedef struct elf64_shdr {
    
    
  Elf64_Word sh_name;           /* Section name, index in string tbl */
  Elf64_Word sh_type;           /* Type of section */
  Elf64_Xword sh_flags;         /* Miscellaneous section attributes */
  Elf64_Addr sh_addr;           /* Section virtual addr at execution */
  Elf64_Off sh_offset;          /* Section file offset */
  Elf64_Xword sh_size;          /* Size of section in bytes */
  Elf64_Word sh_link;           /* Index of another section */
  Elf64_Word sh_info;           /* Additional section information */
  Elf64_Xword sh_addralign;     /* Section alignment */
  Elf64_Xword sh_entsize;       /* Entry size if section holds table */
} Elf64_Shdr;

2.2 Ejemplos de ELF32 y ELF64

2.2.1 Sección ELF32

Tome test.elf como ejemplo para analizar

  • OffIndica la dirección de compensación de los datos de la sección correspondiente en el archivo elf
  • AddrIndica la dirección física para copiar los datos de la sección a
  • SizeIndica el tamaño de la sección actual
  • FlgRepresenta los atributos del segmento de programa actual
  • TypeIndica el tipo de la sección actual
  • NameIndica el nombre de la sección actual
  • FlgRepresenta los atributos de la sección actual.
$ readelf -SW test.elf 
There are 23 section headers, starting at offset 0x9b894:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .reset            PROGBITS        00000000 010000 000040 00   A  0   0  1
  [ 2] .rom              PROGBITS        00000100 010100 000340 00  WA  0   0  1
  [ 3] .ram_mpu          NOBITS          a0000000 0a0000 004100 00  WA  0   0  1
  [ 4] .cpu_vectors      PROGBITS        10000000 020000 000800 00  AX  0   0  4
  [ 5] .init             PROGBITS        10100000 030000 00000c 00  AX  0   0  4
  [ 6] .text             PROGBITS        10100010 030010 0555c0 00  AX  0   0 16
  [ 7] .fini             PROGBITS        101555d0 0855d0 00000c 00  AX  0   0  4
  [ 8] .rodata           PROGBITS        101555e0 0855e0 00d04c 00   A  0   0  8
  [ 9] .ARM.exidx        ARM_EXIDX       1016262c 09262c 000008 00  AL  6   0  4
  [10] .eh_frame         PROGBITS        10162634 092634 000004 00   A  0   0  4
  [11] shell_cmd         PROGBITS        10172740 092740 0000f0 00  WA  0   0 32
  [12] .data             PROGBITS        10172830 092830 004780 00  WA  0   0 16
  [13] .init_array       INIT_ARRAY      10176fb0 096fb0 000004 04  WA  0   0  4
  [14] .fini_array       FINI_ARRAY      10176fb4 096fb4 000004 04  WA  0   0  4
  [15] .init_array.00000 INIT_ARRAY      10176fb8 096fb8 000004 04  WA  0   0  4
  [16] .datasafe         PROGBITS        10176fbc 096fbc 004790 00  WA  0   0  1
  [17] .bss              NOBITS          1017b750 09b74c 07c888 00  WA  0   0 16
  [18] .stack            NOBITS          101f7fe0 09b74c 090000 00  WA  0   0  1
  [19] .heap             NOBITS          10287fe0 09b74c 5c00000 00  WA  0   0  1
  [20] .comment          PROGBITS        00000000 09b74c 000045 01  MS  0   0  1
  [21] .ARM.attributes   ARM_ATTRIBUTES  00000000 09b791 000035 00      0   0  1
  [22] .shstrtab         STRTAB          00000000 09b7c6 0000cb 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)
$

2.2.2 Sección ELF64

Tome vmlinux de linux como ejemplo para analizar

  • OffIndica la dirección de compensación de los datos de la sección correspondiente en el archivo elf
  • AddrIndica la dirección física para copiar los datos de la sección a
  • SizeIndica el tamaño de la sección actual
  • FlgRepresenta los atributos del segmento de programa actual
  • TypeIndica el tipo de la sección actual
  • NameIndica el nombre de la sección actual
  • FlgRepresenta los atributos de la sección actual.
$ readelf -SW vmlinux 
There are 40 section headers, starting at offset 0xd59a938:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .head.text        PROGBITS        ffff800008000000 010000 000040 00  AX  0   0  4
  [ 2] .text             PROGBITS        ffff800008010000 020000 a63d60 08  AX  0   0 65536
  [ 3] .got.plt          PROGBITS        ffff800008a73d60 a83d60 000018 08  WA  0   0  8
  [ 4] .rodata           PROGBITS        ffff800008a80000 a90000 25af18 00  WA  0   0 4096
  [ 5] __ksymtab         PROGBITS        ffff800008cdaf18 ceaf18 00d374 00   A  0   0  4
  [ 6] __ksymtab_gpl     PROGBITS        ffff800008ce828c cf828c 00fe10 00   A  0   0  4
  [ 7] __ksymtab_strings PROGBITS        ffff800008cf809c d0809c 02e361 01 AMS  0   0  1
  [ 8] __param           PROGBITS        ffff800008d26400 d36400 0028a0 00   A  0   0  8
  [ 9] __modver          PROGBITS        ffff800008d28ca0 d38ca0 000318 00  WA  0   0  8
  [10] __ex_table        PROGBITS        ffff800008d28fb8 d38fb8 001a98 00   A  0   0  8
  [11] .notes            NOTE            ffff800008d2aa50 d3aa50 000054 00   A  0   0  4
  [12] .hyp.rodata       PROGBITS        ffff800008d2b000 d3b000 001000 00  WA  0   0  8
  [13] .init.text        PROGBITS        ffff800008d40000 d40000 03fcf4 00  AX  0   0  4
  [14] .exit.text        PROGBITS        ffff800008d7fcf4 d7fcf4 0031c8 00  AX  0   0  4
  [15] .altinstructions  PROGBITS        ffff800008d82ebc d82ebc 015a20 00   A  0   0  1
  [16] .init.data        PROGBITS        ffff800008da0000 da0000 013298 00  WA  0   0 256
  [17] .data..percpu     PROGBITS        ffff800008db4000 db4000 009b58 00  WA  0   0 64
  [18] .hyp.data..percpu PROGBITS        ffff800008dbe000 dbe000 000ed0 00  WA  0   0 16
  [19] .hyp.reloc        PROGBITS        ffff800008dbeed0 dbeed0 000060 00   A  0   0  4
  [20] .rela.dyn         RELA            ffff800008dbef30 dbef30 1fa280 18   A 37   0  8
  [21] .data             PROGBITS        ffff800008fc0000 fc0000 162b20 00  WA  0   0 4096
  [22] __bug_table       PROGBITS        ffff800009122b20 1122b20 013e18 00  WA  0   0  4
  [23] .mmuoff.data.write PROGBITS        ffff800009137000 1137000 000018 00  WA  0   0 2048
  [24] .mmuoff.data.read PROGBITS        ffff800009137800 1137800 000008 00  WA  0   0  8
  [25] .bss              NOBITS          ffff800009138000 1137808 0a6a24 00  WA  0   0 4096
  [26] .debug_aranges    PROGBITS        0000000000000000 1137810 01f600 00      0   0 16
  [27] .debug_info       PROGBITS        0000000000000000 1156e10 8f735c0 00      0   0  1
  [28] .debug_abbrev     PROGBITS        0000000000000000 a0ca3d0 449e7e 00      0   0  1
  [29] .debug_line       PROGBITS        0000000000000000 a51424e f522ac 00      0   0  1
  [30] .debug_frame      PROGBITS        0000000000000000 b466500 261300 00      0   0  8
  [31] .debug_str        PROGBITS        0000000000000000 b6c7800 29f3dc 01  MS  0   0  1
  [32] .debug_ranges     PROGBITS        0000000000000000 b966be0 000230 00      0   0 16
  [33] .debug_line_str   PROGBITS        0000000000000000 b966e10 010dda 01  MS  0   0  1
  [34] .debug_loclists   PROGBITS        0000000000000000 b977bea 152ec46 00      0   0  1
  [35] .debug_rnglists   PROGBITS        0000000000000000 cea6830 2e8174 00      0   0  1
  [36] .comment          PROGBITS        0000000000000000 d18e9a4 000045 01  MS  0   0  1
  [37] .symtab           SYMTAB          0000000000000000 d18e9f0 26caa8 18     38 85372  8
  [38] .strtab           STRTAB          0000000000000000 d3fb498 19f2f0 00      0   0  1
  [39] .shstrtab         STRTAB          0000000000000000 d59a788 0001ab 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),
  p (processor specific)
$

2.3 Diagrama de flujo de datos de la sección elf

La dirección del flujo de datos de la sección elf en la etapa de arranque es copiar los datos del desplazamiento del archivo elf a la memoria de addr de acuerdo con el tamaño.Después de copiar cada sección, se puede activar la operación de reinicio para iniciar la correspondiente centro.

Supongo que te gusta

Origin blog.csdn.net/u014100559/article/details/132220623
Recomendado
Clasificación