This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
link time error linking tinfo.o and tinfo2.o for PE configurations
- To: egcs-bugs at cygnus dot com
- Subject: link time error linking tinfo.o and tinfo2.o for PE configurations
- From: Fred Fish <fnf at ninemoons dot com>
- Date: Fri, 5 Jun 1998 09:09:10 -0700 (MST)
- Cc: fnf at ninemoons dot com (Fred Fish)
I believe there is a problem with the x86 PE compiler when compiling
tinfo2.cc. It generates global symbols that clash with those in
tinfo.cc at link time, making it impossible to include both.
This morning I updated my EGCS source tree and built two
configurations from the same source tree, an i686-pc-linux-gnu native
linux compiler:
../../src/egcs/configure --host=i686-pc-linux-gnu -v --prefix=/usr/local --cache-file=config.cache
and a i586-pe cross compiler:
../../src/egcs/configure --host=i686-pc-linux-gnu -v --prefix=/usr/local --cache-file=config.cache --target=i586-pe
At the end of this email I have included two files, t.cc and t2.cc,
derived from tinfo.cc and tinfo2.cc respectively. If you run the
following commands in egcs/gcc after building the compilers:
$ ./xgcc -B./ -S t.cc t2.cc
$ grep tf9type_info *.s
you get the following results (good) for the native linux compiler:
t.s: .long __tf9type_info
t.s: call __tf9type_info
t.s:.globl __tf9type_info
t.s: .type __tf9type_info,@function
t.s:__tf9type_info:
t.s: .size __tf9type_info,.Lfe21-__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: pushl $__tf9type_info
t2.s: call __tf9type_info
t2.s: call __tf9type_info
t2.s: call __tf9type_info
t2.s: call __tf9type_info
t2.s: call __tf9type_info
t2.s: call __tf9type_info
t2.s: call __tf9type_info
and the following results (bad) for the PE cross compiler:
t.s: .long ___tf9type_info
t.s: .section .text$__tf9type_info,"x"
t.s:.globl ___tf9type_info
t.s:___tf9type_info:
t.s: call ___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: pushl $___tf9type_info
t2.s: call ___tf9type_info
t2.s: call ___tf9type_info
t2.s: call ___tf9type_info
t2.s: call ___tf9type_info
t2.s: .section .text$__tf9type_info,"x"
t2.s:.globl ___tf9type_info
t2.s:___tf9type_info:
t2.s: .long ___tf9type_info
t2.s: call ___tf9type_info
t2.s: call ___tf9type_info
t2.s: call ___tf9type_info
t2.s: call ___tf9type_info
Note that for the cross compiler you have:
t.s:.globl ___tf9type_info
t.s:___tf9type_info:
...
t2.s:.globl ___tf9type_info
t2.s:___tf9type_info:
Here are the source files.
-Fred
============================== begin t.cc ==============================
/* This is a copy of tinfo.cc that has been preprocessed and had all
blank lines and preprocessor lines stripped out. -fnf */
typedef int ptrdiff_t;
typedef unsigned int size_t;
typedef unsigned int wint_t;
extern "C++" {
class exception {
public:
exception () { }
virtual ~exception () { }
virtual const char* what () const;
};
class bad_exception : public exception {
public:
bad_exception () { }
virtual ~bad_exception () { }
};
typedef void (*terminate_handler) ();
typedef void (*unexpected_handler) ();
terminate_handler set_terminate (terminate_handler);
void terminate (void) __attribute__ ((__noreturn__));
unexpected_handler set_unexpected (unexpected_handler);
void unexpected (void) __attribute__ ((__noreturn__));
bool uncaught_exception ();
}
extern "C++" {
class type_info {
private:
type_info& operator= (const type_info&);
type_info (const type_info&);
protected:
type_info (const char *n): _name (n) { }
const char *_name;
public:
virtual ~type_info ();
bool before (const type_info& arg) const;
const char* name () const
{ return _name; }
bool operator== (const type_info& arg) const;
bool operator!= (const type_info& arg) const;
};
inline bool type_info::
operator== (const type_info& arg) const
{
return &arg == this;
}
inline bool type_info::
operator!= (const type_info& arg) const
{
return &arg != this;
}
class bad_cast : public exception {
public:
bad_cast() { }
virtual ~bad_cast() { }
};
class bad_typeid : public exception {
public:
bad_typeid () { }
virtual ~bad_typeid () { }
};
}
struct __user_type_info : public std::type_info {
__user_type_info (const char *n) : type_info (n) {}
virtual void* dcast (const type_info &, int, void *,
const type_info * = 0, void * = 0) const;
};
class __si_type_info : public __user_type_info {
const __user_type_info &base;
public:
__si_type_info (const char *n, const __user_type_info &b)
: __user_type_info (n), base (b) { }
virtual void *dcast (const type_info &, int, void *,
const type_info * = 0, void * = 0) const;
};
typedef unsigned int USItype __attribute__ ((mode (SI)));
struct __class_type_info : public __user_type_info {
enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
struct base_info {
const __user_type_info *base;
USItype offset: 29;
bool is_virtual: 1;
access access: 2;
};
const base_info *base_list;
size_t n_bases;
__class_type_info (const char *name, const base_info *bl, size_t bn)
: __user_type_info (name), base_list (bl), n_bases (bn) {}
virtual void* dcast (const type_info &, int, void *,
const type_info * = 0, void * = 0) const;
};
extern "C++" {
class bad_alloc : public exception {
public:
virtual const char* what() const throw() { return "bad_alloc"; }
};
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler set_new_handler (new_handler);
void *operator new (size_t) throw (std::bad_alloc);
void *operator new[] (size_t) throw (std::bad_alloc);
void operator delete (void *) throw();
void operator delete[] (void *) throw();
void *operator new (size_t, const std::nothrow_t&) throw();
void *operator new[] (size_t, const std::nothrow_t&) throw();
void operator delete (void *, const std::nothrow_t&) throw();
void operator delete[] (void *, const std::nothrow_t&) throw();
inline void *operator new(size_t, void *place) throw() { return place; }
inline void *operator new[](size_t, void *place) throw() { return place; }
}
std::type_info::
~type_info ()
{ }
extern "C" void
__rtti_class (void *addr, const char *name,
const __class_type_info::base_info *bl, size_t bn)
{ new (addr) __class_type_info (name, bl, bn); }
extern "C" void
__rtti_si (void *addr, const char *n, const std::type_info *ti)
{
new (addr) __si_type_info
(n, static_cast <const __user_type_info &> (*ti));
}
extern "C" void
__rtti_user (void *addr, const char *name)
{ new (addr) __user_type_info (name); }
void * __user_type_info::
dcast (const type_info& to, int, void *addr, const type_info *, void *) const
{ return (*this == to) ? addr : 0; }
void * __si_type_info::
dcast (const type_info& to, int require_public, void *addr,
const type_info *sub, void *subptr) const
{
if (*this == to)
return addr;
return base.dcast (to, require_public, addr, sub, subptr);
}
void* __class_type_info::
dcast (const type_info& desired, int is_public, void *objptr,
const type_info *sub, void *subptr) const
{
if (*this == desired)
return objptr;
void *match_found = 0;
for (size_t i = 0; i < n_bases; i++)
{
if (is_public && base_list[i].access != PUBLIC)
continue;
void *p = (char *)objptr + base_list[i].offset;
if (base_list[i].is_virtual)
p = *(void **)p;
p = base_list[i].base->dcast (desired, is_public, p, sub, subptr);
if (p)
{
if (match_found == 0)
match_found = p;
else if (match_found != p)
{
if (sub)
{
const __user_type_info &d =
static_cast <const __user_type_info &> (desired);
void *os = d.dcast (*sub, 1, match_found);
void *ns = d.dcast (*sub, 1, p);
if (os == ns)
;
else if (os == subptr)
continue;
else if (ns == subptr)
{
match_found = p;
continue;
}
}
return 0;
}
}
}
return match_found;
}
============================== begin t2.cc ==============================
/* This is a copy of tinfo2.cc that has been preprocessed and had all
blank lines and preprocessor lines stripped out. -fnf */
typedef int ptrdiff_t;
typedef unsigned int size_t;
typedef unsigned int wint_t;
extern "C++" {
class exception {
public:
exception () { }
virtual ~exception () { }
virtual const char* what () const;
};
class bad_exception : public exception {
public:
bad_exception () { }
virtual ~bad_exception () { }
};
typedef void (*terminate_handler) ();
typedef void (*unexpected_handler) ();
terminate_handler set_terminate (terminate_handler);
void terminate (void) __attribute__ ((__noreturn__));
unexpected_handler set_unexpected (unexpected_handler);
void unexpected (void) __attribute__ ((__noreturn__));
bool uncaught_exception ();
}
extern "C++" {
class type_info {
private:
type_info& operator= (const type_info&);
type_info (const type_info&);
protected:
type_info (const char *n): _name (n) { }
const char *_name;
public:
virtual ~type_info ();
bool before (const type_info& arg) const;
const char* name () const
{ return _name; }
bool operator== (const type_info& arg) const;
bool operator!= (const type_info& arg) const;
};
inline bool type_info::
operator== (const type_info& arg) const
{
return &arg == this;
}
inline bool type_info::
operator!= (const type_info& arg) const
{
return &arg != this;
}
class bad_cast : public exception {
public:
bad_cast() { }
virtual ~bad_cast() { }
};
class bad_typeid : public exception {
public:
bad_typeid () { }
virtual ~bad_typeid () { }
};
}
struct __user_type_info : public std::type_info {
__user_type_info (const char *n) : type_info (n) {}
virtual void* dcast (const type_info &, int, void *,
const type_info * = 0, void * = 0) const;
};
class __si_type_info : public __user_type_info {
const __user_type_info &base;
public:
__si_type_info (const char *n, const __user_type_info &b)
: __user_type_info (n), base (b) { }
virtual void *dcast (const type_info &, int, void *,
const type_info * = 0, void * = 0) const;
};
typedef unsigned int USItype __attribute__ ((mode (SI)));
struct __class_type_info : public __user_type_info {
enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
struct base_info {
const __user_type_info *base;
USItype offset: 29;
bool is_virtual: 1;
access access: 2;
};
const base_info *base_list;
size_t n_bases;
__class_type_info (const char *name, const base_info *bl, size_t bn)
: __user_type_info (name), base_list (bl), n_bases (bn) {}
virtual void* dcast (const type_info &, int, void *,
const type_info * = 0, void * = 0) const;
};
extern "C++" {
class bad_alloc : public exception {
public:
virtual const char* what() const throw() { return "bad_alloc"; }
};
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler set_new_handler (new_handler);
void *operator new (size_t) throw (std::bad_alloc);
void *operator new[] (size_t) throw (std::bad_alloc);
void operator delete (void *) throw();
void operator delete[] (void *) throw();
void *operator new (size_t, const std::nothrow_t&) throw();
void *operator new[] (size_t, const std::nothrow_t&) throw();
void operator delete (void *, const std::nothrow_t&) throw();
void operator delete[] (void *, const std::nothrow_t&) throw();
inline void *operator new(size_t, void *place) throw() { return place; }
inline void *operator new[](size_t, void *place) throw() { return place; }
}
using std::type_info;
static inline int
fast_compare (const char *n1, const char *n2) {
int c;
if (n1 == n2) return 0;
if (n1 == 0) return *n2;
else if (n2 == 0) return *n1;
c = (int)*n1++ - (int)*n2++;
return c == 0 ? strcmp (n1, n2) : c;
};
bool
type_info::before (const type_info &arg) const
{
return fast_compare (name (), arg.name ()) < 0;
}
struct __pointer_type_info : public type_info {
const type_info& type;
__pointer_type_info (const char *n, const type_info& ti)
: type_info (n), type (ti) {}
};
struct __attr_type_info : public type_info {
enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
const type_info& type;
cv attr;
__attr_type_info (const char *n, cv a, const type_info& t)
: type_info (n), type (t), attr (a) {}
};
struct __builtin_type_info : public type_info {
__builtin_type_info (const char *n): type_info (n) {}
};
struct __func_type_info : public type_info {
__func_type_info (const char *n) : type_info (n) {}
};
struct __ptmf_type_info : public type_info {
__ptmf_type_info (const char *n) : type_info (n) {}
};
struct __ptmd_type_info : public type_info {
__ptmd_type_info (const char *n): type_info (n) {}
};
struct __array_type_info : public type_info {
__array_type_info (const char *n): type_info (n) {}
};
extern "C" void*
__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
void *objptr)
{
const type_info &catch_type = *(const type_info *)catch_type_r;
const type_info &throw_type = *(const type_info *)throw_type_r;
if (catch_type == throw_type)
return objptr;
void *new_objptr = 0;
if (const __user_type_info *p
= dynamic_cast <const __user_type_info *> (&throw_type))
{
new_objptr = p->dcast (catch_type, 1, objptr);
}
else if (const __pointer_type_info *fr =
dynamic_cast <const __pointer_type_info *> (&throw_type))
{
const __pointer_type_info *to =
dynamic_cast <const __pointer_type_info *> (&catch_type);
if (! to)
goto fail;
const type_info *subfr = &fr->type, *subto = &to->type;
__attr_type_info::cv cvfrom, cvto;
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subfr))
{
cvfrom = at->attr;
subfr = &at->type;
}
else
cvfrom = __attr_type_info::NONE;
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subto))
{
cvto = at->attr;
subto = &at->type;
}
else
cvto = __attr_type_info::NONE;
if (((cvfrom & __attr_type_info::CONST)
> (cvto & __attr_type_info::CONST))
|| ((cvfrom & __attr_type_info::VOLATILE)
> (cvto & __attr_type_info::VOLATILE)))
goto fail;
if (*subto == *subfr)
new_objptr = objptr;
else if (*subto == typeid (void)
&& dynamic_cast <const __func_type_info *> (subfr) == 0)
new_objptr = objptr;
else if (const __user_type_info *p
= dynamic_cast <const __user_type_info *> (subfr))
{
new_objptr = p->dcast (*subto, 1, objptr);
}
else if (const __pointer_type_info *pfr
= dynamic_cast <const __pointer_type_info *> (subfr))
{
const __pointer_type_info *pto
= dynamic_cast <const __pointer_type_info *> (subto);
if (! pto)
goto fail;
bool constp = (cvto & __attr_type_info::CONST);
for (subto = &pto->type, subfr = &pfr->type; ;
subto = &pto->type, subfr = &pfr->type)
{
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subfr))
{
cvfrom = at->attr;
subfr = &at->type;
}
else
cvfrom = __attr_type_info::NONE;
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subto))
{
cvto = at->attr;
subto = &at->type;
}
else
cvto = __attr_type_info::NONE;
if (((cvfrom & __attr_type_info::CONST)
> (cvto & __attr_type_info::CONST))
|| ((cvfrom & __attr_type_info::VOLATILE)
> (cvto & __attr_type_info::VOLATILE)))
goto fail;
if (! constp
&& (((cvfrom & __attr_type_info::CONST)
< (cvto & __attr_type_info::CONST))
|| ((cvfrom & __attr_type_info::VOLATILE)
< (cvto & __attr_type_info::VOLATILE))))
goto fail;
if (*subto == *subfr)
{
new_objptr = objptr;
break;
}
pto = dynamic_cast <const __pointer_type_info *> (subto);
pfr = dynamic_cast <const __pointer_type_info *> (subfr);
if (! pto || ! pfr)
goto fail;
if (! (cvto & __attr_type_info::CONST))
constp = false;
}
}
}
fail:
return new_objptr;
}
bool
__is_pointer (void *p)
{
const type_info *t = reinterpret_cast <const type_info *>(p);
const __pointer_type_info *pt =
dynamic_cast <const __pointer_type_info *> (t);
return pt != 0;
}
extern "C" void
__rtti_ptr (void *addr, const char *n, const type_info *ti)
{ new (addr) __pointer_type_info (n, *ti); }
extern "C" void
__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
{
new (addr) __attr_type_info
(n, static_cast <__attr_type_info::cv> (attrval), *ti);
}
extern "C" void
__rtti_func (void *addr, const char *name)
{ new (addr) __func_type_info (name); }
extern "C" void
__rtti_ptmf (void *addr, const char *name)
{ new (addr) __ptmf_type_info (name); }
extern "C" void
__rtti_ptmd (void *addr, const char *name)
{ new (addr) __ptmd_type_info (name); }
extern "C" void
__rtti_array (void *addr, const char *name)
{ new (addr) __array_type_info (name); }
extern "C" void *
__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
int require_public, void *address,
const type_info & (*sub)(void), void *subptr)
{
return static_cast <const __user_type_info &> (from ()).dcast
(to (), require_public, address, &(sub ()), subptr);
}
unsigned char __tiv [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfv (void) { if ((*(void **) __tiv ) == 0) new (__tiv ) __builtin_type_info ("v"); return *(type_info *)__tiv ; } ; unsigned char __tix [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfx (void) { if ((*(void **) __tix ) == 0) new (__tix ) __builtin_type_info ("x"); return *(type_info *)__tix ; } ; unsigned char __til [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfl (void) { if ((*(void **) __til ) == 0) new (__til ) __builtin_type_info ("l"); return *(type_info *)__til ; } ; unsigned char __tii [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfi (void) { if ((*(void **) __tii ) == 0) new (__tii ) __builtin_type_info ("i"); return *(type_info *)__tii ;!
} ; unsigned char __tis [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfs (void) { if ((*(void **) __tis ) == 0) new (__tis ) __builtin_type_info ("s"); return *(type_info *)__tis ; } ; unsigned char __tib [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfb (void) { if ((*(void **) __tib ) == 0) new (__tib ) __builtin_type_info ("b"); return *(type_info *)__tib ; } ;
unsigned char __tic [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfc (void) { if ((*(void **) __tic ) == 0) new (__tic ) __builtin_type_info ("c"); return *(type_info *)__tic ; } ; unsigned char __tiw [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfw (void) { if ((*(void **) __tiw ) == 0) new (__tiw ) __builtin_type_info ("w"); return *(type_info *)__tiw ; } ; unsigned char __tir [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfr (void) { if ((*(void **) __tir ) == 0) new (__tir ) __builtin_type_info ("r"); return *(type_info *)__tir ; } ; unsigned char __tid [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfd (void) { if ((*(void **) __tid ) == 0) new (__tid ) __builtin_type_info ("d"); return *(type_info *)__tid ;!
} ; unsigned char __tif [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tff (void) { if ((*(void **) __tif ) == 0) new (__tif ) __builtin_type_info ("f"); return *(type_info *)__tif ; } ;
unsigned char __tiUi [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfUi (void) { if ((*(void **) __tiUi ) == 0) new (__tiUi ) __builtin_type_info ("Ui"); return *(type_info *)__tiUi ; } ; unsigned char __tiUl [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfUl (void) { if ((*(void **) __tiUl ) == 0) new (__tiUl ) __builtin_type_info ("Ul"); return *(type_info *)__tiUl ; } ; unsigned char __tiUx [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfUx (void) { if ((*(void **) __tiUx ) == 0) new (__tiUx ) __builtin_type_info ("Ux"); return *(type_info *)__tiUx ; } ; unsigned char __tiUs [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfUs (void) { if ((*(void **) __tiUs ) == 0) new (__tiUs ) __builtin_type_info ("Us"); retur!
n *(type_info *)__tiUs ; } ; unsigned char __tiUc [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfUc (void) { if ((*(void **) __tiUc ) == 0) new (__tiUc ) __builtin_type_info ("Uc"); return *(type_info *)__tiUc ; } ;
unsigned char __tiSc [sizeof (__builtin_type_info)] __attribute__ ((aligned (__alignof__ (void *)))); extern "C" const type_info &__tfSc (void) { if ((*(void **) __tiSc ) == 0) new (__tiSc ) __builtin_type_info ("Sc"); return *(type_info *)__tiSc ; } ;
================================== end of files ================================