def link_kernel(kernel_el, linker_script, linker_wrapper, kernel, soc, libraries): link_type = get_linker_type(linker_script) kernel_tmp = None if link_type == 'rvct': # Current elfweaver linker does not support RVCT so shell out to an # external linker kernel_tmp = tempfile.NamedTemporaryFile() # Remove the file at exit. atexit.register(os.remove, kernel_tmp.name) command = [ os.path.abspath(linker_wrapper), kernel, kernel_tmp.name, linker_script, soc ] + libraries ret = subprocess.Popen(command, cwd=os.path.dirname(linker_script)).wait() if ret != 0: raise MergeError("Failed to link kernel, return code %d" % ret) elf = UnpreparedElfFile(kernel_tmp.name) kernel_out_name = kernel_tmp.name else: elf = link([kernel, soc]) # Just getting a random temp file name, there must be a nicer way # to do this? tmp = tempfile.NamedTemporaryFile() # Remove the file at exit. atexit.register(os.remove, tmp.name) kernel_out_name = tmp.name tmp.close() kernel_out = elf.prepare(elf.wordsize, elf.endianess) kernel_out.to_filename(kernel_out_name) elf = UnpreparedElfFile(kernel_out_name) # Kernel is linked, now add the segment names (as per old elfadorn) # Kernel elements seg_names overwrites defaults if hasattr(kernel_el, "seg_names"): seglist = [seg.strip() for seg in kernel_el.seg_names.split(",")] else: seglist = None link_type = get_linker_type(linker_script) if link_type == "rvct": scripts = [linker_script] else: scripts = [] add_segment_names(elf, get_segment_names(elf, seglist, scripts, link_type)) return elf, kernel_out_name, kernel_tmp
def link_kernel(kernel_el, linker_script, linker_wrapper, kernel, soc, libraries): link_type = get_linker_type(linker_script) kernel_tmp = None if link_type == 'rvct': # Current elfweaver linker does not support RVCT so shell out to an # external linker kernel_tmp = tempfile.NamedTemporaryFile() # Remove the file at exit. atexit.register(os.remove, kernel_tmp.name) command = [os.path.abspath(linker_wrapper), kernel, kernel_tmp.name, linker_script, soc] + libraries ret = subprocess.Popen(command, cwd = os.path.dirname(linker_script)).wait() if ret != 0: raise MergeError("Failed to link kernel, return code %d" % ret) elf = UnpreparedElfFile(kernel_tmp.name) kernel_out_name = kernel_tmp.name else: elf = link([kernel, soc]) # Just getting a random temp file name, there must be a nicer way # to do this? tmp = tempfile.NamedTemporaryFile() # Remove the file at exit. atexit.register(os.remove, tmp.name) kernel_out_name = tmp.name tmp.close() kernel_out = elf.prepare(elf.wordsize, elf.endianess) kernel_out.to_filename(kernel_out_name) elf = UnpreparedElfFile(kernel_out_name) # Kernel is linked, now add the segment names (as per old elfadorn) # Kernel elements seg_names overwrites defaults if hasattr(kernel_el, "seg_names"): seglist = [seg.strip() for seg in kernel_el.seg_names.split(",")] else: seglist = None link_type = get_linker_type(linker_script) if link_type == "rvct": scripts = [linker_script] else: scripts = [] add_segment_names(elf, get_segment_names(elf, seglist, scripts, link_type)) return elf, kernel_out_name, kernel_tmp
def _update_elf_file(target, seglist, scripts, linker_type, orphaned_sections): # load the elf file elf = UnpreparedElfFile(filename=target) if elf.elf_type != ET_EXEC: return seglist = get_segment_names(elf, seglist, scripts, linker_type, orphaned_sections) add_segment_names(elf, seglist) elf = elf.prepare(elf.wordsize, elf.endianess) # write the file elf.to_filename(target)
def elf_segment_names(elf): """Return a hash of elf segment names, indexed by segment number.""" table = {} seg_names_sect = elf.find_section_named(".segment_names") if seg_names_sect is not None: names = seg_names_sect.get_strings()[1:] else: names = get_segment_names(elf) for i in range(len(names)): table[i] = names[i] return table
def link_cmd(args): """ Link a relocatable ELF """ # Link command shouldn't be run by end users! print >> sys.stderr, "********" print >> sys.stderr, "WARNING: elfweaver link is for internal debugging " \ "and testing purposes only." print >> sys.stderr, "********" print parser = OptionParser("%prog link [options] <file1.o> [<file2.o>, ...]", add_help_option=0) parser.add_option("-H", "--help", action="help") parser.add_option("-o", "--output", dest="output_file", metavar="FILE", help="Destination filename") parser.add_option("--section-start", action="callback", nargs=1, type="string", dest="section_vaddr", callback=parse_options, metavar="SECT_NAME=SECT_ADDR", help="Specify the virtual address of a given section") parser.add_option("-T", action="callback", nargs=1, type="string", dest="section_vaddr", callback=parse_options, metavar="(bss|data|text) SECT_ADDR", help="Specify the virtaul address of the bss, data or" "text sections") parser.add_option("--kernel-soc", action="store_true", default=False, dest="kernel_soc", help="Specify that we are linking the kerenl and soc") parser.add_option("--rvct", action="store_true", default=False, dest="rvct", help="Use rvct specific linker script") parser.add_option("-v", "--verbose", action="store_true", default=False, dest="verbose", help="Print out processing messages") parser.add_option("--verbose-merge", action="store_true", default=False, dest="verbose_merge", help="Print out very detailed merging information") parser.add_option("--verbose-script", action="store_true", default=False, dest="verbose_script", help="Print out linker script handling information") parser.add_option("--verbose-relocs", action="store_true", default=False, dest="verbose_relocs", help="Print out all reloc info") (options, args) = parser.parse_args(args) if len(args) < 1: parser.error("Invalid number of arguments") if options.output_file == None: parser.error("Must specify output file") elf = link(args, options.section_vaddr, options.kernel_soc, options.rvct, options.verbose, options.verbose_merge, options.verbose_script, options.verbose_relocs) if options.verbose: print "Adding default segnames" seglist = get_segment_names(elf, None, [], 'gcc') add_segment_names(elf, seglist) if options.verbose: print "Writing out file" out_file = elf.prepare(elf.wordsize, elf.endianess) out_file.to_filename(options.output_file) os.chmod(options.output_file, 0750) if options.verbose: print "Done"