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()
def collect_machine_element(parsed, ignore_name, machine, namespace): """Collect the attributes of the machine element.""" machine_el = parsed.find_child("machine") assert machine_el is not None # If the file attribute is specified, then read the full version # of the machine element from that file. if hasattr(machine_el, "file"): machine_el = Machine_el.parse_xml_file(machine_el.file) machine.word_size = machine_el.find_child("word_size").size machine.set_page_sizes([el.size for el in machine_el.find_children("page_size")]) machine.add_cache_policies([(el.name, el.value) for el in machine_el.find_children("cache_policy")]) attrs = machine_el.find_child("kernel_heap_attrs") if attrs is not None: machine.kernel_heap_proximity = getattr(attrs, 'distance', None) machine.kernel_heap_align = getattr(attrs, 'align', None) def map_mem_type(region_el): """Map the string memory type to a memory descriptor type.""" mem_type = getattr(region_el, "type", "conventional") if not MEMDESC_DICT.has_key(mem_type): raise MergeError, "Unknown memory type %s" % mem_type return MEMDESC_DICT[mem_type] for p_el in machine_el.find_children("physical_memory"): if not ignore_name.match(p_el.name): mem = [(el.base, el.size, map_mem_type(el)) for el in p_el.find_children("region")] machine.add_physical_mem(p_el.name, mem) for v_el in machine_el.find_children("virtual_memory"): if not ignore_name.match(v_el.name): mem = [(el.base, el.size, MEMDESC_UNDEFINED) for el in v_el.find_children("region")] machine.add_virtual_mem(v_el.name, mem) dev_ns = namespace.root.get_namespace("dev") if dev_ns is None: raise MergeError, "Device namespace does not exist!" for d_el in machine_el.find_children("phys_device"): if not ignore_name.match(d_el.name): device = machine.add_phys_device(d_el.name) create_alias_cap(device, dev_ns) for p_el in d_el.find_children("physical_memory"): if not ignore_name.match(p_el.name): mem = [(el.base, el.size, MEMDESC_RESERVED) for el in p_el.find_children("region")] device.add_physical_mem(p_el.name, mem) for i_el in d_el.find_children("interrupt"): if not ignore_name.match(i_el.name): device.add_interrupt(i_el.name, i_el.number) # extra_func is set by extensions, so pylint incorrectly thinks # that it is not callable. #pylint: disable-msg=E1102 if Machine_el.extra_func is not None: Machine_el.extra_func(machine_el, Machine_el, Kernel_el, RootProgram_el)