Example #1
0
def collect_zone_element(zone_el, ignore_name, namespace, pools,
                         image, bootinfo, machine):
    """Collect the contents of a zone."""
    non_zone_ms = []
    env = weaver.bootinfo.Environment(namespace)

    # New namespace for objects living in the memsection.
    zone_namespace = namespace.add_namespace(zone_el.name)

    virtpool = getattr(zone_el, 'virtpool', None)
    physpool = getattr(zone_el, 'physpool', None)

    attrs = image.new_attrs(zone_namespace)
    attrs.name = zone_el.name

    zone = weaver.bootinfo.Zone(attrs, pools, image, machine)

    bootinfo.add_zone(zone)

    # Push the overriding attributes for the zone.
    image.push_attrs(virtual  = zone_el.name,
                     physical = physpool)

    master = weaver.bootinfo.Cap("master", ["master"])
    zone.add_cap(master)
    zone_namespace.add(master.get_name(), master)

    for ms_el in zone_el.find_children('memsection'):
        if not ignore_name.match(ms_el.name):
            ms = collect_memsection_element(ms_el, ignore_name,
                                            zone_namespace, image,
                                            machine, pools)

            # Memsections that aren't allocated in the zone belong to the PD.
            if ms.get_attrs().virtpool == zone_el.name:
                zone.add_memsection(ms)
                image.add_group(None, [ms.get_ms()])
            else:
                non_zone_ms.append(ms)

    # All of the segments have already been processed by the program/pd, but
    # record the ones probably should belong to the zone.  These will be added
    # to the zone by PD.add_zone()
    segment_els = zone_el.find_children("segment")
    zone.set_claimed_segments([segment_el.name for segment_el in segment_els])

    image.pop_attrs()

    return (zone, non_zone_ms)
Example #2
0
def collect_pd_element(pd_el, ignore_name, namespace, image, machine,
                       bootinfo, pools):
    """Collect the attributes of a PD element."""

    # New namespace for objects living in the PD.
    pd_namespace = namespace.add_namespace(pd_el.name)

    pd = weaver.bootinfo.PD(pd_el.name, pd_namespace, image, machine, pools)
    virtpool = getattr(pd_el, 'virtpool', None)
    physpool = getattr(pd_el, 'physpool', None)
    direct = getattr(pd_el, 'direct', None)
    pd.set_platform_control(getattr(pd_el, "platform_control", False))

    if hasattr(pd_el, 'pager'):
        pager = make_pager_attr(pd_el.pager)
    else:
        pager = None

    # Push the overriding attributes for the pd.
    image.push_attrs(virtual  = virtpool,
                     physical = physpool,
                     pager    = pager,
                     direct   = direct)

    pd.set_default_pools(image, bootinfo)

    # Collect the object environment
    env = collect_environment_element(pd_el.find_child('environment'),
                                      pd_namespace, machine, pools,
                                      image, bootinfo)

    if hasattr(pd_el, "file"):
        elf = PreparedElfFile(filename=pd_el.file)

        if elf.elf_type != ET_EXEC:
            raise MergeError, "All the merged ELF files must be of EXEC type."

        segment_els = pd_el.find_all_children("segment")
        segs = collect_elf_segments(elf,
                                    image.PROGRAM,
                                    segment_els,
                                    pd_el.name,
                                    pd_namespace,
                                    image,
                                    machine,
                                    pools)

        segs_ms = [bootinfo.record_segment_info(pd_el.name, seg,
                                                image, machine, pools)
                   for seg in segs]
        for seg_ms in segs_ms:
            pd.attach_memsection(seg_ms)

        # Record any patches being made to the program.
        patch_els   = pd_el.find_children("patch")
        collect_patches(elf, patch_els, image)

    # Collect threads in the PD.
    for thread_el in pd_el.find_children('thread'):
        if not ignore_name.match(thread_el.name):
            thread = collect_thread(elf, thread_el, ignore_name,
                                    pd_namespace, image, machine, pools,
                                    entry = "_thread_start")
            pd.add_thread(thread)

            # Record the thread and its stack in the environment.
            env.add_entry(key      = thread.get_name(),
                          cap_name = thread.get_name() + '/master')
            env.add_entry(key      = thread.get_name() + "/STACK",
                          cap_name = thread.get_name() + '/stack/master',
                          attach   = thread.get_stack().get_attrs().attach)

    # Collect memsections in the PD.
    for ms_el in pd_el.find_children('memsection'):
        if not ignore_name.match(ms_el.name):
            ms = collect_memsection_element(ms_el, ignore_name,
                                            pd_namespace, image,
                                            machine, pools)
            pd.attach_memsection(ms)

            image.add_group(0, [ms.get_ms()])

            env.add_entry(key      = ms.get_name(),
                          cap_name = ms.get_name() + '/master',
                          attach   = ms.get_attrs().attach)

    # Collect any zones in the program.
    for zone_el in pd_el.find_children('zone'):
        (zone, non_zone_ms) = \
               collect_zone_element(zone_el, ignore_name,
                                    pd_namespace, pools, image,
                                    bootinfo, machine)

        pd.attach_zone(zone)

        # Attach zones that aren't part of the zone to the program.
        for ms in non_zone_ms:
            pd.attach_memsection(ms)

            image.add_group(0, [ms.get_ms()])

            env.add_entry(key      = ms.get_name(),
                          cap_name = ms.get_name() + '/master',
                          attach   = ms.get_attrs().attach)

    pd.add_environment(env)

    bootinfo.add_pd(pd)
    image.pop_attrs()
