Skip to content

Use pyelftools for Realtek post-build script #6621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 11 additions & 112 deletions tools/targets/REALTEK_RTL8195AM.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import shutil
import time
import binascii
import elftools

from tools.paths import TOOLS_BOOTLOADERS
from tools.toolchains import TOOLCHAIN_PATHS
Expand Down Expand Up @@ -100,120 +101,18 @@ def find_symbol(toolchain, mapfile, symbol):

return int(ret,16) | 1

def parse_load_segment_gcc(image_elf):
# Program Headers:
# Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# LOAD 0x000034 0x10006000 0x10006000 0x026bc 0x026bc RW 0x8
# LOAD 0x0026f0 0x30000000 0x30000000 0x06338 0x06338 RWE 0x4
segment_list = []
cmd = os.path.join(TOOLCHAIN_PATHS['GCC_ARM'], 'arm-none-eabi-readelf')
cmd = '"' + cmd + '"' + ' -l ' + image_elf
for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"):
if not line.startswith(" LOAD"):
continue
segment = line.split()
if len(segment) != 8:
continue
offset = int(segment[1][2:], 16)
addr = int(segment[2][2:], 16)
size = int(segment[4][2:], 16)
if addr != 0 and size != 0:
segment_list.append((offset, addr, size))
return segment_list

def parse_load_segment_armcc(image_elf):
# ====================================
#
# ** Program header #2
#
# Type : PT_LOAD (1)
# File Offset : 52 (0x34)
# Virtual Addr : 0x30000000
# Physical Addr : 0x30000000
# Size in file : 27260 bytes (0x6a7c)
# Size in memory: 42168 bytes (0xa4b8)
# Flags : PF_X + PF_W + PF_R + PF_ARM_ENTRY (0x80000007)
# Alignment : 8
#
(offset, addr, size) = (0, 0, 0)
segment_list = []
in_segment = False
cmd = os.path.join(TOOLCHAIN_PATHS['ARM'], 'bin', 'fromelf')
cmd = '"' + cmd + '"' + ' --text -v --only=none ' + image_elf
for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"):
if line == "":
pass
elif line.startswith("** Program header"):
in_segment = True
elif in_segment == False:
pass
elif line.startswith("============"):
if addr != 0 and size != 0:
segment_list.append((offset, addr, size))
in_segment = False
(offset, addr, size) = (0, 0, 0)
elif line.startswith(" Type"):
if not re.match(r'\s+Type\s+:\s+PT_LOAD\s.*$', line):
in_segment = False
elif line.startswith(" File Offset"):
match = re.match(r'^\s+File Offset\s+:\s+(?P<offset>\d+).*$', line)
if match:
offset = int(match.group("offset"))
elif line.startswith(" Virtual Addr"):
match = re.match(r'^\s+Virtual Addr\s+:\s+0x(?P<addr>[0-9a-f]+).*$', line)
if match:
addr = int(match.group("addr"), 16)
elif line.startswith(" Size in file"):
match = re.match(r'^\s+Size in file\s+:.*\(0x(?P<size>[0-9a-f]+)\).*$', line)
if match:
size = int(match.group("size"), 16)
return segment_list


def parse_load_segment_iar(image_elf):
# SEGMENTS:
#
# Type Offset Virtual Physical File Sz Mem Sz Flags Align
# ---- ------ ------- -------- ------- ------ ----- -----
# 0: load 0x34 0x10006000 0x10006000 0x26bc 0x26bc 0x6 WR 0x8
# 1: load 0x26f0 0x30000000 0x30000000 0x6338 0x6338 0x7 XWR 0x4
#
# SECTIONS:
#
# Name Type Addr Offset Size Aln Lnk Inf ESz Flags
# ---- ---- ---- ------ ---- --- --- --- --- -----
# 1: .shstrtab strtab 0xfc4d8 0x60 0x4
# 2: .strtab strtab 0xfc538 0xbb3f 0x4

segment_list = []
in_segment = False
cmd = os.path.join(TOOLCHAIN_PATHS['IAR'], 'bin', 'ielfdumparm')
cmd = '"' + cmd + '"' + ' ' + image_elf
for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"):
if line.startswith(" SEGMENTS:"):
in_segment = True
elif in_segment == False:
pass
elif line.startswith(" SECTIONS:"):
break
elif re.match(r'^\s+\w+:\s+load\s+.*$', line):
segment = line.split()
offset = int(segment[2][2:], 16)
addr = int(segment[3][2:], 16)
size = int(segment[5][2:], 16)
if addr != 0 and size != 0:
segment_list.append((offset, addr, size))
return segment_list
def _parse_load_segment_inner(image_elf):
with open(image_elf, "rb") as fd:
elffile = elftools.elf.elffile.ELFFile(fd)
for segment in elffile.iter_segments():
offset = segment['p_offset']
addr = segment['p_vaddr']
size = segment['p_filesz']
if (addr != 0 and size != 0 and segment['p_type'] == 'PT_LOAD'):
yield offset, addr, size

def parse_load_segment(toolchain, image_elf):
if toolchain == "GCC_ARM":
return parse_load_segment_gcc(image_elf)
elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]:
return parse_load_segment_armcc(image_elf)
elif toolchain == "IAR":
return parse_load_segment_iar(image_elf)
else:
return []
return list(_parse_load_segment_inner(image_elf))

def create_payload(image_elf, ram2_bin, entry, segment):
file_elf = open(image_elf, "rb")
Expand Down