FreeBSD Bugzilla – Attachment 141896 Details for
Bug 188808
New port: science/sigrok-firmware-utils
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
file.shar
file.shar (text/plain), 36.83 KB, created by
Uffe Jakobsen
on 2014-04-19 23:10:00 UTC
(
hide
)
Description:
file.shar
Filename:
MIME Type:
Creator:
Uffe Jakobsen
Created:
2014-04-19 23:10:00 UTC
Size:
36.83 KB
patch
obsolete
># This is a shell archive. Save it in a file, remove anything before ># this line, and then unpack it by entering "sh file". Note, it may ># create directories; files and directories will be owned by you and ># have default permissions. ># ># This archive contains: ># ># sigrok-firmware-utils ># sigrok-firmware-utils/pkg-descr ># sigrok-firmware-utils/Makefile ># sigrok-firmware-utils/files ># sigrok-firmware-utils/files/README.parsepe ># sigrok-firmware-utils/files/parseelf.py ># sigrok-firmware-utils/files/parsepe.py ># sigrok-firmware-utils/files/sigrok-fwextract-hantek-dso ># sigrok-firmware-utils/files/sigrok-fwextract-hantek-dso.1 ># sigrok-firmware-utils/files/sigrok-fwextract-saleae-logic16 ># sigrok-firmware-utils/files/sigrok-fwextract-saleae-logic16.1 ># sigrok-firmware-utils/files/sigrok-fwextract-sysclk-lwla ># sigrok-firmware-utils/files/sigrok-fwextract-sysclk-lwla.1 ># >echo c - sigrok-firmware-utils >mkdir -p sigrok-firmware-utils > /dev/null 2>&1 >echo x - sigrok-firmware-utils/pkg-descr >sed 's/^X//' >sigrok-firmware-utils/pkg-descr << '3b359701d5014b10b79994394229169b' >XThe sigrok project aims at creating a portable, cross-platform, >XFree/Libre/Open-Source signal analysis software suite that supports >Xvarious device types, such as logic analyzers, MSOs, oscilloscopes, >Xmultimeters, LCR meters, sound level meters, thermometers, >Xhygrometers, anemometers, light meters, DAQs, dataloggers, >Xfunction generators, spectrum analyzers, power supplies, >XGPIB interfaces, and more. >X >XWWW: http://www.sigrok.org/wiki/Firmware >3b359701d5014b10b79994394229169b >echo x - sigrok-firmware-utils/Makefile >sed 's/^X//' >sigrok-firmware-utils/Makefile << 'e90f3a2def9b384cd15e058afd9abfa7' >X# Created by: Uffe Jakobsen <uffe@uffe.org> >X# $FreeBSD: $ >X >XPORTNAME= sigrok-firmware-utils >XPORTVERSION= 20140418 >XPORTREVISION= 1 >XCATEGORIES= science >XMASTER_SITES= #none >XDISTFILES= #none >X >XMAINTAINER= uffe@uffe.org >XCOMMENT= Sigrok firmware extraction utils >X >XLICENSE= GPLv2 >X >X#RUN_DEPENDS= >X >XUSE_PYTHON= 3 >XNO_BUILD= yes >X >Xdo-install: >X @${MKDIR} ${STAGEDIR}${DOCSDIR} >X @${INSTALL_MAN} ${FILESDIR}/README.parsepe ${STAGEDIR}${DOCSDIR} >X.for fil in parsepe.py parseelf.py >X @${INSTALL_SCRIPT} ${FILESDIR}/${fil} ${STAGEDIR}${PREFIX}/bin >X.endfor >X.for fil in sigrok-fwextract-hantek-dso sigrok-fwextract-saleae-logic16 sigrok-fwextract-sysclk-lwla >X @${INSTALL_SCRIPT} ${FILESDIR}/${fil} ${STAGEDIR}${PREFIX}/bin >X @${INSTALL_MAN} ${FILESDIR}/${fil}.1 ${STAGEDIR}${MANDIRS}/man1 >X.endfor >X >X.include <bsd.port.mk> >e90f3a2def9b384cd15e058afd9abfa7 >echo c - sigrok-firmware-utils/files >mkdir -p sigrok-firmware-utils/files > /dev/null 2>&1 >echo x - sigrok-firmware-utils/files/README.parsepe >sed 's/^X//' >sigrok-firmware-utils/files/README.parsepe << '2b2202b606c8328182decf01fb94abe2' >XThe parsepe.py tool can list all sections and symbols from a PE (portable >Xexecutable) binary file, and extract the contents of a symbol. >X >Xusage: >Xparsepe.py -l <filename> list all sections and symbols in file >Xparsepe.py -s <symbol> -x <filename> extract symbol from file >X >XTODO: >X- currently only handles COFF symbol tables >X- can only extract external (global) symbols >X >2b2202b606c8328182decf01fb94abe2 >echo x - sigrok-firmware-utils/files/parseelf.py >sed 's/^X//' >sigrok-firmware-utils/files/parseelf.py << '4d80edf57e0d349d85d48ea179dceac6' >X#!/usr/bin/env python3 >X## >X## This file is part of the sigrok-util project. >X## >X## Copyright (C) 2013 Marcus Comstedt <marcus@mc.pp.se> >X## >X## This program is free software; you can redistribute it and/or modify >X## it under the terms of the GNU General Public License as published by >X## the Free Software Foundation; either version 3 of the License, or >X## (at your option) any later version. >X## >X## This program is distributed in the hope that it will be useful, >X## but WITHOUT ANY WARRANTY; without even the implied warranty of >X## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >X## GNU General Public License for more details. >X## >X## You should have received a copy of the GNU General Public License >X## along with this program; if not, see <http://www.gnu.org/licenses/>. >X## >X >Ximport struct >X >Xclass elf: >X >X def read_struct(this, struct_fmt, struct_fields): >X fmt = this.elf_endianprefix+str.translate(struct_fmt, this.elf_format); >X fields = struct.unpack(fmt, this.file.read(struct.calcsize(fmt))) >X return dict(zip(struct_fields, fields)) >X >X def read_ehdr(this): >X return this.read_struct('16sHHWNNNWHHHHHH', >X ('e_ident', 'e_type', 'e_machine', 'e_version', >X 'e_entry', 'e_phoff', 'e_shoff', 'e_flags', >X 'e_ehsize', 'e_phentsize', 'e_phnum', >X 'e_shentsize', 'e_shnum', 'e_shstrndx')) >X >X def read_shdr(this): >X return this.read_struct('WWNNNNWWNN', >X ('sh_name', 'sh_type', 'sh_flags', 'sh_addr', >X 'sh_offset', 'sh_size', 'sh_link', 'sh_info', >X 'sh_addralign', 'sh_entsize')) >X >X def read_section(this, shdr): >X this.file.seek(shdr['sh_offset']) >X return this.file.read(shdr['sh_size']) >X >X def get_name(this, name, strtab=None): >X strtab = strtab or this.strtab >X nul = strtab.find(b'\0', name) >X if nul < 0: >X return bytes.decode(strtab[name:]) >X else: >X return bytes.decode(strtab[name:nul]) >X >X def find_section(this, name): >X for section in this.shdrs: >X if this.get_name(section['sh_name']) == name: >X return section >X raise KeyError(name) >X >X def parse_symbol(this): >X if this.elf_wordsize == 64: >X return this.read_struct('WBBHNX', >X ('st_name', 'st_info', 'st_other', >X 'st_shndx', 'st_value', 'st_size')) >X else: >X return this.read_struct('WNWBBH', >X ('st_name', 'st_value', 'st_size', >X 'st_info', 'st_other', 'st_shndx')) >X >X def parse_rela(this): >X return this.read_struct('NNn', ('r_offset', 'r_info', 'r_addend')) >X >X def parse_rel(this): >X return this.read_struct('NN', ('r_offset', 'r_info')) >X >X def fixup_reloc(this, reloc): >X if not 'r_addend' in reloc: >X reloc['r_addend'] = 0 >X if this.elf_wordsize == 64: >X reloc['r_sym'] = reloc['r_info'] >> 32 >X reloc['r_type'] = reloc['r_info'] & 0xffffffff >X else: >X reloc['r_sym'] = reloc['r_info'] >> 8 >X reloc['r_type'] = reloc['r_info'] & 0xff >X return reloc >X >X def parse_symbols(this, symsecname, strsecname): >X try: >X symsechdr = this.find_section(symsecname) >X strsechdr = this.find_section(strsecname) >X except KeyError: >X return {} >X strsec = this.read_section(strsechdr) >X this.file.seek(symsechdr['sh_offset']) >X syms = [dict(this.parse_symbol(),number=i) for i in >X range(0, symsechdr['sh_size'] // symsechdr['sh_entsize'])] >X return {this.get_name(sym['st_name'], strsec): sym for sym in syms} >X >X def parse_relocs(this, section): >X this.file.seek(section['sh_offset']) >X if section['sh_type'] == 4: >X relocs = [this.fixup_reloc(this.parse_rela()) for i in >X range(0, section['sh_size'] // section['sh_entsize'])] >X else: >X relocs = [this.fixup_reloc(this.parse_rel()) for i in >X range(0, section['sh_size'] // section['sh_entsize'])] >X return relocs >X >X def address_to_offset(this, addr): >X for section in this.shdrs: >X if (section['sh_addr'] <= addr and >X section['sh_addr']+section['sh_size'] > addr): >X return section['sh_offset']+(addr-section['sh_addr']) >X raise IndexError('address out of range') >X >X def load_symbol(this, sym): >X this.file.seek(this.address_to_offset(sym['st_value'])) >X return this.file.read(sym['st_size']) >X >X def __init__(this, filename): >X this.file = open(filename, 'rb') >X magic = this.file.read(16) >X >X if magic[:4] != b'\x7fELF': >X raise Exception("ELF signature not found") >X >X if magic[4] == 1: >X this.elf_wordsize = 32 >X nativeint = 'Ii' >X elif magic[4] == 2: >X this.elf_wordsize = 64 >X nativeint = 'Qq' >X else: >X raise Exception("Invalid ELF file class") >X >X if magic[5] == 1: >X this.elf_endianprefix = '<' >X elif magic[5] == 2: >X this.elf_endianprefix = '>' >X else: >X raise Exception("Invalid ELF data encoding") >X >X this.elf_format = str.maketrans('HWwXxNn', 'HIiQq'+nativeint) >X >X this.file.seek(0) >X this.ehdr = this.read_ehdr() >X this.file.seek(this.ehdr['e_shoff']) >X this.shdrs = [this.read_shdr() for i in range(this.ehdr['e_shnum'])] >X >X this.strtab = this.read_section(this.shdrs[this.ehdr['e_shstrndx']]) >X >X this.symtab = this.parse_symbols('.symtab', '.strtab') >X this.dynsym = this.parse_symbols('.dynsym', '.dynstr') >X >X this.relocs = {} >X for section in this.shdrs: >X if section['sh_type'] == 4 or section['sh_type'] == 9: >X rels = {} >X symsec = this.shdrs[section['sh_link']] >X if this.get_name(symsec['sh_name']) == '.symtab': >X rels['symbols'] = this.symtab >X elif this.get_name(symsec['sh_name']) == '.dynsym': >X rels['symbols'] = this.dynsym >X rels['relocs'] = this.parse_relocs(section) >X this.relocs[this.get_name(section['sh_name'])] = rels >X >X def __del__(this): >X try: >X this.file.close() >X except AttributeError: >X pass >4d80edf57e0d349d85d48ea179dceac6 >echo x - sigrok-firmware-utils/files/parsepe.py >sed 's/^X//' >sigrok-firmware-utils/files/parsepe.py << '3437c7374751c4486815a5c73fb7d553' >X#!/usr/bin/env python3 >X## >X## This file is part of the sigrok-util project. >X## >X## Copyright (C) 2012 Bert Vermeulen <bert@biot.com> >X## >X## This program is free software; you can redistribute it and/or modify >X## it under the terms of the GNU General Public License as published by >X## the Free Software Foundation; either version 3 of the License, or >X## (at your option) any later version. >X## >X## This program is distributed in the hope that it will be useful, >X## but WITHOUT ANY WARRANTY; without even the implied warranty of >X## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >X## GNU General Public License for more details. >X## >X## You should have received a copy of the GNU General Public License >X## along with this program; if not, see <http://www.gnu.org/licenses/>. >X## >X >Ximport sys >Ximport os >Xfrom getopt import getopt >Ximport struct >X >X >Xdef parse(filename): >X f = open(filename, 'rb') >X if f.read(2) != b'MZ': >X raise Exception("MZ signature not found.") >X >X sections = [] >X # long e_lfanew >X f.seek(0x3c) >X pe_ptr = struct.unpack("<L", f.read(4))[0] >X f.seek(pe_ptr) >X if f.read(4) != b'\x50\x45\x00\x00': >X raise Exception("PE signature not found.") >X # skip Machine >X f.seek(f.tell() + 2) >X sections.append(['header', 324, 0]) >X num_sections = struct.unpack("<H", f.read(2))[0] >X # skip TimeDateStamp >X f.seek(f.tell() + 4) >X symboltable_address = struct.unpack("<L", f.read(4))[0] >X num_symbols = struct.unpack("<L", f.read(4))[0] >X optheader_size = struct.unpack("<H", f.read(2))[0] >X # skip past PE header and PE optional header >X f.seek(f.tell() + 2 + optheader_size) >X >X for i in range(num_sections): >X name = f.read(8).decode('ascii', errors='ignore').strip('\x00') >X # skip past Misc and VirtualAddress >X f.seek(f.tell() + 8) >X # SizeOfRawData >X size = struct.unpack("<L", f.read(4))[0] >X # PointerToRawData >X ptr = struct.unpack("<L", f.read(4))[0] >X # skip to next section header >X f.seek(f.tell() + 16) >X sections.append([name, size, ptr]) >X >X symbols = [] >X addr = symboltable_address >X stringtable_address = symboltable_address + num_symbols * 18 >X for i in range(num_symbols): >X f.seek(addr) >X tmp = f.read(8) >X symaddr = struct.unpack("<L", f.read(4))[0] >X # skip SectionNumber and Type >X symtype = struct.unpack("B", f.read(1))[0] >X f.seek(f.tell() + 4) >X if tmp[:4] == b'\x00\x00\x00\x00': >X # symbol name is in the string table >X straddr = stringtable_address + struct.unpack("<l", tmp[4:])[0] >X f.seek(straddr) >X tmpname = f.read(64) >X name = tmpname[:tmpname.find(b'\x00')] >X else: >X name = tmp >X name = name.decode('ascii', errors='ignore').strip('\x00') >X # need IMAGE_SYM_CLASS_EXTERNAL >X if symtype == 0x02: >X size = 0 >X else: >X size = None >X if i != 0 and symbols[-1][2] is not None and symaddr > symbols[-1][1]: >X symbols[-1][2] = symaddr - symbols[-1][1] >X symbols.append([name, symaddr, size]) >X addr += 18 >X >X f.close() >X >X return sections, symbols >X >X >Xdef list_all(filename): >X sections, symbols = parse(filename) >X if sections: >X print("Sections:\n Name Size\t Position") >X cnt = 0 >X for name, size, address in sections: >X print("%-3d %-8s %5d\t 0x%.8x" % (cnt, name, size, address)) >X cnt += 1 >X if symbols: >X print("\nSymbol table:\n Address Size Symbol") >X for symbol, address, size in symbols: >X if size is not None: >X sizestr = "%5d" % size >X else: >X sizestr = " " >X print("0x%.8x %s %-8s" % (address, sizestr, symbol)) >X print() >X >X >Xdef extract_symbol(filename, symbol): >X sections, symbols = parse(filename) >X if not symbols: >X return None >X data = None >X for symbolname, address, size in symbols: >X if symbolname == symbol: >X if size is None: >X raise Exception("symbol %s found, but has unknown size") >X f = open(filename, 'rb') >X f.seek(address) >X data = f.read(size) >X f.close() >X if len(data) != size: >X raise Exception("short file") >X break >X >X if data is None: >X raise Exception("symbol %s not found" % symbol) >X >X return data >X >X >X >Xdef usage(): >X print("usage: parsepe.py [-s <symbol>] <-l|-x> <filename>") >X print(" -l list all sections and symbols in file") >X print(" -x extract symbol from file (specify symbol name with -s)") >X sys.exit() >X >X >X# >X# main >X# >X >Xif __name__ == '__main__': >X filename = symbol = mode = None >X opts, args = getopt(sys.argv[1:], 's:lx') >X for opt, arg in opts: >X if opt == '-s': >X symbol = arg >X elif opt == '-l': >X mode = 'list' >X elif opt == '-x': >X mode = 'extract' >X >X if len(args) != 1: >X usage() >X if mode is None and symbol is None: >X usage() >X >X try: >X filename = args[0] >X if mode == 'list': >X list_all(filename) >X elif mode == 'extract': >X if symbol is None: >X raise Exception("specify a symbol to extract") >X data = extract_symbol(filename, symbol) >X outfile = os.path.splitext(filename)[0] + symbol >X open(outfile, 'wb').write(data) >X print("saved %d bytes to %s" % (len(data), outfile)) >X else: >X raise Exception("specify -l or -x") >X except Exception as e: >X print("Error: %s" % str(e)) >X >X >3437c7374751c4486815a5c73fb7d553 >echo x - sigrok-firmware-utils/files/sigrok-fwextract-hantek-dso >sed 's/^X//' >sigrok-firmware-utils/files/sigrok-fwextract-hantek-dso << '9e8cf85ef81a7022bc78a309937d30db' >X#!/usr/bin/env python3 >X## >X## This file is part of the sigrok-util project. >X## >X## Copyright (C) 2012 Bert Vermeulen <bert@biot.com> >X## >X## This program is free software; you can redistribute it and/or modify >X## it under the terms of the GNU General Public License as published by >X## the Free Software Foundation; either version 3 of the License, or >X## (at your option) any later version. >X## >X## This program is distributed in the hope that it will be useful, >X## but WITHOUT ANY WARRANTY; without even the implied warranty of >X## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >X## GNU General Public License for more details. >X## >X## You should have received a copy of the GNU General Public License >X## along with this program; if not, see <http://www.gnu.org/licenses/>. >X## >X >Ximport sys >Ximport os >Ximport re >Ximport struct >Xfrom array import array >X >Ximport parsepe >X >X >Xdef find_model(filename): >X filename = os.path.split(filename)[-1] >X m = re.search('^dso([a-z0-9]+)1.sys$', filename, re.I) >X if m: >X model = m.group(1).upper() >X model = model.replace('X86', '').replace('AMD64', '').replace('IA64', '') >X if model == '520A': >X model = '5200A' >X else: >X model = 'unknown' >X >X return model >X >X >Xdef unsparse(data): >X p = 0 >X maxaddr = 0 >X blob = array('B', [0] * 0x4000) >X while p <= len(data) and data[p+4] == 0: >X num_bytes = struct.unpack("<H", data[p:p+2])[0] >X address = struct.unpack("<H", data[p+2:p+4])[0] >X chunk = array('B') >X chunk.frombytes(data[p+5:p+5+num_bytes]) >X p += 22 >X >X if address > 0x4000: >X # the FX2 only has 16K RAM. other writes are to registers >X # in the 0xe000 region, skip those >X continue >X >X blob[address:address+num_bytes] = chunk >X >X if address + num_bytes > maxaddr: >X maxaddr = address + num_bytes >X >X return blob[:maxaddr].tostring() >X >X >Xdef usage(): >X print("sigrok-fwextract-hantek-dso <driverfile>") >X sys.exit() >X >X >X# >X# main >X# >X >Xif len(sys.argv) != 2: >X usage() >X >Xtry: >X filename = sys.argv[1] >X binihx = parsepe.extract_symbol(filename, '_firmware') >X if binihx is None: >X raise Exception("no firmware found") >X blob = unsparse(binihx) >X outfile = 'hantek-dso-' + find_model(filename) + '.fw' >X open(outfile, 'wb').write(blob) >X print("saved %d bytes to %s" % (len(blob), outfile)) >Xexcept Exception as e: >X print("Error: %s" % str(e)) >9e8cf85ef81a7022bc78a309937d30db >echo x - sigrok-firmware-utils/files/sigrok-fwextract-hantek-dso.1 >sed 's/^X//' >sigrok-firmware-utils/files/sigrok-fwextract-hantek-dso.1 << '15f3ef99cbaaea18b52bb09edd5060f6' >X.TH SIGROK\-FWEXTRACT\-HANTEK\-DSO 1 "Aug 08, 2013" >X.SH "NAME" >Xsigrok\-fwextract\-hantek\-dso \- Extract Hantek DSO-2xxx/52xx firmware >X.SH "SYNOPSIS" >X.B sigrok\-fwextract\-hantek\-dso [FILE] >X.SH "DESCRIPTION" >XThis tool extracts firmware from the driver that comes with the >XHantek DSO-2xxx/52xx series USB oscilloscopes. Find the 32-bit >Xdriver installed on the Windows system -- typically called >X.B DSOxxxx1.sys >Xor >X.BR DsoxxxxX861.sys , >Xwhere xxxx is your device's model. >X.PP >XUse it like this: >X.PP >X.B " $ sigrok-fwextract-hantek-dso Dso2090X861.sys" >X.br >X.RB " saved 4730 bytes to hantek-dso-2090.fw" >X.PP >XCopy the resulting file over to the location where libsigrok expects >Xto find its firmware files. By default this is >X.BR /usr/local/share/sigrok-firmware . >X.SH OPTIONS >XNone. >X.SH "EXIT STATUS" >XExits with 0 on success, 1 on most failures. >X.SH "SEE ALSO" >X\fBsigrok\-fwextract\-saleae\-logic16\fP(1) >X.SH "BUGS" >XPlease report any bugs via Bugzilla >X.RB "(" http://sigrok.org/bugzilla ")" >Xor on the sigrok\-devel mailing list >X.RB "(" sigrok\-devel@lists.souceforge.net ")." >X.SH "LICENSE" >XThis program is covered by the GNU General Public License (GPL), >Xversion 3 or later. >X.SH "AUTHORS" >XPlease see the individual source code files. >15f3ef99cbaaea18b52bb09edd5060f6 >echo x - sigrok-firmware-utils/files/sigrok-fwextract-saleae-logic16 >sed 's/^X//' >sigrok-firmware-utils/files/sigrok-fwextract-saleae-logic16 << 'e5995e6f703124fdb2c681eb7495d542' >X#!/usr/bin/env python3 >X## >X## This file is part of the sigrok-util project. >X## >X## Copyright (C) 2013 Marcus Comstedt <marcus@mc.pp.se> >X## >X## This program is free software; you can redistribute it and/or modify >X## it under the terms of the GNU General Public License as published by >X## the Free Software Foundation; either version 3 of the License, or >X## (at your option) any later version. >X## >X## This program is distributed in the hope that it will be useful, >X## but WITHOUT ANY WARRANTY; without even the implied warranty of >X## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >X## GNU General Public License for more details. >X## >X## You should have received a copy of the GNU General Public License >X## along with this program; if not, see <http://www.gnu.org/licenses/>. >X## >X >Ximport sys >Ximport struct >Ximport parseelf >X >Xclass searcher: >X >X def reset(this, offs=0): >X if offs < 0 or offs > this.length: >X raise Exception('Reset past end of section') >X this.address = this.baseaddr + offs >X this.offset = offs >X >X def skip(this, cnt): >X if this.offset + cnt > this.length: >X raise Exception('Skip past end of section') >X this.address += cnt >X this.offset += cnt >X >X def peek(this, cnt, offs=0): >X if this.offset + offs + cnt > this.length: >X raise Exception('Peek past end of section') >X return this.data[this.offset + offs : this.offset + offs + cnt] >X >X def look_for(this, needle): >X pos = this.data.find(needle, this.offset) >X if pos < 0: >X raise Exception('Needle not found in haystack') >X this.skip(pos - this.offset) >X >X def look_for_either(this, needle1, needle2): >X pos1 = this.data.find(needle1, this.offset) >X pos2 = this.data.find(needle2, this.offset) >X if pos1 < 0 and pos2 < 0: >X raise Exception('Needle not found in haystack') >X if pos1 < 0 or pos2 < pos1: >X pos1 = pos2 >X this.skip(pos1 - this.offset) >X >X def __init__(this, data, addr): >X this.data = data >X this.baseaddr = addr >X this.length = len(data) >X this.reset() >X >Xdef search_plt_32(plt, addr): >X plt.reset() >X plt.look_for(struct.pack('<BBI', 0xff, 0x25, addr)) # jmp *addr32 >X return plt.address >X >Xdef search_plt_64(plt, addr): >X plt.reset() >X while True: >X plt.look_for(b'\xff\x25') # jmpq *offs32(%rip) >X offs = struct.unpack('<i', plt.peek(4, 2))[0] >X if plt.address + offs + 6 == addr: >X return plt.address >X plt.skip(2) >X >Xdef find_hex_file_lines_constructor_32(text, hex_file_lines_got, got_plt): >X while True: >X text.look_for_either(b'\x8b\xbb', b'\x8b\xb3') # mov offs32(%ebx),{%edi,%esi} >X offs = struct.unpack('<i', text.peek(4, 2))[0] >X if got_plt + offs == hex_file_lines_got: >X text.skip(6) >X return >X text.skip(2) >X >Xdef find_hex_file_lines_constructor_64(text, hex_file_lines_got): >X while True: >X text.look_for(b'\x48\x8b\x2d') # mov offs32(%rip),%rbp >X offs = struct.unpack('<i', text.peek(4, 3))[0] >X if text.address + offs + 7 == hex_file_lines_got: >X text.skip(7) >X return >X text.skip(3) >X >Xdef parse_hex_file_lines_constructor_32(text, basic_string_plt, got_plt, lines): >X text.skip(-5) >X esi = (text.peek(1) == b'\xb3') >X text.skip(5) >X cnt = len(lines) >X while cnt > 0: >X if text.peek(2) == b'\x8d\x45': # lea offs8(%ebp),%eax >X text.skip(3) >X elif text.peek(2) == b'\x8d\x85': # lea offs32(%ebp),%eax >X text.skip(6) >X if text.peek(1) == (b'\xbf' if esi else b'\xbe'): # mov $imm32,%esi >X text.skip(5) >X elif text.peek(2) == (b'\x31\xff' if esi else b'\x31\xf6'): # xor %esi,%esi >X text.skip(2) >X if text.peek(4) == b'\x89\x44\x24\x08': # mov %eax,0x8(%esp) >X text.skip(4) >X if text.peek(2) == b'\x8d\x83': # lea offs32(%ebx),%eax >X straddr = struct.unpack('<i', text.peek(4, 2))[0] >X text.skip(6) >X straddr += got_plt >X else: >X raise Exception('Expected lea offs32(%ebx),%eax @ ' + >X ('0x%x' % text.address)) >X if text.peek(4) == b'\x89\x44\x24\x04': # mov %eax,0x4(%esp) >X text.skip(4) >X if text.peek(3) == (b'\x89\x34\x24' if esi else b'\x89\x3c\x24'): # mov %edi,(%esp) >X offs = 0 >X text.skip(3) >X elif text.peek(2) == (b'\x8d\x46' if esi else b'\x8d\x47'): # lea offs8(%edi),%eax >X offs = struct.unpack('<b', text.peek(1, 2))[0] >X text.skip(3) >X elif text.peek(2) == (b'\x8d\x86' if esi else b'\x8d\x87'): # lea offs32(%edi),%eax >X offs = struct.unpack('<i', text.peek(4, 2))[0] >X text.skip(6) >X else: >X raise Exception('Expected lea offs(%e'+('s' if esi else 'd')+'i),%eax @ ' + >X ('0x%x' % text.address)) >X if offs < 0 or offs > (len(lines) << 2) or (offs & 3) != 0: >X raise Exception('Invalid offset %d' % offs) >X index = offs >> 2 >X if lines[index] != 0: >X raise Exception('Line %d filled multiple times' % index) >X if text.peek(3) == b'\x89\x04\x24': # mov %eax,(%esp) >X text.skip(3) >X if text.peek(1) == b'\xe8': # call offs32 >X offs = struct.unpack('<i', text.peek(4, 1))[0] >X text.skip(5) >X if text.address + offs != basic_string_plt: >X raise Exception('Expected call ZNSsC1EPKcRKSaIcE@plt @ ' + >X ('0x%x' % text.address)) >X else: >X raise Exception('Expected call ZNSsC1EPKcRKSaIcE@plt @ ' + >X ('0x%x' % text.address)) >X if straddr == 0: >X raise Exception('NULL pointer stored to index %d' % index) >X lines[index] = straddr >X cnt -= 1 >X >Xdef parse_hex_file_lines_constructor_64(text, basic_string_plt, lines): >X cnt = len(lines) >X while cnt > 0: >X if text.peek(1) == b'\xbb': # mov $imm32,%ebx >X text.skip(5) >X elif text.peek(2) == b'\x31\xdb': # xor %ebx,%ebx >X text.skip(2) >X if text.peek(4) == b'\x48\x8d\x54\x24': # lea offs8(%rsp),%rdx >X text.skip(5) >X elif text.peek(4) == b'\x48\x8d\x94\x24': # lea offs32(%rsp),%rdx >X text.skip(8) >X if text.peek(3) == b'\x48\x8d\x35': # lea offs32(%rip),%rsi >X straddr = struct.unpack('<i', text.peek(4, 3))[0] >X text.skip(7) >X straddr += text.address >X else: >X raise Exception('Expected lea offs(%rip),%rsi @ ' + >X ('0x%x' % text.address)) >X if text.peek(3) == b'\x48\x89\xef': # mov %rbp,%rdi >X offs = 0 >X text.skip(3) >X elif text.peek(3) == b'\x48\x8d\x7d': # lea offs8(%rbp),%rdi >X offs = struct.unpack('<b', text.peek(1, 3))[0] >X text.skip(4) >X elif text.peek(3) == b'\x48\x8d\xbd': # lea offs32(%rbp),%rdi >X offs = struct.unpack('<i', text.peek(4, 3))[0] >X text.skip(7) >X else: >X raise Exception('Expected lea offs(%rbp),%rdi @ ' + >X ('0x%x' % text.address)) >X if text.peek(1) == b'\xbb': # mov $imm32,%ebx >X text.skip(5) >X elif text.peek(2) == b'\x31\xdb': # xor %ebx,%ebx >X text.skip(2) >X if offs < 0 or offs > (len(lines) << 3) or (offs & 7) != 0: >X raise Exception('Invalid offset %d' % offs) >X index = offs >> 3 >X if lines[index] != 0: >X raise Exception('Line %d filled multiple times' % index) >X if text.peek(1) == b'\xe8': # callq offs32 >X offs = struct.unpack('<i', text.peek(4, 1))[0] >X text.skip(5) >X if text.address + offs != basic_string_plt: >X raise Exception('Expected callq ZNSsC1EPKcRKSaIcE@plt @ ' + >X ('0x%x' % text.address)) >X else: >X raise Exception('Expected callq ZNSsC1EPKcRKSaIcE@plt @ ' + >X ('0x%x' % text.address)) >X if straddr == 0: >X raise Exception('NULL pointer stored to index %d' % index) >X lines[index] = straddr >X cnt -= 1 >X >Xdef find_reloc(elf, symname): >X for section, relocs in elf.relocs.items(): >X if 'symbols' in relocs and symname in relocs['symbols']: >X symnum = relocs['symbols'][symname]['number'] >X for reloc in relocs['relocs']: >X if reloc['r_sym'] == symnum: >X return reloc >X raise Exception('Unable to find a relocation against ' + symname) >X >Xdef ihex_to_binary(lines): >X chunks = {} >X for line in lines: >X if line[0] != ':': >X raise Exception('ihex line does not start with ":"') >X line = bytes.fromhex(line[1:]) >X if (sum(bytearray(line)) & 0xff) != 0: >X raise Exception('Invalid checksum in ihex') >X (byte_count, address, rectype) = struct.unpack('>BHB', line[:4]) >X (data, checksum) = struct.unpack('>%dsB' % (byte_count), line[4:]) >X if rectype == 1 and byte_count == 0: >X pass >X elif rectype != 0 or byte_count == 0: >X raise Exception('Unexpected rectype %d with bytecount %d' % >X (rectype, byte_count)) >X elif address in chunks: >X raise Exception('Multiple ihex lines with address 0x%x' % address) >X else: >X chunks[address] = data >X blob = b'' >X for address in sorted(iter(chunks)): >X if address < len(blob): >X raise Exception('Overlapping ihex chunks') >X elif address > len(blob): >X blob += b'\x00' * (address - len(blob)) >X blob += chunks[address] >X return blob >X >Xdef extract_fx2_firmware(elf, symname, filename): >X blob = elf.load_symbol(elf.dynsym[symname + 'Count']) >X count = struct.unpack('<I', blob)[0] >X got_plt = elf.find_section('.got.plt')['sh_addr'] >X hex_file_lines_got = find_reloc(elf, symname)['r_offset'] >X basic_string_got = find_reloc(elf, '_ZNSsC1EPKcRKSaIcE')['r_offset'] >X pltsec = elf.find_section('.plt') >X plt = searcher(elf.read_section(pltsec), pltsec['sh_addr']) >X try: >X if elf.elf_wordsize == 64: >X basic_string_plt = search_plt_64(plt, basic_string_got) >X else: >X basic_string_plt = search_plt_32(plt, basic_string_got) >X except: >X raise Exception('Unable to find a PLT entry for _ZNSsC1EPKcRKSaIcE') >X textsec = elf.find_section('.text') >X text = searcher(elf.read_section(textsec), textsec['sh_addr']) >X while True: >X try: >X if elf.elf_wordsize == 64: >X find_hex_file_lines_constructor_64(text, hex_file_lines_got) >X else: >X find_hex_file_lines_constructor_32(text, hex_file_lines_got, >X got_plt) >X except: >X raise Exception('Unable to find constructor for ' + symname) >X oldoffs = text.offset >X l = [0]*count >X try: >X if elf.elf_wordsize == 64: >X parse_hex_file_lines_constructor_64(text, basic_string_plt, l) >X else: >X parse_hex_file_lines_constructor_32(text, basic_string_plt, >X got_plt, l) >X break >X except KeyError: >X text.reset(oldoffs) >X rodatasec = elf.find_section('.rodata') >X rodata = elf.read_section(rodatasec) >X lo = rodatasec['sh_addr'] >X hi = lo + rodatasec['sh_size'] >X for i in range(count): >X addr = l[i] >X if addr < lo or addr >= hi: >X raise Exception('Address 0x%x outside of .rodata section' % addr) >X l[i] = elf.get_name(addr - lo, rodata) >X blob = ihex_to_binary(l) >X f = open(filename, 'wb') >X f.write(blob) >X f.close() >X print("saved %d bytes to %s" % (len(blob), filename)) >X >Xdef extract_symbol(elf, symname, filename): >X blob = elf.load_symbol(elf.dynsym[symname]) >X f = open(filename, 'wb') >X f.write(blob) >X f.close() >X print("saved %d bytes to %s" % (len(blob), filename)) >X >Xdef extract_bitstream(elf, lv): >X extract_symbol(elf, 'gLogic16Lv' + lv + 'CompressedBitstream', >X 'saleae-logic16-fpga-' + lv + '.bitstream') >X >Xdef usage(): >X print("sigrok-fwextract-saleae-logic16 <programfile>") >X sys.exit() >X >X >X# >X# main >X# >X >Xif len(sys.argv) != 2: >X usage() >X >Xtry: >X filename = sys.argv[1] >X elf = parseelf.elf(filename) >X if elf.ehdr['e_machine'] != 3 and elf.ehdr['e_machine'] != 62: >X raise Exception('Unsupported e_machine') >X extract_fx2_firmware(elf, 'gLogic16HexFileLines', 'saleae-logic16-fx2.fw') >X extract_bitstream(elf, '18') >X extract_bitstream(elf, '33') >Xexcept Exception as e: >X print("Error: %s" % str(e)) >e5995e6f703124fdb2c681eb7495d542 >echo x - sigrok-firmware-utils/files/sigrok-fwextract-saleae-logic16.1 >sed 's/^X//' >sigrok-firmware-utils/files/sigrok-fwextract-saleae-logic16.1 << '5e8d93a1c27459f149b58d0f2797266d' >X.TH SIGROK\-FWEXTRACT\-SALEAE\-LOGIC16 1 "Aug 08, 2013" >X.SH "NAME" >Xsigrok\-fwextract\-saleae\-logic16 \- Extract Saleae Logic16 firmware >X.SH "SYNOPSIS" >X.B sigrok\-fwextract\-saleae\-logic16 [FILE] >X.SH "DESCRIPTION" >XThis tool extracts FX2 firmware and FPGA bitstreams from the vendor >Xsoftware for the Saleae Logic16 USB logic analyzer. Download the Linux >Xversion (either 32-bit or 64-bit will do), and unpack it to find the >Xmain binary called "Logic". >X.PP >XIn order to extract the firmware/bitstreams, run the following command: >X.PP >X.B " $ sigrok-fwextract-saleae-logic16 Logic" >X.br >X.RB " saved 5214 bytes to saleae-logic16-fx2.fw" >X.br >X.RB " saved 149516 bytes to saleae-logic16-fpga-18.bitstream" >X.br >X.RB " saved 149516 bytes to saleae-logic16-fpga-33.bitstream" >X.PP >XCopy the resulting files over to the location where libsigrok expects >Xto find its firmware files. By default this is >X.BR /usr/local/share/sigrok-firmware . >X.SH OPTIONS >XNone. >X.SH "EXIT STATUS" >XExits with 0 on success, 1 on most failures. >X.SH "SEE ALSO" >X\fBsigrok\-fwextract\-hantek\-dso\fP(1) >X.SH "BUGS" >XPlease report any bugs via Bugzilla >X.RB "(" http://sigrok.org/bugzilla ")" >Xor on the sigrok\-devel mailing list >X.RB "(" sigrok\-devel@lists.souceforge.net ")." >X.SH "LICENSE" >XThis program is covered by the GNU General Public License (GPL), >Xversion 3 or later. >X.SH "AUTHORS" >XPlease see the individual source code files. >5e8d93a1c27459f149b58d0f2797266d >echo x - sigrok-firmware-utils/files/sigrok-fwextract-sysclk-lwla >sed 's/^X//' >sigrok-firmware-utils/files/sigrok-fwextract-sysclk-lwla << '8d651df632ba51faf4f343abde174f15' >X#! /bin/sh -e >X## >X## This file is part of the sigrok-util project. >X## >X## Copyright (C) 2014 Daniel Elstner <daniel.kitta@gmail.com> >X## >X## This program is free software; you can redistribute it and/or modify >X## it under the terms of the GNU General Public License as published by >X## the Free Software Foundation; either version 3 of the License, or >X## (at your option) any later version. >X## >X## This program is distributed in the hope that it will be useful, >X## but WITHOUT ANY WARRANTY; without even the implied warranty of >X## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >X## GNU General Public License for more details. >X## >X## You should have received a copy of the GNU General Public License >X## along with this program; if not, see <http://www.gnu.org/licenses/>. >X## >X >Xinfile=$1 >Xif [ -z "$infile" ]; then >X echo "Usage: $0 SETUP-EXE" >&2 >X exit 1 >Xfi >X >X# Verify the checksum to make sure this is the right binary file >Xexpectsum=f2a9333329200ad1d939d051257f914200cf0c765ff4962b2907dcf30716f455 >Xset '' $(sha256sum -b "$infile") >X >Xif [ "$2" != "$expectsum" ]; then >X echo "$0: checksum mismatch for '$infile'" >&2 >X echo "$0: make sure you picked the right file (lwla1034_EN_setup.exe on the CD-ROM)" >&2 >X exit 1 >Xfi >X >X# Extract the firmware binaries from the executable >Xdd bs=1 skip=34110338 count=78398 if="$infile" of=sysclk-lwla1034-int.bitstream >Xdd bs=1 skip=34266237 count=78247 if="$infile" of=sysclk-lwla1034-extpos.bitstream >Xdd bs=1 skip=34344484 count=79145 if="$infile" of=sysclk-lwla1034-extneg.bitstream >Xdd bs=1 skip=34578631 count=48525 if="$infile" of=sysclk-lwla1034-off.bitstream >8d651df632ba51faf4f343abde174f15 >echo x - sigrok-firmware-utils/files/sigrok-fwextract-sysclk-lwla.1 >sed 's/^X//' >sigrok-firmware-utils/files/sigrok-fwextract-sysclk-lwla.1 << 'e68eba8e6fe272b583a51a3696d35072' >X.TH SIGROK\-FWEXTRACT\-SYSCLK\-LWLA 1 "Jan 04, 2014" >X.SH "NAME" >Xsigrok\-fwextract\-sysclk\-lwla \- Extract SysClk LWLA* firmware >X.SH "SYNOPSIS" >X.B sigrok\-fwextract\-sysclk\-lwla SETUP-EXE >X.SH "DESCRIPTION" >XThis tool extracts FPGA bitstreams from the vendor software for the SysClk >XLWLA1034 USB logic analyzer. Insert the CD-ROM that ships with the device, >Xand locate the Windows installer executable "lwla1034_EN_setup.exe". >X.PP >XIn order to extract the bitstreams, run the following command: >X.PP >X.B " $ sigrok-fwextract-sysclk-lwla lwla1034_EN_setup.exe" >X.PP >XCopy the resulting four bitstream files over to the location where libsigrok >Xexpects to find its firmware files. By default this is >X.BR /usr/local/share/sigrok-firmware . >X.SH OPTIONS >XNone. >X.SH "EXIT STATUS" >XExits with 0 on success, 1 on most failures. >X.SH "SEE ALSO" >X\fBsigrok\-fwextract\-hantek\-dso\fP(1) >X.SH "BUGS" >XPlease report any bugs via Bugzilla >X.RB "(" http://sigrok.org/bugzilla ")" >Xor on the sigrok\-devel mailing list >X.RB "(" sigrok\-devel@lists.souceforge.net ")." >X.SH "LICENSE" >XThis program is covered by the GNU General Public License (GPL), >Xversion 3 or later. >X.SH "AUTHORS" >XPlease see the individual source code files. >e68eba8e6fe272b583a51a3696d35072 >exit
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 188808
:
141896
|
145280
|
145281