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 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)