1
1
package runtime
2
2
3
3
import (
4
- "debug/elf"
5
4
"unsafe"
6
5
)
7
6
8
7
const debugLoader = false
9
8
9
+ const (
10
+ R_AARCH64_RELATIVE = 1027
11
+ DT_NULL = 0 /* Terminating entry. */
12
+ DT_RELA = 7 /* Address of ElfNN_Rela relocations. */
13
+ DT_RELASZ = 8 /* Total size of ElfNN_Rela relocations. */
14
+ )
15
+
16
+ /* ELF64 relocations that need an addend field. */
17
+ type Rela64 struct {
18
+ Off uint64 /* Location to be relocated. */
19
+ Info uint64 /* Relocation type and symbol index. */
20
+ Addend int64 /* Addend. */
21
+ }
22
+
23
+ // ELF64 Dynamic structure. The ".dynamic" section contains an array of them.
24
+ type Dyn64 struct {
25
+ Tag int64 /* Entry type. */
26
+ Val uint64 /* Integer/address value */
27
+ }
28
+
10
29
//export __dynamic_loader
11
- func dynamicLoader (base uintptr , dyn * elf. Dyn64 ) {
12
- var rela * elf. Rela64
30
+ func dynamicLoader (base uintptr , dyn * Dyn64 ) {
31
+ var rela * Rela64
13
32
relasz := uint64 (0 )
14
33
15
34
if debugLoader {
16
35
println ("ASLR Base: " , base )
17
36
}
18
37
19
- for dyn .Tag != int64 ( elf . DT_NULL ) {
20
- switch elf . DynTag ( dyn .Tag ) {
21
- case elf . DT_RELA :
22
- rela = (* elf . Rela64 )(unsafe .Pointer (base + uintptr (dyn .Val )))
23
- case elf . DT_RELASZ :
24
- relasz = uint64 (dyn .Val ) / uint64 (unsafe .Sizeof (elf. Rela64 {}))
38
+ for dyn .Tag != DT_NULL {
39
+ switch dyn .Tag {
40
+ case DT_RELA :
41
+ rela = (* Rela64 )(unsafe .Pointer (base + uintptr (dyn .Val )))
42
+ case DT_RELASZ :
43
+ relasz = uint64 (dyn .Val ) / uint64 (unsafe .Sizeof (Rela64 {}))
25
44
}
26
45
27
46
ptr := uintptr (unsafe .Pointer (dyn ))
28
- ptr += unsafe .Sizeof (elf. Dyn64 {})
29
- dyn = (* elf . Dyn64 )(unsafe .Pointer (ptr ))
47
+ ptr += unsafe .Sizeof (Dyn64 {})
48
+ dyn = (* Dyn64 )(unsafe .Pointer (ptr ))
30
49
}
31
50
32
- if rela == nil {
33
- runtimePanic ("bad reloc" )
34
- }
35
51
if rela == nil {
36
52
runtimePanic ("bad reloc" )
37
53
}
@@ -41,15 +57,15 @@ func dynamicLoader(base uintptr, dyn *elf.Dyn64) {
41
57
}
42
58
43
59
for relasz > 0 && rela != nil {
44
- switch elf . R_AARCH64 ( rela .Info ) {
45
- case elf . R_AARCH64_RELATIVE :
60
+ switch rela .Info {
61
+ case R_AARCH64_RELATIVE :
46
62
ptr := (* uint64 )(unsafe .Pointer (base + uintptr (rela .Off )))
47
63
* ptr = uint64 (base + uintptr (rela .Addend ))
48
64
}
49
65
50
66
rptr := uintptr (unsafe .Pointer (rela ))
51
- rptr += unsafe .Sizeof (elf. Rela64 {})
52
- rela = (* elf . Rela64 )(unsafe .Pointer (rptr ))
67
+ rptr += unsafe .Sizeof (Rela64 {})
68
+ rela = (* Rela64 )(unsafe .Pointer (rptr ))
53
69
relasz --
54
70
}
55
71
}
0 commit comments