1 |
747 |
jeremybenn |
// Copyright 2009 The Go Authors. All rights reserved.
|
2 |
|
|
// Use of this source code is governed by a BSD-style
|
3 |
|
|
// license that can be found in the LICENSE file.
|
4 |
|
|
|
5 |
|
|
package elf
|
6 |
|
|
|
7 |
|
|
import (
|
8 |
|
|
"debug/dwarf"
|
9 |
|
|
"encoding/binary"
|
10 |
|
|
"net"
|
11 |
|
|
"os"
|
12 |
|
|
"reflect"
|
13 |
|
|
"runtime"
|
14 |
|
|
"testing"
|
15 |
|
|
)
|
16 |
|
|
|
17 |
|
|
type fileTest struct {
|
18 |
|
|
file string
|
19 |
|
|
hdr FileHeader
|
20 |
|
|
sections []SectionHeader
|
21 |
|
|
progs []ProgHeader
|
22 |
|
|
}
|
23 |
|
|
|
24 |
|
|
var fileTests = []fileTest{
|
25 |
|
|
{
|
26 |
|
|
"testdata/gcc-386-freebsd-exec",
|
27 |
|
|
FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386},
|
28 |
|
|
[]SectionHeader{
|
29 |
|
|
{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
30 |
|
|
{".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0},
|
31 |
|
|
{".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4},
|
32 |
|
|
{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10},
|
33 |
|
|
{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0},
|
34 |
|
|
{".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8},
|
35 |
|
|
{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0},
|
36 |
|
|
{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4},
|
37 |
|
|
{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0},
|
38 |
|
|
{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0},
|
39 |
|
|
{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0},
|
40 |
|
|
{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0},
|
41 |
|
|
{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0},
|
42 |
|
|
{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8},
|
43 |
|
|
{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0},
|
44 |
|
|
{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0},
|
45 |
|
|
{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0},
|
46 |
|
|
{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4},
|
47 |
|
|
{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0},
|
48 |
|
|
{".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0},
|
49 |
|
|
{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0},
|
50 |
|
|
{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0},
|
51 |
|
|
{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0},
|
52 |
|
|
{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0},
|
53 |
|
|
{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0},
|
54 |
|
|
{".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0},
|
55 |
|
|
{".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0},
|
56 |
|
|
{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0},
|
57 |
|
|
{".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10},
|
58 |
|
|
{".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0},
|
59 |
|
|
},
|
60 |
|
|
[]ProgHeader{
|
61 |
|
|
{PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
|
62 |
|
|
{PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
|
63 |
|
|
{PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
|
64 |
|
|
{PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
|
65 |
|
|
{PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
|
66 |
|
|
},
|
67 |
|
|
},
|
68 |
|
|
{
|
69 |
|
|
"testdata/gcc-amd64-linux-exec",
|
70 |
|
|
FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64},
|
71 |
|
|
[]SectionHeader{
|
72 |
|
|
{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
73 |
|
|
{".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0},
|
74 |
|
|
{".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0},
|
75 |
|
|
{".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4},
|
76 |
|
|
{".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0},
|
77 |
|
|
{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18},
|
78 |
|
|
{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0},
|
79 |
|
|
{".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2},
|
80 |
|
|
{".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0},
|
81 |
|
|
{".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18},
|
82 |
|
|
{".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18},
|
83 |
|
|
{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0},
|
84 |
|
|
{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10},
|
85 |
|
|
{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0},
|
86 |
|
|
{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0},
|
87 |
|
|
{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0},
|
88 |
|
|
{".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0},
|
89 |
|
|
{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0},
|
90 |
|
|
{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0},
|
91 |
|
|
{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0},
|
92 |
|
|
{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0},
|
93 |
|
|
{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10},
|
94 |
|
|
{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8},
|
95 |
|
|
{".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8},
|
96 |
|
|
{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0},
|
97 |
|
|
{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0},
|
98 |
|
|
{".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0},
|
99 |
|
|
{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0},
|
100 |
|
|
{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0},
|
101 |
|
|
{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0},
|
102 |
|
|
{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0},
|
103 |
|
|
{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0},
|
104 |
|
|
{".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1},
|
105 |
|
|
{".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0},
|
106 |
|
|
{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0},
|
107 |
|
|
{".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18},
|
108 |
|
|
{".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0},
|
109 |
|
|
},
|
110 |
|
|
[]ProgHeader{
|
111 |
|
|
{PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
|
112 |
|
|
{PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
|
113 |
|
|
{PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
|
114 |
|
|
{PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
|
115 |
|
|
{PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
|
116 |
|
|
{PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
|
117 |
|
|
{PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
|
118 |
|
|
{PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
|
119 |
|
|
},
|
120 |
|
|
},
|
121 |
|
|
}
|
122 |
|
|
|
123 |
|
|
func TestOpen(t *testing.T) {
|
124 |
|
|
for i := range fileTests {
|
125 |
|
|
tt := &fileTests[i]
|
126 |
|
|
|
127 |
|
|
f, err := Open(tt.file)
|
128 |
|
|
if err != nil {
|
129 |
|
|
t.Error(err)
|
130 |
|
|
continue
|
131 |
|
|
}
|
132 |
|
|
if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
|
133 |
|
|
t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
|
134 |
|
|
continue
|
135 |
|
|
}
|
136 |
|
|
for i, s := range f.Sections {
|
137 |
|
|
if i >= len(tt.sections) {
|
138 |
|
|
break
|
139 |
|
|
}
|
140 |
|
|
sh := &tt.sections[i]
|
141 |
|
|
if !reflect.DeepEqual(&s.SectionHeader, sh) {
|
142 |
|
|
t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh)
|
143 |
|
|
}
|
144 |
|
|
}
|
145 |
|
|
for i, p := range f.Progs {
|
146 |
|
|
if i >= len(tt.progs) {
|
147 |
|
|
break
|
148 |
|
|
}
|
149 |
|
|
ph := &tt.progs[i]
|
150 |
|
|
if !reflect.DeepEqual(&p.ProgHeader, ph) {
|
151 |
|
|
t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph)
|
152 |
|
|
}
|
153 |
|
|
}
|
154 |
|
|
tn := len(tt.sections)
|
155 |
|
|
fn := len(f.Sections)
|
156 |
|
|
if tn != fn {
|
157 |
|
|
t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
|
158 |
|
|
}
|
159 |
|
|
tn = len(tt.progs)
|
160 |
|
|
fn = len(f.Progs)
|
161 |
|
|
if tn != fn {
|
162 |
|
|
t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
|
163 |
|
|
}
|
164 |
|
|
}
|
165 |
|
|
}
|
166 |
|
|
|
167 |
|
|
type relocationTest struct {
|
168 |
|
|
file string
|
169 |
|
|
firstEntry *dwarf.Entry
|
170 |
|
|
}
|
171 |
|
|
|
172 |
|
|
var relocationTests = []relocationTest{
|
173 |
|
|
{
|
174 |
|
|
"testdata/go-relocation-test-gcc441-x86-64.obj",
|
175 |
|
|
&dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
|
176 |
|
|
},
|
177 |
|
|
{
|
178 |
|
|
"testdata/go-relocation-test-gcc441-x86.obj",
|
179 |
|
|
&dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
|
180 |
|
|
},
|
181 |
|
|
{
|
182 |
|
|
"testdata/go-relocation-test-gcc424-x86-64.obj",
|
183 |
|
|
&dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
|
184 |
|
|
},
|
185 |
|
|
}
|
186 |
|
|
|
187 |
|
|
func TestDWARFRelocations(t *testing.T) {
|
188 |
|
|
for i, test := range relocationTests {
|
189 |
|
|
f, err := Open(test.file)
|
190 |
|
|
if err != nil {
|
191 |
|
|
t.Error(err)
|
192 |
|
|
continue
|
193 |
|
|
}
|
194 |
|
|
dwarf, err := f.DWARF()
|
195 |
|
|
if err != nil {
|
196 |
|
|
t.Error(err)
|
197 |
|
|
continue
|
198 |
|
|
}
|
199 |
|
|
reader := dwarf.Reader()
|
200 |
|
|
// Checking only the first entry is sufficient since it has
|
201 |
|
|
// many different strings. If the relocation had failed, all
|
202 |
|
|
// the string offsets would be zero and all the strings would
|
203 |
|
|
// end up being the same.
|
204 |
|
|
firstEntry, err := reader.Next()
|
205 |
|
|
if err != nil {
|
206 |
|
|
t.Error(err)
|
207 |
|
|
continue
|
208 |
|
|
}
|
209 |
|
|
|
210 |
|
|
if !reflect.DeepEqual(test.firstEntry, firstEntry) {
|
211 |
|
|
t.Errorf("#%d: mismatch: got:%#v want:%#v", i, firstEntry, test.firstEntry)
|
212 |
|
|
continue
|
213 |
|
|
}
|
214 |
|
|
}
|
215 |
|
|
}
|
216 |
|
|
|
217 |
|
|
func TestNoSectionOverlaps(t *testing.T) {
|
218 |
|
|
// Ensure 6l outputs sections without overlaps.
|
219 |
|
|
if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
|
220 |
|
|
return // not ELF
|
221 |
|
|
}
|
222 |
|
|
_ = net.ResolveIPAddr // force dynamic linkage
|
223 |
|
|
f, err := Open(os.Args[0])
|
224 |
|
|
if err != nil {
|
225 |
|
|
t.Error(err)
|
226 |
|
|
return
|
227 |
|
|
}
|
228 |
|
|
for i, si := range f.Sections {
|
229 |
|
|
sih := si.SectionHeader
|
230 |
|
|
if sih.Type == SHT_NOBITS {
|
231 |
|
|
continue
|
232 |
|
|
}
|
233 |
|
|
for j, sj := range f.Sections {
|
234 |
|
|
sjh := sj.SectionHeader
|
235 |
|
|
if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 {
|
236 |
|
|
continue
|
237 |
|
|
}
|
238 |
|
|
if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size {
|
239 |
|
|
t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
|
240 |
|
|
sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size)
|
241 |
|
|
}
|
242 |
|
|
}
|
243 |
|
|
}
|
244 |
|
|
}
|