OSDN Git Service

2005-08-19 Dave Brolley <brolley@redhat.com>
authorbrolley <brolley>
Fri, 19 Aug 2005 19:45:22 +0000 (19:45 +0000)
committerbrolley <brolley>
Fri, 19 Aug 2005 19:45:22 +0000 (19:45 +0000)
        * Contribute the following changes:

        2005-07-13  Dave Brolley  <brolley@redhat.com>

        * compLoader.cxx (generic_loader): Inherit virtually from
        fixed_attribute_map_component. Inherit from no_relation_component.

        2005-06-06  Dave Brolley  <brolley@redhat.com>

        * elfload.c (readElfFile): Return and empty symbol table if none found.

        * compLoader.cxx: Add using cleause for
        sidutil::configurable_component.
        (generic_loader): fixed_pin_map_component and configurable_component
        inherited virtually.
        (configure): New virtual override in generic_loader.
        (check_function_pin_handler): Return the empty string if no function
        is associated with the given address.
        * sw-load-elf.xml: Add description of new interfaces.
        * sw-load-elf.txt: Regenerated.

        2005-05-29  Dave Brolley  <brolley@redhat.com>

        * elfload.h (StringTable, Symbol): New struct types.
        (readElfFile): New takes symbol_table argument.
        (SHT_SYMTAB, SHT_STRTAB, ELF32_ST_TYPE, STT_FUNC): New macros.
        * elfload.c (stringTables,stringTableCount,stringTableNum): New
        static variables.
        (newStringTable): New static function.
        (symbolTable,symbolCount,symbolNum): New static variables.
        (newSymbol): New static function.
        (readElfFile): New takes symbol_table argument. Build string tables and
        symbol table while reading the input file.
        * compLoader.cxx (elf_loader): New constructor.
        (load_it): Obtain symmol_table from readElfFile.
        (check_function_pin,symbol_table,current_function): New members
        of elf_loader.
        (check_function_pin_handler): New method of elf_loader.

sid/component/loader/ChangeLog
sid/component/loader/compLoader.cxx
sid/component/loader/elfload.c
sid/component/loader/elfload.h
sid/component/loader/sw-load-elf.txt
sid/component/loader/sw-load-elf.xml

index e2a8d09..477b1b0 100644 (file)
@@ -1,3 +1,44 @@
+2005-08-19  Dave Brolley  <brolley@redhat.com>
+
+       * Contribute the following changes:
+
+       2005-07-13  Dave Brolley  <brolley@redhat.com>
+
+       * compLoader.cxx (generic_loader): Inherit virtually from
+       fixed_attribute_map_component. Inherit from no_relation_component.
+
+       2005-06-06  Dave Brolley  <brolley@redhat.com>
+
+       * elfload.c (readElfFile): Return and empty symbol table if none found.
+
+       * compLoader.cxx: Add using cleause for
+       sidutil::configurable_component.
+       (generic_loader): fixed_pin_map_component and configurable_component
+       inherited virtually.
+       (configure): New virtual override in generic_loader.
+       (check_function_pin_handler): Return the empty string if no function
+       is associated with the given address.
+       * sw-load-elf.xml: Add description of new interfaces.
+       * sw-load-elf.txt: Regenerated.
+
+       2005-05-29  Dave Brolley  <brolley@redhat.com>
+
+       * elfload.h (StringTable, Symbol): New struct types.
+       (readElfFile): New takes symbol_table argument.
+       (SHT_SYMTAB, SHT_STRTAB, ELF32_ST_TYPE, STT_FUNC): New macros.
+       * elfload.c (stringTables,stringTableCount,stringTableNum): New
+       static variables.
+       (newStringTable): New static function.
+       (symbolTable,symbolCount,symbolNum): New static variables.
+       (newSymbol): New static function.
+       (readElfFile): New takes symbol_table argument. Build string tables and
+       symbol table while reading the input file.
+       * compLoader.cxx (elf_loader): New constructor.
+       (load_it): Obtain symmol_table from readElfFile.
+       (check_function_pin,symbol_table,current_function): New members
+       of elf_loader.
+       (check_function_pin_handler): New method of elf_loader.
+
 2005-06-03  Jim Blandy  <jimb@redhat.com>
 
        * Makefile.am (LIBIBERTY): Link against the libiberty.a from
index 697f056..ebc81f4 100644 (file)
@@ -1,6 +1,6 @@
 // compLoader.cxx - object file loader component.  -*- C++ -*-
 
