Bug 43810

Summary: 'echo' is too big
Product: Base System Reporter: kientzle
Component: binAssignee: njl
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description kientzle 2002-10-08 05:00:11 UTC
Compiled, statically linked, and stripped, 'echo' is
over 40k!!  A few space-conscious edits reduce that
to just over 5k.

Fix: Following patch reduces 'echo' to just over 5k
with _no_lost_functionality_ (even that obscure \c
hack still works):
How-To-Repeat: ls -l /bin/echo
<gasp in amazement>
Comment 1 Bruce Evans 2002-10-08 09:04:44 UTC
On Mon, 7 Oct 2002, Tim Kientzle wrote:

> >Description:
> Compiled, statically linked, and stripped, 'echo' is
> over 40k!!  A few space-conscious edits reduce that
> to just over 5k.

I don't approve of hacking on individual utilities to work around
bloated libraries, but note that sync(1) is enormously bloated in
-current and this can be "fixed" by writing it in assembler:

%%%
/* sync.S */

#include <sys/syscall.h>

	.globl	_start
_start:
	movl	$SYS_sync,%eax
	int	$0x80
	movl	$SYS_exit,%eax
	int	$0x80
%%%

Note that this is fully bug for bug compatibile with sync.c: it has the
same error checking (none).

sync(1) has been bloated from about 6k (?) in RELENG_4 to 16K in -current.
This compares unfavourably with the 14 bytes for the above version.  Fixing
the main causes of sync's bloat in libc only reduced it to 3K (still 224
times larger than the above).  Most of 13K library debloating for sync only
helps for rare programs that don't use malloc() or sys_errlist[].  Even
"main() {}" now uses malloc() because atexit() uses it unconditionally and
crt1 uses atexit() unconditionally (to do nothing for "main() {}").  This
is recent bloat.  sys_errlist[] is always used for stupider reasons
(because syscalls reference errno, and sys_errlist[] in in the same
file as errno).  This bloat came with elf.  errno is in crt0 for aout.

Bruce
Comment 2 Giorgos Keramidas freebsd_committer freebsd_triage 2002-10-08 10:47:51 UTC
On 2002-10-07 20:52, Tim Kientzle <kientzle@acm.org> wrote:
>
> diff --context echo.c-original echo.c
> *** echo.c-original     Mon Oct  7 20:44:50 2002
> --- echo.c      Mon Oct  7 20:44:15 2002
> ***************
> *** 45,52 ****
>   #include <sys/cdefs.h>
>   __FBSDID("$FreeBSD: src/bin/echo/echo.c,v 1.13 2002/06/30 05:13:53 obrien Exp 
> $");
>   
> - #include <stdio.h>
> - #include <stdlib.h>
>   #include <string.h>
>   
>   /* ARGSUSED */
> --- 45,50 ----
> ***************
> *** 56,62 ****
>         int nflag;      /* if not set, output a trailing newline. */
>   
>         /* This utility may NOT do getopt(3) option parsing. */
> !       if (*++argv && !strcmp(*argv, "-n")) {
>                 ++argv;
>                 nflag = 1;
>         }
> --- 54,60 ----
>         int nflag;      /* if not set, output a trailing newline. */
>   
>         /* This utility may NOT do getopt(3) option parsing. */
> !       if (*++argv && argv[0][0]=='-' && argv[0][1]=='n') {
>                 ++argv;
>                 nflag = 1;
>         }

You're not checking for argv[0][2] == '\0'.  This will make strange
command lines like work in unexpected ways.

	$ echo -nocheck "foo"

Giorgos.
Comment 3 njl freebsd_committer freebsd_triage 2002-11-24 00:07:54 UTC
State Changed
From-To: open->closed

I committed a patch that removes the getopt and stdio dependencies.  This 
gets echo down to 12820 bytes.  The rest will have to wait on patches to 
atexit() that Tim has submitted. 


Comment 4 njl freebsd_committer freebsd_triage 2002-11-24 00:07:54 UTC
Responsible Changed
From-To: freebsd-bugs->njl

Assign myself to this since I'm working with Tim on size issues.