Bug 65594

Summary: Strange declaration differences on libresolv (.a/.so) (glibc-devel-2.2.5-34)
Product: [Retired] Red Hat Linux Reporter: mehdi.farhat <mehdi.farhat>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.3CC: fweimer
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2002-05-28 11:17:51 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description mehdi.farhat 2002-05-28 10:40:52 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)

Description of problem:
link error when i use libresolv.so

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. gcc -oaxfr axfr.c -lresolv

Actual Results:  /tmp/ccUQ453C.o: In function `main':
/tmp/ccUQ453C.o(.text+0x117): undefined reference to `__ns_initparse'
/tmp/ccUQ453C.o(.text+0x169): undefined reference to `_ns_flagdata'
/tmp/ccUQ453C.o(.text+0x16f): undefined reference to `_ns_flagdata'
/tmp/ccUQ453C.o(.text+0x185): undefined reference to `_ns_flagdata'
/tmp/ccUQ453C.o(.text+0x18b): undefined reference to `_ns_flagdata'
/tmp/ccUQ453C.o(.text+0x203): undefined reference to `__ns_parserr'
/tmp/ccUQ453C.o(.text+0x275): undefined reference to `__ns_name_uncompress'
/tmp/ccUQ453C.o(.text+0x2aa): undefined reference to `__ns_sprintrr'
collect2: ld returned 1 exit status


Additional info:

gcc -static -oaxfr axfr.c -lresolv (work fine)

[root@localhost DNS]# nm /usr/lib/libresolv.a | sed "s/[^ ]* //" |sort >a 
[root@localhost DNS]# nm /usr/lib/libresolv.so | sed "s/[^ ]* //" |sort >so

[root@localhost DNS]# diff a so |grep __ns_initparse
< T __ns_initparse
> t __ns_initparse
<         U __ns_initparse

[root@localhost DNS]# diff a so |grep _ns_flagdata
< D _ns_flagdata
> d _ns_flagdata
<         U _ns_flagdata


What the difference of "T" or "t" ???
I have not seen anything in man or info for "t"

-----------------------------------
axfr.c source for test :
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <errno.h>

main()
{
  char res[512];
  char buf[4512];
  char data[512];
  char *newrr;
  union
  {
    HEADER hdr;                 /* defined in resolv.h */
    u_char buf[4024];           /* defined in arpa/nameser.h */
  }
  response, query;              /* query & response buffers */
  int responseLen, queryLen;    /* buffer length */
  char *nsList[20];
  int nsNum = 0;

  ns_msg handle;
  ns_rr rr;                     /* expanded resource record */
  u_char *cp;
  
  int ret = 0, i;

  ret = res_init();
  if (ret == 0)
  {
    printf("DNS INIT:ok\n");
  }
  else
  {
    fprintf(stderr, "DNS INIT: BAD!!!!");
    exit(1);
  }
  
//_res.options &= ~(RES_DNSRCH | RES_DEFNAMES | RES_USEVC);
_res.options |=  RES_USEVC;

  queryLen = res_mkquery(ns_o_query,    /* regular query         */
                         "localhost",   /* the domain to look up */
                         ns_c_in,       /* Internet type         */
                         ns_t_axfr,     /* Look up an SOA record */
                         (u_char *) NULL,       /* always NULL       */
                         0,     /* length of NULL        */
                         (u_char *) NULL,       /* always NULL       */
                         (u_char *) & query,    /* buffer for the query  */
                         sizeof(query));        /* size of the buffer    */

  printf("queryLen:%i\n", queryLen);

  responseLen =
    res_send((u_char *) & query, queryLen, (u_char *) & response,
             sizeof(response));

  printf("responseLen:%i\n", responseLen);

  if (ns_initparse(response.buf, responseLen, &handle) < 0)
  {
    fprintf(stderr, "ns_initparse: %s\n", strerror(errno));
    return;
  }

  if (ns_msg_getflag(handle, ns_f_rcode) != ns_r_noerror)
  {
    printf("ERROR Dns:%i\n", ns_msg_getflag(handle, ns_f_rcode));
  }
  else
  {
    printf("query ok\n");
  }

  printf("Dns responce count:%i\n", ns_msg_count(handle, ns_s_an));


  for (i = 0; i < ns_msg_count(handle, ns_s_an); i++)
  {
    if (ns_parserr(&handle, ns_s_an, i, &rr))
    {
      if (errno != ENODEV)
      {
        fprintf(stderr, "ns_parserr: %s\n", strerror(errno));
      }
    }

    ns_name_uncompress(ns_msg_base(handle),     /* Start of the packet   */
                       ns_msg_end(handle),      /* End of the packet     */
                       ns_rr_rdata(rr), /* Position in the packet */
                       res,     /* Result                */
                       512) /* Size of nsList buffer */ ;
    
    cp = (u_char *)ns_rr_rdata(rr);
ret = ns_sprintrr(&handle, &rr, NULL, NULL, buf, 512);
                    printf("ns_sprintrr:%s\n", buf);
                    /*
    switch (ns_rr_type(rr))
    {
            case ns_t_soa:
                    ret = ns_sprintrr(&handle, &rr, NULL, NULL, buf, 512);
                    printf("ns_sprintrr:%s\n", buf);
                    printf("SOA:%s\n", cp);
                    ns_name_skip(&cp, ns_msg_end(handle));
                    printf("EMAIL:%s\n", cp);
                    ns_name_skip(&cp, ns_msg_end(handle));
                    printf("Dns data:%d\n", ns_get32(cp));
                    break;
                case 43345:
                    break;
                default:
                    break;
    }
    cp = (u_char *)ns_rr_rdata(rr);
    ns_name_skip(&cp, ns_msg_end(handle));
    ns_name_skip(&cp, ns_msg_end(handle));
    printf("Dns data:%u\n", cp);

*/
  }
  printf("\n\n");

}

Comment 1 mehdi.farhat 2002-05-28 11:17:45 UTC
from 'info nm' "If lowercase,the symbol is local; if uppercase, the symbol is 
global (external)." so why in one case i have a local symbol and another time i 
have a global symbol ???

Comment 2 Jakub Jelinek 2002-05-28 12:36:15 UTC
That's because of symbol versioning (and has been like this for a long time).
IMHO you'd better use -ldns from bind...