Example #3
0
def collect_program_element(program_el, ignore_name, namespace, image,
                            machine, bootinfo, pools):
    """Collect the attributes of a program element."""

    # New namespace for objects living in the program's PD.
    prog_namespace = namespace.add_namespace(program_el.name)

    pd = weaver.bootinfo.PD(program_el.name, prog_namespace, image,
                            machine, pools)

    elf = UnpreparedElfFile(filename=program_el.file)

    if elf.elf_type != ET_EXEC:
        raise MergeError, "All the merged ELF files must be of EXEC type."

    bootinfo.add_elf_info(name = program_el.file,
                          elf_type = image.PROGRAM,
                          entry_point = elf.entry_point)

    pd.elf = elf

    virtpool = getattr(program_el, 'virtpool', None)
    physpool = getattr(program_el, 'physpool', None)
    direct = getattr(program_el, 'direct', None)
    pd.set_platform_control(getattr(program_el, "platform_control", False))

    if hasattr(program_el, 'pager'):
        pager = make_pager_attr(program_el.pager)
    else:
        pager = None

    # Push the overriding attributes for the program.
    image.push_attrs(virtual  = virtpool,
                     physical = physpool,
                     pager    = pager,
                     direct   = direct)

    pd.set_default_pools(image, bootinfo)

    # Collect the object environment
    env = collect_environment_element(program_el.find_child('environment'),
                                      prog_namespace, machine, pools,
                                      image, bootinfo)

    segment_els = program_el.find_all_children("segment")
    segs = collect_elf_segments(elf,
                                image.PROGRAM,
                                segment_els,
                                program_el.name,
                                prog_namespace,
                                image,
                                machine,
                                pools)

    segs_ms = [bootinfo.record_segment_info(program_el.name, seg,
                                            image, machine, pools)
               for seg in segs]
    for seg_ms in segs_ms:
        pd.attach_memsection(seg_ms)

    # Record any patches being made to the program.
    patch_els   = program_el.find_children("patch")
    collect_patches(elf, patch_els, program_el.file, image)

    # Collect the main thread.
    thread = collect_thread(elf, program_el, ignore_name, prog_namespace,
                            image, machine, pools,
                            entry = elf.entry_point,
                            name = program_el.name,
                            namespace_thread_name = "main")
    pd.add_thread(thread)
    pd.set_server_thread(thread)

    # Add the virtual device elements
    # Virtual devices always get added to the global namespace because they
    # should be globally unique
    server_spawn_nvdevs = 0
    dev_ns = namespace.root.get_namespace("dev")

    if dev_ns is None:
        raise MergeError, "Device namespace does not exist!"

    for v_el in program_el.find_children('virt_device'):
        virt_dev = pd.add_virt_dev(v_el.name, program_el.name, pd,
                                   thread, server_spawn_nvdevs)
        create_alias_cap(virt_dev, dev_ns)
        server_spawn_nvdevs += 1

    # Record the main thread and its stack in the environment.
    env.add_entry(key      = "MAIN",
                  cap_name = 'main/master')
    env.add_entry(key      = "MAIN/STACK",
                  cap_name = 'main/stack/master',
                  attach  = thread.get_stack().get_attrs().attach)


    # If marked, sure that the program is exported to every
    # environment so that it can be found by other programs.
    #
    if hasattr(program_el, 'server'):
        bootinfo.add_server(
            key = program_el.server,
            cap_name = prog_namespace.abs_name('main') + '/stack/master')

    # Collect remaining threads.
    elf = pd.elf = pd.elf.prepare(image.wordsize, image.endianess)

    for thread_el in program_el.find_children('thread'):
        if not ignore_name.match(thread_el.name):
            thread = collect_thread(elf, thread_el, ignore_name,
                                    prog_namespace, image, machine, pools,
                                    entry = "_thread_start")
            pd.add_thread(thread)

            # Record the thread and its stack in the environment.
            env.add_entry(key      = thread.get_name(),
                          cap_name = thread.get_name() + '/master')
            env.add_entry(key      = thread.get_name() + "/STACK",
                          cap_name = thread.get_name() + '/stack/master',
                          attach   = thread.get_stack().get_attrs().attach)

    # Collect any other memsections in the program.
    for ms_el in program_el.find_children('memsection'):
        if not ignore_name.match(ms_el.name):
            ms = collect_memsection_element(ms_el, ignore_name,
                                            prog_namespace, image,
                                            machine, pools)

            pd.attach_memsection(ms)
            image.add_group(0, [ms.get_ms()])

            env.add_entry(key      = ms.get_name(),
                          cap_name = ms.get_name() + '/master',
                          attach   = ms.get_attrs().attach)

    # Collect any zones in the program.
    for zone_el in program_el.find_children('zone'):
        (zone, non_zone_ms) = \
               collect_zone_element(zone_el, ignore_name,
                                    prog_namespace, pools, image,
                                    bootinfo, machine)

        pd.attach_zone(zone)

        # Attach memsections that aren't part of the zone to the program.
        for ms in non_zone_ms:
            pd.attach_memsection(ms)

            image.add_group(0, [ms.get_ms()])
            env.add_entry(key      = ms.get_name(),
                          cap_name = ms.get_name() + '/master',
                          attach   = ms.get_attrs().attach)

    # Collect the heap.  Is there no element, create a fake one for
    # the collection code to use.
    heap_el = program_el.find_child('heap')

    if heap_el is None:
        heap_el = ParsedElement('heap')

    heap_ms = collect_memsection_element(heap_el, ignore_name,
                                         prog_namespace, image,
                                         machine, pools)
    pd.attach_heap(heap_ms)
    image.add_group(0, [heap_ms.get_ms()])
    # Fill env with default values.
    env.add_entry(key      = "HEAP",
                  cap_name = 'heap/master',
                  attach   = heap_ms.get_attrs().attach)

    env.add_entry(key      = "HEAP_BASE",
                  base     = heap_ms)
    env.add_entry(key      = "HEAP_SIZE",
                  value    = heap_ms.get_attrs().size)

    pd.add_environment(env)

    bootinfo.add_pd(pd)

    image.pop_attrs()
Example #4
0
def collect_thread(elf, el, ignore_name, namespace, image, machine,
                   pools, entry, name = None,
                   namespace_thread_name = None):
    """Collect the attributes of a thread element."""
    if entry is None:
        raise MergeError, "No entry point specified for thread %s" % name

    # el can be a program element or a thread element.
    if name is None:
        name = el.name

    user_main = getattr(el, 'start', None)

    # HACK:  There is no easy way for a PD to specify the main thread,
    # so is the user entry point is '_start' (the traditional entry
    # point symbol), then start there rather then the thread entry
    # point.
    if user_main == "_start":
        start = "_start"
        user_main = None

    entry = start_to_value(entry, elf)
    user_main = start_to_value(user_main, elf)

    priority = getattr(el, 'priority', None)
    physpool = getattr(el, 'physpool', None)
    virtpool = getattr(el, 'virtpool', None)

    # New namespace for objects living in the thread.
    if namespace_thread_name is None:
        namespace_thread_name = name
    new_namespace = namespace.add_namespace(namespace_thread_name)

    # Push the overriding pools for the thread.
    image.push_attrs(virtual = virtpool,
                     physical = physpool)

    # Create the thread desription object.
    thread = weaver.bootinfo.Thread(name, entry, user_main, priority)

    # Add the standard caps for the thread.
    create_standard_caps(thread, new_namespace)

    # Collect the stack.  Is there no element, create a fake one for
    # the collection code to use.
    stack_el = el.find_child('stack')

    if stack_el is None:
        stack_el = ParsedElement('stack')

    stack_ms = collect_memsection_element(stack_el, ignore_name,
                                          new_namespace, image,
                                          machine, pools)
    thread.attach_stack(stack_ms)
    image.add_group(0, [stack_ms.get_ms()])

    # Collect any command line arguments.
    commandline_el = el.find_child('commandline')

    if commandline_el is not None:
        for arg_el in commandline_el.find_children("arg"):
            thread.add_argv(arg_el.value)

    image.pop_attrs()

    return thread
Example #5
0
def collect_rootprogram_element(parsed, ignore_name, namespace, image, machine, bootinfo, pools):
    """Handle an Iguana Server Compound Object"""

    # Find the tag
    root_program_el = parsed.find_child("rootprogram")

    assert(root_program_el is not None)

    # New namespace for objects living in the root program's PD.
    rp_namespace = namespace.add_namespace('rootprogram')

    pd = weaver.bootinfo.RootServerPD('rootserver', rp_namespace,
                                      image, machine, pools)

    # Declare the default memory pools.
    def_virtpool = getattr(root_program_el, "virtpool", None)
    def_physpool = getattr(root_program_el, "physpool", None)
    def_pager    = getattr(root_program_el, "pager", None)
    def_direct   = getattr(root_program_el, "direct", None)

    bootinfo.set_system_default_attrs(def_virtpool,
                                      def_physpool,
                                      image,
                                      def_pager,
                                      def_direct)

    elf = UnpreparedElfFile(filename=root_program_el.file)

    if elf.elf_type != ET_EXEC:
        raise MergeError, "All the merged ELF files must be of EXEC type."

    # Record the entry point of the root program so that the kernel
    # can start it.
    image.kconfig.set_rootserver_entry(elf.entry_point)

    pd.set_default_pools(image, bootinfo)

    # Collect the object environment
    env = collect_environment_element(root_program_el.find_child('environment'),
                                      rp_namespace, machine, pools, image, bootinfo)

    segment_els = root_program_el.find_children("segment")
    collect_elf_segments(elf,
                         image.ROOT_PROGRAM,
                         segment_els,
                         root_program_el.file,
                         rp_namespace,
                         image,
                         machine,
                         pools)

    # Record any patches being made to the program.
    patch_els   = root_program_el.find_children("patch")
    for p in getattr(RootProgram_el, "extra_patches", []):
        addr = get_symbol(elf, p[0], True)
        if addr == None:
            continue
        addr = int(addr[0])+ int(p[1])
        new_patch = Patch_el(address=hex(addr), bytes=p[2], value=p[3])
        patch_els.append(new_patch)
    collect_patches(elf, patch_els, root_program_el.file, image)

    for extension_el in root_program_el.find_children("extension"):
        if not ignore_name.match(extension_el.name):
            collect_extension_element(extension_el,
                                      pd,
                                      rp_namespace,
                                      elf,
                                      image,
                                      machine,
                                      bootinfo,
                                      pools)

    # Collect the main thread.  The root program can only have one
    # thread, so this call chiefly is used to collect information
    # about the stack.
    #
    # The stack is not set up as a memsection, so it is not put in the
    # object environment.
    thread = collect_thread(elf, root_program_el, ignore_name, rp_namespace,
                            image, machine, pools,
                            entry = elf.entry_point,
                            name = 'rootprogram',
                            namespace_thread_name = "main")
    pd.add_thread(thread)

    # Collect the heap.  Is there no element, create a fake one for
    # the collection code to use.
    #
    # The heap is not set up as a memsection, so it is not put in the
    # object environment.

    heap_el = root_program_el.find_child('heap')

    if heap_el is None:
        heap_el = ParsedElement('heap')
    
    heap_ms = collect_memsection_element(heap_el, ignore_name,
                                         rp_namespace, image, machine,
                                         pools)
    pd.attach_heap(heap_ms)
    image.add_group(0, [heap_ms.get_ms()])

    pd.add_environment(env)
    bootinfo.add_rootserver_pd(pd)
