public inbox for sid@sourceware.org
 help / color / mirror / Atom feed
* RFA: loader Elf64 loader & split insn/data accessors
@ 2001-01-13  4:01 matthew green
  2001-01-13  5:41 ` Frank Ch. Eigler
  0 siblings, 1 reply; 6+ messages in thread
From: matthew green @ 2001-01-13  4:01 UTC (permalink / raw)
  To: sid

hi folks.

this following patch splits the current elf `loader' module from having a
single "load-accessor" bus *, to having one for insn space, and one for
data space.  this is to help support of harvard architecture platforms.

included is support for Elf64 file loading.. however, due to a current
limitiation of sid, >32 bit addresses are not supported.  addresses that
have bit 33 set are considering to be 32 bit instruction space addresses
currently...  this hack allows full 32 bit harvard arch machines to have
a full normal address space, with insn being (at the object file format)
from 0x.10000.0000 ... 0x1.ffff.ffff.  it should be removed when sid can
deal with >32 bit address spaces.

OK to commit?


.mrg.


[bsp/ChangeLog]
2001-01-13  matthew green  <mrg@redhat.com>
	
	* configrun-sid.in: `load-accessor' becomes Harvard architecture
	friendly.  Split into `load-accessor-insn' and `load-accessor-data'.

[component/loader/ChangeLog]
2001-01-13  matthew green  <mrg@redhat.com>

	* compLoader.cxx (load_accessor): Delete member.
	(load_accessor_insn, load_accessor_data): New bus* members.
	(ctor): Initialise load_accessor_insn and load_accessor_data.
	Add `load-accessor-insn' and `load-accessor-data' accessors
	and delete `load-accessor'.
	(load_function): Extend to 64 bit addresses, and have an instruction
	space identifier.
	(load_it): Check both load_accessor_insn and load_accessor_data are set,
	and use the appropriate one.  Extend messages to meantion instruction or
	data loads.
	* elfload.h (fetchQuadLittle, fetchQuadBig, fetchQuad): New macros.
	(PFLOAD): Make 64-bit & Harvard address space friendly
	* elfload.c (readElfFile): Support 64-bit ELF as well as 32-bit ELF.
	Current address space semantics need fixing.
	* sw-load-elf.txt: Document `load-accessor-insn' and `load-accessor-data'
	accessors.


Index: bsp/configrun-sid.in
===================================================================
RCS file: /cvs/src/src/sid/bsp/configrun-sid.in,v
retrieving revision 1.4
diff -p -r1.4 configrun-sid.in
*** configrun-sid.in	2001/01/11 16:32:30	1.4
--- configrun-sid.in	2001/01/13 09:52:19
*************** if ($exec)
*** 821,827 ****
      $second_section .= "# loader
  set loader file \"$exec\"
  set loader verbose? $opt_verbose
! connect-bus loader load-accessor mapper access-port # don't trace loading
  connect-pin init-sequence output-1 -> loader load!
  connect-pin loader start-pc-set -> cpu start-pc-set!
  connect-pin loader endian-set -> cpu endian-set!
--- 821,828 ----
      $second_section .= "# loader
  set loader file \"$exec\"
  set loader verbose? $opt_verbose
! connect-bus loader load-accessor-data mapper access-port # don't trace loading
! connect-bus loader load-accessor-insn mapper access-port # don't trace loading
  connect-pin init-sequence output-1 -> loader load!
  connect-pin loader start-pc-set -> cpu start-pc-set!
  connect-pin loader endian-set -> cpu endian-set!
Index: component/loader/compLoader.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/loader/compLoader.cxx,v
retrieving revision 1.1
diff -p -r1.1 compLoader.cxx
*** compLoader.cxx	2000/12/07 19:30:54	1.1
--- compLoader.cxx	2001/01/13 09:52:19
*************** using sidutil::std_error_string;
*** 60,66 ****
  
  // ----------------------------------------------------------------------------
  
- 
  class generic_loader: public virtual component,
  		      protected no_bus_component,
  		      protected fixed_attribute_map_component,
--- 60,65 ----
*************** protected:
*** 86,92 ****
    string load_file;
  
    // accessors
!   bus* load_accessor;
  
    // The load pin was triggered.
    virtual void load_it (host_int_4) = 0;
--- 85,92 ----
    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;
*************** public:
*** 103,115 ****
      doit_pin(this, & generic_loader::load_it), 
      verbose_p(false),
      load_file("/dev/null"),
