[kernel] r6302 - in people/waldi/linux-kbuild-2.6/src: . mod
Bastian Blank
waldi at costa.debian.org
Tue Mar 28 10:07:33 UTC 2006
Author: waldi
Date: Tue Mar 28 10:07:31 2006
New Revision: 6302
Added:
people/waldi/linux-kbuild-2.6/src/
people/waldi/linux-kbuild-2.6/src/mod/
people/waldi/linux-kbuild-2.6/src/mod/elf.cpp
people/waldi/linux-kbuild-2.6/src/mod/elf.hpp
people/waldi/linux-kbuild-2.6/src/mod/endian.hpp
people/waldi/linux-kbuild-2.6/src/mod/modpost.cpp
people/waldi/linux-kbuild-2.6/src/mod/module.cpp
people/waldi/linux-kbuild-2.6/src/mod/module.hpp
people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.cpp
people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.hpp
people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.tpp
people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.cpp
people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.hpp
people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.tpp
Log:
* src: New directory.
* src/mod: Add own modpost sources.
Added: people/waldi/linux-kbuild-2.6/src/mod/elf.cpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/elf.cpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,243 @@
+/*
+ * elf.cpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "elf.hpp"
+#include "endian.hpp"
+
+#include <stdexcept>
+
+#include <fcntl.h>
+#include <elf.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+using namespace Elf;
+
+namespace
+{
+ template <typename _class>
+ struct _elfdef
+ { };
+
+ template <>
+ struct _elfdef<file_class_32>
+ {
+ typedef Elf32_Ehdr Ehdr;
+ typedef Elf32_Shdr Shdr;
+ typedef Elf32_Sym Sym;
+ static inline uint8_t st_bind (uint8_t st_info) throw () { return ELF32_ST_BIND (st_info); }
+ static inline uint8_t st_type (uint8_t st_info) throw () { return ELF32_ST_TYPE (st_info); }
+ };
+
+ template <>
+ struct _elfdef<file_class_64>
+ {
+ typedef Elf64_Ehdr Ehdr;
+ typedef Elf64_Shdr Shdr;
+ typedef Elf64_Sym Sym;
+ static inline uint8_t st_bind (uint8_t st_info) throw () { return ELF64_ST_BIND (st_info); }
+ static inline uint8_t st_type (uint8_t st_info) throw () { return ELF64_ST_TYPE (st_info); }
+ };
+}
+
+file::file (const char *filename, void *mem, size_t len) throw (std::bad_alloc)
+: filename (std::string (filename)), mem (mem), len (len)
+{ }
+
+file::~file () throw ()
+{
+ ::munmap (mem, len);
+ for (std::vector<section *>::iterator it = sections.begin (); it != sections.end (); ++it)
+ delete *it;
+}
+
+file *file::open (const char *filename) throw (std::bad_alloc, std::runtime_error)
+{
+ struct stat buf;
+ int fd;
+ void *mem;
+ size_t len;
+ if ((fd = ::open (filename, O_RDONLY)) == -1)
+ throw std::runtime_error ("mapping failed");
+ try
+ {
+ if (::fstat (fd, &buf) == -1)
+ throw std::runtime_error ("mapping failed");
+ len = buf.st_size;
+ if ((mem = ::mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
+ throw std::runtime_error ("mapping failed");
+
+ const uint8_t *buf = static_cast <uint8_t *> (mem);
+
+ switch (buf[EI_CLASS])
+ {
+ case ELFCLASS32:
+ return open_class<file_class_32> (filename, buf, mem, len);
+ case ELFCLASS64:
+ return open_class<file_class_64> (filename, buf, mem, len);
+ default:
+ throw std::runtime_error ("Invalid file class");
+ }
+ }
+ catch (...)
+ {
+ ::close (fd);
+ throw;
+ }
+}
+
+template<typename _class>
+file *file::open_class (const char *filename, const uint8_t *buf, void * mem, size_t len) throw (std::bad_alloc, std::runtime_error)
+{
+ switch (buf[EI_DATA])
+ {
+ case ELFDATA2LSB:
+ return new file_data<_class, file_data_2LSB> (filename, mem, len);
+ case ELFDATA2MSB:
+ return new file_data<_class, file_data_2MSB> (filename, mem, len);
+ default:
+ throw std::runtime_error ("Invalid file data");
+ }
+}
+
+template <typename _class, typename _data>
+file_data<_class, _data>::file_data (const char *filename) throw (std::bad_alloc, std::runtime_error)
+: file (filename)
+{
+ construct ();
+}
+
+template <typename _class, typename _data>
+file_data<_class, _data>::file_data (const char *filename, void *mem, size_t len) throw (std::bad_alloc, std::runtime_error)
+: file (filename, mem, len)
+{
+ construct ();
+}
+
+template <typename _class, typename _data>
+void file_data<_class, _data>::construct () throw (std::bad_alloc, std::runtime_error)
+{
+ uint8_t *buf = static_cast <uint8_t *> (this->mem);
+ if (buf[EI_CLASS] != _class::id)
+ throw std::runtime_error ("Wrong file class");
+ if (buf[EI_DATA] != _data::id)
+ throw std::runtime_error ("Wrong data encoding");
+
+ typedef typename _elfdef<_class>::Ehdr Ehdr;
+ Ehdr *ehdr = static_cast <Ehdr *> (this->mem);
+ this->type = convert<_data, typeof (ehdr->e_type )> () (ehdr->e_type );
+ this->machine = convert<_data, typeof (ehdr->e_machine )> () (ehdr->e_machine );
+ this->shoff = convert<_data, typeof (ehdr->e_shoff )> () (ehdr->e_shoff );
+ this->shnum = convert<_data, typeof (ehdr->e_shnum )> () (ehdr->e_shnum );
+ this->shstrndx = convert<_data, typeof (ehdr->e_shstrndx)> () (ehdr->e_shstrndx);
+
+ typedef typename _elfdef<_class>::Shdr Shdr;
+ Shdr *shdrs = static_cast <Shdr *> (static_cast <void *> (static_cast <char *> (this->mem) + this->shoff));
+
+ this->sections.reserve (this->shnum);
+
+ for (unsigned int i = 0; i < this->shnum; i++)
+ {
+ section *temp;
+ switch (convert<_data, typeof (shdrs[i].sh_type)> () (shdrs[i].sh_type))
+ {
+ case section_type_SYMTAB::id:
+ temp = new section_real<_class, _data, section_type_SYMTAB> (&shdrs[i], this->mem);
+ break;
+ default:
+ temp = new section_real<_class, _data, section_type_UNDEFINED> (&shdrs[i], this->mem);
+ break;
+ }
+ this->sections.push_back (temp);
+ }
+
+ for (unsigned int i = 0; i < this->shnum; i++)
+ this->sections[i]->update_string_table (this);
+}
+
+void section::update_string_table (file *file) throw (std::bad_alloc)
+{
+ const section *section = file->get_section (file->get_shstrndx ());
+ this->name_string = std::string (static_cast <const char *> (section->_mem ()) + this->name);
+}
+
+template <typename _class, typename _data>
+section_data<_class, _data>::section_data (void *header, void *mem) throw ()
+{
+ typedef typename _elfdef<_class>::Shdr Shdr;
+ Shdr *shdr = static_cast <Shdr *> (header);
+ this->name = convert<_data, typeof (shdr->sh_name )> () (shdr->sh_name );
+ this->type = convert<_data, typeof (shdr->sh_type )> () (shdr->sh_type );
+ this->offset = convert<_data, typeof (shdr->sh_offset)> () (shdr->sh_offset);
+ this->size = convert<_data, typeof (shdr->sh_size )> () (shdr->sh_size );
+ this->link = convert<_data, typeof (shdr->sh_link )> () (shdr->sh_link );
+ this->mem = static_cast <void *> (static_cast <char *> (mem) + this->offset);
+}
+
+section_type<section_type_SYMTAB>::~section_type () throw ()
+{
+ for (std::vector<symbol *>::iterator it = symbols.begin (); it != symbols.end (); ++it)
+ delete *it;
+}
+
+void section_type<section_type_SYMTAB>::update_string_table (file *file) throw (std::bad_alloc)
+{
+ section::update_string_table (file);
+ for (unsigned int i = 0; i < symbols.size (); i++)
+ this->symbols[i]->update_string_table (file, link);
+}
+
+template <typename _class, typename _data>
+section_real<_class, _data, section_type_SYMTAB>::section_real (void *header, void *mem) throw (std::bad_alloc)
+: section_data<_class, _data> (header, mem)
+{
+ if (this->type != SHT_SYMTAB)
+ throw std::logic_error ("Wrong section type");
+ typedef typename _elfdef<_class>::Sym Sym;
+ Sym *syms = static_cast <Sym *> (this->mem);
+ unsigned int max = this->size / sizeof (Sym);
+
+ this->symbols.reserve (max);
+
+ for (unsigned int i = 0; i < max; i++)
+ this->symbols.push_back (new symbol_data<_class, _data> (&syms[i]));
+}
+
+template <typename _class, typename _data>
+symbol_data<_class, _data>::symbol_data (void *mem) throw ()
+{
+ typedef typename _elfdef<_class>::Sym Sym;
+ Sym *sym = static_cast <Sym *> (mem);
+ this->name = convert<_data, typeof (sym->st_name )> () (sym->st_name);
+ this->info = convert<_data, typeof (sym->st_info )> () (sym->st_info);
+ this->shndx = convert<_data, typeof (sym->st_shndx)> () (sym->st_shndx);
+ this->value = convert<_data, typeof (sym->st_value)> () (sym->st_value);
+ this->size = convert<_data, typeof (sym->st_size )> () (sym->st_size);
+ this->bind = _elfdef<_class>::st_bind (this->info);
+ this->type = _elfdef<_class>::st_type (this->info);
+}
+
+template <typename _class, typename _data>
+void symbol_data<_class, _data>::update_string_table (file *file, uint16_t s) throw (std::bad_alloc)
+{
+ const section *section = file->get_section (s);
+ this->name_string = std::string (static_cast <const char *> (section->_mem ()) + this->name);
+}
+
Added: people/waldi/linux-kbuild-2.6/src/mod/elf.hpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/elf.hpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,219 @@
+/*
+ * elf.hpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ELF_HPP
+#define ELF_HPP
+
+#include "endian.hpp"
+
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include <stdint.h>
+
+namespace Elf
+{
+ class file_class_32 { public: static const unsigned int id = 1; };
+ class file_class_64 { public: static const unsigned int id = 2; };
+ class file_data_2LSB { public: static const unsigned int id = 1; };
+ class file_data_2MSB { public: static const unsigned int id = 2; };
+ class section_type_UNDEFINED { };
+ class section_type_SYMTAB { public: static const unsigned int id = 2; };
+
+ class section;
+
+ class file
+ {
+ public:
+ virtual ~file () throw ();
+
+ virtual const uint8_t get_class () const throw () = 0;
+ virtual const uint8_t get_data () const throw () = 0;
+ const uint16_t get_type () const throw () { return type; }
+ const uint16_t get_machine () const throw () { return machine; }
+ const uint16_t get_shstrndx () const throw () { return shstrndx; }
+
+ const std::vector <section *> get_sections () const throw () { return sections; };
+ const section *get_section (unsigned int i) const throw (std::out_of_range) { return sections.at(i); };
+
+ const void *const _mem () const throw () { return mem; }
+
+ static file *open (const char *filename) throw (std::bad_alloc, std::runtime_error);
+
+ protected:
+ file (const char *, void *, size_t len) throw (std::bad_alloc);
+
+ template<typename _class>
+ static file *open_class (const char *, const uint8_t *, void *, size_t) throw (std::bad_alloc, std::runtime_error);
+
+ uint16_t type;
+ uint16_t machine;
+ uint64_t shoff;
+ uint16_t shnum;
+ uint16_t shstrndx;
+
+ std::vector <section *> sections;
+
+ const std::string filename;
+ void *mem;
+ size_t len;
+ };
+
+ template <typename _class, typename _data>
+ class file_data : public file
+ {
+ public:
+ file_data (const char *) throw (std::bad_alloc, std::runtime_error);
+ file_data (const char *, void *, size_t len) throw (std::bad_alloc, std::runtime_error);
+
+ const uint8_t get_class () const throw () { return _class::id; }
+ const uint8_t get_data () const throw () { return _data::id; }
+
+ private:
+ void construct () throw (std::bad_alloc, std::runtime_error);
+ };
+
+ class section
+ {
+ public:
+ virtual ~section () throw () {}
+
+ uint32_t get_type () const throw () { return type; }
+ uint64_t get_size () const throw () { return size; }
+ const std::string &get_name_string () const throw () { return name_string; }
+
+ const void *const _mem () const throw () { return mem; }
+
+ virtual void update_string_table (file *) throw (std::bad_alloc);
+
+ protected:
+ uint32_t name;
+ uint32_t type;
+ uint64_t offset;
+ uint64_t size;
+ uint32_t link;
+
+ std::string name_string;
+
+ void *mem;
+ };
+
+ template <typename _class, typename _data>
+ class section_data : public virtual section
+ {
+ public:
+ section_data (void *, void *) throw ();
+ };
+
+ template <typename _type>
+ class section_type : public virtual section
+ {
+ };
+
+ class symbol;
+
+ template <>
+ class section_type<section_type_SYMTAB> : public virtual section
+ {
+ public:
+ ~section_type () throw ();
+
+ const std::vector<symbol *> &get_symbols () throw () { return symbols; }
+
+ void update_string_table (file *) throw (std::bad_alloc);
+
+ protected:
+ std::vector<symbol *> symbols;
+ };
+
+ template <typename _class, typename _data, typename _type>
+ class section_real : public section_data<_class, _data>, public section_type<_type>
+ {
+ public:
+ section_real (void *, void *) throw ();
+ };
+
+ template <typename _class, typename _data>
+ class section_real<_class, _data, section_type_UNDEFINED> : public section_data<_class, _data>, public section_type<section_type_UNDEFINED>
+ {
+ public:
+ section_real (void *a, void *b) throw () : section_data<_class, _data> (a, b) { }
+ };
+
+ template <typename _class, typename _data>
+ class section_real<_class, _data, section_type_SYMTAB> : public section_data<_class, _data>, public section_type<section_type_SYMTAB>
+ {
+ public:
+ section_real (void *, void *) throw (std::bad_alloc);
+ };
+
+ class symbol
+ {
+ public:
+ virtual ~symbol () throw () {}
+
+ uint8_t get_info () const throw () { return info; }
+ uint16_t get_shndx () const throw () { return shndx; }
+ uint64_t get_value () const throw () { return value; }
+ uint64_t get_size () const throw () { return size; }
+ uint8_t get_bind () const throw () { return bind; }
+ uint8_t get_type () const throw () { return type; }
+ const std::string &get_name_string () const throw () { return name_string; }
+
+ virtual void update_string_table (file *, uint16_t) throw (std::bad_alloc) = 0;
+
+ protected:
+ uint32_t name;
+ uint8_t info;
+ uint16_t shndx;
+ uint64_t value;
+ uint64_t size;
+ uint8_t bind;
+ uint8_t type;
+
+ std::string name_string;
+ };
+
+ template <typename _class, typename _data>
+ class symbol_data : public symbol
+ {
+ public:
+ symbol_data (void *) throw ();
+
+ void update_string_table (file *, uint16_t) throw (std::bad_alloc);
+
+ protected:
+ };
+
+ template <typename from, typename type>
+ struct convert
+ { };
+
+ template <typename type>
+ struct convert<file_data_2LSB, type> : public endian::convert<endian::little_endian, type>
+ { };
+
+ template <typename type>
+ struct convert<file_data_2MSB, type> : public endian::convert<endian::big_endian, type>
+ { };
+}
+
+#endif
Added: people/waldi/linux-kbuild-2.6/src/mod/endian.hpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/endian.hpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,138 @@
+/*
+ * endian.hpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ENDIAN_HPP
+#define ENDIAN_HPP
+
+#include <endian.h>
+#include <stdint.h>
+
+namespace endian
+{
+ class little_endian
+ { };
+
+ class big_endian
+ { };
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ typedef little_endian host_endian;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ typedef big_endian host_endian;
+#endif
+
+ template <typename type>
+ struct convert_nop
+ {
+ inline type operator () (const type &in) const throw () { return in; }
+ };
+
+ template <typename type>
+ struct convert_simple
+ { };
+
+ template <>
+ struct convert_simple<uint8_t> : public convert_nop<uint8_t>
+ { };
+
+ template <>
+ struct convert_simple<uint16_t>
+ {
+ inline uint16_t operator () (const uint16_t &in) const throw ()
+ {
+ return (in & 0x00ffU) << 8 |
+ (in & 0xff00U) >> 8;
+ }
+ };
+
+ template <>
+ struct convert_simple<uint32_t>
+ {
+ inline uint32_t operator () (const uint32_t &in) const throw ()
+ {
+ return (in & 0x000000ffU) << 24 |
+ (in & 0xff000000U) >> 24 |
+ (in & 0x0000ff00U) << 8 |
+ (in & 0x00ff0000U) >> 8;
+ }
+ };
+
+ template <>
+ struct convert_simple<uint64_t>
+ {
+ inline uint64_t operator () (const uint64_t &in) const throw ()
+ {
+ return (in & 0x00000000000000ffULL) << 56 |
+ (in & 0xff00000000000000ULL) >> 56 |
+ (in & 0x000000000000ff00ULL) << 40 |
+ (in & 0x00ff000000000000ULL) >> 40 |
+ (in & 0x0000000000ff0000ULL) << 24 |
+ (in & 0x0000ff0000000000ULL) >> 24 |
+ (in & 0x00000000ff000000ULL) << 8 |
+ (in & 0x000000ff00000000ULL) >> 8;
+ }
+ };
+
+ template <>
+ struct convert_simple<const uint8_t> : public convert_simple<uint8_t>
+ { };
+
+ template <>
+ struct convert_simple<const uint16_t> : public convert_simple<uint16_t>
+ { };
+
+ template <>
+ struct convert_simple<const uint32_t> : public convert_simple<uint32_t>
+ { };
+
+ template <typename from, typename to, typename type>
+ struct convert_complete
+ { };
+
+ template <typename type>
+ struct convert_complete<little_endian, little_endian, type> : public convert_nop<type>
+ { };
+
+ template <typename type>
+ struct convert_complete<little_endian, big_endian, type> : public convert_simple<type>
+ { };
+
+ template <typename type>
+ struct convert_complete<big_endian, big_endian, type> : public convert_nop<type>
+ { };
+
+ template <typename type>
+ struct convert_complete<big_endian, little_endian, type> : public convert_simple<type>
+ { };
+
+ template <typename from, typename type>
+ struct convert
+ { };
+
+ template <typename type>
+ struct convert<little_endian, type> : public convert_complete<little_endian, host_endian, type>
+ { };
+
+ template <typename type>
+ struct convert<big_endian, type> : public convert_complete<big_endian, host_endian, type>
+ { };
+}
+
+#endif
Added: people/waldi/linux-kbuild-2.6/src/mod/modpost.cpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/modpost.cpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,84 @@
+/*
+ * modpost.cpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "elf.hpp"
+#include "module.hpp"
+
+#include <iostream>
+
+#include <getopt.h>
+
+using namespace linuxkernel;
+
+modulelist modules;
+
+int main (int argc, char *const argv[])
+{
+ int ret = EXIT_SUCCESS;
+ int opt;
+ const char *dump_read = 0, *dump_write = 0;
+ bool all_versions = false, modversions = false;;
+
+ while ((opt = getopt (argc, argv, "ai:mo:")) != -1)
+ {
+ switch(opt) {
+ case 'a':
+ all_versions = true;
+ std::clog << "*** Warning: CONFIG_MODULE_SRCVERSION_ALL is not supported!" << std::endl;
+ return EXIT_FAILURE;
+ break;
+ case 'i':
+ dump_read = optarg;
+ break;
+ case 'm':
+ modversions = true;
+ break;
+ case 'o':
+ dump_write = optarg;
+ break;
+ default:
+ exit(1);
+ }
+ }
+
+ if (dump_read)
+ modules.dump_read (dump_read);
+
+ for (int i = optind; i < argc; i++)
+ {
+ std::string filename (argv[i]);
+ try
+ {
+ modules.insert (filename);
+ }
+ catch (std::runtime_error &e)
+ {
+ std::clog << "*** Warning: \"" << filename << "\" failed to load: " << e.what () << std::endl;
+ ret = EXIT_FAILURE;
+ continue;
+ }
+ }
+ modules.write (modversions);
+
+ if (dump_write)
+ modules.dump_write (dump_write);
+
+ return ret;
+}
Added: people/waldi/linux-kbuild-2.6/src/mod/module.cpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module.cpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,481 @@
+/*
+ * module.cpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "module.hpp"
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <set>
+
+#include <elf.h>
+
+using namespace linuxkernel;
+
+const std::string module_real::symbol_name_cleanup ("cleanup_module");
+const std::string module_real::symbol_name_init ("init_module");
+const std::string module_real::symbol_prefix_crc ("__crc_");
+const std::string module_real::symbol_prefix_ksymtab ("__ksymtab_");
+
+module::module (const std::string &name) throw ()
+: name (name)
+{
+ std::string::size_type t1 = name.find_last_of ('/');
+ if (t1 == std::string::npos)
+ t1 = 0;
+ else
+ t1++;
+ name_short = name.substr (t1, std::string::npos);
+
+ if (name == "vmlinux")
+ is_vmlinux = true;
+}
+
+module::module (const std::string &filename, bool) throw ()
+{
+ std::string::size_type t1 = filename.find_last_of ('/');
+ std::string::size_type t2 = filename.find_last_of ('.');
+ if (t1 == std::string::npos)
+ t1 = 0;
+ else
+ t1++;
+ name = filename.substr (0, t2);
+ if (t2 != std::string::npos)
+ t2 -= t1;
+ name_short = filename.substr (t1, t2);
+
+ if (name == "vmlinux")
+ is_vmlinux = true;
+}
+
+module_real::module_real (const std::string &filename, Elf::file *file) throw (std::runtime_error)
+: module (filename, false), has_init (false), has_cleanup (false), file (file)
+{
+ const std::vector <Elf::section *> §ions = file->get_sections ();
+ Elf::section *modinfo = 0;
+ symtab = 0;
+
+ for (std::vector <Elf::section *>::const_iterator it = sections.begin (); it != sections.end (); ++it)
+ {
+ const std::string &name = (*it)->get_name_string ();
+ uint32_t type = (*it)->get_type ();
+ if (name == ".modinfo")
+ modinfo = *it;
+ if (type == Elf::section_type_SYMTAB::id)
+ symtab = dynamic_cast <Elf::section_type<Elf::section_type_SYMTAB> *> (*it);
+ }
+
+ if (!is_vmlinux && !modinfo)
+ throw std::runtime_error ("Not a kernel module, lacks modinfo section");
+ if (!symtab)
+ throw std::runtime_error ("Not a kernel module, lacks symbol table");
+
+ if (!is_vmlinux)
+ {
+ read_modinfo (modinfo);
+ symbols_undefined.insert (std::pair<std::string, symbol_undefined> ("struct_module", symbol_undefined ("struct_module", 0)));
+ }
+ read_symtab (symtab);
+}
+
+const Elf::symbol *module_real::_get_symbol (const std::string &name) const throw ()
+{
+ for (std::vector<Elf::symbol *>::const_iterator it = symtab->get_symbols ().begin (); it != symtab->get_symbols ().end (); ++it)
+ {
+ Elf::symbol *symbol = *it;
+ std::string symname = symbol->get_name_string ();
+ if (symname == name)
+ return symbol;
+ }
+ return 0;
+}
+
+void module_real::write (const modulelist &list, bool modversions)
+{
+ std::string filename = name + ".mod.c";
+ std::ofstream out (filename.c_str ());
+ write_header (out);
+ if (modversions)
+ write_versions (out, list);
+ write_depends (out, list);
+ write_moddevtable (out);
+}
+
+module_real *module_real::open (const std::string &filename) throw (std::bad_alloc, std::runtime_error)
+{
+ Elf::file *file = Elf::file::open (filename.c_str ());
+ switch (file->get_class ())
+ {
+ case Elf::file_class_32::id:
+ return open_class<Elf::file_class_32> (filename, file);
+ case Elf::file_class_64::id:
+ return open_class<Elf::file_class_64> (filename, file);
+ default:
+ throw std::runtime_error ("Unsupported file class");
+ }
+}
+
+template<typename Elf_class>
+module_real *module_real::open_class (const std::string &filename, Elf::file *file) throw (std::bad_alloc, std::runtime_error)
+{
+ switch (file->get_data ())
+ {
+ case Elf::file_data_2LSB::id:
+ return new module_data<Elf_class, Elf::file_data_2LSB> (filename, file);
+ case Elf::file_data_2MSB::id:
+ return new module_data<Elf_class, Elf::file_data_2MSB> (filename, file);
+ default:
+ throw std::runtime_error ("Unsupported data encoding");
+ }
+}
+
+void module_real::read_modinfo (Elf::section *section) throw (std::runtime_error)
+{
+ const char *act, *end, *temp1, *temp2;
+ act = static_cast <const char *> (section->_mem ());
+ end = act + section->get_size ();
+ while (act <= end)
+ {
+ temp1 = act;
+ for (; *act && *act != '=' && act <= end; act++);
+ if (act > end)
+ break;
+ temp2 = ++act;
+ for (; *act && act <= end; act++);
+ if (act > end)
+ break;
+ modinfo.insert (std::pair<std::string, std::string> (std::string (temp1, temp2 - temp1 - 1), std::string (temp2, act - temp2)));
+ for (; !*act && act <= end; act++);
+ }
+}
+
+void module_real::read_symtab (Elf::section_type<Elf::section_type_SYMTAB> *section) throw (std::runtime_error)
+{
+ for (std::vector<Elf::symbol *>::const_iterator it = section->get_symbols ().begin (); it != section->get_symbols ().end (); ++it)
+ {
+ Elf::symbol *symbol = *it;
+ std::string symname = symbol->get_name_string ();
+
+ switch (symbol->get_shndx ())
+ {
+ case SHN_COMMON:
+ std::clog << "*** Warning: \"" << symname << "\" [" << name << "] is COMMON symbol" << std::endl;
+ break;
+ case SHN_ABS:
+ if (symname.compare (0, symbol_prefix_crc.size (), symbol_prefix_crc) == 0)
+ {
+ std::string symname_real (symname.substr (symbol_prefix_crc.size ()));
+ std::map<std::string, symbol_exported>::iterator it = symbols_exported.find (symname_real);
+ if (it == symbols_exported.end ())
+ symbols_exported.insert (std::pair<std::string, symbol_exported> (symname_real, symbol_exported (symname_real, symbol->get_value ())));
+ else
+ it->second.set_crc (symbol->get_value ());
+ }
+ break;
+ case SHN_UNDEF:
+ if (symbol->get_bind () != STB_GLOBAL &&
+ symbol->get_bind () != STB_WEAK)
+ break;
+ //FIXME: if (symbol->get_type () == STT_REGISTER)
+ // break;
+ /* ignore global offset table */
+ if (symname == "_GLOBAL_OFFSET_TABLE_")
+ break;
+ /* ignore __this_module, it will be resolved shortly */
+ if (symname == "__this_module")
+ break;
+ symbols_undefined.insert (std::pair<std::string, symbol_undefined> (symname, symbol_undefined (symname, symbol->get_bind () == STB_WEAK)));
+ break;
+ default:
+ if (symname.compare (0, symbol_prefix_ksymtab.size (), symbol_prefix_ksymtab) == 0)
+ {
+ std::string symname_real (symname.substr (symbol_prefix_ksymtab.size ()));
+ std::map<std::string, symbol_exported>::iterator it = symbols_exported.find (symname_real);
+ if (it == symbols_exported.end ())
+ symbols_exported.insert (std::pair<std::string, symbol_exported> (symname_real, symbol_exported (symname_real)));
+ }
+ else if (symname == symbol_name_cleanup)
+ has_cleanup = true;
+ else if (symname == symbol_name_init)
+ has_init = true;
+ break;
+ };
+ }
+}
+
+void module_real::write_depends (std::ostream &out, const modulelist &list)
+{
+ std::set<std::string> depends;
+ for (std::map<std::string, symbol_undefined>::const_iterator it = symbols_undefined.begin (); it != symbols_undefined.end (); ++it)
+ {
+ try
+ {
+ const std::string &mod (list.get_module_name_short_for_symbol (it->first));
+ if (mod != "vmlinux")
+ depends.insert (mod);
+ }
+ catch (std::out_of_range &)
+ { }
+ }
+ out <<
+ "static const char __module_depends[]\n"
+ "__attribute_used__\n"
+ "__attribute__((section(\".modinfo\"))) =\n"
+ "\"depends=";
+ if (depends.begin () != depends.end ())
+ {
+ std::set<std::string>::const_iterator it = depends.begin ();
+ out << *it;
+ for (++it; it != depends.end (); ++it)
+ out << ',' << *it;
+ }
+ out << "\";\n\n";
+}
+
+void module_real::write_header (std::ostream &out)
+{
+ out <<
+ "#include <linux/module.h>\n"
+ "#include <linux/vermagic.h>\n"
+ "#include <linux/compiler.h>\n"
+ "\n"
+ "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"
+ "\n"
+ "#undef unix\n" /* We have a module called "unix" */
+ "struct module __this_module\n"
+ "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"
+ " .name = __stringify(KBUILD_MODNAME),\n";
+ if (has_init)
+ out << " .init = init_module,\n";
+ if (has_cleanup)
+ out <<
+ "#ifdef CONFIG_MODULE_UNLOAD\n"
+ " .exit = cleanup_module,\n"
+ "#endif\n";
+ out << "};\n\n";
+}
+
+void module_real::write_moddevtable (std::ostream &out)
+{
+ if (devicetable_ccw)
+ devicetable_ccw->write (out);
+ if (devicetable_ieee1394)
+ devicetable_ieee1394->write (out);
+ if (devicetable_pci)
+ devicetable_pci->write (out);
+ if (devicetable_pnp)
+ devicetable_pnp->write (out);
+ if (devicetable_pnp_card)
+ devicetable_pnp_card->write (out);
+ if (devicetable_usb)
+ devicetable_usb->write (out);
+}
+
+void module_real::write_versions (std::ostream &out, const modulelist &list)
+{
+ out <<
+ "static const struct modversion_info ____versions[]\n"
+ "__attribute_used__\n"
+ "__attribute__((section(\"__versions\"))) = {\n";
+
+ for (std::map<std::string, symbol_undefined>::const_iterator it = symbols_undefined.begin (); it != symbols_undefined.end (); ++it)
+ {
+ try
+ {
+ const symbol_exported &sym (list.get_symbol (it->first));
+ if (sym.get_crc_valid ())
+ out << "\t{ 0x" << std::hex << sym.get_crc () << std::dec << ", \"" << it->first << "\" },\n";
+ else
+ std::clog << "*** Warning: \"" << sym.get_name () << "\" [" << name << "] has no CRC!" << std::endl;
+ }
+ catch (std::out_of_range &)
+ {
+ if (list.report_symbols_missing)
+ std::clog << "*** Warning: \"" << it->first << "\" is undefined!" << std::endl;
+ }
+ }
+
+ out << "};\n\n";
+}
+
+template <typename Elf_class, typename Elf_data>
+module_data<Elf_class, Elf_data>::module_data (const std::string &filename, Elf::file *file) throw (std::runtime_error)
+: module_real (filename, file)
+{
+ devicetable_ccw = module_devicetable::table<module_devicetable::device_ccw, Elf_class, Elf_data>::create (this, file);
+ devicetable_ieee1394 = module_devicetable::table<module_devicetable::device_ieee1394, Elf_class, Elf_data>::create (this, file);
+ devicetable_pci = module_devicetable::table<module_devicetable::device_pci, Elf_class, Elf_data>::create (this, file);
+ devicetable_pnp = module_devicetable::table<module_devicetable::device_pnp, Elf_class, Elf_data>::create (this, file);
+ devicetable_pnp_card = module_devicetable::table<module_devicetable::device_pnp_card, Elf_class, Elf_data>::create (this, file);
+ devicetable_usb = module_devicetable::table<module_devicetable::device_usb, Elf_class, Elf_data>::create (this, file);
+}
+
+modulelist::modulelist () throw ()
+: report_symbols_missing (false)
+{ }
+
+modulelist::~modulelist () throw ()
+{
+ for (_modules_real::iterator it = modules_real.begin (); it != modules_real.end (); ++it)
+ delete it->second;
+ for (_modules_shadow::iterator it = modules_shadow.begin (); it != modules_shadow.end (); ++it)
+ delete it->second;
+}
+
+void modulelist::dump_read (const std::string &filename) throw (std::runtime_error)
+{
+ std::ifstream in (filename.c_str ());
+ while (in.good ())
+ {
+ char buf[512];
+ in.getline (buf, sizeof (buf));
+ std::stringstream str (buf);
+ uint32_t crc;
+ std::string symbol, module_name;
+ str >> std::hex >> crc >> std::dec >> symbol >> module_name;
+ _modules_shadow::const_iterator it = modules_shadow.find (module_name);
+ module *mod;
+ if (it == modules_shadow.end ())
+ {
+ mod = new module (module_name);
+ modules_shadow.insert (_modules_shadow_pair (module_name, mod));
+ }
+ else
+ mod = it->second;
+ mod->symbols_exported.insert (std::pair<std::string, symbol_exported> (symbol, symbol_exported (symbol, crc)));
+ symbols_exported.insert (std::pair<std::string, std::string> (symbol, module_name));
+ if (mod->get_is_vmlinux ())
+ report_symbols_missing = true;
+ }
+}
+
+void modulelist::dump_write (const std::string &filename) const throw (std::runtime_error)
+{
+ char buf[128];
+ std::ofstream out (filename.c_str (), std::ios::trunc);
+
+ for (_symbols::const_iterator it = symbols_exported.begin (); it != symbols_exported.end (); ++it)
+ {
+ const module *mod = get_module (it->second);
+ const symbol_exported &sym = get_symbol (it->first);
+ snprintf (buf, sizeof (buf), "0x%08x\t%s\t%s\n", sym.get_crc (), it->first.c_str (), mod->get_name ().c_str ());
+ out << buf;
+ }
+}
+
+const module *modulelist::get_module (const std::string &name) const throw (std::out_of_range)
+{
+ _modules_real::const_iterator it1 = modules_real.find (name);
+ if (it1 != modules_real.end ())
+ return it1->second;
+ _modules_shadow::const_iterator it2 = modules_shadow.find (name);
+ if (it2 != modules_shadow.end ())
+ return it2->second;
+ throw std::out_of_range ("Don't find module");
+}
+
+const module *modulelist::get_module_for_symbol (const std::string &name) const throw (std::out_of_range)
+{
+ _symbols::const_iterator it = symbols_exported.find (name);
+ if (it == symbols_exported.end ())
+ throw std::out_of_range ("symbol is undefined");
+ return get_module (it->second);
+}
+
+const std::string &modulelist::get_module_name_short_for_symbol (const std::string &name) const throw (std::out_of_range)
+{
+ const module *mod = get_module_for_symbol (name);
+ return mod->get_name_short ();
+}
+
+const symbol_exported &modulelist::get_symbol (const std::string &name) const throw (std::out_of_range)
+{
+ const module *mod = get_module_for_symbol (name);
+ std::map<std::string, symbol_exported>::const_iterator it = mod->get_symbols_exported ().find (name);
+ if (it == mod->get_symbols_exported ().end ())
+ throw std::logic_error ("Don't find symbol");
+ return it->second;
+}
+
+void modulelist::insert (module_real *mod) throw (std::runtime_error)
+{
+ bool overwrite = false;
+
+ if (mod->get_is_vmlinux ())
+ {
+ if (!modules_shadow.insert (_modules_shadow_pair (mod->get_name (), mod)).second)
+ overwrite = true;
+ report_symbols_missing = true;
+ }
+ else
+ {
+ if (!modules_real.insert (_modules_real_pair (mod->get_name (), mod)).second)
+ throw std::runtime_error ("Already know a module with this name");
+ }
+
+ for (std::map<std::string, symbol_exported>::const_iterator it = mod->get_symbols_exported ().begin ();
+ it != mod->get_symbols_exported ().end (); ++it)
+ if (!symbols_exported.insert (std::pair<std::string, std::string> (it->second.get_name (), mod->get_name ())).second)
+ if (!overwrite)
+ std::clog << "*** Warning: \"" << it->second.get_name () << "\" [" << mod->get_name () << "] duplicated symbol!" << std::endl;
+}
+
+void modulelist::insert (const std::string &filename) throw (std::runtime_error)
+{
+ module_real *mod = module_real::open (filename);
+ try
+ {
+ insert (mod);
+ }
+ catch (...)
+ {
+ delete mod;
+ throw;
+ }
+}
+
+void modulelist::write (bool modversions)
+{
+ for (_modules_real::iterator it = modules_real.begin (); it != modules_real.end (); ++it)
+ it->second->write (*this, modversions);
+}
+
+symbol::symbol (const std::string &name) throw ()
+: name (name)
+{ }
+
+symbol_exported::symbol_exported (const std::string &name) throw ()
+: symbol (name), crc_valid (false)
+{ }
+
+symbol_exported::symbol_exported (const std::string &name, uint32_t crc) throw ()
+: symbol (name), crc (crc), crc_valid (true)
+{ }
+
+void symbol_exported::set_crc (uint32_t _crc) throw ()
+{
+ crc = _crc;
+ crc_valid = true;
+}
+
+symbol_undefined::symbol_undefined (const std::string &name, bool weak) throw ()
+: symbol (name), weak (weak)
+{ }
+
Added: people/waldi/linux-kbuild-2.6/src/mod/module.hpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module.hpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,185 @@
+/*
+ * module.hpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MODULE_HPP
+#define MODULE_HPP
+
+#define DISABLE_TEMPLATES
+#include "elf.hpp"
+#include "module_devicetable.hpp"
+
+#include <map>
+#include <ostream>
+
+namespace linuxkernel
+{
+ class modulelist;
+ class symbol_exported;
+ class symbol_undefined;
+
+ class module
+ {
+ public:
+ module (const std::string &name) throw ();
+
+ bool get_is_vmlinux () const throw () { return is_vmlinux; }
+ const std::string &get_name () const throw () { return name; }
+ const std::string &get_name_short () const throw () { return name_short; }
+ const std::map<std::string, symbol_exported> &get_symbols_exported () const throw () { return symbols_exported; }
+
+ protected:
+ module (const std::string &filename, bool) throw ();
+
+ std::string name, name_short;
+ bool is_vmlinux;
+ std::map<std::string, symbol_exported> symbols_exported;
+
+ friend class modulelist;
+ };
+
+ class module_real : public module
+ {
+ public:
+ module_real (const std::string &filename, Elf::file *file) throw (std::runtime_error);
+
+ const Elf::symbol *_get_symbol (const std::string &name) const throw ();
+
+ void write (const modulelist &, bool modversions);
+
+ static module_real *open (const std::string &filename) throw (std::bad_alloc, std::runtime_error);
+
+ const static std::string symbol_name_cleanup;
+ const static std::string symbol_name_init;
+ const static std::string symbol_prefix_crc;
+ const static std::string symbol_prefix_ksymtab;
+
+ protected:
+ template<typename Elf_class>
+ static module_real *open_class (const std::string &filename, Elf::file *) throw (std::bad_alloc, std::runtime_error);
+
+ void read_modinfo (Elf::section *) throw (std::runtime_error);
+ void read_symtab (Elf::section_type<Elf::section_type_SYMTAB> *) throw (std::runtime_error);
+
+ void write_depends (std::ostream &, const modulelist &);
+ void write_header (std::ostream &);
+ void write_moddevtable (std::ostream &);
+ void write_versions (std::ostream &, const modulelist &);
+
+ std::map<std::string, std::string> modinfo;
+ std::map<std::string, symbol_undefined> symbols_undefined;
+ bool has_init;
+ bool has_cleanup;
+ Elf::section_type<Elf::section_type_SYMTAB> *symtab;
+ module_devicetable::table_base<module_devicetable::device_ccw> *devicetable_ccw;
+ module_devicetable::table_base<module_devicetable::device_ieee1394> *devicetable_ieee1394;
+ module_devicetable::table_base<module_devicetable::device_pci> *devicetable_pci;
+ module_devicetable::table_base<module_devicetable::device_pnp> *devicetable_pnp;
+ module_devicetable::table_base<module_devicetable::device_pnp_card> *devicetable_pnp_card;
+ module_devicetable::table_base<module_devicetable::device_usb> *devicetable_usb;
+
+ Elf::file *file;
+ };
+
+ template <typename Elf_class, typename Elf_data>
+ class module_data : public module_real
+ {
+ public:
+ module_data (const std::string &filename, Elf::file *file) throw (std::runtime_error);
+ };
+
+ class modulelist
+ {
+ public:
+ typedef std::map<std::string, module_real *> _modules_real;
+ typedef std::pair<std::string, module_real *> _modules_real_pair;
+ typedef std::map<std::string, module *> _modules_shadow;
+ typedef std::pair<std::string, module *> _modules_shadow_pair;
+ typedef std::map<std::string, std::string> _symbols;
+
+ modulelist () throw ();
+ ~modulelist () throw ();
+
+ void dump_read (const std::string &filename) throw (std::runtime_error);
+ void dump_write (const std::string &filename) const throw (std::runtime_error);
+
+ const _modules_real &get_modules_real () const throw () { return modules_real; }
+ const _modules_shadow &get_modules_shadow () const throw () { return modules_shadow; }
+ const module *get_module (const std::string &name) const throw (std::out_of_range);
+ const module *get_module_for_symbol (const std::string &name) const throw (std::out_of_range);
+ const std::string &get_module_name_short_for_symbol (const std::string &name) const throw (std::out_of_range);
+ const symbol_exported &get_symbol (const std::string &name) const throw (std::out_of_range);
+ const _symbols &get_symbols_exported () const throw () { return symbols_exported; }
+
+ void insert (module_real *) throw (std::runtime_error);
+ void insert (const std::string &filename) throw (std::runtime_error);
+
+ void write (bool modversions);
+
+ bool report_symbols_missing;
+
+ protected:
+ _modules_real modules_real;
+ _modules_shadow modules_shadow;
+ _symbols symbols_exported;
+ };
+
+ class symbol
+ {
+ public:
+ symbol () throw () {}
+ symbol (const std::string &name) throw ();
+
+ const std::string &get_name () const throw () { return name; }
+
+ protected:
+ std::string name;
+ };
+
+ class symbol_exported : public symbol
+ {
+ public:
+ symbol_exported () throw () {}
+ symbol_exported (const std::string &name) throw ();
+ symbol_exported (const std::string &name, uint32_t) throw ();
+
+ uint32_t get_crc () const throw () { return crc; }
+ bool get_crc_valid () const throw () { return crc_valid; }
+ void set_crc (uint32_t) throw ();
+
+ protected:
+ uint32_t crc;
+ bool crc_valid;
+ };
+
+ class symbol_undefined : public symbol
+ {
+ public:
+ symbol_undefined () throw () {}
+ symbol_undefined (const std::string &name, bool weak) throw ();
+
+ protected:
+ bool weak;
+ };
+}
+
+#include "module_devicetable.tpp"
+
+#undef DISABLE_TEMPLATES
+#endif
Added: people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.cpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.cpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,38 @@
+/*
+ * module_devicetable.cpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "module.hpp"
+#include "module_devicetable.hpp"
+
+namespace linuxkernel
+{
+ namespace module_devicetable
+ {
+ namespace internal
+ {
+ const std::string def<device_ccw>::symbol = "__mod_ccw_device_table";
+ const std::string def<device_ieee1394>::symbol = "__mod_ieee1394_device_table";
+ const std::string def<device_pci>::symbol = "__mod_pci_device_table";
+ const std::string def<device_pnp>::symbol = "__mod_pnp_device_table";
+ const std::string def<device_pnp_card>::symbol = "__mod_pnp_card_device_table";
+ const std::string def<device_usb>::symbol = "__mod_usb_device_table";
+ }
+ }
+}
Added: people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.hpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.hpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,135 @@
+/*
+ * module_devicetable.hpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MODULE_DEVICETABLE_HPP
+#define MODULE_DEVICETABLE_HPP
+
+#include "elf.hpp"
+
+#include <ostream>
+#include <stdexcept>
+#include <vector>
+
+namespace linuxkernel
+{
+ class module_real;
+
+ namespace module_devicetable
+ {
+ class device_ccw { };
+ class device_ieee1394 { };
+ class device_pci { };
+ class device_pnp { };
+ class device_pnp_card { };
+ class device_usb { };
+
+ class version_2_6_10 { };
+
+ namespace internal
+ {
+ template<typename device>
+ struct def {};
+ template<>
+ struct def<device_ccw>
+ {
+ static const std::string symbol;
+ };
+ template<>
+ struct def<device_ieee1394>
+ {
+ static const std::string symbol;
+ };
+ template<>
+ struct def<device_pci>
+ {
+ static const std::string symbol;
+ };
+ template<>
+ struct def<device_pnp>
+ {
+ static const std::string symbol;
+ };
+ template<>
+ struct def<device_pnp_card>
+ {
+ static const std::string symbol;
+ };
+ template<>
+ struct def<device_usb>
+ {
+ static const std::string symbol;
+ };
+ }
+
+ class table_entry
+ {
+ public:
+ virtual ~table_entry () {};
+ virtual void write (std::ostream &) const throw (std::runtime_error) = 0;
+ };
+
+ template<typename device, typename version>
+ class table_entry_version : public table_entry
+ {
+ };
+
+ template<typename device, typename version, typename Elf_class, typename Elf_data>
+ class table_entry_data : public table_entry_version<device, version>
+ {
+ };
+
+ template<typename device>
+ class table_base
+ {
+ public:
+ virtual ~table_base () throw () {};
+
+ void write (std::ostream &out) const throw (std::runtime_error);
+
+ protected:
+ table_base () throw () {};
+
+ std::vector<table_entry *> entries;
+ };
+
+ template<typename device, typename Elf_class, typename Elf_data>
+ class table : public table_base<device>
+ {
+ public:
+ static table_base<device> *create (const module_real *m, const Elf::file *f) throw (std::runtime_error);
+
+ protected:
+ table () {};
+ };
+
+ template<typename device, typename version, typename Elf_class, typename Elf_data>
+ class table_data : public table<device, Elf_class, Elf_data>
+ {
+ public:
+ table_data (const void *, size_t) throw (std::runtime_error);
+ };
+ }
+}
+
+#ifndef DISABLE_TEMPLATES
+#include "module_devicetable.tpp"
+#endif
+
+#endif
Added: people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.tpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module_devicetable.tpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,54 @@
+/*
+ * module_devicetable.tpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MODULE_DEVICETABLE_TPP
+#define MODULE_DEVICETABLE_TPP
+
+#include "module.hpp"
+
+namespace linuxkernel
+{
+ namespace module_devicetable
+ {
+ template<typename device>
+ void table_base<device>::write (std::ostream &out) const throw (std::runtime_error)
+ {
+ for (std::vector<table_entry *>::const_iterator it = entries.begin (); it != entries.end (); ++it)
+ {
+ out << "MODULE_ALIAS(\"";
+ (*it)->write (out);
+ out << "\");\n";
+ }
+ }
+
+ template<typename device, typename Elf_class, typename Elf_data>
+ table_base<device> *table<device, Elf_class, Elf_data>::create (const module_real *m, const Elf::file *f) throw (std::runtime_error)
+ {
+ const Elf::symbol *sym = m->_get_symbol (internal::def<device>::symbol);
+ if (!sym)
+ return 0;
+ const Elf::section *sec = f->get_section (sym->get_shndx ());
+ const char *mem = static_cast <const char *> (sec->_mem ());
+ return new table_data<device, version_2_6_10, Elf_class, Elf_data> (mem + sym->get_value (), sym->get_size ());
+ }
+ }
+}
+
+#endif
Added: people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.cpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.cpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,180 @@
+/*
+ * module_devicetable_impl_2_6_10.cpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "module_devicetable_impl_2_6_10.hpp"
+
+#include <cstdio>
+#include <stdint.h>
+
+using namespace linuxkernel::module_devicetable;
+
+std::ostream &operator << (std::ostream &out, const identifier_value<uint8_t> &id) throw ()
+{
+ char buf[4];
+ snprintf (buf, sizeof (buf), "%02X", id.value);
+ out << buf;
+ return out;
+}
+
+std::ostream &operator << (std::ostream &out, const identifier_value<uint16_t> &id) throw ()
+{
+ char buf[8];
+ snprintf (buf, sizeof (buf), "%04X", id.value);
+ out << buf;
+ return out;
+}
+
+std::ostream &operator << (std::ostream &out, const identifier_value<uint32_t> &id) throw ()
+{
+ char buf[12];
+ snprintf (buf, sizeof (buf), "%08X", id.value);
+ out << buf;
+ return out;
+}
+
+table_entry_version<device_ccw, version_2_6_10>::table_entry_version () throw () :
+ cu_type ("t"),
+ dev_type ("m"),
+ cu_model ("dt"),
+ dev_model ("dm")
+{ }
+
+void table_entry_version<device_ccw, version_2_6_10>::write (std::ostream &out) const throw (std::runtime_error)
+{
+ out << "ccw:";
+ cu_type.write (out, match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE);
+ cu_model.write (out, match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL);
+ dev_type.write (out, match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE);
+ dev_model.write (out, match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE);
+}
+
+table_entry_version<device_ieee1394, version_2_6_10>::table_entry_version () throw () :
+ vendor_id ("ven"),
+ model_id ("mo"),
+ specifier_id ("sp"),
+ version ("ver")
+{ }
+
+void table_entry_version<device_ieee1394, version_2_6_10>::write (std::ostream &out) const throw (std::runtime_error)
+{
+ out << "ieee1394:";
+ vendor_id.write (out, match_flags & IEEE1394_MATCH_VENDOR_ID);
+ model_id.write (out, match_flags & IEEE1394_MATCH_MODEL_ID);
+ specifier_id.write (out, match_flags & IEEE1394_MATCH_SPECIFIER_ID);
+ version.write (out, match_flags & IEEE1394_MATCH_VERSION, true);
+}
+
+table_entry_version<device_pci, version_2_6_10>::table_entry_version () throw () :
+ vendor ("v"),
+ device ("d"),
+ subvendor ("sv"),
+ subdevice ("sd")
+{ }
+
+void table_entry_version<device_pci, version_2_6_10>::write (std::ostream &out) const throw (std::runtime_error)
+{
+ out << "pci:";
+ vendor.write (out, vendor != PCI_ANY_ID);
+ device.write (out, device != PCI_ANY_ID);
+ subvendor.write (out, subvendor != PCI_ANY_ID);
+ subdevice.write (out, subdevice != PCI_ANY_ID);
+
+ identifier<uint8_t> baseclass ("bc", class_id >> 16);
+ identifier_value<uint8_t> baseclass_mask (class_mask >> 16);
+ identifier<uint8_t> subclass ("sc", class_id >> 8);
+ identifier_value<uint8_t> subclass_mask (class_mask >> 8);
+ identifier<uint8_t> interface ("i", class_id);
+ identifier_value<uint8_t> interface_mask (class_mask);
+
+ if ((baseclass_mask != 0 && baseclass_mask != 0xFF) ||
+ (subclass_mask != 0 && subclass_mask != 0xFF) ||
+ (interface_mask != 0 && interface_mask != 0xFF))
+ throw std::runtime_error ("Can't handle masks");
+
+ baseclass.write (out, baseclass_mask == 0xFF);
+ subclass.write (out, subclass_mask == 0xFF);
+ interface.write (out, interface_mask == 0xFF, true);
+}
+
+void table_entry_version<device_pnp, version_2_6_10>::write (std::ostream &out) const throw (std::runtime_error)
+{
+ out << "pnp:" << str << '*';
+}
+
+void table_entry_version<device_pnp_card, version_2_6_10>::write (std::ostream &out) const throw (std::runtime_error)
+{
+ out << "pnp:" << str << '*';
+}
+
+table_entry_version<device_usb, version_2_6_10>::table_entry_version () throw () :
+ idVendor ("v"),
+ idProduct ("p"),
+ bcdDevice_lo ("dl"),
+ bcdDevice_hi ("dh"),
+ bDeviceClass ("dc"),
+ bDeviceSubClass ("dsc"),
+ bDeviceProtocol ("dp"),
+ bInterfaceClass ("ic"),
+ bInterfaceSubClass ("isc"),
+ bInterfaceProtocol ("ip")
+{ }
+
+void table_entry_version<device_usb, version_2_6_10>::write (std::ostream &out) const throw (std::runtime_error)
+{
+ if (!idVendor && !bDeviceClass && !bInterfaceClass)
+ return;
+
+ out << "usb:";
+ idVendor.write (out, match_flags & USB_DEVICE_ID_MATCH_VENDOR);
+ idProduct.write (out, match_flags & USB_DEVICE_ID_MATCH_PRODUCT);
+ bcdDevice_lo.write (out, match_flags & USB_DEVICE_ID_MATCH_DEV_LO);
+ bcdDevice_hi.write (out, match_flags & USB_DEVICE_ID_MATCH_DEV_HI);
+ bDeviceClass.write (out, match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS);
+ bDeviceSubClass.write (out, match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS);
+ bDeviceProtocol.write (out, match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL);
+ bInterfaceClass.write (out, match_flags & USB_DEVICE_ID_MATCH_INT_CLASS);
+ bInterfaceSubClass.write (out, match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS);
+ bInterfaceProtocol.write (out, match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL, true);
+}
+
+template class table_data<device_ccw, version_2_6_10, Elf::file_class_32, Elf::file_data_2LSB>;
+template class table_data<device_ccw, version_2_6_10, Elf::file_class_32, Elf::file_data_2MSB>;
+template class table_data<device_ccw, version_2_6_10, Elf::file_class_64, Elf::file_data_2LSB>;
+template class table_data<device_ccw, version_2_6_10, Elf::file_class_64, Elf::file_data_2MSB>;
+template class table_data<device_ieee1394, version_2_6_10, Elf::file_class_32, Elf::file_data_2LSB>;
+template class table_data<device_ieee1394, version_2_6_10, Elf::file_class_32, Elf::file_data_2MSB>;
+template class table_data<device_ieee1394, version_2_6_10, Elf::file_class_64, Elf::file_data_2LSB>;
+template class table_data<device_ieee1394, version_2_6_10, Elf::file_class_64, Elf::file_data_2MSB>;
+template class table_data<device_pci, version_2_6_10, Elf::file_class_32, Elf::file_data_2LSB>;
+template class table_data<device_pci, version_2_6_10, Elf::file_class_32, Elf::file_data_2MSB>;
+template class table_data<device_pci, version_2_6_10, Elf::file_class_64, Elf::file_data_2LSB>;
+template class table_data<device_pci, version_2_6_10, Elf::file_class_64, Elf::file_data_2MSB>;
+template class table_data<device_pnp, version_2_6_10, Elf::file_class_32, Elf::file_data_2LSB>;
+template class table_data<device_pnp, version_2_6_10, Elf::file_class_32, Elf::file_data_2MSB>;
+template class table_data<device_pnp, version_2_6_10, Elf::file_class_64, Elf::file_data_2LSB>;
+template class table_data<device_pnp, version_2_6_10, Elf::file_class_64, Elf::file_data_2MSB>;
+template class table_data<device_pnp_card, version_2_6_10, Elf::file_class_32, Elf::file_data_2LSB>;
+template class table_data<device_pnp_card, version_2_6_10, Elf::file_class_32, Elf::file_data_2MSB>;
+template class table_data<device_pnp_card, version_2_6_10, Elf::file_class_64, Elf::file_data_2LSB>;
+template class table_data<device_pnp_card, version_2_6_10, Elf::file_class_64, Elf::file_data_2MSB>;
+template class table_data<device_usb, version_2_6_10, Elf::file_class_32, Elf::file_data_2LSB>;
+template class table_data<device_usb, version_2_6_10, Elf::file_class_32, Elf::file_data_2MSB>;
+template class table_data<device_usb, version_2_6_10, Elf::file_class_64, Elf::file_data_2LSB>;
+template class table_data<device_usb, version_2_6_10, Elf::file_class_64, Elf::file_data_2MSB>;
Added: people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.hpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.hpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,340 @@
+/*
+ * module_devicetable_impl_2_6_10.hpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MODULE_DEVICETABLE_IMPL_2_6_10_HPP
+#define MODULE_DEVICETABLE_IMPL_2_6_10_HPP
+
+#include "module_devicetable.hpp"
+
+#include "elf.hpp"
+
+namespace
+{
+ using namespace linuxkernel::module_devicetable;
+
+ template<typename _class>
+ struct _elfdef
+ { };
+
+ template<>
+ struct _elfdef<Elf::file_class_32>
+ {
+ typedef uint32_t pointer;
+ };
+
+ template<>
+ struct _elfdef<Elf::file_class_64>
+ {
+ typedef uint64_t pointer;
+ };
+
+ template<typename device, typename Elf_class>
+ struct device_id
+ { };
+
+ template<typename Elf_class>
+ struct device_id<device_ccw, Elf_class>
+ {
+ uint16_t match_flags;
+ uint16_t cu_type;
+ uint16_t dev_type;
+ uint8_t cu_model;
+ uint8_t dev_model;
+ typename _elfdef<Elf_class>::pointer driver_info;
+ };
+
+ enum
+ {
+ CCW_DEVICE_ID_MATCH_CU_TYPE = 0x01,
+ CCW_DEVICE_ID_MATCH_CU_MODEL = 0x02,
+ CCW_DEVICE_ID_MATCH_DEVICE_TYPE = 0x04,
+ CCW_DEVICE_ID_MATCH_DEVICE_MODEL = 0x08,
+ };
+
+ template<typename Elf_class>
+ struct device_id<device_ieee1394, Elf_class>
+ {
+ uint32_t match_flags;
+ uint32_t vendor_id;
+ uint32_t model_id;
+ uint32_t specifier_id;
+ uint32_t version;
+ typename _elfdef<Elf_class>::pointer driver_info;
+ };
+
+ enum
+ {
+ IEEE1394_MATCH_VENDOR_ID = 0x0001,
+ IEEE1394_MATCH_MODEL_ID = 0x0002,
+ IEEE1394_MATCH_SPECIFIER_ID = 0x0004,
+ IEEE1394_MATCH_VERSION = 0x0008,
+ };
+
+ template<typename Elf_class>
+ struct device_id<device_pci, Elf_class>
+ {
+ uint32_t vendor, device;
+ uint32_t subvendor, subdevice;
+ uint32_t class_id, class_mask;
+ typename _elfdef<Elf_class>::pointer driver_info;
+ };
+
+ const unsigned int PCI_ANY_ID = ~0U;
+ const int PNP_ID_LEN = 8;
+ const int PNP_MAX_DEVICES = 8;
+
+ template <typename Elf_class>
+ struct device_id<device_pnp, Elf_class>
+ {
+ uint8_t id[PNP_ID_LEN];
+ typename _elfdef<Elf_class>::pointer driver_info;
+ };
+
+ template <typename Elf_class>
+ struct device_id<device_pnp_card, Elf_class>
+ {
+ uint8_t id[PNP_ID_LEN];
+ typename _elfdef<Elf_class>::pointer driver_info;
+ struct
+ {
+ uint8_t id[PNP_ID_LEN];
+ }
+ devs[PNP_MAX_DEVICES];
+ };
+
+ template <typename Elf_class>
+ struct device_id<device_usb, Elf_class>
+ {
+ uint16_t match_flags;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice_lo;
+ uint16_t bcdDevice_hi;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ typename _elfdef<Elf_class>::pointer driver_info;
+ };
+
+ enum
+ {
+ USB_DEVICE_ID_MATCH_VENDOR = 0x0001,
+ USB_DEVICE_ID_MATCH_PRODUCT = 0x0002,
+ USB_DEVICE_ID_MATCH_DEV_LO = 0x0004,
+ USB_DEVICE_ID_MATCH_DEV_HI = 0x0008,
+ USB_DEVICE_ID_MATCH_DEV_CLASS = 0x0010,
+ USB_DEVICE_ID_MATCH_DEV_SUBCLASS = 0x0020,
+ USB_DEVICE_ID_MATCH_DEV_PROTOCOL = 0x0040,
+ USB_DEVICE_ID_MATCH_INT_CLASS = 0x0080,
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS = 0x0100,
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL = 0x0200,
+ };
+
+ template<typename type>
+ class identifier_value
+ {
+ public:
+ type value;
+
+ identifier_value () : value (0) { }
+ identifier_value (const type &value) : value (value) { }
+ const type &operator = (const type &_value) { value = _value; return value; }
+ bool operator ! () const { return !value; }
+ operator type () const { return value; }
+ template<typename Elf_data>
+ void set (const type _value)
+ { value = Elf::convert<Elf_data, type> () (_value); }
+ };
+
+ template<typename type>
+ class identifier
+ {
+ public:
+ identifier_value<type> value;
+ std::string sep;
+
+ identifier (const std::string &sep) : sep (sep) { }
+ identifier (const std::string &sep, const type &value) : value (value), sep (sep) { }
+ const type &operator = (const type &_value) { value = _value; return value.value; }
+ bool operator ! () const { return !value; }
+ operator type () const { return value; }
+ void write (std::ostream &out, bool enable, bool last = false) const
+ {
+ out << sep;
+ if (enable)
+ {
+ out << value;
+ if (last)
+ out << '*';
+ }
+ else
+ out << '*';
+ }
+ };
+}
+
+std::ostream &operator << (std::ostream &out, const identifier_value<uint8_t> &id) throw ();
+std::ostream &operator << (std::ostream &out, const identifier_value<uint16_t> &id) throw ();
+std::ostream &operator << (std::ostream &out, const identifier_value<uint32_t> &id) throw ();
+
+namespace linuxkernel
+{
+ namespace module_devicetable
+ {
+ template<>
+ class table_entry_version<device_ccw, version_2_6_10> : public table_entry
+ {
+ public:
+ table_entry_version () throw ();
+ void write (std::ostream &) const throw (std::runtime_error);
+
+ identifier_value<uint16_t> match_flags;
+ identifier<uint16_t> cu_type;
+ identifier<uint16_t> dev_type;
+ identifier<uint8_t> cu_model;
+ identifier<uint8_t> dev_model;
+ };
+
+ template<typename Elf_class, typename Elf_data>
+ class table_entry_data<device_ccw, version_2_6_10, Elf_class, Elf_data> : public table_entry_version<device_ccw, version_2_6_10>
+ {
+ public:
+ table_entry_data (const device_id<device_ccw, Elf_class> &) throw ();
+ };
+
+ template<>
+ class table_entry_version<device_ieee1394, version_2_6_10> : public table_entry
+ {
+ public:
+ table_entry_version () throw ();
+ void write (std::ostream &) const throw (std::runtime_error);
+
+ identifier_value<uint32_t> match_flags;
+ identifier<uint32_t> vendor_id;
+ identifier<uint32_t> model_id;
+ identifier<uint32_t> specifier_id;
+ identifier<uint32_t> version;
+ };
+
+ template<typename Elf_class, typename Elf_data>
+ class table_entry_data<device_ieee1394, version_2_6_10, Elf_class, Elf_data> : public table_entry_version<device_ieee1394, version_2_6_10>
+ {
+ public:
+ table_entry_data (const device_id<device_ieee1394, Elf_class> &) throw ();
+ };
+
+ template<>
+ class table_entry_version<device_pci, version_2_6_10> : public table_entry
+ {
+ public:
+ table_entry_version () throw ();
+ void write (std::ostream &) const throw (std::runtime_error);
+
+ identifier<uint32_t> vendor, device;
+ identifier<uint32_t> subvendor, subdevice;
+ identifier_value<uint32_t> class_id, class_mask;
+ };
+
+ template<typename Elf_class, typename Elf_data>
+ class table_entry_data<device_pci, version_2_6_10, Elf_class, Elf_data> : public table_entry_version<device_pci, version_2_6_10>
+ {
+ public:
+ table_entry_data (const device_id<device_pci, Elf_class> &) throw ();
+ };
+
+ template<>
+ class table_entry_version<device_pnp, version_2_6_10> : public table_entry
+ {
+ public:
+ void write (std::ostream &) const throw (std::runtime_error);
+
+ std::string str;
+ };
+
+ template<typename Elf_class, typename Elf_data>
+ class table_entry_data<device_pnp, version_2_6_10, Elf_class, Elf_data> : public table_entry_version<device_pnp, version_2_6_10>
+ {
+ public:
+ table_entry_data (const device_id<device_pnp, Elf_class> &) throw ();
+ };
+
+ template<>
+ class table_entry_version<device_pnp_card, version_2_6_10> : public table_entry
+ {
+ public:
+ void write (std::ostream &) const throw (std::runtime_error);
+
+ std::string str;
+ };
+
+ template<typename Elf_class, typename Elf_data>
+ class table_entry_data<device_pnp_card, version_2_6_10, Elf_class, Elf_data> : public table_entry_version<device_pnp_card, version_2_6_10>
+ {
+ public:
+ table_entry_data (const device_id<device_pnp_card, Elf_class> &) throw ();
+ };
+
+ template<>
+ class table_entry_version<device_usb, version_2_6_10> : public table_entry
+ {
+ public:
+ table_entry_version () throw ();
+ void write (std::ostream &) const throw (std::runtime_error);
+
+ identifier_value<uint16_t> match_flags;
+ identifier<uint16_t> idVendor;
+ identifier<uint16_t> idProduct;
+ identifier<uint16_t> bcdDevice_lo;
+ identifier<uint16_t> bcdDevice_hi;
+ identifier<uint8_t> bDeviceClass;
+ identifier<uint8_t> bDeviceSubClass;
+ identifier<uint8_t> bDeviceProtocol;
+ identifier<uint8_t> bInterfaceClass;
+ identifier<uint8_t> bInterfaceSubClass;
+ identifier<uint8_t> bInterfaceProtocol;
+ };
+
+ template<typename Elf_class, typename Elf_data>
+ class table_entry_data<device_usb, version_2_6_10, Elf_class, Elf_data> : public table_entry_version<device_usb, version_2_6_10>
+ {
+ public:
+ table_entry_data (const device_id<device_usb, Elf_class> &) throw ();
+ };
+
+ template<typename device, typename Elf_class, typename Elf_data>
+ class table_data<device, version_2_6_10, Elf_class, Elf_data> : public table<device_ccw, Elf_class, Elf_data>
+ {
+ protected:
+ typedef device_id<device, Elf_class> devin;
+
+ public:
+ table_data (const void *mem, size_t size) throw (std::runtime_error);
+ };
+ }
+}
+
+#ifndef DISABLE_TEMPLATES
+#include "module_devicetable_impl_2_6_10.tpp"
+#endif
+
+#endif
Added: people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.tpp
==============================================================================
--- (empty file)
+++ people/waldi/linux-kbuild-2.6/src/mod/module_devicetable_impl_2_6_10.tpp Tue Mar 28 10:07:31 2006
@@ -0,0 +1,120 @@
+/*
+ * module_devicetable_impl_2_6_10.tpp
+ *
+ * Copyright (C) 2005 Bastian Blank <waldi at debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MODULE_DEVICETABLE_IMPL_2_6_10_TPP
+#define MODULE_DEVICETABLE_IMPL_2_6_10_TPP
+
+#include <sstream>
+
+namespace linuxkernel
+{
+ namespace module_devicetable
+ {
+#define _do_convert(name) name = Elf::convert<Elf_data, typeof (id.name)> () (id.name)
+
+ template<typename Elf_class, typename Elf_data>
+ table_entry_data<device_ccw, version_2_6_10, Elf_class, Elf_data>::table_entry_data (const device_id<device_ccw, Elf_class> &id) throw ()
+ {
+ _do_convert (match_flags);
+ _do_convert (cu_type);
+ _do_convert (dev_type);
+ _do_convert (cu_model);
+ _do_convert (dev_model);
+ }
+
+ template<typename Elf_class, typename Elf_data>
+ table_entry_data<device_ieee1394, version_2_6_10, Elf_class, Elf_data>::table_entry_data (const device_id<device_ieee1394, Elf_class> &id) throw ()
+ {
+ _do_convert (match_flags);
+ _do_convert (vendor_id);
+ _do_convert (model_id);
+ _do_convert (specifier_id);
+ _do_convert (version);
+ }
+
+ template<typename Elf_class, typename Elf_data>
+ table_entry_data<device_pci, version_2_6_10, Elf_class, Elf_data>::table_entry_data (const device_id<device_pci, Elf_class> &id) throw ()
+ {
+ _do_convert (vendor);
+ _do_convert (device);
+ _do_convert (subvendor);
+ _do_convert (subdevice);
+ _do_convert (class_id);
+ _do_convert (class_mask);
+ }
+
+ template<typename Elf_class, typename Elf_data>
+ table_entry_data<device_pnp, version_2_6_10, Elf_class, Elf_data>::table_entry_data (const device_id<device_pnp, Elf_class> &id) throw ()
+ {
+ std::stringstream s;
+ s << 'd';
+ s << static_cast <const char *> (static_cast <const void *> (id.id));
+ str = s.str ();
+ }
+
+ template<typename Elf_class, typename Elf_data>
+ table_entry_data<device_pnp_card, version_2_6_10, Elf_class, Elf_data>::table_entry_data (const device_id<device_pnp_card, Elf_class> &id) throw ()
+ {
+ std::stringstream s;
+ s << 'c';
+ s << static_cast <const char *> (static_cast <const void *> (id.id));
+ for (int i = 0; i < PNP_MAX_DEVICES; i++)
+ {
+ if (! *id.devs[i].id)
+ break;
+ s << 'd';
+ s << static_cast <const char *> (static_cast <const void *> (id.devs[i].id));
+ }
+ str = s.str ();
+ }
+
+ template<typename Elf_class, typename Elf_data>
+ table_entry_data<device_usb, version_2_6_10, Elf_class, Elf_data>::table_entry_data (const device_id<device_usb, Elf_class> &id) throw ()
+ {
+ _do_convert (match_flags);
+ _do_convert (idVendor);
+ _do_convert (idProduct);
+ _do_convert (bcdDevice_lo);
+ _do_convert (bcdDevice_hi);
+ _do_convert (bDeviceClass);
+ _do_convert (bDeviceSubClass);
+ _do_convert (bDeviceProtocol);
+ _do_convert (bInterfaceClass);
+ _do_convert (bInterfaceSubClass);
+ _do_convert (bInterfaceProtocol);
+ }
+
+ template<typename device, typename Elf_class, typename Elf_data>
+ table_data<device, version_2_6_10, Elf_class, Elf_data>::table_data (const void *mem, size_t size) throw (std::runtime_error)
+ {
+ if (size % sizeof (devin))
+ throw std::runtime_error ("Bad size");
+ size_t len = size / sizeof (devin);
+ // Remove the terminator.
+ len--;
+ const devin *e = static_cast <const devin *> (mem);
+ this->entries.reserve (len);
+ for (size_t i = 0; i < len; ++i)
+ this->entries.push_back (new table_entry_data<device, version_2_6_10, Elf_class, Elf_data> (e[i]));
+ }
+ }
+}
+
+#endif
More information about the Kernel-svn-changes
mailing list