Example #1
0
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)
Example #2
0
def run_adorn(linker_cmd,
              target=None,
              create_segments=False,
              file_segment_list=None,
              cmd_segment_list=None):
    """
    The programming interface to elf adorn.

    linker_cmd: A list of strings representing the linker command to be executed
    target: A target file into which to place the final output. If not
            specified, a "-o" option is expected in the linker_cmd
    create_segment: A boolean indicating whether orphaned sections should be
                    gathered and each placed in a new segment
    file_segment_list: The filename of a file containing segment names to be
                       added to .segment_names. (Mutually exclusive with
                       cmd_segment_list, this takes precedence if both given)
    cmd_segment_list: A list of segment names to be added to .segment_names.
                      (Mutually exclusive with file_segment_names)
    """

    (linker_name, linker_args, linker_type, scripts,
     object_files) = _parse_linker_cmd(linker_cmd)
    target = _get_target(target, linker_args)

    if linker_type == "rvct":
        if create_segments:
            print "Warning: creating segments from sections not applicable " \
                  "to RVCT. Disabling option."
        create_segments = False

    # segments specifed in a file
    if file_segment_list:
        segfile = open(file_segment_list, 'r')
        seglist = segfile.readlines()
    # segments specified on command line
    elif cmd_segment_list:
        seglist = cmd_segment_list
    else:
        seglist = None

    # next get section names
    (sections, additional_scripts) = get_section_names(object_files)
    scripts += additional_scripts

    # then get the text of the linker script
    # FIXME: why no linker args?
    script_text = get_linker_script_text(linker_name, scripts,
                                         additional_scripts, [])

    if 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(linker_name, [], [], linker_args)
            open("default.lds", "w").write(default)
            scripts.append("default.lds")
            if len(orphaned_sections) != 0:
                linker_cmd += ["--script=default.lds"]

        # write out an additional linker script file to pass to the linker
        if orphaned_sections:
            write_linker_script(orphaned_sections, "additional.lds")
            scripts.append("additional.lds")
            linker_cmd += ["--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, linker_name, linker_cmd) != 0:
        sys.exit(1)

    _update_elf_file(target, seglist, scripts, linker_type, orphaned_sections)
Example #3
0
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)
Example #4
0
File: main.py Project: BruceYi/okl4
def run_adorn(linker_cmd, target=None, create_segments=False,
              file_segment_list=None, cmd_segment_list=None):
    """
    The programming interface to elf adorn.

    linker_cmd: A list of strings representing the linker command to be executed
    target: A target file into which to place the final output. If not
            specified, a "-o" option is expected in the linker_cmd
    create_segment: A boolean indicating whether orphaned sections should be
                    gathered and each placed in a new segment
    file_segment_list: The filename of a file containing segment names to be
                       added to .segment_names. (Mutually exclusive with
                       cmd_segment_list, this takes precedence if both given)
    cmd_segment_list: A list of segment names to be added to .segment_names.
                      (Mutually exclusive with file_segment_names)
    """
    
    (linker_name, linker_args,
     linker_type, scripts, object_files) = _parse_linker_cmd(linker_cmd)
    target = _get_target(target, linker_args)

    if linker_type == "rvct":
        if create_segments:
            print "Warning: creating segments from sections not applicable " \
                  "to RVCT. Disabling option."
        create_segments = False

    # segments specifed in a file
    if file_segment_list:
        segfile = open(file_segment_list, 'r')
        seglist = segfile.readlines()
    # segments specified on command line
    elif cmd_segment_list:
        seglist = cmd_segment_list
    else:
        seglist = None

    # next get section names
    (sections, additional_scripts) = get_section_names(object_files)
    scripts += additional_scripts

    # then get the text of the linker script
    # FIXME: why no linker args?
    script_text = get_linker_script_text(linker_name, scripts,
                                         additional_scripts, [])

    if 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(linker_name, [], [], linker_args)
            open("default.lds", "w").write(default)
            scripts.append("default.lds")
            if len(orphaned_sections) != 0:
                linker_cmd += ["--script=default.lds"]

        # write out an additional linker script file to pass to the linker
        if orphaned_sections:
            write_linker_script(orphaned_sections, "additional.lds")
            scripts.append("additional.lds")
            linker_cmd += ["--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, linker_name, linker_cmd) != 0:
        sys.exit(1)

    _update_elf_file(target, seglist, scripts, linker_type, orphaned_sections)