def _parse_linker_cmd(linker_cmd): linker_name = linker_cmd[0] linker_args = linker_cmd[1:] linker_type = get_linker_name(linker_cmd, linker_name) scripts = get_script_names(linker_cmd) object_files = remove_arguments(linker_args) return linker_name, linker_args, linker_type, scripts, object_files
def test_arguments(self): iter = 0 for args in test_args: expected_output = args[1] script = adorn_arguments.get_script_names(args[0]) name = adorn_arguments.get_linker_name(args[0], "") ret = (name, script) self.assertEquals(ret, expected_output)
def hacky_link_cmd(args): """ Link an ELF using either elfweaver or elfadorn. """ print "********" print "WARNING: elfweaver hacky_link is for internal debugging and testing purposes only." print "********" print # We should be able ot use 'elfadorn ld' as a drop-in replacement for 'ld' # Here we detect if this is the case, and patch the command line args # appropriately. This way we avoid maintainig two different methods of # dealing with args if "--" not in args: args.insert(1, "--") parser = optparse.OptionParser("%prog [options] -- <linker> [linker_options]", add_help_option=0) parser.add_option("-H", "--help", action="help") parser.add_option("-o", "--output", dest="target", metavar="FILE", help="Linker will create FILE.") parser.add_option("-f", "--file-segment-list", dest="file_segment_list", metavar="FILE", help="File containing segment names to be added to \ .segment_names, one per line") parser.add_option("-c", "--cmd-segment-list", dest="cmd_segment_list", help="quoted list of comma separated segment names to \ be added to .segment_names,") parser.add_option("-s", "--create-segments", dest="create_segments", action="store_true", help="Set to enable gathering orphaned sections and \ placing each in a new segment") (options, args) = parser.parse_args(args) create_segments = options.create_segments file_segment_list = options.file_segment_list cmd_segment_list = options.cmd_segment_list if cmd_segment_list: cmd_segment_list = cmd_segment_list.split(r',') target = options.target scripts = get_script_names(args) # If there are any scripts let elfadorn handle it if len(scripts) != 0 or args[0].lower().find('rvds') != -1: run_adorn(args, target, create_segments, file_segment_list, cmd_segment_list) return # Okay, now we want elfweaver to link things # First, run the linker command after inserting an -r into the commands args.insert(1, '-r') if subprocess.Popen(args).wait() != 0: sys.exit(1) # Construct the link command's arguments target = args[args.index('-o') + 1] text_loc = None data_loc = None # Because apparantly one can use both -Ttext addr and -Ttext=addr as valid # syntax. Blarg. if '-Ttext' in args: text_loc = args[args.index('-Ttext') + 1] if '-Tdata' in args: data_loc = args[args.index('-Tdata') + 1] for arg in args: if len(arg) == 6: continue if arg.find('-Ttext') == 0: text_loc = arg.split('=')[1] if arg.find('-Tdata') == 0: data_loc = arg.split('=')[1] link_args = ['-o', target, target] if text_loc != None: link_args.append('-Ttext') link_args.append(text_loc) if data_loc != None: link_args.append('-Tdata') link_args.append(data_loc) link_cmd(link_args)
def hacky_link_cmd(args): """ Link an ELF using either elfweaver or elfadorn. """ print "********" print "WARNING: elfweaver hacky_link is for internal debugging and testing purposes only." print "********" print # We should be able ot use 'elfadorn ld' as a drop-in replacement for 'ld' # Here we detect if this is the case, and patch the command line args # appropriately. This way we avoid maintainig two different methods of # dealing with args if "--" not in args: args.insert(1, "--") parser = optparse.OptionParser("%prog [options] -- <linker> [linker_options]", add_help_option=0) parser.add_option("-H", "--help", action="help") parser.add_option("-o", "--output", dest="target", metavar="FILE", help="Linker will create FILE.") parser.add_option( "-f", "--file-segment-list", dest="file_segment_list", metavar="FILE", help="File containing segment names to be added to \ .segment_names, one per line", ) parser.add_option( "-c", "--cmd-segment-list", dest="cmd_segment_list", help="quoted list of comma separated segment names to \ be added to .segment_names,", ) parser.add_option( "-s", "--create-segments", dest="create_segments", action="store_true", help="Set to enable gathering orphaned sections and \ placing each in a new segment", ) (options, args) = parser.parse_args(args) create_segments = options.create_segments file_segment_list = options.file_segment_list cmd_segment_list = options.cmd_segment_list if cmd_segment_list: cmd_segment_list = cmd_segment_list.split(r",") target = options.target scripts = get_script_names(args) # If there are any scripts let elfadorn handle it if len(scripts) != 0 or args[0].lower().find("rvds") != -1: run_adorn(args, target, create_segments, file_segment_list, cmd_segment_list) return # Okay, now we want elfweaver to link things # First, run the linker command after inserting an -r into the commands args.insert(1, "-r") if subprocess.Popen(args).wait() != 0: sys.exit(1) # Construct the link command's arguments target = args[args.index("-o") + 1] text_loc = None data_loc = None # Because apparantly one can use both -Ttext addr and -Ttext=addr as valid # syntax. Blarg. if "-Ttext" in args: text_loc = args[args.index("-Ttext") + 1] if "-Tdata" in args: data_loc = args[args.index("-Tdata") + 1] for arg in args: if len(arg) == 6: continue if arg.find("-Ttext") == 0: text_loc = arg.split("=")[1] if arg.find("-Tdata") == 0: data_loc = arg.split("=")[1] link_args = ["-o", target, target] if text_loc != None: link_args.append("-Ttext") link_args.append(text_loc) if data_loc != None: link_args.append("-Tdata") link_args.append(data_loc) link_cmd(link_args)
def main(args): """Main program entry point.""" # We should be able ot use 'elfadorn ld' as a drop-in replacement for 'ld' # Here we detect if this is the case, and patch the command line args appropriately. # This way we avoid maintainid two different methods of dealing with args if "--" not in args: args = [args[0] , "--"] + args[1:] parser = optparse.OptionParser("%prog [options] -- <linker> [linker_options]", add_help_option=0) parser.add_option("-H", "--help", action="help") parser.add_option("-o", "--output", dest="target", metavar="FILE", help="Linker will create FILE.") parser.add_option("-f", "--file-segment-list", dest="file_segment_list", metavar="FILE", help="File containing segment names to be added to .segment_names, \ one per line") parser.add_option("-c", "--cmd-segment-list", dest="cmd_segment_list", help="quoted list of comma separated segment names to be added to .segment_names,") parser.add_option("-s", "--create-segments", dest="create_segments", action="store_true", help="Set to enable gathering orphaned sections and placing each in a new segment") (options, args) = parser.parse_args(args) if not options.target: i = 0 for a in args: if a == "-o": options.target = args[i+1] break i = i + 1 if not options.target: print "Error: -o flag must be supplied." sys.exit(1) # we need to parse the options # we are interested in any -T, --scatter or --script= options # plus the ordinary files specified on the command line scripts = get_script_names(args) objects = remove_arguments(args) linker_name = objects[1] objects = objects[2:] linker_type = get_linker_name(args, linker_name) if linker_type == "rvct": if options.create_segments: print "Warning: creating segments from sections not applicable to RVCT. Disabling option." options.create_segments = False # next get section names (sections, additional_scripts) = get_section_names(objects) scripts = scripts + additional_scripts # then get the text of the linker script script_text = get_linker_script_text(linker_name, scripts, additional_scripts, []) if options.create_segments: # get rid of any sections named in the script_text mentioned_sections = linker_script_sections(script_text) orphaned_sections = sections for section in mentioned_sections: # Our grammar is not perfect, sometimes it gets confused and gives back * # as a section but it is actually a filename if section != "*": remove_sections_wildcard(orphaned_sections, section) # mips-ld treats .reginfo sections somewhat magically, we do not want to treat this # as an orphan and create a segment for him, else ld will drop the text data and bss # sections completely. Magic. if '.reginfo' in orphaned_sections: orphaned_sections.remove('.reginfo') # work out the new linker command line if scripts == []: default = get_linker_script_text(args[1], [], [], args[2:]) open("default.lds", "w").write(default) if len(orphaned_sections) != 0: args += ["--script=default.lds"] # write out an additional linker script file to pass to the linker if len(orphaned_sections) != 0: write_linker_script(orphaned_sections, "additional.lds") additional_scripts.append("additional.lds") args += ["--script=additional.lds"] else: # if we dont care about these, just say there are none. orphaned_sections = [] # execute the linker if os.spawnvp(os.P_WAIT, args[1], args[1:]) != 0: sys.exit(1) # load the elf file elf = UnpreparedElfFile(filename=options.target) wordsize = elf.wordsize endianess = elf.endianess seglist = get_segment_names(options, elf, scripts, linker_type, orphaned_sections) # create the string table segname_tab = UnpreparedElfStringTable(".segment_names") # add the segment names for segname in seglist: segname = segname.strip() segname_tab.add_string("%s" % segname) # add the table to the file elf.add_section(segname_tab) elf = elf.prepare(wordsize, endianess) # write the file elf.to_filename(options.target)
def main(args): """Main program entry point.""" # We should be able ot use 'elfadorn ld' as a drop-in replacement for 'ld' # Here we detect if this is the case, and patch the command line args appropriately. # This way we avoid maintainid two different methods of dealing with args if "--" not in args: args = [args[0], "--"] + args[1:] parser = optparse.OptionParser( "%prog [options] -- <linker> [linker_options]", add_help_option=0) parser.add_option("-H", "--help", action="help") parser.add_option("-o", "--output", dest="target", metavar="FILE", help="Linker will create FILE.") parser.add_option( "-f", "--file-segment-list", dest="file_segment_list", metavar="FILE", help="File containing segment names to be added to .segment_names, \ one per line") parser.add_option( "-c", "--cmd-segment-list", dest="cmd_segment_list", help= "quoted list of comma separated segment names to be added to .segment_names," ) parser.add_option( "-s", "--create-segments", dest="create_segments", action="store_true", help= "Set to enable gathering orphaned sections and placing each in a new segment" ) (options, args) = parser.parse_args(args) if not options.target: i = 0 for a in args: if a == "-o": options.target = args[i + 1] break i = i + 1 if not options.target: print "Error: -o flag must be supplied." sys.exit(1) # we need to parse the options # we are interested in any -T, --scatter or --script= options # plus the ordinary files specified on the command line scripts = get_script_names(args) objects = remove_arguments(args) linker_name = objects[1] objects = objects[2:] linker_type = get_linker_name(args, linker_name) if linker_type == "rvct": if options.create_segments: print "Warning: creating segments from sections not applicable to RVCT. Disabling option." options.create_segments = False # next get section names (sections, additional_scripts) = get_section_names(objects) scripts = scripts + additional_scripts # then get the text of the linker script script_text = get_linker_script_text(linker_name, scripts, additional_scripts, []) if options.create_segments: # get rid of any sections named in the script_text mentioned_sections = linker_script_sections(script_text) orphaned_sections = sections for section in mentioned_sections: # Our grammar is not perfect, sometimes it gets confused and gives back * # as a section but it is actually a filename if section != "*": remove_sections_wildcard(orphaned_sections, section) # mips-ld treats .reginfo sections somewhat magically, we do not want to treat this # as an orphan and create a segment for him, else ld will drop the text data and bss # sections completely. Magic. if '.reginfo' in orphaned_sections: orphaned_sections.remove('.reginfo') # work out the new linker command line if scripts == []: default = get_linker_script_text(args[1], [], [], args[2:]) open("default.lds", "w").write(default) if len(orphaned_sections) != 0: args += ["--script=default.lds"] # write out an additional linker script file to pass to the linker if len(orphaned_sections) != 0: write_linker_script(orphaned_sections, "additional.lds") additional_scripts.append("additional.lds") args += ["--script=additional.lds"] else: # if we dont care about these, just say there are none. orphaned_sections = [] # execute the linker if os.spawnvp(os.P_WAIT, args[1], args[1:]) != 0: sys.exit(1) # load the elf file elf = UnpreparedElfFile(filename=options.target) wordsize = elf.wordsize endianess = elf.endianess seglist = get_segment_names(options, elf, scripts, linker_type, orphaned_sections) # create the string table segname_tab = UnpreparedElfStringTable(".segment_names") # add the segment names for segname in seglist: segname = segname.strip() segname_tab.add_string("%s" % segname) # add the table to the file elf.add_section(segname_tab) elf = elf.prepare(wordsize, endianess) # write the file elf.to_filename(options.target)