From: brolley Date: Tue, 21 Oct 2003 21:30:44 +0000 (+0000) Subject: 2003-10-07 Dave Brolley X-Git-Tag: corinna-01~299 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=a2142f91802e84106ddaa8d23e1f84300ec6ea87;p=pf3gnuchains%2Fpf3gnuchains4x.git 2003-10-07 Dave Brolley * compLoader.cxx (loader_probe_bus): Now takes pin as an argument. Remove warn_write_to_code_p. Initialize write_to_code_address_pin. (SID_GB_WRITE): Drive write_to_code_address_pin instead of generating a message here. (write_to_code_address_pin): New member of generic_loader. (set_warn_write_to_code): Removed. (generic_loader): remove "warn-write-to-code?" attribute and pin. Add "write-to-code-address" pin. * sw-load-elf.xml: Remove reference to "warn-write-to-code?" pin and attribute. Document "write-to-code-address" pin. * sw-load-elf.txt: Regenerated. 2003-10-07 Dave Brolley * compLoader.cxx: Use sidutil::fixed_bus_map_component. (loader_probe_bus): New class. (warn_write_to_code_pin): New member of generic_loader. (probe_upstream): Ditto. (probe_downstream): Ditto. (set_warn_write_to_code): New method of generic_loader. (generic_loader): Now inherits fixed_bus_map_component. Initialize new members. 2003-10-07 Dave Brolley For Stan Cox * elfload.c (textSegmentAddress): New function. * elfload.h (textSegmentAddress): Likewise. --- diff --git a/sid/component/loader/ChangeLog b/sid/component/loader/ChangeLog index 5150acf3e1..4618d8b208 100644 --- a/sid/component/loader/ChangeLog +++ b/sid/component/loader/ChangeLog @@ -1,3 +1,34 @@ +2003-10-07 Dave Brolley + + * compLoader.cxx (loader_probe_bus): Now takes pin as an argument. + Remove warn_write_to_code_p. Initialize write_to_code_address_pin. + (SID_GB_WRITE): Drive write_to_code_address_pin instead of + generating a message here. + (write_to_code_address_pin): New member of generic_loader. + (set_warn_write_to_code): Removed. + (generic_loader): remove "warn-write-to-code?" attribute and pin. + Add "write-to-code-address" pin. + * sw-load-elf.xml: Remove reference to "warn-write-to-code?" pin + and attribute. Document "write-to-code-address" pin. + * sw-load-elf.txt: Regenerated. + +2003-10-07 Dave Brolley + + * compLoader.cxx: Use sidutil::fixed_bus_map_component. + (loader_probe_bus): New class. + (warn_write_to_code_pin): New member of generic_loader. + (probe_upstream): Ditto. + (probe_downstream): Ditto. + (set_warn_write_to_code): New method of generic_loader. + (generic_loader): Now inherits fixed_bus_map_component. + Initialize new members. + +2003-10-07 Dave Brolley + + For Stan Cox + * elfload.c (textSegmentAddress): New function. + * elfload.h (textSegmentAddress): Likewise. + 2002-02-05 Dave Brolley * elfload.c (readElfFile): Obtain the load address from offset 24 for diff --git a/sid/component/loader/compLoader.cxx b/sid/component/loader/compLoader.cxx index 1b379b1a9e..c78c68238b 100644 --- a/sid/component/loader/compLoader.cxx +++ b/sid/component/loader/compLoader.cxx @@ -1,6 +1,6 @@ // compLoader.cxx - object file loader component. -*- C++ -*- -// Copyright (C) 1999, 2000 Red Hat. +// 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. @@ -44,7 +44,7 @@ using sid::host_int_4; using sid::component_library; using sid::COMPONENT_LIBRARY_MAGIC; -using sidutil::no_bus_component; +using sidutil::fixed_bus_map_component; using sidutil::fixed_attribute_map_component; using sidutil::fixed_pin_map_component; using sidutil::fixed_accessor_map_component; @@ -60,8 +60,50 @@ using sidutil::std_error_string; // ---------------------------------------------------------------------------- +// 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 no_bus_component, + protected fixed_bus_map_component, protected fixed_attribute_map_component, protected fixed_pin_map_component, protected fixed_accessor_map_component, @@ -77,17 +119,25 @@ protected: // 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; - // loadable file names + // 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; @@ -104,15 +154,20 @@ public: verbose_p(false), load_file("/dev/null"), load_accessor_insn(0), - load_accessor_data(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, diff --git a/sid/component/loader/elfload.c b/sid/component/loader/elfload.c index a51432b4f9..6300789033 100644 --- a/sid/component/loader/elfload.c +++ b/sid/component/loader/elfload.c @@ -29,6 +29,29 @@ struct LoadAreas 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. @@ -100,6 +123,17 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian) 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++; } } @@ -118,6 +152,17 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian) 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++; } } diff --git a/sid/component/loader/elfload.h b/sid/component/loader/elfload.h index 2a7bb188d0..9208f7aa30 100644 --- a/sid/component/loader/elfload.h +++ b/sid/component/loader/elfload.h @@ -40,6 +40,8 @@ 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*); diff --git a/sid/component/loader/sw-load-elf.xml b/sid/component/loader/sw-load-elf.xml index 9e7b2bc65c..53ef69b0ac 100644 --- a/sid/component/loader/sw-load-elf.xml +++ b/sid/component/loader/sw-load-elf.xml @@ -8,13 +8,17 @@ + + + + @@ -62,6 +66,17 @@ 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. +

+
+ state is minimal.