DAY 26
0
Software Development

## 第二十六日：探究 Rela 結構

### 展示 main.o 使用到的重定

``````\$ riscv64-unknown-linux-gnu-readelf -r ~/main.o

Relocation section '.rela.text' at offset 0x1b8 contains 9 entries:
Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000000  00000000002b R_RISCV_ALIGN                        0
00000000000c  000900000012 R_RISCV_CALL      0000000000000000 add + 0
00000000000c  000000000033 R_RISCV_RELAX                        0
000000000018  00060000001a R_RISCV_HI20      0000000000000000 .LC0 + 0
000000000018  000000000033 R_RISCV_RELAX                        0
00000000001c  00060000001b R_RISCV_LO12_I    0000000000000000 .LC0 + 0
00000000001c  000000000033 R_RISCV_RELAX                        0
000000000020  000a00000012 R_RISCV_CALL      0000000000000000 printf + 0
000000000020  000000000033 R_RISCV_RELAX                        0
``````

``````type R_PPC int

const (
R_PPC_NONE            R_PPC = 0 /* No relocation. */
...
{115, "R_PPC_EMB_BIT_FLD"},
{116, "R_PPC_EMB_RELSDA"},
}

func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, false) }
func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
``````

### 重定結構

``````Section Header:
0               .shstrtab  elf.SHT_STRTAB   0x0                             0       290    66   0    0    0x1
1               .strtab    elf.SHT_STRTAB   0x0                             0       198    29   0    0    0x1
2               .symtab    elf.SHT_SYMTAB   0x0                             0       90     264  8    8    0x8
3               .comment   elf.SHT_PROGBITS elf.SHF_MERGE+elf.SHF_STRINGS   0       7c     18   0    0    0x1
4               .rodata    elf.SHT_PROGBITS elf.SHF_ALLOC                   0       78     4    0    0    0x8
5               .bss       elf.SHT_NOBITS   elf.SHF_WRITE+elf.SHF_ALLOC     0       74     0    0    0    0x1
6               .data      elf.SHT_PROGBITS elf.SHF_WRITE+elf.SHF_ALLOC     0       74     0    0    0    0x1
7               .rela.text elf.SHT_RELA     elf.SHF_INFO_LINK               0       1b8    216  7    1    0x8
8               .text      elf.SHT_PROGBITS elf.SHF_ALLOC+elf.SHF_EXECINSTR 0       40     52   0    0    0x2
9                          elf.SHT_NULL     0x0                             0       0      0    0    0    0x0
``````

``````/* ELF64 relocations that don't need an addend field. */
type Rel64 struct {
Off  uint64 /* Location to be relocated. */
Info uint64 /* Relocation type and symbol index. */
}

/* ELF64 relocations that need an addend field. */
type Rela64 struct {
Off    uint64 /* Location to be relocated. */
Info   uint64 /* Relocation type and symbol index. */
}
``````

Enum ELF Reloc Type Description Details
0 _NONE None
1 _32 Runtime relocation word32 = S + A
2 _64 Runtime relocation word64 = S + A
3 _RELATIVE Runtime relocation word32,64 = B + A
... ... ... ...

``````Section Header:
...
7               .rela.text elf.SHT_RELA     elf.SHF_INFO_LINK               0       1b8    216  7    1    0x8
``````

`Size` 是 9？沒錯。`Rela64` 結構包含 3 個 `uint64` 整數，所以是 24 個 bytes；總共有 9 個重定被安插在 main.o 中，所以總共是 216 位元組無誤。對齊量是 8 bytes，所以我們不用考慮其他修修補補的問題。

### 觀察內裡內容

``````000001b0                           00 00 00 00 00 00 00 00  |        ........|
000001c0  2b 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |+...............|

000001d0  0c 00 00 00 00 00 00 00  12 00 00 00 09 00 00 00  |................|
000001e0  00 00 00 00 00 00 00 00  0c 00 00 00 00 00 00 00  |................|
000001f0  33 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |3...............|

00000200  18 00 00 00 00 00 00 00  1a 00 00 00 06 00 00 00  |................|
00000210  00 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|
00000220  33 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |3...............|

00000230  1c 00 00 00 00 00 00 00  1b 00 00 00 06 00 00 00  |................|
00000240  00 00 00 00 00 00 00 00  1c 00 00 00 00 00 00 00  |................|
00000250  33 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |3...............|

00000260  20 00 00 00 00 00 00 00  12 00 00 00 0a 00 00 00  | ...............|
00000270  00 00 00 00 00 00 00 00  20 00 00 00 00 00 00 00  |........ .......|
00000280  33 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |3...............|
``````

``````type Rela64 struct {
Off    uint64 /* Location to be relocated. */
Info   uint64 /* Relocation type and symbol index. */
}
``````

``````func R_SYM64(info uint64) uint32    { return uint32(info >> 32) }
func R_TYPE64(info uint64) uint32   { return uint32(info) }
func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
``````

``````0000000000000000 <main>:
...
20:   00000097                auipc   ra,0x0
20: R_RISCV_CALL        printf
20: R_RISCV_RELAX       *ABS*
``````