-// Copyright (C) 1999, 2000, 2003, 2004 Red Hat.
+// Copyright (C) 1999, 2000, 2003, 2004, 2005 Red Hat.
 // This file is part of SID and is licensed under the GPL.
 // See the file COPYING.SID for conditions for redistribution.
 
@@ -50,6 +50,7 @@ using sidutil::fixed_attribute_map_component;
 using sidutil::fixed_pin_map_component;
 using sidutil::fixed_accessor_map_component;
 using sidutil::no_relation_component;
+using sidutil::configurable_component;
 using sidutil::output_pin;
 using sidutil::callback_pin;
 using sidutil::string2stream;
@@ -112,10 +113,11 @@ class loader_probe_bus: public sidutil::passthrough_bus
 
 class generic_loader: public virtual component,
                      protected fixed_bus_map_component,
-                     protected fixed_attribute_map_component,
-                     protected fixed_pin_map_component,
+                     protected virtual fixed_attribute_map_component,
+                     protected virtual fixed_pin_map_component,
                      protected fixed_accessor_map_component,
-                     protected no_relation_component
+                     protected no_relation_component,
+                     protected virtual configurable_component
 {
 private:
   callback_pin<generic_loader> doit_pin;
@@ -164,6 +166,8 @@ protected:
   sid::component::status restore_state(const string& state)
     { return parse_attribute(state, *this); }
 
+  virtual void configure (const string &config);
+
 public:
   generic_loader(): 
     doit_pin(this, & generic_loader::load_it), 
@@ -196,6 +200,22 @@ public:
     
 };
 
+void
+generic_loader::configure (const string &config)
+{
+  // Call up to the base class first
+  configurable_component::configure (config);
+
+  // Now handle relevent configuration for us.
+  if (config.size () < 12)
+    return;
+  if (config.substr (0, 8) == "verbose=")
+    {
+      verbose_p = (config.substr (8) == "true");
+      return;
+    }
+}
+
 ostream& 
 operator << (ostream& out, const generic_loader& it)
 {
@@ -229,6 +249,19 @@ operator >> (istream& in, generic_loader& it)
 
 class elf_loader: public generic_loader
 {
+public:
+  elf_loader ()
+    : generic_loader (),
+      symbol_table (0),
+      current_function (""),
+      check_function_pin (this, &elf_loader::check_function_pin_handler)
+    {
+      add_pin ("function?", &check_function_pin);
+      add_attribute ("current-function", & current_function);
+    }
+  ~elf_loader () throw () {}
+
+private:
   // static pointer to active instance (XXX: concurrency?)
   static elf_loader* freeloader;
 
@@ -270,7 +303,7 @@ class elf_loader: public generic_loader
       const struct TextSection *section_table;
       int success_p = readElfFile(& elf_loader::load_function,
                                  & entry_point, & little_endian_p,
-                                 & eflags, & section_table);
+                                 & eflags, & section_table, & symbol_table);
       probe_upstream.set_section_table (section_table);
       elf_loader::freeloader = 0;
 
@@ -300,6 +333,13 @@ class elf_loader: public generic_loader
       delete this->file;
       this->file = 0;
     }
+
+protected:
+  callback_pin<elf_loader> check_function_pin;
+  void check_function_pin_handler (host_int_4 addr);
+
+  const struct Symbol *symbol_table;
+  string current_function;
 };
 
 // static variable
@@ -376,6 +416,48 @@ elf_loader::load_function(host_int_8 dest_addr, char *host_addr, host_int_8 file
   return bytes;
 }
 
+void
+elf_loader::check_function_pin_handler (host_int_4 addr)
+{
+  // Find the function corresponding to the given address in the symbol
+  // table, if any, and set current_function to that name. If no function is
+  // found, set current_function to a string representing the address.
+  if (symbol_table)
+    {
+      unsigned closest = 0;
+      host_int_8 min_difference = ~(host_int_8)0;
+      unsigned ix;
+      for (ix = 0; symbol_table[ix].name; ++ix)
+       {
+         // Don't consider unnamed symbols.
+         if (! symbol_table[ix].name[0])
+           continue;
+         host_int_8 sym_addr = symbol_table[ix].addr;
+         host_int_8 sym_size = symbol_table[ix].size;
+         if (addr == sym_addr)
+           break;
+         if (addr > sym_addr && addr < (sym_addr + sym_size))
+           break;
+         if (addr - sym_addr < min_difference)
+           {
+             min_difference = addr - sym_addr;
+             closest = ix;
+           }
+       }
+      if (symbol_table[ix].name)
+       {
+         current_function = symbol_table[ix].name;
+         return;
+       }
+      if (closest != 0)
+       {
+         current_function = symbol_table[closest].name;
+         return;
+       }
+    }
+  current_function = "";
+}
+
 // ----------------------------------------------------------------------------
 
 static
index e184d67..2bf92f4 100644 (file)
@@ -1,6 +1,6 @@
 /* Simple ELF loader
  *
- * Copyright (c) 1998, 2002, 2004 Red Hat
+ * Copyright (c) 1998, 2002, 2004, 2005 Red Hat
  *
  * The authors hereby grant permission to use, copy, modify, distribute,
  * and license this software and its documentation for any purpose, provided
@@ -59,7 +59,7 @@ textSectionAddress (unsigned long long address, const struct TextSection *sectio
 {
   int i;
 
-  // Not a text section address if there is no table.
+  /* Not a text section address if there is no table.  */
   if (! section_table)
     return 0;
 
@@ -74,6 +74,36 @@ textSectionAddress (unsigned long long address, const struct TextSection *sectio
   return 0;
 }
 
+/* A new string table table is created for each loader in the system.  */
+static struct StringTable *stringTables;
+static int stringTableCount;
+static int stringTableNum;
+
+static void
+newStringTable (int index)
+{
+  if (index >= stringTableNum)
+    {
+      stringTableNum = index + 10;
+      stringTables = xrealloc (stringTables, stringTableNum * sizeof (*stringTables));
+    }
+}
+
+/* A new symbol table is created for each loader in the system.  */
+static struct Symbol *symbolTable;
+static int symbolCount;
+static int symbolNum;
+
+static void
+newSymbol (int index)
+{
+  if (index >= symbolNum)
+    {
+      symbolNum = index + 10;
+      symbolTable = xrealloc (symbolTable, symbolNum * sizeof (*symbolTable));
+    }
+}
+
 
 /* Read in an ELF file, using FUNC to read data from the stream.
    The result is a boolean indicating success.
@@ -83,14 +113,19 @@ textSectionAddress (unsigned long long address, const struct TextSection *sectio
 
 int
 readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian,
-            unsigned* e_flags, const struct TextSection **section_table)
+            unsigned* e_flags, const struct TextSection **section_table,
+            const struct Symbol **symbol_table)
 {
   unsigned char fileHeader [64];
   unsigned char psymHdr [56];
   unsigned char secHdr [64];
+  unsigned char symTabEntry [16];
   unsigned long long psymOffset;
   int psymSize;
   int psymNum;
+  unsigned long long symbolTableOffset;
+  unsigned long long symbolTableSize;
+  unsigned long long symbolTableStringTableIx;
   int eFlags;
   unsigned long long secOffset;
   int secSize;
@@ -211,11 +246,7 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian,
   /* FIXME: admin part of program segment is loaded.  */
 
   /* Look in the section table in order to determine which sections contain
-     code and which contain data.  */
-  textSections = 0;
-  textSectionNum = 0;
-  textSectionCount = 0;
-  newTextSection (textSectionCount);
+     code, data, symbols and strings.  */
   if (sixtyfourbit) 
     {
       secOffset = fetchQuad (fileHeader+40, littleEndian);
@@ -228,6 +259,13 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian,
       secSize = fetchShort (fileHeader+46, littleEndian);
       secNum = fetchShort (fileHeader+48, littleEndian);
     }
+  textSections = 0;
+  textSectionNum = 0;
+  textSectionCount = 0;
+  stringTables = 0;
+  stringTableNum = 0;
+  stringTableCount = 0;
+  newTextSection (textSectionCount);
   for (x = 0; x < secNum; x++)
     {
       if (func (0, secHdr, secOffset, secSize, 0) != secSize)
@@ -249,7 +287,8 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian,
         }
       else
         {
-         if (fetchWord(secHdr+8, littleEndian) & SHF_EXECINSTR)
+         unsigned flags = fetchWord(secHdr+8, littleEndian);
+         if (flags & SHF_EXECINSTR)
            {
              textSections[textSectionCount].lbound = 
                fetchWord(secHdr+12, littleEndian);
@@ -259,6 +298,24 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian,
              textSectionCount++;
              newTextSection (textSectionCount);
            }
+         else if (fetchWord(secHdr+4, littleEndian) == SHT_STRTAB)
+           {
+             unsigned offset = fetchWord(secHdr+16, littleEndian);
+             unsigned size = fetchWord(secHdr+20, littleEndian);
+             char *strings = xmalloc (size);
+             newStringTable (stringTableCount);
+             stringTables[stringTableCount].ix = x;
+             stringTables[stringTableCount].strings = strings;
+             if (func (0, strings, offset, size, 0) != size)
+               return 0;
+             ++stringTableCount;
+           }
+         else if (fetchWord(secHdr+4, littleEndian) == SHT_SYMTAB)
+           {
+             symbolTableOffset = fetchWord(secHdr+16, littleEndian);
+             symbolTableSize = fetchWord(secHdr+20, littleEndian);
+             symbolTableStringTableIx = fetchWord(secHdr+24, littleEndian);
+           }
         }
       secOffset += secSize;
     }
@@ -267,9 +324,49 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian,
   textSections[textSectionCount].lbound = 0;
   textSections[textSectionCount].hbound = 0;
 
+  /* Can't look for functions in the symbol table until all the sections have been
+     examined, since the string table for the symbol table may follow the symbol
+     table itself.  Identify the correct string table first.  */
+  const char *strings = 0;
+  for (x = 0; x < stringTableCount; ++x)
+    {
+      if (stringTables[x].ix == symbolTableStringTableIx)
+       strings = stringTables[x].strings;
+    }
+
+  /* Now look for functions and record their addresses and lengths.  */
+  symbolTable = 0;
+  symbolCount = 0;
+  symbolNum = 0;
+  newSymbol (symbolCount);
+  if (strings)
+    {
+      for (x = 0; x < symbolTableSize; x += sizeof (symTabEntry))
+       {
+         if (func (0, symTabEntry, symbolTableOffset + x, sizeof (symTabEntry), 0) != sizeof (symTabEntry))
+           return 0;
+         // TODO: Save only symbols representing functions
+         // PROBLEM: Some don't have the STT_FUNC flag set
+         symbolTable[symbolCount].name = strings + fetchWord(symTabEntry+0, littleEndian);
+         symbolTable[symbolCount].addr = fetchWord(symTabEntry+4, littleEndian);
+         symbolTable[symbolCount].size = fetchWord(symTabEntry+8, littleEndian);
+#if 0
+         printf ("found symbol %s at 0x%Lx for 0x%Lx\n",
+                 symbolTable[symbolCount].name,
+                 symbolTable[symbolCount].addr,
+                 symbolTable[symbolCount].size);
+#endif
+         symbolCount++;
+         newSymbol (symbolCount);
+       }
+    }
+  // Terminate the symbol table.
+  symbolTable[symbolCount].name = 0;
+
   *entry_point = entryPoint;
   *little_endian = littleEndian;
   *section_table = textSections;
+  *symbol_table = symbolTable;
   *e_flags = eFlags;
 
   return 1;
index 032ba78..8708b20 100644 (file)
@@ -1,6 +1,6 @@
 /* Header for simple ELF loader
  *
- * Copyright (c) 1998, 2004 Red Hat
+ * Copyright (c) 1998, 2004, 2005 Red Hat
  *
  * The authors hereby grant permission to use, copy, modify, distribute,
  * and license this software and its documentation for any purpose, provided
@@ -32,6 +32,19 @@ struct TextSection
   unsigned long long hbound;
 };
 
+struct StringTable
+{
+  unsigned ix;
+  const char *strings;
+};
+
+struct Symbol
+{
+  const char *name;
+  unsigned long long addr;
+  unsigned long long size;
+};
+
 /* 
    PFLOAD represents a function that will read file data. 
    DEST or DEST2 is used as the destination address to be written with the
@@ -48,7 +61,7 @@ typedef int (*PFLOAD)(unsigned long long dest, char *dest2, unsigned long long o
 extern int textSectionAddress(unsigned long long, const struct TextSection *);
 /* Load an ELF executable into memory. FUNC is used to actually read the
    file. */
-extern int readElfFile(PFLOAD func, unsigned*, int*, unsigned*, const struct TextSection **);
+extern int readElfFile(PFLOAD func, unsigned*, int*, unsigned*, const struct TextSection **, const struct Symbol **);
 
 #define EI_CLASS 4
 #define ELFCLASS64  2 /* 64 bit */
