📄 memmap.cpp
字号:
if (relocates && (find_region_by_section (parent_section, final_location)->type == read_only)) return ERR_MEMMAP_SECTION_VMA_READONLY; // final anchor of relocating section must be in a read/write memory region } // add the new section to the section map mem_section new_mem_section; list <mem_section>::iterator new_section = section_list.insert (section_list.begin (), new_mem_section); new_section->name = section_name; new_section->size = section_size; new_section->alignment = section_alignment; new_section->relocates = relocates; new_section->note = note; new_section->linker_defined = linker_defined; new_section->initial_location = new mem_location; new_section->final_location = new mem_location; new_section->initial_location->following_section = NULL; // initialize struct new_section->final_location->following_section = NULL; // initialize struct new_section->initial_location->anchor = initial_section_anchor; new_section->final_location->anchor = final_section_anchor; if ((initial_section_anchor == relative) && (!relocates) && (find_memory_section (initial_anchor_section_name)->relocates)) { // a non-relocating relative section anchored to a relocating section if (anchor_to_initial_location) // new section is anchored to the initial location of a relocating section { list <mem_section>::iterator anchor_section = find_memory_section (initial_anchor_section_name); new_section->initial_location->following_section = anchor_section->initial_location->following_section; anchor_section->initial_location->following_section = new_section; } else // new section is anchored to the final location of a relocating section { list <mem_section>::iterator anchor_section = find_memory_section (initial_anchor_section_name); new_section->final_location->following_section = anchor_section->final_location->following_section; anchor_section->final_location->following_section = new_section; } } else { // copy initial location data if (initial_section_anchor == relative) // new section follows the named anchor section { list <mem_section>::iterator anchor_section = find_memory_section (initial_anchor_section_name); new_section->initial_location->following_section = anchor_section->initial_location->following_section; // move anchor of the following section anchor_section->initial_location->following_section = new_section; // anchor the new section } else // new section has an absolute anchor new_section->initial_location->address = initial_anchor_address; // copy final location data if (final_section_anchor == relative) // new section follows the named anchor section { list <mem_section>::iterator anchor_section = find_memory_section (final_anchor_section_name); new_section->final_location->following_section = anchor_section->final_location->following_section; // move anchor of the following section anchor_section->final_location->following_section = new_section; // anchor the new section } else // new section has an absolute anchor new_section->final_location->address = final_anchor_address; } // recalculate section lists for all regions calc_section_lists (); map_modified_flag = true; return 0;}////////////////////////////////////////////////////////////////////////// calc_section_lists() updates the lists of memory sections for all// memory regionsbool mem_map::calc_section_lists (){ for (list <mem_region>::iterator region = region_list.begin (); region != region_list.end(); ++region) calc_section_list (region); return true;}////////////////////////////////////////////////////////////////////////// calc_section_list() updates the list of memory sections which reside // in the specified memory region. It is called whenever the section// map is modified.bool mem_map::calc_section_list (list <mem_region>::iterator region){ // clear the old list (if any) TRACE (_T("Calculating section list for region '%s'\n"), CString (region->name.c_str())); region->section_view_list.clear (); // add the initial and final locations of each absolute section as necessary for (list <mem_section>::iterator section = section_list.begin (); section != section_list.end (); ++section) { if (section->relocates) // the section is relocated and must be added to the view twice { add_absolute_section_to_list (region, section, initial_location); add_absolute_section_to_list (region, section, final_location); } else // the section is not relocated and must be added to the view once only add_absolute_section_to_list (region, section, fixed_location); } // add unused sections to section view list where appropriate list <mem_section_view>::iterator previous_section_view = region->section_view_list.begin (); if (previous_section_view == region->section_view_list.end ()) // no used sections in this region { // add a single unused section to the section view list mem_section_view new_section_view; new_section_view.section = NULL; // an unused section region->section_view_list.push_back (new_section_view); // add to the section list for this region } else // there are used sections in this region { list <mem_section_view>::iterator second_section_view = region->section_view_list.begin (); ++second_section_view; // add unused sections between used sections where they do not meet in either initial or final locations for (list <mem_section_view>::iterator section_view = second_section_view; section_view != region->section_view_list.end (); ++section_view) { if (! (absolute_sections_meet (previous_section_view->section, section_view->section))) { list <mem_section_view>::iterator new_section_view = region->section_view_list.insert (section_view); // add an unused section new_section_view->section = NULL; } previous_section_view = section_view; } // add an unused section to end of region if the last section does not reach the end of the region in initial or final locations if (! at_end_of_region (region->section_view_list.back().section, region)) { mem_section_view new_section_view; new_section_view.section = NULL; // an unused section region->section_view_list.push_back (new_section_view); // add an unused section } // add an unused section to start of region if the first section does not start at the start of the region in initial or final locations if (! at_start_of_region (region->section_view_list.front().section, region)) { mem_section_view new_section_view; new_section_view.section = NULL; // an unused section region->section_view_list.push_front (new_section_view); // add an unused section } } // add the initial and final locations of the each relative section as necessary for (list <mem_section_view>::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) if (section_view->section != NULL) // if section is used { list <mem_section>::iterator section = section_view->section; TRACE (_T("Calculating relative sections for section view '%s' %s\n"), CString (section->name.c_str ()), section_view->section_location == final_location ? _T("(final)") : section_view->section_location == initial_location ? _T("(initial)") : _T("(fixed)")); if (section_view->section_location == final_location) { if (section->final_location->anchor == absolute) add_relative_sections_to_list (region, section_view, final_location); } else if (section_view->section_location == initial_location) { if (section->initial_location->anchor == absolute) add_relative_sections_to_list (region, section_view, initial_location); } else // section_view->section_location == fixed_location { if (section->initial_location->anchor == absolute) add_relative_sections_to_list (region, section_view, initial_location); if (section->final_location->anchor == absolute) add_relative_sections_to_list (region, section_view, final_location); } } // remove unused sections where user-defined section of unknown size will be placed section_view = region->section_view_list.begin (); while (section_view != region->section_view_list.end ()) { bool expanding_section = false; if ((section_view->section != NULL) && (section_view->section->size == 0) && (! section_view->section->linker_defined)) expanding_section = true; ++section_view; if (expanding_section && (section_view != region->section_view_list.end ()) && (section_view->section == NULL)) section_view = region->section_view_list.erase (section_view); } return true;}/////////////////////////////////////////////////////////////////////// add_relative_sections_to_list() inserts the sections defined relative// to the specified section list item to the section list for the// specified region in the appropriate orderbool mem_map::add_relative_sections_to_list (list <mem_region>::iterator region, list <mem_section_view>::iterator section_view, section_location_type location_type){ // insert following relative sections of type 'location_type' in region_view.section_view_list list <mem_section>::iterator new_section = section_view->section; mem_location * new_section_location = (location_type == initial_location ? new_section->initial_location : new_section->final_location); list <mem_section_view>::iterator insertion_point = section_view; ++insertion_point; while (new_section_location->following_section != NULL) { // add the new section to the section view list mem_section_view new_section_view; new_section_view.section = new_section_location->following_section; const bool section_relocates = new_section->relocates; new_section = new_section_view.section; new_section_view.section_location = (new_section->relocates ? location_type : fixed_location); if ((new_section_view.section_location == fixed_location) && (location_type == final_location) && (! section_view->section->relocates) && (! section_relocates)) { // section already added to the view } else { TRACE (_T("Inserting section %s %s location (relative) preceding %s\n"), CString (new_section_location->following_section->name.c_str()), location_type == initial_location ? _T("initial") : _T("final"), ((insertion_point != region->section_view_list.end ()) && (insertion_point->section != NULL)) ? CString (insertion_point->section->name.c_str()) : _T("(null)")); region->section_view_list.insert (insertion_point, new_section_view); } new_section_location = (location_type == initial_location ? new_section->initial_location : new_section->final_location); } return true;}/////////////////////////////////////////////////////////////////////// add_absolute_section_to_list() inserts the specified section to the// specified section list at the appropriate place if it has an// absolute location and that location is within the specified memory// regionbool mem_map::add_absolute_section_to_list (list <mem_region>::iterator region, list <mem_section>::iterator additional_section, section_location_type location_type){ // get location of new section mem_location * new_section_location = (location_type == initial_location ? additional_section->initial_location : additional_section->final_location); if ((new_section_location->anchor == absolute) && (new_section_location->address >= region->address) && (new_section_location->address < region->address + region->size)) { // the section lies in the region // initialise the insertion point for the new section list <mem_section_view>::iterator insertion_point = region->section_view_list.end (); for (list <mem_section_view>::iterator section = region->section_view_list.begin (); section != region->section_view_list.end (); ++section) { // get location of section mem_location * section_location = (section->section_location == initial_location ? section->section->initial_location : section->section->final_location); // compare with location of new section if ((new_section_location->anchor == absolute) && (section_location->address >= new_section_location->address)) { // insert new section here if the current section has a higher address insertion_point = section; break; } } // add the new section to the section view list TRACE (_T("Inserting section %s %s location (absolute) preceding %s\n"), CString (additional_section->name.c_str()), location_type == initial_location ? _T("initial") : _T("final"), insertion_point != region->section_view_list.end () ? CString (insertion_point->section->name.c_str()) : _T("(end)")); mem_section_view new_section_view; new_section_view.section = additional_section; new_section_view.section_location = location_type; region->section_view_list.insert (insertion_point, new_section_view); } return true;}////////////////////////////////////////////////////////////////////// absolute_sections_meet() determines whether the specified// absolute memory sections meet. It assumes that section2 comes// after section1 in the memory map.bool mem_map::absolute_sections_meet(list <mem_section>::iterator section1, list <mem_section>::iterator section2){ if (section1->size == 0) // size of section1 is unknown return false; // check if initial section locations meet if ((section1->initial_location->anchor == absolute) && ((section2->initial_location->anchor == absolute) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -