mirror of
https://github.com/openbsd/src.git
synced 2025-01-03 06:45:37 -08:00
Grow -P (POSIX output) and -t (POSIX output radix) support. Several 3rd-party
software depend upon this. Requested by feinerer@, ok millert@; manpage bits ok jmc@
This commit is contained in:
parent
ade61d9934
commit
1a0915b634
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: elf.c,v 1.32 2015/06/23 15:16:34 semarie Exp $ */
|
||||
/* $OpenBSD: elf.c,v 1.33 2015/08/13 19:13:28 miod Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Michael Shalayeff
|
||||
@ -37,8 +37,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "elfuncs.h"
|
||||
#include "util.h"
|
||||
#include "elfuncs.h"
|
||||
|
||||
#if ELFSIZE == 32
|
||||
#define swap_addr swap32
|
||||
@ -116,7 +116,7 @@
|
||||
#endif
|
||||
|
||||
int elf_shn2type(Elf_Ehdr *, u_int, const char *);
|
||||
int elf2nlist(Elf_Sym *, Elf_Ehdr *, Elf_Shdr *, char *, struct nlist *);
|
||||
int elf2nlist(Elf_Sym *, Elf_Ehdr *, Elf_Shdr *, char *, struct xnlist *);
|
||||
|
||||
int
|
||||
elf_fix_header(Elf_Ehdr *eh)
|
||||
@ -342,11 +342,12 @@ elf_shn2type(Elf_Ehdr *eh, u_int shn, const char *sn)
|
||||
}
|
||||
|
||||
/*
|
||||
* Devise nlist's type from Elf_Sym.
|
||||
* Devise xnlist's type from Elf_Sym.
|
||||
* XXX this task is done as well in libc and kvm_mkdb.
|
||||
*/
|
||||
int
|
||||
elf2nlist(Elf_Sym *sym, Elf_Ehdr *eh, Elf_Shdr *shdr, char *shstr, struct nlist *np)
|
||||
elf2nlist(Elf_Sym *sym, Elf_Ehdr *eh, Elf_Shdr *shdr, char *shstr,
|
||||
struct xnlist *np)
|
||||
{
|
||||
u_char stt;
|
||||
const char *sn;
|
||||
@ -372,60 +373,61 @@ elf2nlist(Elf_Sym *sym, Elf_Ehdr *eh, Elf_Shdr *shdr, char *shstr, struct nlist
|
||||
type = elf_shn2type(eh, sym->st_shndx, sn);
|
||||
if (type < 0) {
|
||||
if (sn == NULL)
|
||||
np->n_other = '?';
|
||||
np->nl.n_other = '?';
|
||||
else
|
||||
np->n_type = stt == STT_NOTYPE? N_COMM : N_DATA;
|
||||
np->nl.n_type = stt == STT_NOTYPE ?
|
||||
N_COMM : N_DATA;
|
||||
} else {
|
||||
/* a hack for .rodata check (; */
|
||||
if (type == N_SIZE) {
|
||||
np->n_type = N_DATA;
|
||||
np->n_other = 'r';
|
||||
np->nl.n_type = N_DATA;
|
||||
np->nl.n_other = 'r';
|
||||
} else
|
||||
np->n_type = type;
|
||||
np->nl.n_type = type;
|
||||
}
|
||||
if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
|
||||
np->n_other = 'W';
|
||||
np->nl.n_other = 'W';
|
||||
break;
|
||||
|
||||
case STT_FUNC:
|
||||
type = elf_shn2type(eh, sym->st_shndx, NULL);
|
||||
np->n_type = type < 0? N_TEXT : type;
|
||||
np->nl.n_type = type < 0? N_TEXT : type;
|
||||
if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
|
||||
np->n_other = 'W';
|
||||
np->nl.n_other = 'W';
|
||||
} else if (sn != NULL && *sn != 0 &&
|
||||
strcmp(sn, ELF_INIT) &&
|
||||
strcmp(sn, ELF_TEXT) &&
|
||||
strcmp(sn, ELF_FINI)) /* XXX GNU compat */
|
||||
np->n_other = '?';
|
||||
np->nl.n_other = '?';
|
||||
break;
|
||||
|
||||
case STT_SECTION:
|
||||
type = elf_shn2type(eh, sym->st_shndx, NULL);
|
||||
if (type < 0)
|
||||
np->n_other = '?';
|
||||
np->nl.n_other = '?';
|
||||
else
|
||||
np->n_type = type;
|
||||
np->nl.n_type = type;
|
||||
break;
|
||||
|
||||
case STT_FILE:
|
||||
np->n_type = N_FN | N_EXT;
|
||||
np->nl.n_type = N_FN | N_EXT;
|
||||
break;
|
||||
|
||||
case STT_PARISC_MILLI:
|
||||
if (eh->e_machine == EM_PARISC)
|
||||
np->n_type = N_TEXT;
|
||||
np->nl.n_type = N_TEXT;
|
||||
else
|
||||
np->n_other = '?';
|
||||
np->nl.n_other = '?';
|
||||
break;
|
||||
|
||||
default:
|
||||
np->n_other = '?';
|
||||
np->nl.n_other = '?';
|
||||
break;
|
||||
}
|
||||
if (np->n_type != N_UNDF && ELF_ST_BIND(sym->st_info) != STB_LOCAL) {
|
||||
np->n_type |= N_EXT;
|
||||
if (np->n_other)
|
||||
np->n_other = toupper((unsigned char)np->n_other);
|
||||
if (np->nl.n_type != N_UNDF && ELF_ST_BIND(sym->st_info) != STB_LOCAL) {
|
||||
np->nl.n_type |= N_EXT;
|
||||
if (np->nl.n_other)
|
||||
np->nl.n_other = toupper((unsigned char)np->nl.n_other);
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -456,12 +458,12 @@ elf_size(Elf_Ehdr *head, Elf_Shdr *shdr,
|
||||
|
||||
int
|
||||
elf_symloadx(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh,
|
||||
Elf_Shdr *shdr, char *shstr, long shstrsize, struct nlist **pnames,
|
||||
struct nlist ***psnames, size_t *pstabsize, int *pnrawnames,
|
||||
Elf_Shdr *shdr, char *shstr, long shstrsize, struct xnlist **pnames,
|
||||
struct xnlist ***psnames, size_t *pstabsize, int *pnrawnames,
|
||||
const char *strtab, const char *symtab)
|
||||
{
|
||||
long symsize;
|
||||
struct nlist *np;
|
||||
struct xnlist *np;
|
||||
Elf_Sym sbuf;
|
||||
int i;
|
||||
|
||||
@ -532,8 +534,9 @@ elf_symloadx(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh,
|
||||
continue;
|
||||
|
||||
elf2nlist(&sbuf, eh, shdr, shstr, np);
|
||||
np->n_value = sbuf.st_value;
|
||||
np->n_un.n_strx = sbuf.st_name;
|
||||
np->nl.n_value = sbuf.st_value;
|
||||
np->nl.n_un.n_strx = sbuf.st_name;
|
||||
np->n_size = sbuf.st_size;
|
||||
np++;
|
||||
}
|
||||
*pnrawnames = np - *pnames;
|
||||
@ -544,7 +547,7 @@ elf_symloadx(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh,
|
||||
|
||||
int
|
||||
elf_symload(const char *name, FILE *fp, off_t foff, Elf_Ehdr *eh,
|
||||
Elf_Shdr *shdr, struct nlist **pnames, struct nlist ***psnames,
|
||||
Elf_Shdr *shdr, struct xnlist **pnames, struct xnlist ***psnames,
|
||||
size_t *pstabsize, int *pnrawnames)
|
||||
{
|
||||
long shstrsize;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: elfuncs.h,v 1.4 2015/06/23 15:02:58 semarie Exp $ */
|
||||
/* $OpenBSD: elfuncs.h,v 1.5 2015/08/13 19:13:28 miod Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Michael Shalayeff
|
||||
@ -36,10 +36,10 @@ int elf32_fix_phdrs(Elf32_Ehdr *eh, Elf32_Phdr *phdr);
|
||||
int elf32_fix_sym(Elf32_Ehdr *eh, Elf32_Sym *sym);
|
||||
int elf32_size(Elf32_Ehdr *, Elf32_Shdr *, u_long *, u_long *, u_long *);
|
||||
int elf32_symloadx(const char *, FILE *, off_t, Elf32_Ehdr *, Elf32_Shdr *,
|
||||
char *, long, struct nlist **, struct nlist ***, size_t *, int *,
|
||||
char *, long, struct xnlist **, struct xnlist ***, size_t *, int *,
|
||||
const char *, const char *);
|
||||
int elf32_symload(const char *, FILE *, off_t, Elf32_Ehdr *, Elf32_Shdr *,
|
||||
struct nlist **, struct nlist ***, size_t *, int *);
|
||||
struct xnlist **, struct xnlist ***, size_t *, int *);
|
||||
|
||||
int elf64_fix_header(Elf64_Ehdr *eh);
|
||||
Elf64_Shdr*elf64_load_shdrs(const char *, FILE *, off_t, Elf64_Ehdr *);
|
||||
@ -49,7 +49,7 @@ int elf64_fix_phdrs(Elf64_Ehdr *eh, Elf64_Phdr *phdr);
|
||||
int elf64_fix_sym(Elf64_Ehdr *eh, Elf64_Sym *sym);
|
||||
int elf64_size(Elf64_Ehdr *, Elf64_Shdr *, u_long *, u_long *, u_long *);
|
||||
int elf64_symloadx(const char *, FILE *, off_t, Elf64_Ehdr *, Elf64_Shdr *,
|
||||
char *, long, struct nlist **, struct nlist ***, size_t *, int *,
|
||||
char *, long, struct xnlist **, struct xnlist ***, size_t *, int *,
|
||||
const char *, const char *);
|
||||
int elf64_symload(const char *, FILE *, off_t, Elf64_Ehdr *, Elf64_Shdr *,
|
||||
struct nlist **, struct nlist ***, size_t *, int *);
|
||||
struct xnlist **, struct xnlist ***, size_t *, int *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: nm.1,v 1.27 2015/05/17 20:19:08 guenther Exp $
|
||||
.\" $OpenBSD: nm.1,v 1.28 2015/08/13 19:13:28 miod Exp $
|
||||
.\" $NetBSD: nm.1,v 1.3 1995/08/31 23:41:58 jtc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1990, 1993
|
||||
@ -30,7 +30,7 @@
|
||||
.\"
|
||||
.\" @(#)nm.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd $Mdocdate: May 17 2015 $
|
||||
.Dd $Mdocdate: August 13 2015 $
|
||||
.Dt NM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -38,7 +38,8 @@
|
||||
.Nd display name list (symbol table)
|
||||
.Sh SYNOPSIS
|
||||
.Nm nm
|
||||
.Op Fl aCDegnoprsuw
|
||||
.Op Fl AaCDegnoPprsuw
|
||||
.Op Fl t d|o|x
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The symbol table (name list) of each object in
|
||||
@ -58,6 +59,8 @@ and displays its symbol table if it exists.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl A
|
||||
Display the full path or library name of object on every line.
|
||||
.It Fl a
|
||||
Display symbol table entries inserted for use by debuggers.
|
||||
.It Fl C
|
||||
@ -73,13 +76,36 @@ Restrict display to external (global) symbols.
|
||||
.It Fl n
|
||||
Present results in numerical order.
|
||||
.It Fl o
|
||||
Display full path or library name of object on every line.
|
||||
Display the full path or library name of object on every line
|
||||
.Pq this is similar to Fl A .
|
||||
.It Fl P
|
||||
Report information in POSIX format: full path or library name of object if
|
||||
either
|
||||
.Fl A
|
||||
or
|
||||
.Fl o
|
||||
has been specified; symbol name; symbol type;
|
||||
symbol value and size (unless the symbol is undefined).
|
||||
The radix of symbol values and sizes defaults to decimal, and may be changed
|
||||
with the
|
||||
.Fl t
|
||||
option.
|
||||
.It Fl p
|
||||
Do not sort at all.
|
||||
.It Fl r
|
||||
Reverse order sort.
|
||||
.It Fl s
|
||||
Show archive index.
|
||||
.It Fl t Ar d|o|x
|
||||
In POSIX format output, choose the numeric radix as follows:
|
||||
.Bl -tag -width 3n -compact
|
||||
.It d
|
||||
Decimal.
|
||||
.It o
|
||||
Octal.
|
||||
.It x
|
||||
Hexadecimal.
|
||||
.El
|
||||
.It Fl u
|
||||
Display undefined symbols only.
|
||||
.It Fl w
|
||||
|
144
usr.bin/nm/nm.c
144
usr.bin/nm/nm.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: nm.c,v 1.46 2015/05/17 21:41:50 guenther Exp $ */
|
||||
/* $OpenBSD: nm.c,v 1.47 2015/08/13 19:13:28 miod Exp $ */
|
||||
/* $NetBSD: nm.c,v 1.7 1996/01/14 23:04:03 pk Exp $ */
|
||||
|
||||
/*
|
||||
@ -49,8 +49,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include "elfuncs.h"
|
||||
#include "util.h"
|
||||
#include "elfuncs.h"
|
||||
|
||||
#define SYMTABMAG "/ "
|
||||
#define STRTABMAG "//"
|
||||
@ -70,6 +70,9 @@ int print_all_symbols;
|
||||
int print_file_each_line;
|
||||
int show_extensions;
|
||||
int issize;
|
||||
char posix_fmtstr[6];
|
||||
int posix_output;
|
||||
char posix_radix = 'x';
|
||||
int usemmap = 1;
|
||||
int dynamic_only;
|
||||
|
||||
@ -81,9 +84,9 @@ int rev;
|
||||
int fname(const void *, const void *);
|
||||
int rname(const void *, const void *);
|
||||
int value(const void *, const void *);
|
||||
char *otherstring(struct nlist *);
|
||||
char *otherstring(struct xnlist *);
|
||||
int (*sfunc)(const void *, const void *) = fname;
|
||||
char typeletter(struct nlist *);
|
||||
char typeletter(struct xnlist *);
|
||||
int mmbr_name(struct ar_hdr *, char **, int, int *, FILE *);
|
||||
int show_symtab(off_t, u_long, const char *, FILE *);
|
||||
int show_symdef(off_t, u_long, const char *, FILE *);
|
||||
@ -94,13 +97,13 @@ int show_symdef(off_t, u_long, const char *, FILE *);
|
||||
|
||||
void pipe2cppfilt(void);
|
||||
void usage(void);
|
||||
char *symname(struct nlist *);
|
||||
char *symname(struct xnlist *);
|
||||
int process_file(int, const char *);
|
||||
int show_archive(int, const char *, FILE *);
|
||||
int show_file(int, int, const char *, FILE *fp, off_t, union hdr *);
|
||||
void print_symbol(const char *, struct nlist *);
|
||||
void print_symbol(const char *, struct xnlist *);
|
||||
|
||||
#define OPTSTRING_NM "aABCDegnoprsuvw"
|
||||
#define OPTSTRING_NM "aABCDegnopPrst:uvw"
|
||||
const struct option longopts_nm[] = {
|
||||
{ "debug-syms", no_argument, 0, 'a' },
|
||||
{ "demangle", no_argument, 0, 'C' },
|
||||
@ -171,6 +174,9 @@ main(int argc, char *argv[])
|
||||
case 'p':
|
||||
sfunc = NULL;
|
||||
break;
|
||||
case 'P':
|
||||
posix_output = 1;
|
||||
break;
|
||||
case 'r':
|
||||
rev = 1;
|
||||
break;
|
||||
@ -186,14 +192,23 @@ main(int argc, char *argv[])
|
||||
case 't':
|
||||
if (issize) {
|
||||
print_totals = 1;
|
||||
break;
|
||||
} else {
|
||||
posix_radix = *optarg;
|
||||
if (strlen(optarg) != 1 ||
|
||||
(posix_radix != 'd' && posix_radix != 'o' &&
|
||||
posix_radix != 'x'))
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (posix_output)
|
||||
(void)snprintf(posix_fmtstr, sizeof posix_fmtstr, "%%%c %%%c",
|
||||
posix_radix, posix_radix);
|
||||
if (demangle)
|
||||
pipe2cppfilt();
|
||||
argv += optind;
|
||||
@ -468,6 +483,8 @@ show_archive(int count, const char *fname, FILE *fp)
|
||||
u_long mmbrlen, symtablen;
|
||||
|
||||
baselen = strlen(fname) + 3;
|
||||
if (posix_output)
|
||||
baselen += 2;
|
||||
namelen = sizeof(ar_head.ar_name);
|
||||
if ((name = malloc(baselen + namelen)) == NULL)
|
||||
err(1, NULL);
|
||||
@ -555,7 +572,9 @@ show_archive(int count, const char *fname, FILE *fp)
|
||||
* on each output line
|
||||
*/
|
||||
*name = '\0';
|
||||
if (count > 1)
|
||||
if (posix_output)
|
||||
snprintf(name, baselen - 1, "%s[", fname);
|
||||
else if (count > 1)
|
||||
snprintf(name, baselen - 1, "%s:", fname);
|
||||
|
||||
if (mmbr_name(&ar_head, &name, baselen, &namelen, fp)) {
|
||||
@ -563,6 +582,9 @@ show_archive(int count, const char *fname, FILE *fp)
|
||||
break;
|
||||
}
|
||||
|
||||
if (posix_output)
|
||||
strlcat(name, "]", baselen + namelen);
|
||||
|
||||
foff = ftello(fp);
|
||||
|
||||
/* get and check current object's header */
|
||||
@ -605,7 +627,7 @@ int
|
||||
show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union hdr *head)
|
||||
{
|
||||
u_long text, data, bss, total;
|
||||
struct nlist *np, *names, **snames;
|
||||
struct xnlist *np, *names, **snames;
|
||||
int i, nrawnames, nnames;
|
||||
size_t stabsize;
|
||||
|
||||
@ -693,14 +715,14 @@ show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union
|
||||
*
|
||||
* don't mess with zero offsets
|
||||
*/
|
||||
if (np->n_un.n_strx)
|
||||
np->n_un.n_name = stab + np->n_un.n_strx;
|
||||
if (np->nl.n_un.n_strx)
|
||||
np->nl.n_un.n_name = stab + np->nl.n_un.n_strx;
|
||||
else
|
||||
np->n_un.n_name = "";
|
||||
if (print_only_external_symbols && !IS_EXTERNAL(np->n_type))
|
||||
np->nl.n_un.n_name = "";
|
||||
if (print_only_external_symbols && !IS_EXTERNAL(np->nl.n_type))
|
||||
continue;
|
||||
if (print_only_undefined_symbols &&
|
||||
SYMBOL_TYPE(np->n_type) != N_UNDF)
|
||||
SYMBOL_TYPE(np->nl.n_type) != N_UNDF)
|
||||
continue;
|
||||
|
||||
snames[nnames++] = np;
|
||||
@ -724,9 +746,9 @@ show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union
|
||||
}
|
||||
|
||||
char *
|
||||
symname(struct nlist *sym)
|
||||
symname(struct xnlist *sym)
|
||||
{
|
||||
return sym->n_un.n_name;
|
||||
return sym->nl.n_un.n_name;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -734,30 +756,42 @@ symname(struct nlist *sym)
|
||||
* show one symbol
|
||||
*/
|
||||
void
|
||||
print_symbol(const char *name, struct nlist *sym)
|
||||
print_symbol(const char *name, struct xnlist *sym)
|
||||
{
|
||||
if (print_file_each_line)
|
||||
(void)printf("%s:", name);
|
||||
|
||||
/*
|
||||
* handle undefined-only format especially (no space is
|
||||
* left for symbol values, no type field is printed)
|
||||
*/
|
||||
if (!print_only_undefined_symbols) {
|
||||
/* print symbol's value */
|
||||
if (SYMBOL_TYPE(sym->n_type) == N_UNDF)
|
||||
(void)printf(" ");
|
||||
if (print_file_each_line) {
|
||||
if (posix_output)
|
||||
(void)printf("%s: ", name);
|
||||
else
|
||||
(void)printf("%08lx", sym->n_value);
|
||||
|
||||
/* print type information */
|
||||
if (show_extensions)
|
||||
(void)printf(" %c ", typeletter(sym));
|
||||
else
|
||||
(void)printf(" %c ", typeletter(sym));
|
||||
(void)printf("%s:", name);
|
||||
}
|
||||
|
||||
(void)puts(symname(sym));
|
||||
if (posix_output) {
|
||||
(void)printf("%s %c ", symname(sym), typeletter(sym));
|
||||
if (SYMBOL_TYPE(sym->nl.n_type) != N_UNDF)
|
||||
(void)printf(posix_fmtstr, sym->nl.n_value,
|
||||
sym->n_size);
|
||||
(void)printf("\n");
|
||||
} else {
|
||||
/*
|
||||
* handle undefined-only format especially (no space is
|
||||
* left for symbol values, no type field is printed)
|
||||
*/
|
||||
if (!print_only_undefined_symbols) {
|
||||
/* print symbol's value */
|
||||
if (SYMBOL_TYPE(sym->nl.n_type) == N_UNDF)
|
||||
(void)printf(" ");
|
||||
else
|
||||
(void)printf("%08lx", sym->nl.n_value);
|
||||
|
||||
/* print type information */
|
||||
if (show_extensions)
|
||||
(void)printf(" %c ", typeletter(sym));
|
||||
else
|
||||
(void)printf(" %c ", typeletter(sym));
|
||||
}
|
||||
|
||||
(void)puts(symname(sym));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -767,14 +801,14 @@ print_symbol(const char *name, struct nlist *sym)
|
||||
* external, lower case for internal symbols.
|
||||
*/
|
||||
char
|
||||
typeletter(struct nlist *np)
|
||||
typeletter(struct xnlist *np)
|
||||
{
|
||||
int ext = IS_EXTERNAL(np->n_type);
|
||||
int ext = IS_EXTERNAL(np->nl.n_type);
|
||||
|
||||
if (np->n_other)
|
||||
return np->n_other;
|
||||
if (np->nl.n_other)
|
||||
return np->nl.n_other;
|
||||
|
||||
switch(SYMBOL_TYPE(np->n_type)) {
|
||||
switch(SYMBOL_TYPE(np->nl.n_type)) {
|
||||
case N_ABS:
|
||||
return(ext? 'A' : 'a');
|
||||
case N_BSS:
|
||||
@ -802,39 +836,39 @@ typeletter(struct nlist *np)
|
||||
int
|
||||
fname(const void *a0, const void *b0)
|
||||
{
|
||||
struct nlist * const *a = a0, * const *b = b0;
|
||||
struct xnlist * const *a = a0, * const *b = b0;
|
||||
|
||||
return(strcmp((*a)->n_un.n_name, (*b)->n_un.n_name));
|
||||
return(strcmp((*a)->nl.n_un.n_name, (*b)->nl.n_un.n_name));
|
||||
}
|
||||
|
||||
int
|
||||
rname(const void *a0, const void *b0)
|
||||
{
|
||||
struct nlist * const *a = a0, * const *b = b0;
|
||||
struct xnlist * const *a = a0, * const *b = b0;
|
||||
|
||||
return(strcmp((*b)->n_un.n_name, (*a)->n_un.n_name));
|
||||
return(strcmp((*b)->nl.n_un.n_name, (*a)->nl.n_un.n_name));
|
||||
}
|
||||
|
||||
int
|
||||
value(const void *a0, const void *b0)
|
||||
{
|
||||
struct nlist * const *a = a0, * const *b = b0;
|
||||
struct xnlist * const *a = a0, * const *b = b0;
|
||||
|
||||
if (SYMBOL_TYPE((*a)->n_type) == N_UNDF)
|
||||
if (SYMBOL_TYPE((*b)->n_type) == N_UNDF)
|
||||
if (SYMBOL_TYPE((*a)->nl.n_type) == N_UNDF)
|
||||
if (SYMBOL_TYPE((*b)->nl.n_type) == N_UNDF)
|
||||
return(0);
|
||||
else
|
||||
return(-1);
|
||||
else if (SYMBOL_TYPE((*b)->n_type) == N_UNDF)
|
||||
else if (SYMBOL_TYPE((*b)->nl.n_type) == N_UNDF)
|
||||
return(1);
|
||||
if (rev) {
|
||||
if ((*a)->n_value == (*b)->n_value)
|
||||
if ((*a)->nl.n_value == (*b)->nl.n_value)
|
||||
return(rname(a0, b0));
|
||||
return((*b)->n_value > (*a)->n_value ? 1 : -1);
|
||||
return((*b)->nl.n_value > (*a)->nl.n_value ? 1 : -1);
|
||||
} else {
|
||||
if ((*a)->n_value == (*b)->n_value)
|
||||
if ((*a)->nl.n_value == (*b)->nl.n_value)
|
||||
return(fname(a0, b0));
|
||||
return((*a)->n_value > (*b)->n_value ? 1 : -1);
|
||||
return((*a)->nl.n_value > (*b)->nl.n_value ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -875,7 +909,7 @@ usage(void)
|
||||
if (issize)
|
||||
fprintf(stderr, "usage: %s [-tw] [file ...]\n", __progname);
|
||||
else
|
||||
fprintf(stderr, "usage: %s [-aCDegnoprsuw] [file ...]\n",
|
||||
fprintf(stderr, "usage: %s [-AaCDegnoPprsuw] [-t d|o|x] [file ...]\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: util.h,v 1.4 2015/06/23 15:16:34 semarie Exp $ */
|
||||
/* $OpenBSD: util.h,v 1.5 2015/08/13 19:13:28 miod Exp $ */
|
||||
|
||||
/*
|
||||
* Placed in the public domain by Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
@ -31,3 +31,8 @@
|
||||
|
||||
extern int usemmap;
|
||||
extern int dynamic_only;
|
||||
|
||||
struct xnlist {
|
||||
struct nlist nl;
|
||||
unsigned long n_size;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user