Example #6
0
def collect_rootprogram_element(parsed, ignore_name, namespace, image, machine,
                                bootinfo, pools):
    """Handle an Iguana Server Compound Object"""

    # Find the tag
    root_program_el = parsed.find_child("rootprogram")

    assert (root_program_el is not None)

    # New namespace for objects living in the root program's PD.
    rp_namespace = namespace.add_namespace('rootprogram')

    pd = weaver.bootinfo.RootServerPD('rootserver', rp_namespace, image,
                                      machine, pools)

    # Declare the default memory pools.
    def_virtpool = getattr(root_program_el, "virtpool", None)
    def_physpool = getattr(root_program_el, "physpool", None)
    def_pager = getattr(root_program_el, "pager", None)
    def_direct = getattr(root_program_el, "direct", None)

    bootinfo.set_system_default_attrs(def_virtpool, def_physpool, image,
                                      def_pager, def_direct)

    elf = UnpreparedElfFile(filename=root_program_el.file)

    if elf.elf_type != ET_EXEC:
        raise MergeError, "All the merged ELF files must be of EXEC type."

    # Record the entry point of the root program so that the kernel
    # can start it.
    image.kconfig.set_rootserver_entry(elf.entry_point)

    pd.set_default_pools(image, bootinfo)

    # Collect the object environment
    env = collect_environment_element(
        root_program_el.find_child('environment'), rp_namespace, machine,
        pools, image, bootinfo)

    segment_els = root_program_el.find_children("segment")
    collect_elf_segments(elf, image.ROOT_PROGRAM, segment_els,
                         root_program_el.file, rp_namespace, image, machine,
                         pools)

    # Record any patches being made to the program.
    patch_els = root_program_el.find_children("patch")
    for p in getattr(RootProgram_el, "extra_patches", []):
        addr = get_symbol(elf, p[0], True)
        if addr == None:
            continue
        addr = int(addr[0]) + int(p[1])
        new_patch = Patch_el(address=hex(addr), bytes=p[2], value=p[3])
        patch_els.append(new_patch)
    collect_patches(elf, patch_els, root_program_el.file, image)

    for extension_el in root_program_el.find_children("extension"):
        if not ignore_name.match(extension_el.name):
            collect_extension_element(extension_el, pd, rp_namespace, elf,
                                      image, machine, bootinfo, pools)

    # Collect the main thread.  The root program can only have one
    # thread, so this call chiefly is used to collect information
    # about the stack.
    #
    # The stack is not set up as a memsection, so it is not put in the
    # object environment.
    thread = collect_thread(elf,
                            root_program_el,
                            ignore_name,
                            rp_namespace,
                            image,
                            machine,
                            pools,
                            entry=elf.entry_point,
                            name='rootprogram',
                            namespace_thread_name="main")
    pd.add_thread(thread)

    # Collect the heap.  Is there no element, create a fake one for
    # the collection code to use.
    #
    # The heap is not set up as a memsection, so it is not put in the
    # object environment.

    heap_el = root_program_el.find_child('heap')

    if heap_el is None:
        heap_el = ParsedElement('heap')

    heap_ms = collect_memsection_element(heap_el, ignore_name, rp_namespace,
                                         image, machine, pools)
    pd.attach_heap(heap_ms)
    image.add_group(0, [heap_ms.get_ms()])

    pd.add_environment(env)
    bootinfo.add_rootserver_pd(pd)