📄 rlink.py
字号:
#!/usr/bin/env python# -*- Mode: Python -*-# # ***** BEGIN LICENSE BLOCK *****# Source last modified: $Id: rlink.py,v 1.5 2004/07/07 22:00:03 hubbe Exp $# # Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.# # The contents of this file, and the files included with this file,# are subject to the current version of the RealNetworks Public# Source License (the "RPSL") available at# http://www.helixcommunity.org/content/rpsl unless you have licensed# the file under the current version of the RealNetworks Community# Source License (the "RCSL") available at# http://www.helixcommunity.org/content/rcsl, in which case the RCSL# will apply. You may also obtain the license terms directly from# RealNetworks. You may not use this file except in compliance with# the RPSL or, if you have a valid RCSL with RealNetworks applicable# to this file, the RCSL. Please see the applicable RPSL or RCSL for# the rights, obligations and limitations governing use of the# contents of the file.# # Alternatively, the contents of this file may be used under the# terms of the GNU General Public License Version 2 or later (the# "GPL") in which case the provisions of the GPL are applicable# instead of those above. If you wish to allow use of your version of# this file only under the terms of the GPL, and not to allow others# to use your version of this file under the terms of either the RPSL# or RCSL, indicate your decision by deleting the provisions above# and replace them with the notice and other provisions required by# the GPL. If you do not delete the provisions above, a recipient may# use your version of this file under the terms of any one of the# RPSL, the RCSL or the GPL.# # This file is part of the Helix DNA Technology. RealNetworks is the# developer of the Original Code and owns the copyrights in the# portions it created.# # This file, and the files included with this file, is distributed# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET# ENJOYMENT OR NON-INFRINGEMENT.# # Technology Compatibility Kit Test Suite(s) Location:# http://www.helixcommunity.org/content/tck# # Contributor(s):# # ***** END LICENSE BLOCK *****##### What it does:## Rlink emulates the broken --gc-sections ld option and allows## for some fairly significant code size reductions by eliminating## any functions you don't actually use from the final binary.## You will need to give the flags -ffunction-sections and## -fdata-sections for this to have any noticable effect.#### How it works:## To achive this, rlink runs objdump on all object files (even## those embedded in archives). From the objdump output, information## about relocations, symbols and sections is extracted and used to## find out which sections aren't needed. It then proceeds to use## objcopy to remove those sections.#### Control & Debugging## There are two environment variables which can be used to control## Rlink's behaviour:## RLINK_DEBUG: if this is set, rlink will print *lots* of debug## RLINK_DISABLE: if this is set, rlink will do nothing #### TODO## Make rlink still perform library merging when RLINK_DISABLE is on## so that it can replace armerge.#### -Hubbe##import osimport sysimport stringimport reimport typesimport stat## add Python import pathsbuild_root = os.environ['BUILD_ROOT']sys.path.insert(0, os.path.join(build_root, 'lib'))sys.path.insert(0, os.path.join(build_root, 'umake'))import shellglobal_symbols={}all_objects=[]output_name = "a.out"if os.environ.get("RLINK_DEBUG"): def debug(s,*args): print s % argselse: def debug(*args): pass if os.name == "posix": maxcmdlen=100000 ## FIXME def quote(s): if re.match("^[-a-zA-Z0-9./_=]+$", s): return s return '"' + s + '"'else: maxcmdlen=4000 def quote(s): if re.match("^[-a-zA-Z0-9./_=$\\\\]+$", s): return s return '"' + s + '"'def run(cmd): debug("rlink, running: %s" % cmd) (e, out) = shell.run(cmd) if string.strip(out) != "": print out if e: print "Cmd '%s' failed with error code %d" % (cmd, e) sys.exit(1) def run2(args): run(string.join(map(quote,args)))class Section: def __init__(self, name, o=None): self.mark=0 self.name=name self.relocs=[] ## list of symbol names self.object=oclass Symbol: def __init__(self, name): self.done=0 self.name=name self.sections=[] ## List of all sections where this is definedclass Object: def __init__(self, name): debug("rlink, parsing %s",name) self.name=name self.sections=[] self.sections_byname={} self.symbols={} self.parse() def translate(self, to): debug("rlink, translating %s => %s", self.name, to) cnt=1 cmd="objcopy" from_to=' %s %s' % (quote(self.name),quote(to)) mlen=maxcmdlen - len(from_to) for x in self.sections: if not x.mark: ncmd=cmd+' %s' % quote("-R"+x.name) if len(ncmd) >= mlen: tmp='%s.%d.o' % (to, cnt) cnt = cnt+1 run('%s %s' % (cmd, from_to)) ncmd='objcopy %s' % quote("-R"+x.name) from_to=' %s' % (quote(to)) mlen=maxcmdlen - len(from_to) cmd=ncmd run('%s %s' % (cmd, from_to)) if not os.path.exists(to): print "Translation of %s failed" % self.name sys.exit(1) def parse(self): data=os.popen('objdump -w -h -r -t %s' % quote(self.name), "r").read() data=string.replace(data,"\r\n","\n") secstart=string.find(data,"\nIdx") secstart=string.find(data,"\n",secstart+1)+1 secend=string.find(data,"\nSYMBOL TABLE:",secstart) symstart=string.find(data,"\n",secend+1)+1 symend=string.find(data,"\nRELOCATION RECORDS FOR") self.read_sections(data[secstart:secend]) self.read_symbols(data[symstart:symend]) self.read_relocs(data[symend:]) def read_sections(self, data): for l in string.split(data,"\n"): #debug("read_sections: %s", l) w=string.split(l) s=Section(w[1], self) self.sections.append(s) self.sections_byname[w[1]]=s def read_symbols(self, data): for l in string.split(data,"\n"): debug("read_symbols2: %s", l) w=string.split(l) if len(w) < 2: continue sec=None symname=None status=None if l[0] == '[': # PE STYLE sec_num=string.split(l,"(sec")[1] sec_num=string.split(sec_num,")")[0] sec_num=int(sec_num) scl=string.split(l,"(scl")[1] scl=string.split(scl,")")[0] scl=int(scl) # C_EXT, C_WEAKEXT, C_THUMBEXT, C_THUMBEXTFUNC, # C_HIDEXT, C_SYSTEM if scl in [ 2, 127, 130, 150, 107, 23 ]: status="global" # C_STAT, C_LEAFSTAT, C_LABEL # C_THUMBSTAT, C_THUMBLABEL, C_THUMBSTATFUNC if scl == [ 3, 6, 113, 131, 134, 151]: status = "local" symname=string.split(l,")")[-1] symname=string.split(symname)[-1] if sec_num: sec=self.sections[sec_num-1] else: status="undefined" else: # ELF style tmp=string.split(l[17:]) sec_name=tmp[0] sec=self.sections_byname.get(sec_name) if len(tmp) >= 3: symname=tmp[2] else: symname=sec_name if l[9] == 'l': status="local" if l[9] == 'g': status="global" if sec_name == "*UND*": status="undefined" if symname and ' ' in symname: print "BOGUS SYMBOL NAME: %s" % repr(symname) sys.exit(3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -