From dufault@hda.com  Tue Dec 27 00:31:55 1994
Received: from hda.com (hda.com [199.232.40.182]) by freefall.cdrom.com (8.6.9/8.6.6) with ESMTP id AAA02415 for <FreeBSD-gnats-submit@freebsd.org>; Tue, 27 Dec 1994 00:31:52 GMT
Received: (dufault@localhost) by hda.com (8.6.9/8.3) id TAA12646; Mon, 26 Dec 1994 19:33:07 -0500
Message-Id: <199412270033.TAA12646@hda.com>
Date: Mon, 26 Dec 1994 19:33:07 -0500
From: Peter Dufault <dufault@hda.com>
Reply-To: dufault@hda.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: nm can't hack long object names in an archive
X-Send-Pr-Version: 3.2

>Number:         87
>Category:       bin
>Synopsis:       nm can't hack long object names in an archive
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    core
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 26 16:40:00 1994
>Closed-Date:    Mon Dec 26 16:40:00 1994
>Last-Modified:  Thu Sep 13 12:55:37 GMT 2007
>Originator:     Peter &
>Release:        FreeBSD 2.1.0-Development i386
>Organization:
Peter Dufault               Real Time Machine Control and Simulation
HD Associates, Inc.         Voice: 508 433 6936
dufault@hda.com             Fax:   508 433 5267
++++ Formerly hd@world.std.com.  E-mail problems? Tell hdslip@iii.net
>Environment:

-current

>Description:

"nm" can't handle long object names in an archive.  It skips over them.

>How-To-Repeat:
Run this shell script.

#!/bin/csh
set A=012345
set B=0123456789ABCDEF
set C=0123456

set ALL=( ${A} ${B} ${C} )

foreach i (${ALL})
	echo ${i}.c":"
	echo "_${i}(){}" > ${i}.c ; cc -c ${i}.c
end

rm -f libfoo.a

echo "ar:"
ar cq libfoo.a ${A}.o ${B}.o ${C}.o
echo "ranlib:"
ranlib libfoo.a
nm -o libfoo.a

foreach i (${ALL})
	rm -f ${i}.c ${i}.o
end

>Fix:
	
*** nm.c.orig	Mon Dec 26 17:22:27 1994
--- nm.c	Mon Dec 26 19:21:02 1994
***************
*** 48,53 ****
--- 48,54 ----
  #include <a.out.h>
  #include <stab.h>
  #include <ar.h>
+ #include <dirent.h>
  #include <ranlib.h>
  #include <unistd.h>
  #include <errno.h>
***************
*** 182,187 ****
--- 183,203 ----
  	return(retval);
  }
  
+ /* scat: concatenate strings, returning new concatenation point
+  * and permitting overlap.
+  */
+ static char *scat(char *dest, char *src)
+ {
+ 	char *end;
+ 	int l1 = strlen(dest), l2 = strlen(src);
+ 
+ 	memmove(dest + l1, src, l2);
+ 	end = dest + l1 + l2;
+ 	*end = 0;
+ 
+ 	return end;
+ }
+ 
  /*
   * show_archive()
   *	show symbols in the given archive file
***************
*** 194,202 ****
  	struct exec exec_head;
  	int i, rval;
  	long last_ar_off;
! 	char *p, *name;
  
! 	name = emalloc(sizeof(ar_head.ar_name) + strlen(fname) + 3);
  
  	rval = 0;
  
--- 210,219 ----
  	struct exec exec_head;
  	int i, rval;
  	long last_ar_off;
! 	char *p, *name, *ar_name;
! 	int buffend = strlen(fname) + 3;
  
! 	name = emalloc(sizeof(MAXNAMLEN) + buffend);
  
  	rval = 0;
  
***************
*** 214,238 ****
  		last_ar_off = ftell(fp);
  
  		/* skip ranlib entries */
! 		if (!strncmp(ar_head.ar_name, RANLIBMAG, sizeof(RANLIBMAG) - 1))
  			goto skip;
  
  		/*
  		 * construct a name of the form "archive.a:obj.o:" for the
  		 * current archive entry if the object name is to be printed
  		 * on each output line
  		 */
  		p = name;
  		if (print_file_each_line)
! 			p += sprintf(p, "%s:", fname);
! 		for (i = 0; i < sizeof(ar_head.ar_name); ++i)
! 			if (ar_head.ar_name[i] && ar_head.ar_name[i] != ' ')
! 				*p++ = ar_head.ar_name[i];
! 		*p++ = '\0';
  
  		/* get and check current object's header */
! 		if (fread((char *)&exec_head, sizeof(exec_head),
! 		    (size_t)1, fp) != 1) {
  			(void)fprintf(stderr, "nm: %s: premature EOF.\n", name);
  			(void)free(name);
  			return(1);
--- 231,286 ----
  		last_ar_off = ftell(fp);
  
  		/* skip ranlib entries */
! 		if (!bcmp(ar_head.ar_name, RANLIBMAG, sizeof(RANLIBMAG) - 1))
  			goto skip;
  
+ 		/* handle long names.  If one is present, read it in at the
+ 		 * end of the "name" buffer.
+ 		 */
+ 		if (!bcmp(ar_head.ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1))
+ 		{
+ 			char *end_part = name + buffend;
+ 			size_t len = atoi(ar_head.ar_name + sizeof(AR_EFMT1) - 1);
+ 
+ 			if (len <= 0 || len > MAXNAMLEN)
+ 			{
+ 				fprintf(stderr, "nm: Illegal length for format 1 long name.\n");
+ 				goto skip;
+ 			}
+ 			if (fread(end_part, 1, len, fp) != len)
+ 			{
+ 				(void)fprintf(stderr, "nm: EOF reading format 1 long name.\n");
+ 				(void)free(name);
+ 				return(1);
+ 			}
+ 			end_part[len] = 0;
+ 			ar_name = end_part;
+ 		}
+ 		else
+ 		{
+ 			p = ar_name = ar_head.ar_name;
+ 			for (i = 0; i < sizeof(ar_head.ar_name); i++)
+ 				if (*p && *p != ' ')
+ 					p++;
+ 			*p = '\0';
+ 		}
+ 
  		/*
  		 * construct a name of the form "archive.a:obj.o:" for the
  		 * current archive entry if the object name is to be printed
  		 * on each output line
  		 */
  		p = name;
+ 		*p = 0;
  		if (print_file_each_line)
! 		{
! 			p = scat(p, fname);
! 			p = scat(p, ":");
! 		}
! 		p = scat(p, ar_name);
  
  		/* get and check current object's header */
! 		if (fread((char *)&exec_head, sizeof(exec_head), (size_t)1, fp) != 1) {
  			(void)fprintf(stderr, "nm: %s: premature EOF.\n", name);
  			(void)free(name);
  			return(1);

>Release-Note:
>Audit-Trail:
>Unformatted:




