* elf32-fr30.c: Fix formatting.
* elf32-hppa.c: Likewise.
* elf32-i370.c: Likewise.
* elf32-i386.c: Likewise.
* elf32-i860.c: Likewise.
* elf32-i960.c: Likewise.
+2000-12-05 Kazu Hirata <kazu@hxi.com>
+
+ * elf32-fr30.c: Fix formatting.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-i860.c: Likewise.
+ * elf32-i960.c: Likewise.
+
2000-12-03 Kazu Hirata <kazu@hxi.com>
* elf32-arm.h: Fix formatting.
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static reloc_howto_type * fr30_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-static void fr30_info_to_howto_rela
+static void fr30_info_to_howto_rela
PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
-static boolean fr30_elf_relocate_section
+static boolean fr30_elf_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static bfd_reloc_status_type fr30_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
0x0000, /* src_mask */
0x00f0, /* dst_mask */
false), /* pcrel_offset */
-
+
/* An 8 bit absolute relocation. */
HOWTO (R_FR30_8_IN_8, /* type */
0, /* rightshift */
0x0000, /* src_mask */
0x0ff0, /* dst_mask */
false), /* pcrel_offset */
-
+
/* A 9 bit absolute relocation. */
HOWTO (R_FR30_9_IN_8, /* type */
1, /* rightshift */
0x0000, /* src_mask */
0x0ff0, /* dst_mask */
false), /* pcrel_offset */
-
+
/* A 10 bit absolute relocation. */
HOWTO (R_FR30_10_IN_8, /* type */
2, /* rightshift */
0, /* src_mask */
0, /* dst_mask */
false), /* pcrel_offset */
-
+
};
\f
/* Utility to actually perform an R_FR30_20 reloc. */
{
bfd_vma relocation;
unsigned long x;
-
+
/* This part is from bfd_elf_generic_reloc. */
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
--i;)
if (fr30_reloc_map [i].bfd_reloc_val == code)
return & fr30_elf_howto_table [fr30_reloc_map[i].fr30_reloc_val];
-
+
return NULL;
}
bfd_reloc_status_type r = bfd_reloc_ok;
bfd_vma x;
bfd_signed_vma srel;
-
+
switch (howto->type)
{
case R_FR30_20:
if (relocation > ((1 << 20) - 1))
return bfd_reloc_overflow;
-
+
x = bfd_get_32 (input_bfd, contents);
x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
bfd_put_32 (input_bfd, x, contents);
break;
-
+
case R_FR30_48:
contents += rel->r_offset + 2;
relocation += rel->r_addend;
srel = (bfd_signed_vma) relocation;
srel += rel->r_addend;
srel -= rel->r_offset;
- srel -= 2; /* Branch instructions add 2 to the PC... */
+ srel -= 2; /* Branch instructions add 2 to the PC... */
srel -= (input_section->output_section->vma +
input_section->output_offset);
-
+
if (srel & 1)
return bfd_reloc_outofrange;
if (srel > ((1 << 8) - 1) || (srel < - (1 << 8)))
srel = (bfd_signed_vma) relocation;
srel += rel->r_addend;
srel -= rel->r_offset;
- srel -= 2; /* Branch instructions add 2 to the PC... */
+ srel -= 2; /* Branch instructions add 2 to the PC... */
srel -= (input_section->output_section->vma +
input_section->output_offset);
-
+
if (srel & 1)
return bfd_reloc_outofrange;
if (srel > ((1 << 11) - 1) || (srel < - (1 << 11)))
return bfd_reloc_overflow;
-
+
x = bfd_get_16 (input_bfd, contents);
x = (x & 0xf800) | ((srel >> 1) & 0x7ff);
bfd_put_16 (input_bfd, x, contents);
bfd_reloc_status_type r;
const char * name = NULL;
int r_type;
-
+
r_type = ELF32_R_TYPE (rel->r_info);
-
+
if ( r_type == R_FR30_GNU_VTINHERIT
|| r_type == R_FR30_GNU_VTENTRY)
continue;
-
+
r_symndx = ELF32_R_SYM (rel->r_info);
if (info->relocateable)
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
-
+
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
{
sec = local_sections [r_symndx];
h = NULL;
sym = NULL;
sec = NULL;
-
+
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
relocation = (sec->output_section->vma
+ sec->output_offset
+ sym->st_value);
-
+
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
else
{
h = sym_hashes [r_symndx - symtab_hdr->sh_info];
-
+
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
name = h->root.root.string;
-
+
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
relocation = 0;
}
}
-
+
r = fr30_final_link_relocate (howto, input_bfd, input_section,
contents, rel, relocation);
(info, name, howto->name, (bfd_vma) 0,
input_bfd, input_section, rel->r_offset);
break;
-
+
case bfd_reloc_undefined:
r = info->callbacks->undefined_symbol
(info, name, input_bfd, input_section, rel->r_offset,
true);
break;
-
+
case bfd_reloc_outofrange:
msg = _("internal error: out of range error");
break;
/* Look through the relocs for a section during the first phase.
Since we don't do .gots or .plts, we just need to consider the
virtual table relocs for gc. */
-
+
static boolean
fr30_elf_check_relocs (abfd, info, sec, relocs)
bfd *abfd;
struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
-
+
if (info->relocateable)
return true;
-
+
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
- sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
if (!elf_bad_symtab (abfd))
sym_hashes_end -= symtab_hdr->sh_info;
-
+
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
struct elf_link_hash_entry *h;
unsigned long r_symndx;
-
+
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-
+
switch (ELF32_R_TYPE (rel->r_info))
{
/* This relocation describes the C++ object vtable hierarchy.
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return false;
break;
-
+
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_FR30_GNU_VTENTRY:
break;
}
}
-
+
return true;
}
\f
#include "elf-hppa.h"
#include "elf32-hppa.h"
-
/* In order to gain some understanding of code in this file without
knowing all the intricate details of the linker, note the
following:
early in the link process, elf32_hppa_finish_dynamic_sections is
one of the last functions. */
-
/* We use two hash tables to hold information for linking PA ELF objects.
The first is the elf32_hppa_link_hash_table which is derived
#define RELATIVE_DYNAMIC_RELOCS 0
#endif
-
enum elf32_hppa_stub_type {
hppa_stub_long_branch,
hppa_stub_long_branch_shared,
hppa_stub_none
};
-
struct elf32_hppa_stub_hash_entry {
/* Base hash table entry structure. */
asection *id_sec;
};
-
struct elf32_hppa_link_hash_entry {
struct elf_link_hash_entry elf;
unsigned int plt_abs:1;
};
-
struct elf32_hppa_link_hash_table {
/* The main hash table. */
unsigned int need_plt_stub:1;
};
-
/* Various hash macros and functions. */
#define hppa_link_hash_table(p) \
((struct elf32_hppa_link_hash_table *) ((p)->hash))
static struct bfd_link_hash_table *elf32_hppa_link_hash_table_create
PARAMS ((bfd *));
-
/* Stub handling functions. */
static char *hppa_stub_name
PARAMS ((const asection *, const asection *,
static boolean hppa_size_one_stub
PARAMS ((struct bfd_hash_entry *, PTR));
-
/* BFD and elf backend functions. */
static boolean elf32_hppa_object_p PARAMS ((bfd *));
static int elf32_hppa_elf_get_symbol_type
PARAMS ((Elf_Internal_Sym *, int));
-
/* Assorted hash table functions. */
/* Initialize an entry in the stub hash table. */
return (struct bfd_hash_entry *) ret;
}
-
/* Initialize an entry in the link hash table. */
static struct bfd_hash_entry *
return (struct bfd_hash_entry *) ret;
}
-
/* Create the derived linker hash table. The PA ELF port uses the derived
hash table to keep information specific to the PA ELF linker (without
using static variables). */
return &ret->root.root;
}
-
/* Build a name for an entry in the stub hash table. */
static char *
return stub_name;
}
-
/* Look up an entry in the stub hash. Stub entries are cached because
creating the stub name takes a bit of time. */
return stub_entry;
}
-
/* Add a new stub entry to the stub hash. Not all fields of the new
stub entry are initialised. */
return stub_entry;
}
-
/* Determine the type of stub needed, if any, for a call. */
static enum elf32_hppa_stub_type
return hppa_stub_none;
}
-
/* Build one linker stub as defined by the stub hash table entry GEN_ENTRY.
IN_ARG contains the link info pointer. */
#undef LDSID_RP_R1
#undef BE_SR0_RP
-
/* As above, but don't actually build the stub. Just bump offset so
we know stub section sizes. */
return true;
}
-
/* Return nonzero if ABFD represents an HPPA ELF32 file.
Additionally we set the default architecture and machine. */
return true;
}
-
/* Undo the generic ELF code's subtraction of section->vma from the
value of each external symbol. */
return true;
}
-
/* Create the .plt and .got sections, and set up our hash table
short-cuts to various dynamic sections. */
return true;
}
-
/* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage
table. At this point we haven't necessarily read all the input
return true;
}
-
/* Return the section that should be marked against garbage collection
for a given relocation. */
return NULL;
}
-
/* Update the got and plt entry reference counts for the section being
removed. */
return true;
}
-
/* Our own version of hide_symbol, so that we can keep plt entries for
plabels. */
}
}
-
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
return true;
}
-
/* Called via elf_link_hash_traverse to create .plt entries for an
application that uses statically linked PIC functions. Similar to
the first part of elf32_hppa_adjust_dynamic_symbol. */
return true;
}
-
#if ((! LONG_BRANCH_PIC_IN_SHLIB && LONG_BRANCH_VIA_PLT) \
|| RELATIVE_DYNAMIC_RELOCS)
/* This function is called via elf_link_hash_traverse to discard space
}
#endif
-
/* This function is called via elf_link_hash_traverse to force
millicode symbols local so they do not end up as globals in the
dynamic symbol table. We ought to be able to do this in
return true;
}
-
/* Set the sizes of the dynamic sections. */
static boolean
{
struct elf_link_hash_entry *h;
- h = elf_link_hash_lookup (&hplink->root,
+ h = elf_link_hash_lookup (&hplink->root,
funcname,
false, false, false);
if (h != NULL
return true;
}
-
/* External entry points for sizing and building linker stubs. */
/* Determine and set the size of the stub section for a final link.
return ret;
}
-
/* For a final link, this function is called after we have sized the
stubs to provide a value for __gp. */
return true;
}
-
/* Build all the stubs associated with the current output file. The
stubs are kept in a hash table attached to the main linker hash
table. We also set up the .plt entries for statically linked PIC
return true;
}
-
/* Perform a relocation as part of a final link. */
static bfd_reloc_status_type
return bfd_reloc_ok;
}
-
/* Relocate an HPPA ELF section. */
static boolean
&& (is_absolute_reloc (r_type)
|| ((!info->symbolic
|| (h != NULL
- && ((h->elf.elf_link_hash_flags
+ && ((h->elf.elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0
|| h->elf.root.type == bfd_link_hash_defweak)))
&& (h == NULL || h->elf.dynindx != -1)))
return true;
}
-
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
return true;
}
-
/* Finish up the dynamic sections. */
static boolean
{
struct elf_link_hash_entry *h;
const char *funcname;
-
+
if (dyn.d_tag == DT_INIT)
funcname = info->init_function;
else
return true;
}
-
/* Called when writing out an object file to decide the type of a
symbol. */
static int
return type;
}
-
/* Misc BFD support code. */
#define bfd_elf32_bfd_is_local_label_name elf_hppa_is_local_label_name
#define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-
/* This file is based on a preliminary PowerPC ELF ABI.
But its been hacked on for the IBM 360/370 architectures.
Basically, the 31bit relocation works, and just about everything
dynamic loading to work ... its never been tested ...
*/
-
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
for (i = 0; i < sizeof (i370_elf_howto_raw) / sizeof (i370_elf_howto_raw[0]); i++)
{
type = i370_elf_howto_raw[i].type;
- BFD_ASSERT (type < sizeof(i370_elf_howto_table) / sizeof(i370_elf_howto_table[0]));
+ BFD_ASSERT (type < sizeof (i370_elf_howto_table) / sizeof (i370_elf_howto_table[0]));
i370_elf_howto_table[type] = &i370_elf_howto_raw[i];
}
}
#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
-
/* Set the howto pointer for an i370 ELF reloc. */
static void
/* hack alert -- the following several routines look generic to me ...
* why are we bothering with them ???
*/
-/* Function to set whether a module needs the -mrelocatable bit set. */
+/* Function to set whether a module needs the -mrelocatable bit set. */
static boolean
i370_elf_set_private_flags (abfd, flags)
bfd *abfd;
return true;
}
-
\f
/* Set up any other section flags and such that may be necessary. */
/* XXX hack alert bogus This routine is mostly all junk and almost
* just enough to allow glibc-2.1 ld.so to compile & link.
*/
-
static boolean
i370_elf_fake_sections (abfd, shdr, asect)
bfd *abfd ATTRIBUTE_UNUSED;
return false;
}
- /* xxx beats me, seem to need a rela.text ... */
+ /* xxx beats me, seem to need a rela.text ... */
s = bfd_make_section (abfd, ".rela.text");
if (s == NULL
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
&& (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0)));
-
s = bfd_get_section_by_name (dynobj, ".rela.text");
BFD_ASSERT (s != NULL);
s->_raw_size += sizeof (Elf32_External_Rela);
asection *target;
const char *outname;
- /* Remember whether there are any relocation sections. */
+ /* Remember whether there are any relocation sections. */
relocs = true;
/* If this relocation section applies to a read only
relocation = 0;
else
{
- (*info->callbacks->undefined_symbol)(info,
- h->root.root.string,
- input_bfd,
- input_section,
- rel->r_offset,
- true);
+ (*info->callbacks->undefined_symbol) (info,
+ h->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset,
+ true);
ret = false;
continue;
}
#ifdef DEBUG
if (indx <= 0)
{
- printf("indx=%d section=%s flags=%08x name=%s\n",
- indx, osec->name, osec->flags,
- h->root.root.string);
+ printf ("indx=%d section=%s flags=%08x name=%s\n",
+ indx, osec->name, osec->flags,
+ h->root.root.string);
}
#endif
}
continue;
}
-
#ifdef DEBUG
fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n",
howto->name,
name = bfd_section_name (input_bfd, sec);
}
- (*info->callbacks->reloc_overflow)(info,
- name,
- howto->name,
- (bfd_vma) 0,
- input_bfd,
- input_section,
- offset);
+ (*info->callbacks->reloc_overflow) (info,
+ name,
+ howto->name,
+ (bfd_vma) 0,
+ input_bfd,
+ input_section,
+ offset);
}
break;
}
}
-
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
#define ELF_MAXPAGESIZE 0x1000
#define elf_info_to_howto i370_elf_info_to_howto
-
-
#define elf_backend_plt_not_loaded 1
#define elf_backend_got_symbol_offset 4
};
-
#ifdef DEBUG_GEN_RELOC
#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
#else
space allocated to copy PC relative relocs against symbols which
are defined in regular objects. For the normal non-symbolic case,
we also discard space for relocs that have become local due to
- symbol visibility changes. We allocated space for them in the
+ symbol visibility changes. We allocated space for them in the
check_relocs routine, but we won't fill them in in the
relocate_section routine. */
#include "elf-bfd.h"
#include "elf/i860.h"
-
/* Prototypes. */
static reloc_howto_type *lookup_howto
PARAMS ((unsigned int));
static reloc_howto_type *elf32_i860_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
-static void elf32_i860_info_to_howto_rela
+static void elf32_i860_info_to_howto_rela
PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
static bfd_reloc_status_type elf32_i860_relocate_splitn
static bfd_reloc_status_type elf32_i860_relocate_highadj
PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
-static boolean elf32_i860_relocate_section
+static boolean elf32_i860_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static boolean elf32_i860_is_local_label_name
PARAMS ((bfd *, const char *));
-
-
/* This howto table is preliminary. */
static reloc_howto_type elf32_i860_howto_table [] =
{
return elf32_i860_howto_table + i;
}
-
/* Given a BFD reloc, return the matching HOWTO structure. */
static reloc_howto_type *
elf32_i860_reloc_type_lookup (abfd, code)
rtype = R_860_COPY;
break;
case BFD_RELOC_860_GLOB_DAT:
- rtype = R_860_GLOB_DAT;
+ rtype = R_860_GLOB_DAT;
break;
case BFD_RELOC_860_JUMP_SLOT:
rtype = R_860_JUMP_SLOT;
return lookup_howto (rtype);
}
-
/* Given a ELF reloc, return the matching HOWTO structure. */
static void
elf32_i860_info_to_howto_rela (abfd, bfd_reloc, elf_reloc)
bfd_reloc->howto = lookup_howto (ELF32_R_TYPE (elf_reloc->r_info));
}
-
\f
/* Specialized relocation handler for R_860_SPLITn. These relocations
involves a 16-bit field that is split into two contiguous parts. */
return bfd_reloc_ok;
}
-
/* Specialized relocation handler for R_860_PC16. This relocation
involves a 16-bit, PC-relative field that is split into two contiguous
parts. */
}
-
/* Specialized relocation handler for R_860_PC26. This relocation
involves a 26-bit, PC-relative field which must be adjusted by 4. */
static bfd_reloc_status_type
value += rello->r_addend;
/* Adjust value by 4 and insert the field. */
- value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
+ value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
insn = (insn & ~howto->dst_mask) | value;
bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
}
-
/* Specialized relocation handler for R_860_HIGHADJ. */
static bfd_reloc_status_type
elf32_i860_relocate_highadj (input_bfd, rel, contents, value)
return bfd_reloc_ok;
}
-
/* Perform a single relocation. By default we use the standard BFD
routines. However, we handle some specially. */
static bfd_reloc_status_type
rel->r_addend);
}
-
/* Relocate an i860 ELF section.
This is boiler-plate code copied from fr30.
bfd_reloc_status_type r;
const char * name = NULL;
int r_type;
-
+
r_type = ELF32_R_TYPE (rel->r_info);
-
+
#if 0
if ( r_type == R_860_GNU_VTINHERIT
|| r_type == R_860_GNU_VTENTRY)
continue;
#endif
-
+
r_symndx = ELF32_R_SYM (rel->r_info);
if (info->relocateable)
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
-
+
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
{
sec = local_sections [r_symndx];
h = NULL;
sym = NULL;
sec = NULL;
-
+
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
relocation = (sec->output_section->vma
+ sec->output_offset
+ sym->st_value);
-
+
name = bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link, sym->st_name);
name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
else
{
h = sym_hashes [r_symndx - symtab_hdr->sh_info];
-
+
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
name = h->root.root.string;
-
+
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
relocation = 0;
}
}
-
+
switch (r_type)
{
default:
case R_860_HIGOTOFF:
r = bfd_reloc_notsupported;
break;
- }
+ }
if (r != bfd_reloc_ok)
{
(info, name, howto->name, (bfd_vma) 0,
input_bfd, input_section, rel->r_offset);
break;
-
+
case bfd_reloc_undefined:
r = info->callbacks->undefined_symbol
(info, name, input_bfd, input_section, rel->r_offset, true);
break;
-
+
case bfd_reloc_outofrange:
msg = _("internal error: out of range error");
break;
return true;
}
-
/* Return whether a symbol name implies a local label. SVR4/860 compilers
generate labels of the form ".ep.function_name" to denote the end of a
function prolog. These should be local.
return _bfd_elf_is_local_label_name (abfd, name);
}
-
\f
#define TARGET_BIG_SYM bfd_elf32_i860_vec
#define TARGET_BIG_NAME "elf32-i860"
{
reloc_entry->addend -= symbol->value;
}
- /* This is more dubious. */
+ /* This is more dubious. */
else if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) != 0)
{