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 ----
+ 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. +