@@ -63,4 +76,12 @@ extern int readElfFile(PFLOAD func, unsigned*, int*, unsigned*, const struct Tex
 /* ELF section header flags */
 #define SHF_EXECINSTR  (1 << 2)        /* Executable machine instructions */
 
+/* ELF section header types */
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+
+/* ELF Symbol Table fields */
+#define ELF32_ST_TYPE(i) ((i)&0xf)
+#define STT_FUNC 2
+
 #endif
index 10459ed..6e8a294 100644 (file)
@@ -24,6 +24,16 @@ Functionality:
    |                | encourages this component to   |
    |                | provide informative messages   |
    |                | to cout during loading.        |
+   |                |                                |
+   |                | When the configure! is set,    |
+   |                | the new value is interpreted   |
+   |                | as a configuration spec. The   |
+   |                | spec is a colon-separated list |
+   |                | of items, each of which is     |
+   |                | passed in turn to the          |
+   |                | 'configure' method for         |
+   |                | interpretation and possible    |
+   |                | action.                        |
    |----------------+--------------------------------|
    |        loading | When the load! pin is driven,  |
    |                | this component will attempt to |
@@ -117,25 +127,25 @@ Component Reference:
 
   Component: sw-load-elf
 
-   +-------------------------------------------------------------+
-   |                            pins                             |
-   |-------------------------------------------------------------|
-   |         name          | direction | legalvalues | behaviors |
-   |-----------------------+-----------+-------------+-----------|
-   |load!                  |in         |any          |loading    |
-   |-----------------------+-----------+-------------+-----------|
-   |start-pc-set           |out        |any          |loading    |
-   |-----------------------+-----------+-------------+-----------|
-   |endian-set             |out        |0/1/2        |loading    |
-   |-----------------------+-----------+-------------+-----------|
-   |error                  |out        |any          |loading    |
-   |-----------------------+-----------+-------------+-----------|
-   |write-to-code-address  |out        |any address  |error      |
-   |                       |           |             |checking   |
-   |-----------------------+-----------+-------------+-----------|
-   |probe                  |in         |any address  |error      |
-   |                       |           |             |checking   |
-   +-------------------------------------------------------------+
+   +-----------------------------------------------------------------+
+   |                              pins                               |
+   |-----------------------------------------------------------------|
+   |         name          | direction | legalvalues |   behaviors   |
+   |-----------------------+-----------+-------------+---------------|
+   |function-address?      |in         |address      |configuration  |
+   |-----------------------+-----------+-------------+---------------|
+   |load!                  |in         |any          |loading        |
+   |-----------------------+-----------+-------------+---------------|
+   |start-pc-set           |out        |any          |loading        |
+   |-----------------------+-----------+-------------+---------------|
+   |endian-set             |out        |0/1/2        |loading        |
+   |-----------------------+-----------+-------------+---------------|
+   |error                  |out        |any          |loading        |
+   |-----------------------+-----------+-------------+---------------|
+   |write-to-code-address  |out        |any address  |error checking |
+   |-----------------------+-----------+-------------+---------------|
+   |probe                  |in         |any address  |error checking |
+   +-----------------------------------------------------------------+
 
    +-----------------------------------------------------+
    |                        buses                        |
@@ -159,6 +169,8 @@ Component Reference:
    |                |          |name    |             |               ||
    |----------------+----------+--------+-------------+---------------||
    |verbose?        |setting   |1/0     |0            |configuration  ||
+   |----------------+----------+--------+-------------+---------------||
+   |configure!      |setting   |string  |-            |configuration  ||
    +-------------------------------------------------------------------+
 
    +-------------------------------------------------+
index fe31b0c..42f26fd 100644 (file)
@@ -4,6 +4,11 @@
 <defcomplib lib="libloader.la" dlsym="loader_component_library">
   <defcomponent name="sw-load-elf" type="concrete">
 
+    <!-- relationships -->
+    <defrelationship name="dynamic-configurator"       behaviors="configuration" />
+
+    <!-- pins -->
+    <defpin name="function-address?"   direction="in"  legalvalues="address"   behaviors="configuration" />
     <defpin name="load!" direction="in" legalvalues="any" behaviors="loading"/>
     <defpin name="start-pc-set" direction="out" legalvalues="any" behaviors="loading"/>
     <defpin name="endian-set" direction="out" legalvalues="0/1/2" behaviors="loading"/>
@@ -14,6 +19,7 @@
     <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"/>
+    <defattribute name="configure!" category="setting" legalvalues="string" behaviors="configuration" />
     
     <defbus name="probe-upstream" accesses="read/write" behaviors="error checking"/>
 
       The "verbose?" attribute, when set, encourages this component to provide 
       informative messages to cout during loading.
       </p>
+
+      <p>When the <attribute>configure!</attribute> is set, the new value is interpreted
+         as a configuration spec.  The spec is a colon-separated list of items, each of
+         which is passed in turn to the 'configure' method for interpretation and possible
+         action.</p>
+
     </behavior>
 
     <behavior name="loading">