Index: sid/component/loader/compLoader.cxx =================================================================== RCS file: /cvs/src/src/sid/component/loader/compLoader.cxx,v retrieving revision 1.5 diff -c -p -r1.5 compLoader.cxx *** sid/component/loader/compLoader.cxx 3 Aug 2001 06:02:45 -0000 1.5 --- sid/component/loader/compLoader.cxx 21 Oct 2003 17:52:55 -0000 *************** *** 1,6 **** // compLoader.cxx - object file loader component. -*- C++ -*- ! // Copyright (C) 1999, 2000 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,6 ---- // compLoader.cxx - object file loader component. -*- C++ -*- ! // Copyright (C) 1999, 2000, 2003 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** using sid::host_int_4; *** 44,50 **** using sid::component_library; using sid::COMPONENT_LIBRARY_MAGIC; ! using sidutil::no_bus_component; using sidutil::fixed_attribute_map_component; using sidutil::fixed_pin_map_component; using sidutil::fixed_accessor_map_component; --- 44,50 ---- using sid::component_library; using sid::COMPONENT_LIBRARY_MAGIC; ! using sidutil::fixed_bus_map_component; using sidutil::fixed_attribute_map_component; using sidutil::fixed_pin_map_component; using sidutil::fixed_accessor_map_component; *************** using sidutil::std_error_string; *** 60,67 **** // ---------------------------------------------------------------------------- class generic_loader: public virtual component, ! protected no_bus_component, protected fixed_attribute_map_component, protected fixed_pin_map_component, protected fixed_accessor_map_component, --- 60,109 ---- // ---------------------------------------------------------------------------- + // A bus for allowing the loader to perform random checks against reads and writes + // to memory. For example writing to a code area. Default implementation + extern "C" int textSegmentAddress(int); + + class loader_probe_bus: public sidutil::passthrough_bus + { + public: + loader_probe_bus (sid::bus **t, output_pin *p) : + sidutil::passthrough_bus (t), + write_to_code_address_pin (p) + { + assert (t); + } + ~loader_probe_bus() throw() {} + + // Some macros to make manufacturing of the cartesian-product + // calls simpler. + #define SID_GB_WRITE(dtype) \ + sid::bus::status write(sid::host_int_4 addr, dtype data) throw ()\ + { if (LIKELY(*target)) \ + { \ + if (write_to_code_address_pin && textSegmentAddress (addr)) \ + write_to_code_address_pin->drive (addr); \ + return (*target)->write(addr, data); \ + } \ + else return sid::bus::unpermitted; \ + } + + SID_GB_WRITE(sid::little_int_1) + SID_GB_WRITE(sid::big_int_1) + SID_GB_WRITE(sid::little_int_2) + SID_GB_WRITE(sid::big_int_2) + SID_GB_WRITE(sid::little_int_4) + SID_GB_WRITE(sid::big_int_4) + SID_GB_WRITE(sid::little_int_8) + SID_GB_WRITE(sid::big_int_8) + + #undef SID_GB_WRITE + + output_pin *write_to_code_address_pin; + }; + class generic_loader: public virtual component, ! protected fixed_bus_map_component, protected fixed_attribute_map_component, protected fixed_pin_map_component, protected fixed_accessor_map_component, *************** protected: *** 77,93 **** // The value is one of sidutil::endian_*. output_pin endian_pin; // Signal this if something went wrong. output_pin error_pin; ! // loadable file names bool verbose_p; string load_file; // accessors bus* load_accessor_insn; bus* load_accessor_data; // The load pin was triggered. virtual void load_it (host_int_4) = 0; --- 119,143 ---- // The value is one of sidutil::endian_*. output_pin endian_pin; + // Provide address of write attempt to code section + output_pin write_to_code_address_pin; + // Signal this if something went wrong. output_pin error_pin; ! // Attribute settings bool verbose_p; + + // loadable file names string load_file; // accessors bus* load_accessor_insn; bus* load_accessor_data; + loader_probe_bus probe_upstream; + bus *probe_downstream; + // The load pin was triggered. virtual void load_it (host_int_4) = 0; *************** public: *** 104,118 **** verbose_p(false), load_file("/dev/null"), load_accessor_insn(0), ! load_accessor_data(0) { add_pin("load!", & this->doit_pin); add_pin("start-pc-set", & this->start_pc_pin); add_pin("endian-set", & this->endian_pin); add_pin("error", & this->error_pin); add_accessor("load-accessor-insn", & this->load_accessor_insn); add_accessor("load-accessor-data", & this->load_accessor_data); add_attribute("file", & this->load_file, "setting"); add_attribute("verbose?", & this->verbose_p, "setting"); add_attribute_virtual ("state-snapshot", this, & generic_loader::save_state, --- 154,173 ---- verbose_p(false), load_file("/dev/null"), load_accessor_insn(0), ! load_accessor_data(0), ! probe_upstream (& probe_downstream, & this->write_to_code_address_pin), ! probe_downstream(0) { add_pin("load!", & this->doit_pin); add_pin("start-pc-set", & this->start_pc_pin); add_pin("endian-set", & this->endian_pin); add_pin("error", & this->error_pin); + add_pin("write-to-code-address", & this->write_to_code_address_pin); add_accessor("load-accessor-insn", & this->load_accessor_insn); add_accessor("load-accessor-data", & this->load_accessor_data); add_attribute("file", & this->load_file, "setting"); + add_bus ("probe-upstream", & this->probe_upstream); + add_accessor ("probe-downstream", & this->probe_downstream); add_attribute("verbose?", & this->verbose_p, "setting"); add_attribute_virtual ("state-snapshot", this, & generic_loader::save_state, Index: sid/component/loader/elfload.c =================================================================== RCS file: /cvs/src/src/sid/component/loader/elfload.c,v retrieving revision 1.4 diff -c -p -r1.4 elfload.c *** sid/component/loader/elfload.c 5 Feb 2002 16:36:48 -0000 1.4 --- sid/component/loader/elfload.c 21 Oct 2003 17:52:55 -0000 *************** struct LoadAreas *** 29,34 **** --- 29,57 ---- int loaded; } loadAreas[100]; // XXX: limit on number of loadable sections + static struct TextSegment + { + host_int_8 lbound; + host_int_8 hbound; + } textSegments[100]; + static int textSegmentsCount = 0; + enum {execute_flag = 1}; + + + int + textSegmentAddress (int address) + { + int i; + for (i = 0; i < textSegmentsCount ; i++) + { + if (textSegments[i].lbound <= address + && address <= textSegments[i].hbound) + return 1; + } + return 0; + } + + /* Read in an ELF file, using FUNC to read data from the stream. The result is a boolean indicating success. The entry point as specified in the ELF header is stored in *ENTRY_POINT. *************** readElfFile (PFLOAD func, unsigned* entr *** 100,105 **** --- 123,139 ---- littleEndian); loadAreas[loadAreaCount].flags = fetchWord(psymHdr+4, littleEndian); loadAreas[loadAreaCount].loaded = 0; + + if (loadAreas[loadAreaCount].flags & execute_flag) + { + textSegments[textSegmentsCount].lbound = + loadAreas[loadAreaCount].loadAddr; + textSegments[textSegmentsCount].hbound = + loadAreas[loadAreaCount].loadAddr + + loadAreas[loadAreaCount].filesize; + textSegmentsCount++; + } + loadAreaCount++; } } *************** readElfFile (PFLOAD func, unsigned* entr *** 118,123 **** --- 152,168 ---- littleEndian); loadAreas[loadAreaCount].flags = fetchWord(psymHdr+24, littleEndian); loadAreas[loadAreaCount].loaded = 0; + + if (loadAreas[loadAreaCount].flags & execute_flag) + { + textSegments[textSegmentsCount].lbound = + loadAreas[loadAreaCount].loadAddr; + textSegments[textSegmentsCount].hbound = + loadAreas[loadAreaCount].loadAddr + + loadAreas[loadAreaCount].filesize; + textSegmentsCount++; + } + loadAreaCount++; } } Index: sid/component/loader/elfload.h =================================================================== RCS file: /cvs/src/src/sid/component/loader/elfload.h,v retrieving revision 1.2 diff -c -p -r1.2 elfload.h *** sid/component/loader/elfload.h 13 Jan 2001 14:26:05 -0000 1.2 --- sid/component/loader/elfload.h 21 Oct 2003 17:52:55 -0000 *************** *** 40,45 **** --- 40,47 ---- typedef unsigned long long host_int_8; /* XXX */ typedef int (*PFLOAD)(host_int_8 dest, char *dest2, host_int_8 offset, host_int_8 amount, int insn_space); + /* Is address in the text segment? */ + extern int textSegmentAddress(int); /* Load an ELF executable into memory. FUNC is used to actually read the file. */ extern int readElfFile(PFLOAD func, unsigned*, int*); Index: sid/component/loader/sw-load-elf.xml =================================================================== RCS file: /cvs/src/src/sid/component/loader/sw-load-elf.xml,v retrieving revision 1.2 diff -c -p -r1.2 sw-load-elf.xml *** sid/component/loader/sw-load-elf.xml 5 Oct 2001 00:36:17 -0000 1.2 --- sid/component/loader/sw-load-elf.xml 21 Oct 2003 17:52:55 -0000 *************** *** 8,20 **** --- 8,24 ---- + + + + *************** *** 60,65 **** --- 64,80 ---- to identify the bytes to load into memory. It does not use the "section header". This means that it tends to load more bytes than gdb would.

+ + + +

+ All read requests coming in though the "probe-upstream" bus are + checked against known code segments and, for each attempt to write + to a code segment, the write-to-code-address pin is driven with the + address of the write attempt. All reads and writes + coming in through the probe-upstream bus are passed on to the + probe-downstream accessor. +

Index: sid/include/sidbusutil.h =================================================================== RCS file: /cvs/src/src/sid/include/sidbusutil.h,v retrieving revision 1.13 diff -c -p -r1.13 sidbusutil.h *** sid/include/sidbusutil.h 6 Feb 2003 20:27:49 -0000 1.13 --- sid/include/sidbusutil.h 21 Oct 2003 17:59:06 -0000 *************** namespace sidutil *** 251,257 **** #undef SID_GB_WRITE #undef SID_GB_READ ! private: sid::bus** target; }; --- 251,257 ---- #undef SID_GB_WRITE #undef SID_GB_READ ! protected: sid::bus** target; };