This is the mail archive of the sid@sources.redhat.com mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch][rfa] Error checking by the loader


Hi,

This patch adds code to the elf loader which allows it to classify input sections as code or not-code. It also adds a passthrough bus to the loader ("probe-upstream", "probe-downstream"). When the "probe-upstream" bus is accessed, the loader checks the address against known code sections and drives the "write-to-code_address" pin if a write to a code section is attempted. All accesses are passed on to "probe-downstream" accessor.

This is useful in generating simulation time warnings for writes to code sections.

ok to commit?

Dave
2003-10-07  Dave Brolley  <brolley@redhat.com>

	* 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  <brolley@redhat.com>

	* 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  <brolley@redhat.com>

	For Stan Cox  <scox@redhat.com>
	* elfload.c (textSegmentAddress): New function.
	* elfload.h (textSegmentAddress): Likewise.

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 ----
      <defpin name="start-pc-set" direction="out" legalvalues="any" behaviors="loading"/>
      <defpin name="endian-set" direction="out" legalvalues="0/1/2" behaviors="loading"/>
      <defpin name="error" direction="out" legalvalues="any" behaviors="loading"/>
+     <defpin name="write-to-code-address" direction="out" legalvalues="any address" behaviors="error checking"/>
  
      <defattribute name="state-snapshot" legalvalues="opaque string" behaviors="save/restore"/>
      <defattribute name="file" category="setting" legalvalues="file name" defaultvalue='"/dev/null"' behaviors="configuration"/>
      <defattribute name="verbose?" category="setting" legalvalues="1/0" defaultvalue="0" behaviors="configuration"/>
      
+     <defbus name="probe-upstream" accesses="read/write" behaviors="error checking"/>
+ 
      <defaccessor name="load-accessor-insn" accesses="write little_int_1" behaviors="loading"/>
      <defaccessor name="load-accessor-data" accesses="write little_int_1" behaviors="loading"/>
+     <defaccessor name="probe-downstream" accesses="read/write" behaviors="error checking"/>
  
    </defcomponent>
  
***************
*** 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 <tt>gdb</tt> would.</p>
+     </behavior>
+ 
+     <behavior name="error checking">
+       <p>
+       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.
+       </p>
      </behavior>
  
      <convention name="functional" supported="true" />
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;
    };
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]