!     load_accessor(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", & this->load_accessor);
        add_attribute("file", & this->load_file, "setting");
        add_attribute("verbose?", & this->verbose_p, "setting");
        add_attribute_virtual ("state-snapshot", this,
--- 103,117 ----
      doit_pin(this, & generic_loader::load_it), 
      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,
*************** public:
*** 119,125 ****
      
  };
  
- 
  ostream& 
  operator << (ostream& out, const generic_loader& it)
  {
--- 121,126 ----
*************** operator >> (istream& in, generic_loader
*** 149,175 ****
    return in;
  }
  
- 
- 
  // ----------------------------------------------------------------------------
  
- 
  class elf_loader: public generic_loader
  {
    // static pointer to active instance (XXX: concurrency?)
    static elf_loader* freeloader;
  
    // callback function from C code in elfload.c
!   static int load_function(char* dest_addr, char* host_addr, int file_offset, int bytes);
  
    // stream for current file  
    ifstream* file;
  
    void load_it (host_int_4)
      {
!       if (this->load_accessor == 0)
  	{
! 	  cerr << "loader: error - target accessor not configured!" << endl;
  	  this->error_pin.drive (0);
  	  return;
  	}
--- 150,174 ----
    return in;
  }
  
  // ----------------------------------------------------------------------------
  
  class elf_loader: public generic_loader
  {
    // static pointer to active instance (XXX: concurrency?)
    static elf_loader* freeloader;
  
    // callback function from C code in elfload.c
!   static int load_function(host_int_8 dest_addr, char* host_addr, host_int_8 file_offset, host_int_8 bytes, int insn_space);
!   static int verbose_function(char* s);
  
    // stream for current file  
    ifstream* file;
  
    void load_it (host_int_4)
      {
!       if (this->load_accessor_insn == 0 || this->load_accessor_data == 0)
  	{
! 	  cerr << "loader: error - target accessors not configured!" << endl;
  	  this->error_pin.drive (0);
  	  return;
  	}
*************** class elf_loader: public generic_loader
*** 181,187 ****
  
        assert(elf_loader::freeloader == 0);
        this->file = new ifstream(this->load_file.c_str(), ios::binary | ios::in);
!       if(! this->file->good())
  	{
  	  cerr << "loader: error opening " << load_file << ": "
  	       << std_error_string() << endl;
--- 180,186 ----
  
        assert(elf_loader::freeloader == 0);
        this->file = new ifstream(this->load_file.c_str(), ios::binary | ios::in);
!       if (! this->file->good())
  	{
  	  cerr << "loader: error opening " << load_file << ": "
  	       << std_error_string() << endl;
*************** class elf_loader: public generic_loader
*** 215,254 ****
      }
  };
  
- 
  // static variable
  elf_loader* elf_loader::freeloader = 0;
  
  // static function
  int
! elf_loader::load_function(char* dest_addr, char* host_addr, int file_offset, int bytes)
  {
!   if (elf_loader::freeloader->verbose_p)
      {
!       if(host_addr == 0)
  	cout << "loader: reading "
  	     << make_numeric_attribute (bytes, ios::hex | ios::showbase)
  	     << " bytes from file offset "
  	     << make_numeric_attribute (file_offset, ios::hex | ios::showbase)
! 	     << " into target memory at "
  	     << make_numeric_attribute ((void *)dest_addr, ios::hex | ios::showbase)
  	     << endl;
      }
  
-   elf_loader& l = * elf_loader::freeloader;
    ifstream& f = * l.file;
!   bus* b = l.load_accessor;
    assert (b);
  
    // go to proper offset in file
    f.seekg(file_offset);
  
    // fetch lots of characters
!   for(int n=0; n<bytes; n++)
      {
        char c;
        f.get(c);
!       if(! f.good())
  	{
  	  cerr << "loader: error reading byte " << file_offset+n
  	       << " from file " << l.load_file << endl;
--- 214,259 ----
      }
  };
  
  // static variable
  elf_loader* elf_loader::freeloader = 0;
  
  // static function
  int
! elf_loader::load_function(host_int_8 dest_addr, char *host_addr, host_int_8 file_offset, host_int_8 bytes, int insn_space)
  {
!   elf_loader& l = * elf_loader::freeloader;
!   string who = insn_space ? "instruction" : "data";
! 
!   if (l.verbose_p)
      {
!       if (host_addr == 0)
  	cout << "loader: reading "
  	     << make_numeric_attribute (bytes, ios::hex | ios::showbase)
  	     << " bytes from file offset "
  	     << make_numeric_attribute (file_offset, ios::hex | ios::showbase)
! 	     << " into target " << who << " memory at "
  	     << make_numeric_attribute ((void *)dest_addr, ios::hex | ios::showbase)
  	     << endl;
      }
  
    ifstream& f = * l.file;
!   bus* b;
! 
!   if (insn_space)
!     b = l.load_accessor_insn;
!   else
!     b = l.load_accessor_data;
    assert (b);
  
    // go to proper offset in file
    f.seekg(file_offset);
  
    // fetch lots of characters
!   for (int n = 0; n < bytes; n++)
      {
        char c;
        f.get(c);
!       if (!f.good())
  	{
  	  cerr << "loader: error reading byte " << file_offset+n
  	       << " from file " << l.load_file << endl;
*************** elf_loader::load_function(char* dest_add
*** 262,280 ****
  	}
        else // read into target memory
  	{
! 	  host_int_4 a = (host_int_4)(dest_addr ++);
  	  little_int_1 data = c;
  	  host_int_4 addr = a;
  
  	  bus::status s;
  	  do // loop while memory getting ready
  	    {
  	      s = b->write(addr, data);
! 	    } while(s == bus::delayed);
  
! 	  if(s != bus::ok) // abort on error
  	    {
! 	      cerr << "loader: write to accessor failed at address "
  		   << make_numeric_attribute (addr, ios::hex | ios::showbase)
  		   << ", status "
  		   << (int) s << endl;
--- 267,286 ----
  	}
        else // read into target memory
  	{
! 	  host_int_8 a = dest_addr++;
  	  little_int_1 data = c;
  	  host_int_4 addr = a;
  
  	  bus::status s;
+ 
  	  do // loop while memory getting ready
  	    {
  	      s = b->write(addr, data);
! 	    } while (s == bus::delayed);
  
! 	  if (s != bus::ok) // abort on error
  	    {
! 	      cerr << "loader: write to " << who << " accessor failed at address "
  		   << make_numeric_attribute (addr, ios::hex | ios::showbase)
  		   << ", status "
  		   << (int) s << endl;
*************** elf_loader::load_function(char* dest_add
*** 287,297 ****
    return bytes;
  }
  
- 
- 
  // ----------------------------------------------------------------------------
  
- 
  static
  vector<string>
  compLoaderListTypes()
--- 293,300 ----
*************** compLoaderListTypes()
*** 301,325 ****
    return types;
  }
  
- 
  static
  component*
  compLoaderCreate(const string& typeName)
  {
!   if(typeName == "sw-load-elf")
      return new elf_loader();
    else
      return 0;
  }
  
- 
  static
  void
  compLoaderDelete(component* c)
  {
    delete dynamic_cast<elf_loader*>(c);
  }
- 
  
  // static object
  extern const component_library loader_component_library;
--- 304,325 ----
    return types;
  }
  
  static
  component*
  compLoaderCreate(const string& typeName)
  {
!   if (typeName == "sw-load-elf")
      return new elf_loader();
    else
      return 0;
  }
  
  static
  void
  compLoaderDelete(component* c)
  {
    delete dynamic_cast<elf_loader*>(c);
  }
  
  // static object
  extern const component_library loader_component_library;
Index: component/loader/elfload.c
===================================================================
RCS file: /cvs/src/src/sid/component/loader/elfload.c,v
retrieving revision 1.1
diff -p -r1.1 elfload.c
*** elfload.c	2000/12/07 19:30:54	1.1
--- elfload.c	2001/01/13 09:52:20
***************
*** 15,35 ****
  #include <elfload.h>
  #include <unistd.h>
  
! unsigned char fileHeader [52];
! unsigned char psymHdr[32];
  
  #define PT_LOAD 1
  
  struct LoadAreas
  {
!   char *loadAddr;
!   int memsize;
!   int filesize;
!   int offset;
    int loaded;
  } loadAreas[100]; // XXX: limit on number of loadable sections
  
- 
  /* 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.
--- 15,34 ----
  #include <elfload.h>
  #include <unistd.h>
  
! unsigned char fileHeader [64];
! unsigned char psymHdr[56];
  
  #define PT_LOAD 1
  
  struct LoadAreas
  {
!   host_int_8 loadAddr;
!   host_int_8 filesize;
!   host_int_8 offset;
!   int flags;
    int loaded;
  } loadAreas[100]; // XXX: limit on number of loadable sections
  
  /* 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.
*************** struct LoadAreas
*** 39,51 ****
  int
  readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian)
  {
!   int psymOffset;
    int psymSize;
    int psymNum;
!   unsigned entryPoint = 0;
    int loadAreaCount = 0;
    int x;
    int littleEndian;
  
    /* This is relatively straightforward. We first read in the file header,
       find out how many sections there are, determine which ones are loadable
--- 38,51 ----
  int
  readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian)
  {
!   host_int_8 psymOffset;
    int psymSize;
    int psymNum;
!   host_int_8 entryPoint = 0;
    int loadAreaCount = 0;
    int x;
    int littleEndian;
+   int sixtyfourbit;
  
    /* This is relatively straightforward. We first read in the file header,
       find out how many sections there are, determine which ones are loadable
*************** readElfFile (PFLOAD func, unsigned* entr
*** 53,90 ****
  
       There is one major failing, tho--if the psym header isn't at the front
       of the file, and we're loading from a stream that we can't back
!      up on, we will lose. */
!   if (func (NULL, fileHeader, 0, 52) != 52)
      {
        return 0;
      }
    littleEndian = (fileHeader[EI_DATA] == ELFDATA2LSB);
!   entryPoint = fetchWord (fileHeader+24, littleEndian);
!   psymOffset = fetchWord (fileHeader+28, littleEndian);
!   psymSize = fetchShort (fileHeader+42, littleEndian);
!   psymNum = fetchShort (fileHeader+44, littleEndian);
    for (x = 0; x < psymNum; x++)
      {
!       if (func (NULL, psymHdr, psymOffset, 32) != 32)
! 	{
! 	  return 0;
! 	}
!       if (fetchWord (psymHdr, littleEndian) == PT_LOAD)
! 	{
! 	  loadAreas[loadAreaCount].loadAddr = (char *)fetchWord(psymHdr+8,
! 								littleEndian);
! 	  loadAreas[loadAreaCount].offset = fetchWord(psymHdr+4, littleEndian);
! 	  loadAreas[loadAreaCount].filesize = fetchWord(psymHdr+16,
! 							littleEndian);
! 	  loadAreas[loadAreaCount].loaded = 0;
! 	  loadAreaCount++;
! 	}
        psymOffset += psymSize;
      }
    /* Yuck. N^2 behavior (where N is the # of loadable sections). */
    for (x = 0; x < loadAreaCount; x++)
      {
!       int which;
        int smallest = -1, smallestSz = -1;
        /* Find smallest not-loaded */
        for (which = 0; which < loadAreaCount; which++)
--- 53,132 ----
  
       There is one major failing, tho--if the psym header isn't at the front
       of the file, and we're loading from a stream that we can't back
!      up on, we will lose.  */
!   if (func (NULL, fileHeader, 0, 64, 0) != 64)
      {
        return 0;
      }
+ 
+   /* Check this is an ELF file.  */
+   if (fileHeader[0] != 0x7f
+     || fileHeader[1] != 'E'
+     || fileHeader[2] != 'L'
+     || fileHeader[3] != 'F')
+       return 0;
+ 
+   sixtyfourbit = (fileHeader[EI_CLASS] == ELFCLASS64);
    littleEndian = (fileHeader[EI_DATA] == ELFDATA2LSB);
! 
!   if (sixtyfourbit) 
!     {
!       entryPoint = fetchQuad (fileHeader+24, littleEndian);
!       psymOffset = fetchQuad (fileHeader+32, littleEndian);
!       psymSize = fetchShort (fileHeader+54, littleEndian);
!       psymNum = fetchShort (fileHeader+56, littleEndian);
!     }
!   else
!     {
!       entryPoint = fetchWord (fileHeader+24, littleEndian);
!       psymOffset = fetchWord (fileHeader+28, littleEndian);
!       psymSize = fetchShort (fileHeader+42, littleEndian);
!       psymNum = fetchShort (fileHeader+44, littleEndian);
!     }
    for (x = 0; x < psymNum; x++)
      {
!       if (sixtyfourbit)
!         {
! 	  if (func (NULL, psymHdr, psymOffset, 56, 0) != 56)
! 	    {
! 	      return 0;
! 	    }
! 	  if (fetchWord (psymHdr, littleEndian) == PT_LOAD)
! 	    {
! 	      loadAreas[loadAreaCount].loadAddr = fetchQuad(psymHdr+16,
! 							    littleEndian);
! 	      loadAreas[loadAreaCount].offset = fetchQuad(psymHdr+8, littleEndian);
! 	      loadAreas[loadAreaCount].filesize = fetchQuad(psymHdr+32,
! 							    littleEndian);
! 	      loadAreas[loadAreaCount].flags = fetchWord(psymHdr+4, littleEndian);
! 	      loadAreas[loadAreaCount].loaded = 0;
! 	      loadAreaCount++;
! 	    }
!         }
!       else
!         {
! 	  if (func (NULL, psymHdr, psymOffset, 32, 0) != 32)
! 	    {
! 	      return 0;
! 	    }
! 	  if (fetchWord (psymHdr, littleEndian) == PT_LOAD)
! 	    {
! 	      loadAreas[loadAreaCount].loadAddr = fetchWord(psymHdr+8,
! 								    littleEndian);
! 	      loadAreas[loadAreaCount].offset = fetchWord(psymHdr+4, littleEndian);
! 	      loadAreas[loadAreaCount].filesize = fetchWord(psymHdr+16,
! 							    littleEndian);
! 	      loadAreas[loadAreaCount].flags = fetchWord(psymHdr+24, littleEndian);
! 	      loadAreas[loadAreaCount].loaded = 0;
! 	      loadAreaCount++;
! 	    }
!         }
        psymOffset += psymSize;
      }
    /* Yuck. N^2 behavior (where N is the # of loadable sections). */
    for (x = 0; x < loadAreaCount; x++)
      {
!       int which, is_insn;
        int smallest = -1, smallestSz = -1;
        /* Find smallest not-loaded */
        for (which = 0; which < loadAreaCount; which++)
*************** readElfFile (PFLOAD func, unsigned* entr
*** 98,107 ****
  		}
  	    }
  	}
        if (func (loadAreas[smallest].loadAddr,
  		NULL,
  		loadAreas[smallest].offset,
! 		loadAreas[smallest].filesize) != loadAreas[smallest].filesize)
  	{
  	  return 0;
  	}
--- 140,152 ----
  		}
  	    }
  	}
+       is_insn = (((loadAreas[smallest].loadAddr) & PF_X|PF_R) == (PF_X|PF_R))
+ 	      || ((loadAreas[smallest].loadAddr >> 32) & 1);
        if (func (loadAreas[smallest].loadAddr,
  		NULL,
  		loadAreas[smallest].offset,
! 		loadAreas[smallest].filesize,
! 		is_insn) != loadAreas[smallest].filesize)
  	{
  	  return 0;
  	}
Index: component/loader/elfload.h
===================================================================
RCS file: /cvs/src/src/sid/component/loader/elfload.h,v
retrieving revision 1.1
diff -p -r1.1 elfload.h
*** elfload.h	2000/12/07 19:30:54	1.1
--- elfload.h	2001/01/13 09:52:20
***************
*** 18,27 ****
  #define BYTE(X,offset) (((X)[offset]) & 255)
  #define fetchShortLittle(addr) (BYTE((addr),1)*256+BYTE((addr),0))
  #define fetchWordLittle(addr) (fetchShortLittle (addr) + fetchShortLittle((addr) + 2) * 65536)
  #define fetchShortBig(addr) (BYTE((addr),0)*256+BYTE((addr),1))
  #define fetchWordBig(addr) (fetchShortBig (addr) * 65536 + fetchShortBig((addr) + 2))
! #define fetchWord(ADDR,LITTLE) ((LITTLE) ? fetchWordLittle((ADDR)) : fetchWordBig((ADDR)))
  #define fetchShort(ADDR,LITTLE) ((LITTLE) ? fetchShortLittle((ADDR)) : fetchShortBig((ADDR)))
  
  /* 
     PFLOAD represents a function that will read file data. 
--- 18,30 ----
  #define BYTE(X,offset) (((X)[offset]) & 255)
  #define fetchShortLittle(addr) (BYTE((addr),1)*256+BYTE((addr),0))
  #define fetchWordLittle(addr) (fetchShortLittle (addr) + fetchShortLittle((addr) + 2) * 65536)
+ #define fetchQuadLittle(addr) (fetchWordLittle ((addr)) + ((host_int_8)fetchWordLittle((addr) + 4) << 32))
  #define fetchShortBig(addr) (BYTE((addr),0)*256+BYTE((addr),1))
  #define fetchWordBig(addr) (fetchShortBig (addr) * 65536 + fetchShortBig((addr) + 2))
! #define fetchQuadBig(addr) (((host_int_8)fetchWordBig ((addr)) << 32) + fetchWordBig((addr) + 4))
  #define fetchShort(ADDR,LITTLE) ((LITTLE) ? fetchShortLittle((ADDR)) : fetchShortBig((ADDR)))
+ #define fetchWord(ADDR,LITTLE) ((LITTLE) ? fetchWordLittle((ADDR)) : fetchWordBig((ADDR)))
+ #define fetchQuad(ADDR,LITTLE) ((LITTLE) ? fetchQuadLittle((ADDR)) : fetchQuadBig((ADDR)))
  
  /* 
     PFLOAD represents a function that will read file data. 
***************
*** 29,45 ****
     raw file data. If DEST is NULL, then DEST2 should be used.
     OFFSET is the byte offset into the file to be read.
     AMOUNT is the number of bytes to read.
  
     If OFFSET and AMOUNT are both negative, then the file should be
     closed (any remaining bytes are to be ignored). */
  
! typedef int (*PFLOAD)(char *dest, char *dest2, int offset, int amount);
  /* Load an ELF executable into memory. FUNC is used to actually read the
     file. */
  extern int readElfFile(PFLOAD func, unsigned*, int*);
  
  #define EI_DATA 5
  #define ELFDATA2LSB 1 /* little endian */
  #define ELFDATA2MSB 2 /* big endian */
  
  #endif
--- 32,57 ----
     raw file data. If DEST is NULL, then DEST2 should be used.
     OFFSET is the byte offset into the file to be read.
     AMOUNT is the number of bytes to read.
+    INSN_SPACE is true if this data should be loaded into instruction space.
  
     If OFFSET and AMOUNT are both negative, then the file should be
     closed (any remaining bytes are to be ignored). */
  
! 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);
  /* Load an ELF executable into memory. FUNC is used to actually read the
     file. */
  extern int readElfFile(PFLOAD func, unsigned*, int*);
  
+ #define EI_CLASS 4
+ #define ELFCLASS64  2 /* 64 bit */
  #define EI_DATA 5
  #define ELFDATA2LSB 1 /* little endian */
  #define ELFDATA2MSB 2 /* big endian */
+ 
+ /* Elf program header flags */
+ #define PF_X	0x01	/* executable */
+ #define PF_R	0x04	/* readable */
  
  #endif
Index: component/loader/sw-load-elf.txt
===================================================================
RCS file: /cvs/src/src/sid/component/loader/sw-load-elf.txt,v
retrieving revision 1.1
diff -p -r1.1 sw-load-elf.txt
*** sw-load-elf.txt	2000/12/07 19:30:54	1.1
--- sw-load-elf.txt	2001/01/13 09:52:20
***************
*** 6,12 ****
  
    Attributes: file verbose? state-snapshot
    Pins: load! start-pc-set endian-set error
!   Accessors: load-accessor
  
    Shared library: libloader.la
    Symbol: loader_component_library
--- 6,12 ----
  
    Attributes: file verbose? state-snapshot
    Pins: load! start-pc-set endian-set error
!   Accessors: load-accessor-insn load-accessor-data
  
    Shared library: libloader.la
    Symbol: loader_component_library
***************
*** 61,67 ****
  	new mapper bus
  	connect-pin reset-manager input <- main starting
  	connect-pin reset-manager output-1 -> loader load!
!         connect-bus loader load-accessor bus access-port
  	set loader file "/foo/bar.x"
          set loader verbose? 1
  	connect-pin loader start-pc-set -> cpu start-pc-set!
--- 61,68 ----
  	new mapper bus
  	connect-pin reset-manager input <- main starting
  	connect-pin reset-manager output-1 -> loader load!
!         connect-bus loader load-accessor-insn bus access-port
!         connect-bus loader load-accessor-data bus access-port
  	set loader file "/foo/bar.x"
          set loader verbose? 1
  	connect-pin loader start-pc-set -> cpu start-pc-set!
***************
*** 82,85 ****
        - verbose? | setting | 1/0 | 0 | configuration
  
      * accessors
!       - load-accessor | write little_int_1 | loading
--- 83,87 ----
        - verbose? | setting | 1/0 | 0 | configuration
  
      * accessors
!       - load-accessor-insn | write little_int_1 | loading
!       - load-accessor-data | write little_int_1 | loading

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: RFA: loader Elf64 loader & split insn/data accessors
  2001-01-13  4:01 RFA: loader Elf64 loader & split insn/data accessors matthew green
@ 2001-01-13  5:41 ` Frank Ch. Eigler
  2001-01-13 19:12   ` matthew green
  0 siblings, 1 reply; 6+ messages in thread
From: Frank Ch. Eigler @ 2001-01-13  5:41 UTC (permalink / raw)
  To: matthew green; +Cc: sid

Hi -

On Sat, Jan 13, 2001 at 11:00:32PM +1100, matthew green wrote:
: [...]
: this following patch splits the current elf `loader' module
: [...] this hack allows full 32 bit harvard arch machines to have
: a full normal address space, with insn being (at the object file format)
: from 0x.10000.0000 ... 0x1.ffff.ffff.  

Right.


: it should be removed when sid can deal with >32 bit address spaces.

How do you suggest that should be done?  We used to have a host_int_8
address option in the sid::bus class; maybe it's time to bring it back.
At another point in history, the host_int_4 address option didn't exist,
forcing all address arithmetic to be done on long-long types, which was
a performance loser.

(I hesitate to mention the other option of writing new sidutil classes
that grow accessors & buses on demand in order to represent a sparsely
populated 64-bit address space.)


: OK to commit?

Sure - it's a good first step.  

I would suggest though renaming the "insn"/"data" portions of the code and
accessor names names to something like "0" and "1", in an attempt to encode
the 33rd bit of the address in the name, rather than our specific
interpretation of that bit for a single target port.

Also, what about the "set-pc!" output signal?

Also, it would be nice to commit some elf32 and elf64 executables into
the test suite, and run the elf-loader on them.

- FChE
-- 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE6YFrwVZbdDOm/ZT0RArKQAKCF5xklWn/KdbbGhrqjqlduHGpVnACeKgqU
VqUJAVY1NFNzXiOljaqL5g8=
=Ca7u
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 6+ messages in thread

* re: RFA: loader Elf64 loader & split insn/data accessors
  2001-01-13  5:41 ` Frank Ch. Eigler
@ 2001-01-13 19:12   ` matthew green
  2001-01-13 21:08     ` matthew green
  0 siblings, 1 reply; 6+ messages in thread
From: matthew green @ 2001-01-13 19:12 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: sid

   
   
   : it should be removed when sid can deal with >32 bit address spaces.
   
   How do you suggest that should be done?  We used to have a host_int_8

ideally, we should have a host_int_8 version of the bus write/read
interfaces.. but that's 16 more functions..

   : OK to commit?
   
   Sure - it's a good first step.  

OK, done.  i still need to finish the debugger changes for this also.
   
   I would suggest though renaming the "insn"/"data" portions of the code and
   accessor names names to something like "0" and "1", in an attempt to encode
   the 33rd bit of the address in the name, rather than our specific
   interpretation of that bit for a single target port.

actually, i kinda prefer insn vs. data here.  i think going the 0/1 way is
only useful if we don't have host_int_8 address calls available (and i think
not doing that would be a bad idea).
   
   Also, what about the "set-pc!" output signal?

i assume you mean start-pc-set! ?  what about it?
   
   Also, it would be nice to commit some elf32 and elf64 executables into
   the test suite, and run the elf-loader on them.

ok.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* re: RFA: loader Elf64 loader & split insn/data accessors
  2001-01-13 19:12   ` matthew green
@ 2001-01-13 21:08     ` matthew green
  2001-01-14  9:55       ` Frank Ch. Eigler
  0 siblings, 1 reply; 6+ messages in thread
From: matthew green @ 2001-01-13 21:08 UTC (permalink / raw)
  To: sid

   
   OK, done.  i still need to finish the debugger changes for this also.


this is the debugger patch.  it adds a new "debugger_bus_insn" to each
component, default to the insn_bus (as "debugger_bus" defaults to the
data_bus).  in the GDB component, it looks for the "debugger-bus-insn"
for accesses with bit 33 set, or in the old "debugger-bus" otherwise.

i've tested this change with a couple of internal ports and it seems
to work OK...


.mrg.


[component/gdb/ChangeLog]
2001-01-14  matthew green  <mrg@redhat.com>

	* gdb.cxx (gdb::process_get_mem): Use "debugger-bus-insn" for
	addresses with bit 33 set.
	(gdb::process_set_mem): Likewise.

[include/ChangeLog]
2001-01-14  matthew green  <mrg@redhat.com>

	* include/sidcpuutil.h (basic_cpu): New debugger_bus_insn bus
	for debugger access to the instruction bus, attribute name of
	"debugger-bus-insn".


Index: component/gdb/gdb.cxx
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/component/gdb/gdb.cxx,v
retrieving revision 1.36
diff -p -r1.36 gdb.cxx
*** gdb.cxx	2001/01/04 17:08:41	1.36
--- gdb.cxx	2001/01/14 04:31:46
*************** gdb::process_get_mem (struct gdbserv_reg
*** 545,563 ****
        gdbserv_output_string (gdbserv, "E01");
        return;
      }
-   sid::bus* memory = cpu->find_bus ("debugger-bus");
-   if (! memory)
-     {
-       cerr << "No debugger-bus!" << endl;
-       gdbserv_output_string (gdbserv, "E02");
-       return;
-     }
   
    endian e;
    component::status s = 
      parse_attribute (cpu->attribute_value ("endian"), e);
    if (s != component::ok) assert (e == endian_unknown);
  
    // XXX: 64-bit addresses unsupported
    if (0 && addr8 >= (1ULL << 32))
      {
--- 545,570 ----
        gdbserv_output_string (gdbserv, "E01");
        return;
      }
   
    endian e;
    component::status s = 
      parse_attribute (cpu->attribute_value ("endian"), e);
    if (s != component::ok) assert (e == endian_unknown);
  
+   // XXX: 33-bit addresses -> 0x1.0000.0000 -> insn ram
+   string which_bus;
+   if (addr8 & 0x100000000ULL)
+     which_bus = "debugger-bus-insn";
+   else
+     which_bus = "debugger-bus";
+   sid::bus* memory = cpu->find_bus (which_bus);
+   if (!memory)
+     {
+       cerr << "No " << which_bus << "!" << endl;
+       gdbserv_output_string (gdbserv, "E02");
+       return;
+     }
+ 
    // XXX: 64-bit addresses unsupported
    if (0 && addr8 >= (1ULL << 32))
      {
*************** gdb::process_set_mem (struct gdbserv_reg
*** 625,642 ****
        gdbserv_output_string (gdbserv, "E01");
        return;
      }
-   sid::bus* memory = cpu->find_bus ("debugger-bus");
-   if (! memory)
-     {
-       cerr << "No debugger-bus!" << endl;
-       gdbserv_output_string (gdbserv, "E02");
-       return;
-     }
   
    endian e;
    component::status s = 
      parse_attribute (cpu->attribute_value ("endian"), e);
    if (s != component::ok) assert (e == endian_unknown);
  
    // XXX: 64-bit addresses unsupported
    if (0 && addr8 >= (1ULL << 32))
--- 632,656 ----
        gdbserv_output_string (gdbserv, "E01");
        return;
      }
   
    endian e;
    component::status s = 
      parse_attribute (cpu->attribute_value ("endian"), e);
    if (s != component::ok) assert (e == endian_unknown);
+ 
+   // XXX: 33-bit addresses -> 0x1.0000.0000 -> insn ram
+   string which_bus;
+   if (addr8 & 0x100000000ULL)
+     which_bus = "debugger-bus-insn";
+   else
+     which_bus = "debugger-bus";
+   sid::bus* memory = cpu->find_bus (which_bus);
+   if (! memory)
+     {
+       cerr << "No " << which_bus << "!" << endl;
+       gdbserv_output_string (gdbserv, "E02");
+       return;
+     }
  
    // XXX: 64-bit addresses unsupported
    if (0 && addr8 >= (1ULL << 32))
Index: include/sidcpuutil.h
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/sidcpuutil.h,v
retrieving revision 1.17
diff -p -r1.17 sidcpuutil.h
*** sidcpuutil.h	2001/01/10 19:41:02	1.17
--- sidcpuutil.h	2001/01/14 04:31:46
*************** namespace sidutil
*** 350,355 ****
--- 350,356 ----
      // debugger access functions
    private:
      passthrough_bus debugger_bus;
+     passthrough_bus debugger_bus_insn;
      virtual std::string dbg_get_reg (sid::host_int_4 n) = 0;
      virtual sid::component::status dbg_set_reg (sid::host_int_4 n, const std::string& s) = 0;
  
*************** public:
*** 402,408 ****
        flush_icache_pin (this, & basic_cpu::flush_icache_pin_handler),
        pc_set_pin (this, & basic_cpu::pc_set_pin_handler),
        endian_set_pin (this, & basic_cpu::endian_set_pin_handler),
!       debugger_bus (& this->data_bus)
        {
  	// buses
  	this->data_bus = 0;
--- 403,410 ----
        flush_icache_pin (this, & basic_cpu::flush_icache_pin_handler),
        pc_set_pin (this, & basic_cpu::pc_set_pin_handler),
        endian_set_pin (this, & basic_cpu::endian_set_pin_handler),
!       debugger_bus (& this->data_bus),
!       debugger_bus_insn (& this->insn_bus)
        {
  	// buses
  	this->data_bus = 0;
*************** public:
*** 410,415 ****
--- 412,418 ----
  	this->insn_bus = 0;
  	add_accessor ("insn-memory", & this->insn_bus);
  	add_bus ("debugger-bus", & this->debugger_bus);
+ 	add_bus ("debugger-bus-insn", & this->debugger_bus_insn);
  
  	// pins
  	add_pin ("step!", & this->step_pin);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: RFA: loader Elf64 loader & split insn/data accessors
  2001-01-13 21:08     ` matthew green
@ 2001-01-14  9:55       ` Frank Ch. Eigler
  2001-01-15  8:28         ` debugger_bus_insn dead (was: re: RFA: loader Elf64 loader & split insn/data accessors) matthew green
  0 siblings, 1 reply; 6+ messages in thread
From: Frank Ch. Eigler @ 2001-01-14  9:55 UTC (permalink / raw)
  To: matthew green; +Cc: sid

Hi -

On Sun, Jan 14, 2001 at 04:04:48PM +1100, matthew green wrote:
: [...]
:    OK, done.  i still need to finish the debugger changes for this also.
: 
: this is the debugger patch.  it adds a new "debugger_bus_insn" to each
: component, default to the insn_bus (as "debugger_bus" defaults to the
: data_bus).  [...]

Since this code does hard-code the bit-33 interpretation, I'd rather
not leave it mainstream for long.  Do you swear, by penalty of certain
dehairization, that when the bus api enlargements occur, you will
unhackify this component?

Even if yes, code hygiene may make it worth it to identify this
extension with a new component type, such as "sw-debug-gdb-bit33hack",
even if the same (parametrized, inherited, or even completely 
identical) C++ code implements both.

- FChE
-- 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE6YegVVZbdDOm/ZT0RAstqAJ0eJbXoez2xS+uTjDvB+Ub1Nr4/xACfZxDa
4KT2PCzMhAKSoVp6r6vrtsQ=
=gEsj
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 6+ messages in thread

* debugger_bus_insn dead (was: re: RFA: loader Elf64 loader & split insn/data accessors)
  2001-01-14  9:55       ` Frank Ch. Eigler
@ 2001-01-15  8:28         ` matthew green
  0 siblings, 0 replies; 6+ messages in thread
From: matthew green @ 2001-01-15  8:28 UTC (permalink / raw)
  To: sid

patch withdrawn.

   
   On Sun, Jan 14, 2001 at 04:04:48PM +1100, matthew green wrote:
   : [...]
   :    OK, done.  i still need to finish the debugger changes for this also.
   : 
   : this is the debugger patch.  it adds a new "debugger_bus_insn" to each
   : component, default to the insn_bus (as "debugger_bus" defaults to the
   : data_bus).  [...]
   
   Since this code does hard-code the bit-33 interpretation, I'd rather
   not leave it mainstream for long.  Do you swear, by penalty of certain
   dehairization, that when the bus api enlargements occur, you will
   unhackify this component?

actually, i've worked around this another way, though i would have
most definately sworn to unhackify the component, had not this been
the case...

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-01-15  8:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-01-13  4:01 RFA: loader Elf64 loader & split insn/data accessors matthew green
2001-01-13  5:41 ` Frank Ch. Eigler
2001-01-13 19:12   ` matthew green
2001-01-13 21:08     ` matthew green
2001-01-14  9:55       ` Frank Ch. Eigler
2001-01-15  8:28         ` debugger_bus_insn dead (was: re: RFA: loader Elf64 loader & split insn/data accessors) matthew green

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).