# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # include $(SRC)/Makefile.master SUBDIRS = $(MACH64) all : TARGET= all clean : TARGET= clean clobber : TARGET= clobber install : TARGET= install catalog : TARGET= catalog chkmsg : TARGET= chkmsg .KEEP_STATE: .KEEP_STATE_FILE: .make.state.$(MACH) all clean clobber install catalog chkmsg: \ $(SUBDIRS) $(SUBDIRS): FRC @ cd $@; pwd; $(MAKE) $(TARGET) FRC: # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # PROG= size include $(SRC)/cmd/Makefile.cmd include $(SRC)/cmd/sgs/Makefile.com COMOBJS= main.o process.o fcns.o SRCS= $(COMOBJS:%.o=../common/%.c) CERRWARN += -Wno-unused-variable OBJS = $(COMOBJS) .PARALLEL: $(OBJS) RPATH = '-R$$ORIGIN/../../lib/$(MACH64)' LDFLAGS += $(RPATH) LDLIBS += $(CONVLIBDIR64) -lconv $(ELFLIBDIR64) -lelf CLEANFILES += $(OBJS) # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # %.o: ../common/%.c $(COMPILE.c) $< $(POST_PROCESS_O) $(PROG): $(OBJS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) all: $(PROG) install: all $(ROOTPROG) $(ROOTCCSBINLINK) clean: $(RM) $(CLEANFILES) include $(SRC)/cmd/Makefile.targ # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # include ../Makefile.com DEFLIST= -DAMD64 -DELF .KEEP_STATE: # Hammerhead: ROOTPROG64=ROOTPROG, ROOTCCSBINLINK64=ROOTCCSBINLINK (path flattening) # Removed duplicate 64-bit targets and ../../bin symlink (circular when /bin -> usr/bin) install: all $(ROOTPROG) \ $(ROOTCCSBINLINK) include ../Makefile.targ include $(SRC)/Makefile.master.64 /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ #define FATAL 1 #define HEX 0 #define OCTAL 1 #define DECIMAL 2 #define TROUBLE -1L #define MAXLEN 512 /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include /* * error(file, string) * simply prints the error message string * simply returns */ void error(char *file, char *string) { extern int exitcode; extern int is_archive; extern char *archive; (void) fflush(stdout); if (is_archive) { (void) fprintf(stderr, "size: %s[%s]: %s\n", archive, file, string); } else { (void) fprintf(stderr, "size: %s: %s\n", file, string); } exitcode++; } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1988 AT&T * Copyright (c) 1989 AT&T * All Rights Reserved * * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* UNIX HEADERS */ #include #include #include #include #include /* SIZE HEADER */ #include "defs.h" /* RELEASE STRING */ #include "conv.h" #include "sgs.h" /* EXTERNAL VARIABLES DEFINED */ int fflag = 0, /* print full output if -f option is supplied */ Fflag = 0, /* print full output if -F option is supplied */ nflag = 0; /* include NOLOAD sections in size if -n */ /* option is supplied */ int numbase = DECIMAL; static int errflag = 0; /* Global error flag */ int oneflag = 0; int exitcode = 0; /* Global exit code */ char *fname; char *archive; int is_archive = 0; static char *tool_name; static void usagerr(); #define OPTSTR "VoxnfF" /* option string for usage error message */ #define GETOPTSTR "VoxnfF?" /* option string for getopt */ static Elf *elf; static Elf_Arhdr *arhdr; /* * main(argc, argv) * * parses the command line * opens, processes and closes each object file command line argument * * defines: * - int numbase = HEX if the -x flag is in the command line * = OCTAL if the -o flag is in the command line * = DECIMAL if the -d flag is in the command line * * calls: * - process(filename) to print the size information in the object file * filename * * prints: * - an error message if any unknown options appear on the command line * - a usage message if no object file args appear on the command line * - an error message if it can't open an object file * or if the object file has the wrong magic number * * exits 1 - errors found, 0 - no errors */ int main(int argc, char ** argv, char ** envp) { /* UNIX FUNCTIONS CALLED */ extern void error(); /* SIZE FUNCTIONS CALLED */ extern void process(); /* EXTERNAL VARIABLES USED */ extern int numbase; extern int errflag; extern int oneflag; extern int optind; extern char *fname; int c; static int fd; extern char *archive; Elf_Cmd cmd; Elf *arf; unsigned Vflag = 0; tool_name = argv[0]; while ((c = getopt(argc, argv, GETOPTSTR)) != EOF) { switch (c) { case 'o': if (numbase != HEX) numbase = OCTAL; else (void) fprintf(stderr, "size: -x set, -o ignored\n"); break; case 'd': numbase = DECIMAL; break; case 'x': if (numbase != OCTAL) numbase = HEX; else (void) fprintf(stderr, "size: -o set, -x ignored\n"); break; case 'f': fflag++; break; case 'F': Fflag++; break; case 'n': nflag++; break; case 'V': (void) fprintf(stderr, "size: %s %s\n", (const char *)SGU_PKG, (const char *)SGU_REL); Vflag++; break; case '?': errflag++; break; default: break; } } if (errflag || (optind >= argc)) { if (!(Vflag && (argc == 2) && !errflag)) { usagerr(); } } if ((argc - optind) == 1) { oneflag++; /* only one file to process */ } if (elf_version(EV_CURRENT) == EV_NONE) { (void) fprintf(stderr, "size: Libelf is out of date"); exit(FATAL); /* library out of date */ } for (; optind < argc; optind++) { fname = argv[optind]; if ((fd = open(argv[optind], O_RDONLY)) == -1) { error(fname, "cannot open"); } else { cmd = ELF_C_READ; arf = 0; if ((arf = elf_begin(fd, cmd, arf)) == 0) { /* error(fname, "cannot open"); */ (void) fprintf(stderr, "size: %s: %s\n", fname, elf_errmsg(-1)); return (FATAL); } if (elf_kind(arf) == ELF_K_AR) { archive = argv[optind]; } else { archive = ""; } while ((elf = elf_begin(fd, cmd, arf)) != 0) { if ((arhdr = elf_getarhdr(elf)) == 0) { if (elf_kind(arf) == ELF_K_NONE) { /* BEGIN CSTYLED */ (void) fprintf(stderr, "%s: %s: invalid file type\n", tool_name, fname); /* END CSTYLED */ exitcode++; break; } else { process(elf); } } else if (arhdr->ar_name[0] != '/') { fname = arhdr->ar_name; if (elf_kind(arf) == ELF_K_NONE) { /* BEGIN CSTYLED */ (void) fprintf(stderr, "%s: %s[%s]: invalid file type\n", tool_name, archive, fname); /* END CSTYLED */ exitcode++; break; } else { is_archive++; process(elf); } } cmd = elf_next(elf); (void) elf_end(elf); } (void) elf_end(arf); (void) close(fd); } } if (exitcode) exit(FATAL); else exit(0); return (0); } static void usagerr() { (void) fprintf(stderr, "usage: %s [-%s] file(s)...\n", tool_name, OPTSTR); exitcode++; } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* Copyright (c) 1989 AT&T */ /* All Rights Reserved */ /* UNIX HEADER */ #include /* SIZE HEADERS */ #include "defs.h" /* ELF HEADERS */ #include "gelf.h" /* SIZE FUNCTIONS CALLED */ extern void error(); /* FORMAT STRINGS */ static const char *prusect[3] = { "%llx", "%llo", "%lld" }; static const char *prusum[3] = { " = 0x%llx\n", " = 0%llo\n", " = %lld\n" }; static const char *format[3] = { "%llx + %llx + %llx = 0x%llx\n", "%llo + %llo + %llo = 0%llo\n", "%lld + %lld + %lld = %lld\n" }; static void process_phdr(Elf *elf, GElf_Half num); void process(Elf * elf) { /* EXTERNAL VARIABLES USED */ extern int fflag; /* full format for sections */ extern int Fflag; /* full format for segments */ extern int nflag; /* include non-loadable segments or sections */ extern int numbase; /* hex, octal, or decimal */ extern char *fname; extern char *archive; extern int is_archive; extern int oneflag; /* LOCAL VARIABLES */ GElf_Xword size; /* total size in non-default case for sections */ /* * size of first, second, third number and total size * in default case for sections. */ GElf_Xword first; GElf_Xword second; GElf_Xword third; GElf_Xword totsize; GElf_Ehdr ehdr; GElf_Shdr shdr; Elf_Scn *scn; size_t ndx = 0, shnum = 0; int numsect = 0; int notfirst = 0; int i; char *name = 0; /* * If there is a program header and the -f flag requesting section infor- * mation is not set, then process segments with the process_phdr function. * Otherwise, process sections. For the default case, the first number * shall be the size of all sections that are allocatable, nonwritable and * not of type NOBITS; the second number shall be the size of all sections * that are allocatable, writable, and not of type NOBITS; the third number * is the size of all sections that are writable and not of type NOBITS. * If -f is set, print the size of each allocatable section, followed by * the section name in parentheses. * If -n is set, print the size of all sections, followed by the section * name in parentheses. */ if (gelf_getehdr(elf, &ehdr) == 0) { error(fname, "invalid file type"); return; } if ((ehdr.e_phnum != 0) && !(fflag)) { process_phdr(elf, ehdr.e_phnum); return; } if (is_archive) { (void) printf("%s[%s]: ", archive, fname); } else if (!oneflag && !is_archive) { (void) printf("%s: ", fname); } if (elf_getshdrstrndx(elf, &ndx) == -1) error(fname, "no string table"); scn = 0; size = 0; first = second = third = totsize = 0; if (elf_getshdrnum(elf, &shnum) == -1) error(fname, "can't get number of sections"); if (shnum == 0) error(fname, "no section data"); numsect = shnum; for (i = 0; i < numsect; i++) { if ((scn = elf_nextscn(elf, scn)) == 0) { break; } if (gelf_getshdr(scn, &shdr) == 0) { error(fname, "could not get section header"); break; } if ((Fflag) && !(fflag)) { error(fname, "no segment data"); return; } else if ((!(shdr.sh_flags & SHF_ALLOC)) && fflag && !(nflag)) { continue; } else if ((!(shdr.sh_flags & SHF_ALLOC)) && !(nflag)) { continue; } else if ((shdr.sh_flags & SHF_ALLOC) && (!(shdr.sh_flags & SHF_WRITE)) && (!(shdr.sh_type == SHT_NOBITS)) && !(fflag) && !(nflag)) { first += shdr.sh_size; } else if ((shdr.sh_flags & SHF_ALLOC) && (shdr.sh_flags & SHF_WRITE) && (!(shdr.sh_type == SHT_NOBITS)) && !(fflag) && !(nflag)) { second += shdr.sh_size; } else if ((shdr.sh_flags & SHF_WRITE) && (shdr.sh_type == SHT_NOBITS) && !(fflag) && !(nflag)) { third += shdr.sh_size; } name = elf_strptr(elf, ndx, (size_t)shdr.sh_name); if (fflag || nflag) { size += shdr.sh_size; if (notfirst) { (void) printf(" + "); } (void) printf(prusect[numbase], shdr.sh_size); (void) printf("(%s)", name); } notfirst++; } if ((fflag || nflag) && (numsect > 0)) { (void) printf(prusum[numbase], size); } if (!fflag && !nflag) { totsize = first + second + third; (void) printf(format[numbase], first, second, third, totsize); } if (Fflag) { if (ehdr.e_phnum != 0) { process_phdr(elf, ehdr.e_phnum); return; } else { error(fname, "no segment data"); return; } } } /* * If there is a program exection header, process segments. In the default * case, the first number is the file size of all nonwritable segments * of type PT_LOAD; the second number is the file size of all writable * segments whose type is PT_LOAD; the third number is the memory size * minus the file size of all writable segments of type PT_LOAD. * If the -F flag is set, size will print the memory size of each loadable * segment, followed by its permission flags. * If -n is set, size will print the memory size of all loadable segments * and the file size of all non-loadable segments, followed by their * permission flags. */ static void process_phdr(Elf * elf, GElf_Half num) { int i; int notfirst = 0; GElf_Phdr p; GElf_Xword memsize; GElf_Xword total; GElf_Xword First; GElf_Xword Second; GElf_Xword Third; GElf_Xword Totsize; extern int Fflag; extern int nflag; extern int numbase; extern char *fname; extern char *archive; extern int is_archive; extern int oneflag; memsize = total = 0; First = Second = Third = Totsize = 0; if (is_archive) { (void) printf("%s[%s]: ", archive, fname); } else if (!oneflag && !is_archive) { (void) printf("%s: ", fname); } for (i = 0; i < (int)num; i++) { if (gelf_getphdr(elf, i, &p) == NULL) { error(fname, "no segment data"); return; } if ((!(p.p_flags & PF_W)) && (p.p_type == PT_LOAD) && !(Fflag)) { First += p.p_filesz; } else if ((p.p_flags & PF_W) && (p.p_type == PT_LOAD) && !(Fflag)) { Second += p.p_filesz; Third += p.p_memsz; } memsize += p.p_memsz; if ((p.p_type == PT_LOAD) && nflag) { if (notfirst) { (void) printf(" + "); } (void) printf(prusect[numbase], p.p_memsz); total += p.p_memsz; notfirst++; } if (!(p.p_type == PT_LOAD) && nflag) { if (notfirst) { (void) printf(" + "); } (void) printf(prusect[numbase], p.p_filesz); total += p.p_filesz; notfirst++; } if ((p.p_type == PT_LOAD) && Fflag && !nflag) { if (notfirst) { (void) printf(" + "); } (void) printf(prusect[numbase], p.p_memsz); notfirst++; } if ((Fflag) && !(nflag) && (!(p.p_type == PT_LOAD))) { continue; } if (Fflag || nflag) { switch (p.p_flags) { case 0: (void) printf("(---)"); break; case PF_X: (void) printf("(--x)"); break; case PF_W: (void) printf("(-w-)"); break; case PF_W+PF_X: (void) printf("(-wx)"); break; case PF_R: (void) printf("(r--)"); break; case PF_R+PF_X: (void) printf("(r-x)"); break; case PF_R+PF_W: (void) printf("(rw-)"); break; case PF_R+PF_W+PF_X: (void) printf("(rwx)"); break; default: (void) printf("flags(%#x)", p.p_flags); } } } if (nflag) { (void) printf(prusum[numbase], total); } if (Fflag && !nflag) { (void) printf(prusum[numbase], memsize); } if (!Fflag && !nflag) { Totsize = First + Second + (Third - Second); (void) printf(format[numbase], First, Second, Third - Second, Totsize); } }