|
9 | 9 | import shutil
|
10 | 10 | import time
|
11 | 11 | import binascii
|
| 12 | +import elftools |
12 | 13 |
|
13 | 14 | from tools.paths import TOOLS_BOOTLOADERS
|
14 | 15 | from tools.toolchains import TOOLCHAIN_PATHS
|
@@ -100,120 +101,18 @@ def find_symbol(toolchain, mapfile, symbol):
|
100 | 101 |
|
101 | 102 | return int(ret,16) | 1
|
102 | 103 |
|
103 |
| -def parse_load_segment_gcc(image_elf): |
104 |
| - # Program Headers: |
105 |
| - # Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align |
106 |
| - # LOAD 0x000034 0x10006000 0x10006000 0x026bc 0x026bc RW 0x8 |
107 |
| - # LOAD 0x0026f0 0x30000000 0x30000000 0x06338 0x06338 RWE 0x4 |
108 |
| - segment_list = [] |
109 |
| - cmd = os.path.join(TOOLCHAIN_PATHS['GCC_ARM'], 'arm-none-eabi-readelf') |
110 |
| - cmd = '"' + cmd + '"' + ' -l ' + image_elf |
111 |
| - for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"): |
112 |
| - if not line.startswith(" LOAD"): |
113 |
| - continue |
114 |
| - segment = line.split() |
115 |
| - if len(segment) != 8: |
116 |
| - continue |
117 |
| - offset = int(segment[1][2:], 16) |
118 |
| - addr = int(segment[2][2:], 16) |
119 |
| - size = int(segment[4][2:], 16) |
120 |
| - if addr != 0 and size != 0: |
121 |
| - segment_list.append((offset, addr, size)) |
122 |
| - return segment_list |
123 |
| - |
124 |
| -def parse_load_segment_armcc(image_elf): |
125 |
| - # ==================================== |
126 |
| - # |
127 |
| - # ** Program header #2 |
128 |
| - # |
129 |
| - # Type : PT_LOAD (1) |
130 |
| - # File Offset : 52 (0x34) |
131 |
| - # Virtual Addr : 0x30000000 |
132 |
| - # Physical Addr : 0x30000000 |
133 |
| - # Size in file : 27260 bytes (0x6a7c) |
134 |
| - # Size in memory: 42168 bytes (0xa4b8) |
135 |
| - # Flags : PF_X + PF_W + PF_R + PF_ARM_ENTRY (0x80000007) |
136 |
| - # Alignment : 8 |
137 |
| - # |
138 |
| - (offset, addr, size) = (0, 0, 0) |
139 |
| - segment_list = [] |
140 |
| - in_segment = False |
141 |
| - cmd = os.path.join(TOOLCHAIN_PATHS['ARM'], 'bin', 'fromelf') |
142 |
| - cmd = '"' + cmd + '"' + ' --text -v --only=none ' + image_elf |
143 |
| - for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"): |
144 |
| - if line == "": |
145 |
| - pass |
146 |
| - elif line.startswith("** Program header"): |
147 |
| - in_segment = True |
148 |
| - elif in_segment == False: |
149 |
| - pass |
150 |
| - elif line.startswith("============"): |
151 |
| - if addr != 0 and size != 0: |
152 |
| - segment_list.append((offset, addr, size)) |
153 |
| - in_segment = False |
154 |
| - (offset, addr, size) = (0, 0, 0) |
155 |
| - elif line.startswith(" Type"): |
156 |
| - if not re.match(r'\s+Type\s+:\s+PT_LOAD\s.*$', line): |
157 |
| - in_segment = False |
158 |
| - elif line.startswith(" File Offset"): |
159 |
| - match = re.match(r'^\s+File Offset\s+:\s+(?P<offset>\d+).*$', line) |
160 |
| - if match: |
161 |
| - offset = int(match.group("offset")) |
162 |
| - elif line.startswith(" Virtual Addr"): |
163 |
| - match = re.match(r'^\s+Virtual Addr\s+:\s+0x(?P<addr>[0-9a-f]+).*$', line) |
164 |
| - if match: |
165 |
| - addr = int(match.group("addr"), 16) |
166 |
| - elif line.startswith(" Size in file"): |
167 |
| - match = re.match(r'^\s+Size in file\s+:.*\(0x(?P<size>[0-9a-f]+)\).*$', line) |
168 |
| - if match: |
169 |
| - size = int(match.group("size"), 16) |
170 |
| - return segment_list |
171 |
| - |
172 |
| - |
173 |
| -def parse_load_segment_iar(image_elf): |
174 |
| - # SEGMENTS: |
175 |
| - # |
176 |
| - # Type Offset Virtual Physical File Sz Mem Sz Flags Align |
177 |
| - # ---- ------ ------- -------- ------- ------ ----- ----- |
178 |
| - # 0: load 0x34 0x10006000 0x10006000 0x26bc 0x26bc 0x6 WR 0x8 |
179 |
| - # 1: load 0x26f0 0x30000000 0x30000000 0x6338 0x6338 0x7 XWR 0x4 |
180 |
| - # |
181 |
| - # SECTIONS: |
182 |
| - # |
183 |
| - # Name Type Addr Offset Size Aln Lnk Inf ESz Flags |
184 |
| - # ---- ---- ---- ------ ---- --- --- --- --- ----- |
185 |
| - # 1: .shstrtab strtab 0xfc4d8 0x60 0x4 |
186 |
| - # 2: .strtab strtab 0xfc538 0xbb3f 0x4 |
187 |
| - |
188 |
| - segment_list = [] |
189 |
| - in_segment = False |
190 |
| - cmd = os.path.join(TOOLCHAIN_PATHS['IAR'], 'bin', 'ielfdumparm') |
191 |
| - cmd = '"' + cmd + '"' + ' ' + image_elf |
192 |
| - for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"): |
193 |
| - if line.startswith(" SEGMENTS:"): |
194 |
| - in_segment = True |
195 |
| - elif in_segment == False: |
196 |
| - pass |
197 |
| - elif line.startswith(" SECTIONS:"): |
198 |
| - break |
199 |
| - elif re.match(r'^\s+\w+:\s+load\s+.*$', line): |
200 |
| - segment = line.split() |
201 |
| - offset = int(segment[2][2:], 16) |
202 |
| - addr = int(segment[3][2:], 16) |
203 |
| - size = int(segment[5][2:], 16) |
204 |
| - if addr != 0 and size != 0: |
205 |
| - segment_list.append((offset, addr, size)) |
206 |
| - return segment_list |
| 104 | +def _parse_load_segment_inner(image_elf): |
| 105 | + with open(image_elf, "rb") as fd: |
| 106 | + elffile = elftools.elf.elffile.ELFFile(fd) |
| 107 | + for segment in elffile.iter_segments(): |
| 108 | + offset = segment['p_offset'] |
| 109 | + addr = segment['p_vaddr'] |
| 110 | + size = segment['p_filesz'] |
| 111 | + if (addr != 0 and size != 0 and segment['p_type'] == 'PT_LOAD'): |
| 112 | + yield offset, addr, size |
207 | 113 |
|
208 | 114 | def parse_load_segment(toolchain, image_elf):
|
209 |
| - if toolchain == "GCC_ARM": |
210 |
| - return parse_load_segment_gcc(image_elf) |
211 |
| - elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]: |
212 |
| - return parse_load_segment_armcc(image_elf) |
213 |
| - elif toolchain == "IAR": |
214 |
| - return parse_load_segment_iar(image_elf) |
215 |
| - else: |
216 |
| - return [] |
| 115 | + return list(_parse_load_segment_inner(image_elf)) |
217 | 116 |
|
218 | 117 | def create_payload(image_elf, ram2_bin, entry, segment):
|
219 | 118 | file_elf = open(image_elf, "rb")
|
|
0 commit comments