##----------------------------------------------------------------------##

# Errors to suppress by default for glibc 2.1.3

# Format of this file is:
# {
#     name_of_suppression
#     skin_name:supp_kind
#     (optional extra info for some suppression types)
#     caller0 name, or /name/of/so/file.so
#     caller1 name, or ditto
#     (optionally: caller2 name)
#     (optionally: caller3 name)
#  }
#
# For Memcheck, the supp_kinds are:
#
#     Param Value1 Value2 Value4 Value8
#     Free Addr1 Addr2 Addr4 Addr8
#     Cond (previously known as Value0)
#
# and the optional extra info is:
#     if Param: name of system call param
#     if Free: name of free-ing fn)

#-------- Suppress errors appearing as a result of calling
#-------- __libc_freeres()

{
   __libc_freeres/free_mem(Addr4)
   Addrcheck,Memcheck:Addr4
   fun:free_mem
   fun:__libc_freeres
}


##----------------------------------------------------------------------##

{
   __pthread_mutex_unlock/__register_frame_info_bases
   core:PThread
   fun:__pthread_mutex_unlock
   fun:__register_frame_info_bases
}

{
   socketcall.connect(serv_addr)/__libc_connect/*(Param)
   Addrcheck,Memcheck:Param
   socketcall.connect(serv_addr)
   fun:__libc_connect
   fun:*
}

{
   strrchr/_dl_map_object_from_fd/_dl_map_object(Addr4)
   Addrcheck,Memcheck:Addr4
   fun:strrchr
   fun:_dl_map_object_from_fd
   fun:_dl_map_object
}

{
   strrchr/_dl_map_object_from_fd/_dl_map_object(Value1)
   Memcheck:Value1
   fun:strrchr
   fun:_dl_map_object_from_fd
   fun:_dl_map_object
}

{
   llseek(result)/__libc_lseek64/_IO_file_seek(Param)
   Addrcheck,Memcheck:Param
   llseek(result)
   fun:__libc_lseek64
   fun:_IO_file_seek
}

{
   __rawmemchr/_nl_*/*locale(Addr4)
   Addrcheck,Memcheck:Addr4
   fun:__rawmemchr
   fun:_nl_*
   fun:*locale
}

# new ones for RH62 ls -l 
{
   __strchrnul/__nss_database_lookup(Cond)
   Memcheck:Cond
   fun:__strchrnul
   fun:__nss_database_lookup
}
{
   __strchrnul/__gethostbyname_r(Cond)
   Memcheck:Cond
   fun:__strchrnul
   fun:__gethostbyname_r
}

{
   strrchr/_dl_map*/_dl_map*(Cond)
   Memcheck:Cond
   fun:strrchr
   fun:_dl_map*
   fun:_dl_map*
}

{
   strchr/dl_open_worker/_dl_catch_error(Cond)
   Memcheck:Cond
   fun:strchr
   fun:dl_open_worker
   fun:_dl_catch_error
}

{
   __rawmemchr/???/__getgrgid_r(Cond)
   Memcheck:Cond
   fun:__rawmemchr
   fun:*
   fun:__getgrgid_r
}

{
   __rawmemchr/_nl_*/*locale*(Cond)
   Memcheck:Cond
   fun:__rawmemchr
   fun:_nl_*
   fun:*locale*
}

{
   _dl_relocate_object/dl_open_worker(Value0)
   Memcheck:Cond
   fun:_dl_relocate_object
   fun:dl_open_worker
}

##----------------------------------------------------------------------##
## from a Debian machine running kernel 2.2.19 I believe
## I guess most of these are the same as above really, but
## Debian stripped their libc-2.1.3

{
   libc-2.1.3.so/libc-2.1.3.so/libc-2.1.3.so(Cond)
   Memcheck:Cond
   obj:*libc-2.1.3.so
   obj:*libc-2.1.3.so
   obj:*libc-2.1.3.so
}

{
   strchr/libc-2.1.3.so(Cond)
   Memcheck:Cond
   fun:*strchr*
   obj:*libc-2.1.3.so
}

{
   libc-2.1.3.so/libXt.so(Cond)
   Memcheck:Cond
   obj:*libc-2.1.3.so
   obj:*libXt.so*
}

{
   socketcall.connect(serv_addr)/__libc_connect/*(Param)
   Addrcheck,Memcheck:Param
   socketcall.connect(serv_addr)
   obj:*libc-2.1.3.so
   obj:*libX11.so*
}

##----------------------------------------------------------------------##
