mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
recording file death
This commit is contained in:
@ -1,730 +0,0 @@
|
||||
\input texinfo
|
||||
@setfilename binutils.info
|
||||
@synindex ky cp
|
||||
@c
|
||||
@c This file documents the GNU binary utilities "ar", "ld", "objdump", "nm",
|
||||
@c "size", "strip", and "ranlib".
|
||||
@c
|
||||
@c Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
@c
|
||||
@c This text may be freely distributed under the terms of the GNU
|
||||
@c General Public License.
|
||||
@c
|
||||
@c $Id$
|
||||
@iftex
|
||||
@finalout
|
||||
@c @smallbook
|
||||
@end iftex
|
||||
@c @cropmarks
|
||||
@setchapternewpage odd
|
||||
@settitle GNU Binary Utilities
|
||||
@titlepage
|
||||
@title The GNU Binary Utilities
|
||||
@subtitle Version 1.90
|
||||
@sp 1
|
||||
@subtitle October 1991
|
||||
@author Roland H. Pesch
|
||||
@author Cygnus Support
|
||||
@page
|
||||
|
||||
@tex
|
||||
\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
|
||||
\xdef\manvers{\$Revision$} % For use in headers, footers too
|
||||
{\parskip=0pt \hfill Cygnus Support\par \hfill \manvers\par \hfill
|
||||
\TeX{}info \texinfoversion\par }
|
||||
@end tex
|
||||
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1991 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided also that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions.
|
||||
@end titlepage
|
||||
|
||||
@node Top, ar, (dir), (dir)
|
||||
@chapter Introduction
|
||||
|
||||
@cindex version
|
||||
This brief manual contains preliminary documentation for the GNU binary
|
||||
utilities (collectively version 1.90):
|
||||
@table @code
|
||||
@item ar
|
||||
Create, modify, and extract from archives
|
||||
|
||||
@item nm
|
||||
List symbols from object files
|
||||
|
||||
@item objdump
|
||||
Display information from object files
|
||||
|
||||
@item ranlib
|
||||
Generate index to archive contents
|
||||
|
||||
@item size
|
||||
List section sizes and total size
|
||||
|
||||
@item strip
|
||||
Discard symbols
|
||||
@end table
|
||||
|
||||
@ifinfo
|
||||
Copyright @copyright{} 1991 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries a copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
|
||||
@end ignore
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided also that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions.
|
||||
@end ifinfo
|
||||
|
||||
@menu
|
||||
* ar:: Create, modify, and extract from archives
|
||||
* ld:: See ld.info
|
||||
* nm:: List symbols from object files
|
||||
* objdump:: Display information from object files
|
||||
* ranlib:: Generate index to archive contents
|
||||
* size:: List section sizes and total size
|
||||
* strip:: Discard symbols
|
||||
* Index::
|
||||
@end menu
|
||||
|
||||
@node ar, ld, Top, Top
|
||||
@chapter ar
|
||||
|
||||
@kindex ar
|
||||
@cindex archives
|
||||
@cindex collections of files
|
||||
@smallexample
|
||||
ar [-]@var{p}@var{mod} [ @var{membername} ] @var{archive} @var{files}@dots{}
|
||||
@end smallexample
|
||||
|
||||
The GNU @code{ar} program creates, modifies, and extracts from
|
||||
archives. An @dfn{archive} is a single file holding a collection of
|
||||
other files in a structure that makes it possible to retrieve
|
||||
the original individual files (called @dfn{members} of the archive).
|
||||
|
||||
The original files' contents, mode (permissions), timestamp, owner, and
|
||||
group are preserved in the archive, and may be reconstituted on
|
||||
extraction.
|
||||
|
||||
@cindex name length
|
||||
GNU @code{ar} can maintain archives whose members have names of any
|
||||
length; however, depending on how @code{ar} is configured on your
|
||||
system, a limit on member-name length may be imposed (for compatibility
|
||||
with archive formats maintained with other tools). If it exists, the
|
||||
limit is often 15 characters (typical of formats related to a.out) or 16
|
||||
characters (typical of formats related to coff).
|
||||
|
||||
@cindex libraries
|
||||
@code{ar} is considered a binary utility because archives of this sort
|
||||
are most often used as @dfn{libraries} holding commonly needed
|
||||
subroutines.
|
||||
|
||||
@cindex symbol index
|
||||
@code{ar} will create an index to the symbols defined in relocatable
|
||||
object modules in the archive when you specify the modifier @samp{s}.
|
||||
Once created, this index is updated in the archive whenever @code{ar}
|
||||
makes a change to its contents (save for the @samp{q} update operation).
|
||||
An archive with such an index speeds up linking to the library, and
|
||||
allows routines in the library to call each other without regard to
|
||||
their placement in the archive.
|
||||
|
||||
You may use @samp{nm -s} or @samp{nm +print-armap} to list this index
|
||||
table. If an archive lacks the table, another form of @code{ar} called
|
||||
@code{ranlib} can be used to add just the table.
|
||||
|
||||
@code{ar} insists on at least two arguments to execute: one
|
||||
keyletter specifying the @emph{operation} (optionally accompanied by other
|
||||
keyletters specifying @emph{modifiers}), and the archive name to act on.
|
||||
|
||||
Most operations can also accept further @var{files} arguments,
|
||||
specifying particular files to operate on.
|
||||
|
||||
GNU @code{ar} allows you to mix the operation code @var{p} and modifier
|
||||
flags @var{mod} in any order, within the first command-line argument.
|
||||
|
||||
If you wish, you may begin the first command-line argument with a
|
||||
dash.
|
||||
|
||||
@cindex operations on archive
|
||||
The @var{p} keyletter specifies what operation to execute; it may be
|
||||
any of the following, but you must specify only one of them:
|
||||
|
||||
@table @code
|
||||
@item d
|
||||
@cindex deleting from archive
|
||||
@emph{Delete} modules from the archive. Specify the names of modules to
|
||||
be deleted as @var{files}; the archive is untouched if you
|
||||
specify no files to delete.
|
||||
|
||||
If you specify the @samp{v} modifier, @code{ar} will list each module
|
||||
as it is deleted.
|
||||
|
||||
@item m
|
||||
@cindex moving in archive
|
||||
Use this operation to @emph{move} members in an archive.
|
||||
|
||||
The ordering of members in an archive can make a difference in how
|
||||
programs are linked using the library, if a symbol is defined in more
|
||||
than one member.
|
||||
|
||||
If no modifiers are used with @code{m}, any members you name in the
|
||||
@var{files} arguments are moved to the @emph{end} of the archive;
|
||||
you can use the @samp{a}, @samp{b}, or @samp{i} modifiers to move them to a
|
||||
specified place instead.
|
||||
|
||||
@item p
|
||||
@cindex printing from archive
|
||||
@emph{Print} the specified members of the archive, to the standard
|
||||
output file. If the @samp{v} modifier is specified, show the member
|
||||
name before copying its contents to standard output.
|
||||
|
||||
If you specify no @var{files}, all the files in the archive are printed.
|
||||
|
||||
@item q
|
||||
@cindex quick append to archive
|
||||
@emph{Quick append}; add @var{files} to the end of @var{archive},
|
||||
without checking for replacement.
|
||||
|
||||
The modifiers @samp{a}, @samp{b}, and @samp{i} do @emph{not} affect this
|
||||
operation; new members are always placed at the end of the archive.
|
||||
|
||||
The modifier @samp{v} makes @code{ar} list each file as it is appended.
|
||||
|
||||
Since the point of this operation is speed, the archive's symbol table
|
||||
index is not updated, even if it already existed; you can use @samp{ar s} or
|
||||
@code{ranlib} explicitly to update the symbol table index.
|
||||
|
||||
@item r
|
||||
@cindex replacement in archive
|
||||
Insert @var{files} into @var{archive} (with @emph{replacement}). This
|
||||
operation differs from @samp{q} in that any previously existing members
|
||||
are deleted if their names match those being added.
|
||||
|
||||
If one of the files named in @var{files} doesn't exist, @code{ar}
|
||||
displays an error message, and leaves undisturbed any existing members
|
||||
of the archive matching that name.
|
||||
|
||||
By default, new members are added at the end of the file; but you may
|
||||
use one of the modifiers @samp{a}, @samp{b}, or @samp{i} to request
|
||||
placement relative to some existing member.
|
||||
|
||||
The modifier @samp{v} used with this operation elicits a line of
|
||||
output for each file inserted, along with one of the letters @samp{a} or
|
||||
@samp{r} to indicate whether the file was appended (no old member
|
||||
deleted) or replaced.
|
||||
|
||||
@item t
|
||||
@cindex contents of archive
|
||||
Display a @emph{table} listing the contents of @var{archive}, or those
|
||||
of the files listed in @var{files} that are present in the
|
||||
archive. Normally only the member name is shown; if you also want to
|
||||
see the modes (permissions), timestamp, owner, group, and size, you can
|
||||
request that by also specifying the @samp{v} modifier.
|
||||
|
||||
If you do not specify any @var{files}, all files in the archive
|
||||
are listed.
|
||||
|
||||
@cindex repeated names in archive
|
||||
@cindex name duplication in archive
|
||||
If there is more than one file with the same name (say, @samp{fie}) in
|
||||
an archive (say @samp{b.a}), @samp{ar t b.a fie} will list only the
|
||||
first instance; to see them all, you must ask for a complete
|
||||
listing---in our example, @samp{ar t b.a}.
|
||||
@c WRS only; per Gumby, this is implementation-dependent, and in a more
|
||||
@c recent case in fact works the other way.
|
||||
|
||||
@item x
|
||||
@cindex extract from archive
|
||||
@emph{Extract} members (named @var{files}) from the archive. You can
|
||||
use the @samp{v} modifier with this operation, to request that
|
||||
@code{ar} list each name as it extracts it.
|
||||
|
||||
If you do not specify any @var{files}, all files in the archive
|
||||
are extracted.
|
||||
|
||||
@end table
|
||||
|
||||
A number of modifiers (@var{mod}) may immediately follow the @var{p}
|
||||
keyletter, to specify variations on an operation's behavior:
|
||||
|
||||
@table @code
|
||||
@item a
|
||||
@cindex relative placement in archive
|
||||
Add new files @emph{after} an existing member of the
|
||||
archive. If you use the modifier @code{a}, the name of an existing archive
|
||||
member must be present as the @var{membername} argument, before the
|
||||
@var{archive} specification.
|
||||
|
||||
@item b
|
||||
Add new files @emph{before} an existing member of the
|
||||
archive. If you use the modifier @code{b}, the name of an existing archive
|
||||
member must be present as the @var{membername} argument, before the
|
||||
@var{archive} specification. (same as @samp{i}).
|
||||
|
||||
@item c
|
||||
@cindex creating archives
|
||||
@emph{Create} the archive. The specified @var{archive} is always
|
||||
created if it didn't exist, when you request an update. But a warning is
|
||||
issued unless you specify in advance that you expect to create it, by
|
||||
using this modifier.
|
||||
|
||||
@item i
|
||||
Insert new files @emph{before} an existing member of the
|
||||
archive. If you use the modifier @code{i}, the name of an existing archive
|
||||
member must be present as the @var{membername} argument, before the
|
||||
@var{archive} specification. (same as @samp{b}).
|
||||
|
||||
@item l
|
||||
This modifier is accepted but not used.
|
||||
@c whaffor ar l modifier??? presumably compat; with
|
||||
@c what???---pesch@@cygnus.com, 25jan91
|
||||
|
||||
@item o
|
||||
@cindex dates in archive
|
||||
Preserve the @emph{original} dates of members when extracting them. If
|
||||
you do not specify this modifier, files extracted from the archive
|
||||
will be stamped with the time of extraction.
|
||||
|
||||
@item s
|
||||
@cindex writing archive index
|
||||
Write an object-file index into the archive, or update an existing one,
|
||||
even if no other change is made to the archive. You may use this modifier
|
||||
flag either with any operation, or alone. Running @samp{ar s} on an
|
||||
archive is equivalent to running @samp{ranlib} on it.
|
||||
|
||||
@item u
|
||||
@cindex updating an archive
|
||||
Normally, @code{ar r}@dots{} inserts all files
|
||||
listed into the archive. If you would like to insert @emph{only} those
|
||||
of the files you list that are newer than existing members of the same
|
||||
names, use this modifier. The @samp{u} modifier is allowed only for the
|
||||
operation @samp{r} (replace). In particular, the combination @samp{qu} is
|
||||
not allowed, since checking the timestamps would lose any speed
|
||||
advantage from the operation @samp{q}.
|
||||
|
||||
@item v
|
||||
This modifier requests the @emph{verbose} version of an operation. Many
|
||||
operations display additional information, such as filenames processed,
|
||||
when the modifier @samp{v} is appended.
|
||||
|
||||
@end table
|
||||
|
||||
@node ld, nm, ar, Top
|
||||
@chapter ld
|
||||
@cindex linker
|
||||
@kindex ld
|
||||
The GNU linker @code{ld} is now described in a separate manual.
|
||||
@xref{Top,, Overview,, GLD: the GNU linker}.
|
||||
|
||||
@node nm, objdump, ld, Top
|
||||
@chapter nm
|
||||
@cindex symbols
|
||||
@kindex nm
|
||||
|
||||
@smallexample
|
||||
nm [ -a | +debug-syms ] [ -g | +extern-only ]
|
||||
[ -s | +print-armap ] [ -o | +print-file-name ]
|
||||
[ -n | +numeric-sort ] [ -p | +no-sort ]
|
||||
[ -r | +reverse-sort ] [ -u | +undefined-only ]
|
||||
[ +target @var{bfdname} ]
|
||||
[ @var{objfiles}@dots{} ]
|
||||
@end smallexample
|
||||
|
||||
GNU @code{nm} will list the symbols from object files @var{objfiles}.
|
||||
|
||||
The long and short forms of options, shown here as alternatives, are
|
||||
equivalent.
|
||||
|
||||
@table @code
|
||||
@item @var{objfiles}@dots{}
|
||||
@kindex a.out
|
||||
Object files whose symbols are to be listed. If no object files are
|
||||
listed as arguments, @code{nm} assumes @samp{a.out}.
|
||||
|
||||
@item -a
|
||||
@itemx +debug-syms
|
||||
@cindex debugging symbols
|
||||
Display debugger-only symbols; normally these are not listed.
|
||||
|
||||
@item -g
|
||||
@itemx +extern-only
|
||||
@cindex external symbols
|
||||
Display only external symbols.
|
||||
|
||||
@item -p
|
||||
@itemx +no-sort
|
||||
@cindex sorting symbols
|
||||
Don't bother to sort the symbols in any order; just print them in the
|
||||
order encountered.
|
||||
|
||||
@item -n
|
||||
@itemx +numeric-sort
|
||||
Sort symbols numerically by their addresses, not alphabetically by their
|
||||
names.
|
||||
|
||||
@item -s
|
||||
@itemx +print-armap
|
||||
@cindex symbol index, listing
|
||||
When listing symbols from archive members, include the index: a mapping
|
||||
(stored in the archive by @code{ar} or @code{ranlib}) of what modules
|
||||
contain definitions for what names.
|
||||
|
||||
@item -o
|
||||
@itemx +print-file-name
|
||||
@cindex input file name
|
||||
@cindex file name
|
||||
@cindex source file name
|
||||
Precede each symbol by the name of the input file where it was found,
|
||||
rather than identifying the input file once only before all of its
|
||||
symbols.
|
||||
|
||||
@item -r
|
||||
@itemx +reverse-sort
|
||||
Reverse the sense of the sort (whether numeric or alphabetic); let the
|
||||
last come first.
|
||||
|
||||
@item +target @var{bfdname}
|
||||
@c @item +target
|
||||
@cindex object code format
|
||||
Specify an object code format other than your system's default format.
|
||||
@xref{objdump}, for information on listing available formats.
|
||||
@c FIXME what *does* +target/no arg do?
|
||||
|
||||
@item -u
|
||||
@itemx +undefined-only
|
||||
@cindex external symbols
|
||||
@cindex undefined symbols
|
||||
Display only undefined symbols (those external to each object file).
|
||||
|
||||
@end table
|
||||
|
||||
@node objdump, ranlib, nm, Top
|
||||
@chapter objdump
|
||||
|
||||
@cindex object file information
|
||||
@kindex objdump
|
||||
|
||||
@smallexample
|
||||
objdump [ -a ] [ -b @var{bfdname} ] [ -d ] [ -f ]
|
||||
[ -h | +header ] [ -i ] [ -j @var{section} ] [ -l ]
|
||||
[ -m @var{machine} ] [ -r | +reloc ] [ -s ]
|
||||
[ -t | +syms ] [ -x ]
|
||||
@var{objfiles}@dots{}
|
||||
@end smallexample
|
||||
|
||||
@code{objdump} displays information about one or more object files.
|
||||
The options control what particular information to display. This
|
||||
information is mostly useful to programmers who are working on the
|
||||
compilation tools, as opposed to programmers who just want their
|
||||
program to compile and work.
|
||||
|
||||
The long and short forms of options, shown here as alternatives, are
|
||||
equivalent.
|
||||
|
||||
@table @code
|
||||
@item @var{objfiles}@dots{}
|
||||
The object files to be examined. When you specify archives,
|
||||
@code{objdump} shows information on each of the member object files.
|
||||
|
||||
@item -a
|
||||
@c print_arelt_descr
|
||||
@cindex archive headers
|
||||
If any files from @var{objfiles} are archives, display the archive
|
||||
header information (in a format similar to @samp{ls -l}). Besides the
|
||||
information you could list with @samp{ar tv}, @samp{objdump -a} shows
|
||||
the object file format of each archive member.
|
||||
|
||||
@c suggest longname +target or +format or +bfd
|
||||
@item -b @var{bfdname}
|
||||
@cindex object code format
|
||||
You can specify a particular object-code format for your object files as
|
||||
@var{bfdname}. This may not be necessary; @var{objdump} can
|
||||
automatically recognize many formats. For example,
|
||||
@example
|
||||
objdump -b oasys -m vax -h fu.o
|
||||
@end example
|
||||
@noindent
|
||||
Displays summary information from the section headers (@samp{-h}) of
|
||||
@file{fu.o}, which is explicitly identified (@samp{-m}) as a Vax object
|
||||
file in the format produced by Oasys compilers. You can list the
|
||||
formats available with the @samp{-i} option.
|
||||
|
||||
@item -d
|
||||
@cindex disassembling object code
|
||||
@cindex machine instructions
|
||||
Disassemble. Display the assembler mnemonics for the machine
|
||||
instructions from @var{objfiles}.
|
||||
|
||||
@item -f
|
||||
@cindex object file header
|
||||
File header. Display summary information from the overall header of
|
||||
each file in @var{objfiles}.
|
||||
|
||||
@item -h
|
||||
@itemx +header
|
||||
@cindex section headers
|
||||
Header. Display summary information from the section headers of the
|
||||
object file.
|
||||
|
||||
@item -i
|
||||
@cindex architectures available
|
||||
@cindex object formats available
|
||||
Display a list showing all architectures and object formats available
|
||||
for specification with @code{-b} or @code{-m}.
|
||||
|
||||
@c suggest longname +section
|
||||
@item -j @var{name}
|
||||
@cindex section information
|
||||
Display information only for section @var{name}
|
||||
|
||||
@c suggest longname +label or +linespec
|
||||
@item -l
|
||||
@cindex source filenames for object files
|
||||
Label the display (using debugging information) with the source filename
|
||||
and line numbers corresponding to the object code shown.
|
||||
|
||||
@c suggest longname +architecture
|
||||
@item -m @var{machine}
|
||||
@cindex architecture
|
||||
Specify the object files @var{objfiles} are for architecture
|
||||
@var{machine}. You can list available architectures using the @samp{-i}
|
||||
option.
|
||||
|
||||
@item -r
|
||||
@itemx +reloc
|
||||
@cindex relocation entries, in object file
|
||||
Relocation. Print the relocation entries of the file.
|
||||
|
||||
@item -s
|
||||
@cindex sections, full contents
|
||||
@cindex object file sections
|
||||
Display the full contents of any sections requested.
|
||||
|
||||
@item -t
|
||||
@itemx +syms
|
||||
@cindex symbol table entries, printing
|
||||
Symbol Table. Print the symbol table entries of the file.
|
||||
This is similar to the information provided by the @samp{nm} program.
|
||||
|
||||
@item -x
|
||||
@cindex all header information, object file
|
||||
@cindex header information, all
|
||||
Display all available header information, including the symbol table and
|
||||
relocation entries. Using @samp{-x} is equivalent to specifying all of
|
||||
@samp{-a -f -h -r -t}.
|
||||
|
||||
@end table
|
||||
|
||||
@node ranlib, size, objdump, Top
|
||||
@chapter ranlib
|
||||
|
||||
@kindex ranlib
|
||||
@cindex archive contents
|
||||
@cindex symbol index
|
||||
|
||||
@smallexample
|
||||
ranlib @var{archive}
|
||||
@end smallexample
|
||||
|
||||
@code{ranlib} generates an index to the contents of an archive, and
|
||||
stores it in the archive. The index lists each symbol defined by a
|
||||
member of an archive that is a relocatable object file.
|
||||
|
||||
You may use @samp{nm -s} or @samp{nm +print-armap} to list this index.
|
||||
|
||||
An archive with such an index speeds up linking to the library, and
|
||||
allows routines in the library to call each other without regard to
|
||||
their placement in the archive.
|
||||
|
||||
The GNU @code{ranlib} program is another form of GNU @code{ar}; running
|
||||
@code{ranlib} is completely equivalent to executing @samp{ar -s}.
|
||||
@xref{ar}.
|
||||
|
||||
@node size, strip, ranlib, Top
|
||||
@chapter size
|
||||
|
||||
@kindex size
|
||||
@cindex section sizes
|
||||
|
||||
@smallexample
|
||||
size [ -A | -B | +format @var{compatibility} ]
|
||||
[ +help ] [ -d | -o | -x | +radix @var{number} ]
|
||||
[ +target @var{bfdname} ] [ -V | +version ]
|
||||
@var{objfiles}@dots{}
|
||||
@end smallexample
|
||||
|
||||
The GNU @code{size} utility lists the section sizes---and the total
|
||||
size---for each of the object files @var{objfiles} in its argument list.
|
||||
By default, one line of output is generated for each object file or each
|
||||
module in an archive.
|
||||
|
||||
The command line options have the following meanings:
|
||||
@table @code
|
||||
@item @var{objfiles}@dots{}
|
||||
The object files to be examined.
|
||||
|
||||
@item -A
|
||||
@itemx -B
|
||||
@itemx +format @var{compatibility}
|
||||
@cindex size display format
|
||||
Using one of these options, you can choose whether the output from GNU
|
||||
@code{size} resembles output from System V @code{size} (using @samp{-A},
|
||||
or @samp{+format sysv}), or Berkeley @code{size} (using @samp{-B}, or
|
||||
@samp{+format berkeley}). The default is the one-line format similar to
|
||||
Berkeley's.
|
||||
@c Bonus for doc-source readers: you can also say +format=strange (or
|
||||
@c anything else that starts with 's') for sysv, and +format=boring (or
|
||||
@c anything else that starts with 'b') for Berkeley.
|
||||
|
||||
Here is an example of the Berkeley (default) format of output from
|
||||
@code{size}:
|
||||
@smallexample
|
||||
eg$ size +format Berkeley ranlib size
|
||||
text data bss dec hex filename
|
||||
294880 81920 11592 388392 5ed28 ranlib
|
||||
294880 81920 11888 388688 5ee50 size
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
This is the same data, but displayed closer to System V conventions:
|
||||
|
||||
@smallexample
|
||||
eg$ size +format SysV ranlib size
|
||||
ranlib :
|
||||
section size addr
|
||||
.text 294880 8192
|
||||
.data 81920 303104
|
||||
.bss 11592 385024
|
||||
Total 388392
|
||||
|
||||
|
||||
size :
|
||||
section size addr
|
||||
.text 294880 8192
|
||||
.data 81920 303104
|
||||
.bss 11888 385024
|
||||
Total 388688
|
||||
@end smallexample
|
||||
|
||||
@item +help
|
||||
Show a summary of acceptable arguments and options.
|
||||
|
||||
@item -d
|
||||
@itemx -o
|
||||
@itemx -x
|
||||
@itemx +radix @var{number}
|
||||
@cindex size number format
|
||||
@cindex radix for section sizes
|
||||
Using one of these options, you can control whether the size of each
|
||||
section is given in decimal (@samp{-d}, or @samp{+radix 10}); octal
|
||||
(@samp{-o}, or @samp{+radix 8}); or hexadecimal (@samp{-x}, or
|
||||
@samp{+radix 16}). In @samp{+radix @var{number}}, only the three
|
||||
values (8, 10, 16) are supported. The total size is always given in two
|
||||
radices; decimal and hexadecimal for @samp{-d} or @samp{-x} output, or
|
||||
octal and hexadecimal if you're using @samp{-o}.
|
||||
|
||||
@item +target @var{bfdname}
|
||||
@cindex object code format
|
||||
You can specify a particular object-code format for @var{objfiles} as
|
||||
@var{bfdname}. This may not be necessary; @var{size} can
|
||||
automatically recognize many formats. @xref{objdump}, for information
|
||||
on listing available formats.
|
||||
|
||||
@item -V
|
||||
@itemx +version
|
||||
Display version number information on @code{size} itself.
|
||||
|
||||
@end table
|
||||
|
||||
@node strip, Index, size, Top
|
||||
@chapter strip
|
||||
|
||||
@kindex strip
|
||||
@cindex removing symbols
|
||||
@cindex discarding symbols
|
||||
|
||||
@smallexample
|
||||
strip [ -s | +strip-all ] [ -g | -S | +strip-debug ]
|
||||
[ -x | +discard-all ] [ -X | +discard-locals ]
|
||||
[ -T @var{bfdname} ]
|
||||
@var{objfiles}@dots{}
|
||||
@end smallexample
|
||||
|
||||
GNU @code{strip} will discard all symbols from object files
|
||||
@var{objfiles}, if no options are specified; or only certain symbols,
|
||||
depending on its command-line options.
|
||||
|
||||
@code{strip} will not execute unless at least one object file is listed.
|
||||
|
||||
@quotation
|
||||
@emph{WARNING:} @code{strip} modifies the files named in its argument,
|
||||
rather than writing modified copies under different names.
|
||||
@end quotation
|
||||
|
||||
The long and short forms of options, shown here as alternatives, are
|
||||
equivalent.
|
||||
|
||||
@table @code
|
||||
@item -s
|
||||
@itemx +strip-all
|
||||
@cindex all symbols, discarding
|
||||
This is the default case: strip all symbol entries from @var{objfiles}.
|
||||
|
||||
@item -g
|
||||
@itemx -S
|
||||
@itemx +strip-debug
|
||||
@cindex debugging symbols, discarding
|
||||
Discard only debugging symbol information from @var{objfiles}.
|
||||
|
||||
@item -x
|
||||
@itemx +discard-all
|
||||
@cindex local symbols, discarding
|
||||
Discard all symbols local to each file in @var{objfiles}.
|
||||
@emph{WARNING:} Note that @code{+discard-all} discards only @emph{local}
|
||||
symbols, in spite of its name.
|
||||
|
||||
@item -X
|
||||
@itemx +discard-locals
|
||||
Discard local symbols starting with @samp{L} from each file in
|
||||
@var{objfiles}. (Some compilers produce internally-used symbols that
|
||||
begin with @samp{L}.)
|
||||
|
||||
@item -T @var{bfdname}
|
||||
@cindex object code format
|
||||
You can specify a particular object-code format @var{bfdname} for
|
||||
@var{objfiles}. This may not be necessary; @var{strip} can automatically
|
||||
recognize many formats. @xref{objdump}, for information on listing
|
||||
available formats.
|
||||
@end table
|
||||
|
||||
@node Index, , strip, Top
|
||||
@unnumbered Index
|
||||
|
||||
@printindex cp
|
||||
|
||||
@contents
|
||||
@bye
|
446
binutils/config.sub
vendored
446
binutils/config.sub
vendored
@ -1,446 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
# Each package is responsible for reporting which valid configurations
|
||||
# it does not support. The user should be able to distinguish
|
||||
# a failure to support a valid configuration from a meaningless
|
||||
# configuration (e.g. a typo).
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# configure@cygnus.com
|
||||
|
||||
# decode aliases into canonical names
|
||||
|
||||
case "$1" in
|
||||
# cpu alone is a valid alias for cpu-none-none.
|
||||
vax | tahoe | i386 | i860 | m68k | m68000 | m88k | sparc | ns32k \
|
||||
| alliant | arm | c1 | c2 | mips | pyramid | tron | a29k \
|
||||
| romp | rs6000 | i960 | h8300)
|
||||
cpu=$1
|
||||
vendor=none
|
||||
os=none
|
||||
;;
|
||||
altos | altos3068)
|
||||
cpu=m68k
|
||||
vendor=altos
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
altosgas)
|
||||
cpu=m68k
|
||||
vendor=altos
|
||||
os=gas
|
||||
;;
|
||||
am29k)
|
||||
cpu=a29k
|
||||
vendor=none
|
||||
os=bsd
|
||||
;;
|
||||
amdahl)
|
||||
cpu=580
|
||||
vendor=amdahl
|
||||
os=uts
|
||||
;;
|
||||
amigados)
|
||||
cpu=m68k
|
||||
vendor=cbm
|
||||
os=amigados # Native AmigaDOS
|
||||
;;
|
||||
amigaunix | amix)
|
||||
cpu=m68k
|
||||
vendor=cbm
|
||||
os=svr4 # System V Release 4 (svr4 is an industry recognized acronym)
|
||||
;;
|
||||
apollo68)
|
||||
cpu=m68k
|
||||
vendor=apollo
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
balance)
|
||||
cpu=ns32k
|
||||
vendor=sequent
|
||||
os=dynix
|
||||
;;
|
||||
convex-c1)
|
||||
cpu=c1
|
||||
vendor=convex
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
convex-c2)
|
||||
cpu=c2
|
||||
vendor=convex
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
cray | ymp)
|
||||
cpu=ymp
|
||||
vendor=cray
|
||||
os=unicos
|
||||
;;
|
||||
cray2)
|
||||
cpu=cray2
|
||||
vendor=cray
|
||||
os=unicos
|
||||
;;
|
||||
dec3100 | decstatn | decstation | decstation-3100 | pmax | pmin)
|
||||
cpu=mips
|
||||
vendor=dec
|
||||
os=ultrix
|
||||
;;
|
||||
delta | 3300 | motorola-3300 | motorola-delta \
|
||||
| 3300-motorola | delta-motorola)
|
||||
cpu=m68k
|
||||
vendor=motorola
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
|
||||
delta88)
|
||||
cpu=m88k
|
||||
vendor=motorola
|
||||
os=m88kbcs
|
||||
;;
|
||||
|
||||
gmicro)
|
||||
cpu=tron
|
||||
vendor=gmicro
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
|
||||
h8300hds)
|
||||
cpu=h8300
|
||||
vendor=hitachi
|
||||
os=hds
|
||||
;;
|
||||
|
||||
# start-sanitize-v9
|
||||
hal-32 | hal32)
|
||||
cpu=sparc64
|
||||
vendor=hal
|
||||
os=hal32
|
||||
;;
|
||||
hal-64 | hal64)
|
||||
cpu=sparc64
|
||||
vendor=hal
|
||||
os=hal64
|
||||
;;
|
||||
sparc64)
|
||||
cpu=sparc64
|
||||
vendor=sun
|
||||
os=v9
|
||||
;;
|
||||
sparc64-v7 | sparc64v7)
|
||||
cpu=sparc64
|
||||
vendor=sun
|
||||
os=v7
|
||||
;;
|
||||
# end-sanitize-v9
|
||||
hp300bsd)
|
||||
cpu=m68k
|
||||
vendor=hp
|
||||
os=bsd
|
||||
;;
|
||||
hp300hpux | hpux | hp9k3[2-9][0-9])
|
||||
cpu=m68k
|
||||
vendor=hp
|
||||
os=hpux
|
||||
;;
|
||||
hp9k31[0-9] | hp9k2[0-9][0-9])
|
||||
cpu=m68000
|
||||
vendor=hp
|
||||
os=hpux
|
||||
;;
|
||||
i386sco)
|
||||
cpu=i386
|
||||
vendor=sco
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
i386v)
|
||||
cpu=i386
|
||||
vendor=none
|
||||
os=sysv
|
||||
;;
|
||||
i386v32)
|
||||
cpu=i386
|
||||
vendor=none
|
||||
os=sysv32
|
||||
;;
|
||||
iris | iris4d)
|
||||
cpu=mips
|
||||
vendor=sgi
|
||||
os=irix # maybe?
|
||||
;;
|
||||
|
||||
dpx2)
|
||||
vendor=bull
|
||||
cpu=m68k
|
||||
os=sysv
|
||||
;;
|
||||
isi | isi68)
|
||||
cpu=m68k
|
||||
vendor=isi
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
littlemips)
|
||||
cpu=mips
|
||||
vendor=little
|
||||
os=bsd
|
||||
;;
|
||||
magnum | m3230)
|
||||
cpu=mips
|
||||
vendor=mips
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
merlin)
|
||||
cpu=ns32k
|
||||
vendor=utek
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
miniframe)
|
||||
cpu=m68000
|
||||
vendor=convergent
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
mmax)
|
||||
cpu=ns32k
|
||||
vendor=encore
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
news | news700 | news800 | news900)
|
||||
cpu=m68k
|
||||
vendor=sony
|
||||
os=newsos3 # Based on bsd-4.3
|
||||
;;
|
||||
news1000)
|
||||
cpu=m68030
|
||||
vendor=sony
|
||||
os=newsos3 # ?
|
||||
;;
|
||||
news-3600 | bigmips | risc-news)
|
||||
cpu=mips
|
||||
vendor=sony
|
||||
os=newsos4 # Presumably?
|
||||
;;
|
||||
next)
|
||||
cpu=m68k
|
||||
vendor=next
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
nindy960)
|
||||
cpu=i960
|
||||
vendor=intel
|
||||
os=nindy
|
||||
;;
|
||||
none)
|
||||
cpu=none
|
||||
vendor=none
|
||||
os=none
|
||||
;;
|
||||
np1)
|
||||
cpu=np1
|
||||
vendor=gould
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
rtpc)
|
||||
cpu=romp
|
||||
vendor=ibm
|
||||
os=aix # maybe?
|
||||
;;
|
||||
pbd)
|
||||
cpu=sparc
|
||||
vendor=unicom
|
||||
os=sysv
|
||||
;;
|
||||
pn)
|
||||
cpu=pn
|
||||
vendor=gould
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
ps2)
|
||||
cpu=i386
|
||||
vendor=ibm
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
sun2)
|
||||
cpu=m68000
|
||||
vendor=sun
|
||||
os=sunos4
|
||||
;;
|
||||
sun2os3)
|
||||
cpu=m68000
|
||||
vendor=sun
|
||||
os=sunos3
|
||||
;;
|
||||
sun2os4)
|
||||
cpu=m68000
|
||||
vendor=sun
|
||||
os=sunos4
|
||||
;;
|
||||
sun3)
|
||||
cpu=m68k
|
||||
vendor=sun
|
||||
os=sunos4
|
||||
;;
|
||||
sun3os3)
|
||||
cpu=m68k
|
||||
vendor=sun
|
||||
os=sunos3
|
||||
;;
|
||||
sun3os4)
|
||||
cpu=m68k
|
||||
vendor=sun
|
||||
os=sunos4
|
||||
;;
|
||||
sun386 | roadrunner | sun386i)
|
||||
cpu=i386
|
||||
vendor=sun
|
||||
os=sunos
|
||||
;;
|
||||
sun4)
|
||||
cpu=sparc
|
||||
vendor=sun
|
||||
os=sunos4
|
||||
;;
|
||||
sun4os3)
|
||||
cpu=sparc
|
||||
vendor=sun
|
||||
os=sunos3
|
||||
;;
|
||||
sun4os4)
|
||||
cpu=sparc
|
||||
vendor=sun
|
||||
os=sunos4
|
||||
;;
|
||||
symmetry)
|
||||
cpu=i386
|
||||
vendor=sequent
|
||||
os=dynix
|
||||
;;
|
||||
tower | tower-32)
|
||||
cpu=m68k
|
||||
vendor=ncr
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
ultra3)
|
||||
cpu=a29k
|
||||
vendor=nyu
|
||||
os=sym1
|
||||
;;
|
||||
umax)
|
||||
cpu=ns32k
|
||||
vendor=encore
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
unixpc | safari | pc7300 | 3b1 | 7300 | 7300-att | att-7300)
|
||||
cpu=m68k
|
||||
vendor=att
|
||||
os=sysv # maybe?
|
||||
;;
|
||||
vax-dec)
|
||||
cpu=vax
|
||||
vendor=dec
|
||||
os=ultrix # maybe?
|
||||
;;
|
||||
vxworks68)
|
||||
cpu=m68k
|
||||
vendor=wrs
|
||||
os=vxworks
|
||||
;;
|
||||
vxworks960)
|
||||
cpu=i960
|
||||
vendor=wrs
|
||||
os=vxworks
|
||||
;;
|
||||
xmp)
|
||||
cpu=xmp
|
||||
vendor=cray
|
||||
os=unicos
|
||||
;;
|
||||
# not an alias. parse what we expect to be a canonical name.
|
||||
*)
|
||||
cpu=`echo $1 | sed 's/-.*$//'`
|
||||
|
||||
if [ "${cpu}" = "$1" ] ; then
|
||||
# no vendor so this is an invalid name.
|
||||
echo '***' No vendor: configuration \`$1\' not recognized 1>&2
|
||||
exit 1
|
||||
else
|
||||
# parse out vendor
|
||||
rest=`echo $1 | sed "s/${cpu}-//"`
|
||||
vendor=`echo ${rest} | sed 's/-.*$//'`
|
||||
|
||||
if [ "${vendor}" = "${rest}" ] ; then
|
||||
# a missing os is acceptable
|
||||
os=none
|
||||
else
|
||||
os=`echo ${rest} | sed "s/${vendor}-//"`
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# At this point we should have three parts of a canonical name in cpu,
|
||||
# vendor, and os.
|
||||
|
||||
# verify that the cpu is known.
|
||||
|
||||
case "${cpu}" in
|
||||
none | vax | tahoe | i386 | i860 | m68k | m68000 | m88k | sparc \
|
||||
| ns32k | alliant | arm | c1 | c2 | mips | pyramid | tron \
|
||||
| a29k | romp | rs6000 | i960 | xmp | ymp | cray2 | 580 | h8300)
|
||||
;;
|
||||
|
||||
# start-sanitize-v9
|
||||
sparc64) ;;
|
||||
# end-sanitize-v9
|
||||
|
||||
*)
|
||||
echo '***' Invalid cpu \`${cpu}\': configuration \`$1\' not recognized 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# verify that the vendor is known.
|
||||
|
||||
case "${vendor}" in
|
||||
altos | amdahl | aout | apollo | att | bcs | bout |\
|
||||
cbm | convergent | convex | coff | cray | dec | encore |\
|
||||
gould | hitachi | intel | isi | hp | ibm | little | mips | motorola |\
|
||||
ncr | next | none | nyu | sco | sequent | sgi | sony | sun |\
|
||||
unicom | utek | wrs | bull ) ;;
|
||||
|
||||
# start-sanitize-v9
|
||||
hal) ;;
|
||||
# end-sanitize-v9
|
||||
|
||||
*)
|
||||
echo '***' Invalid vendor \`${vendor}\': configuration \`$1\' not recognized 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# verify that the os is known, if it exists.
|
||||
|
||||
case "${os}" in
|
||||
aix* | aout | bout | bsd* | coff | ctix* | dynix* | esix* | hpux* \
|
||||
| hds | irix* | isc* | kern | mach* | newsos* | nindy* | none \
|
||||
| osf* | sco* | sunos* | sysv* | ultrix* | unos* | v88r* \
|
||||
| vms* | vxworks* | sym[1-9]* | unicos* | uts | svr4 \
|
||||
| amigados)
|
||||
;;
|
||||
|
||||
# start-sanitize-v9
|
||||
hal32 | hal64 | v7 | v9) ;;
|
||||
# end-sanitize-v9
|
||||
|
||||
*)
|
||||
echo '***' Invalid os \`${os}\': configuration \`$1\' not recognized 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ${cpu}-${vendor}-${os}
|
@ -1,6 +0,0 @@
|
||||
@echo off
|
||||
@echo Configuring binutils for H8/300, hosted on MS-DOS
|
||||
|
||||
copy ..\bfd\hosts\h-go32.h sysdep.h
|
||||
|
||||
copy makefile.dos makefile
|
@ -1,934 +0,0 @@
|
||||
/* Demangler for GNU C++
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
written by James Clark (jjc@jclark.uucp)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This is for g++ 1.36.1 (November 6 version). It will probably
|
||||
require changes for any other version.
|
||||
|
||||
Modified for g++ 1.36.2 (November 18 version). */
|
||||
|
||||
/* This file exports one function
|
||||
|
||||
char *cplus_demangle (const char *name)
|
||||
|
||||
If `name' is a mangled function name produced by g++, then
|
||||
a pointer to a malloced string giving a C++ representation
|
||||
of the name will be returned; otherwise NULL will be returned.
|
||||
It is the caller's responsibility to free the string which
|
||||
is returned.
|
||||
|
||||
For example,
|
||||
|
||||
cplus_demangle ("_foo__1Ai")
|
||||
|
||||
returns
|
||||
|
||||
"A::foo(int)"
|
||||
|
||||
This file imports xmalloc and xrealloc, which are like malloc and
|
||||
realloc except that they generate a fatal error if there is no
|
||||
available memory. */
|
||||
|
||||
#if 0 /* Should really be part of BFD */
|
||||
#define nounderscore 1 /* define this is names don't start with _ */
|
||||
#endif
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef __STDC__
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
extern char *cplus_demangle (const char *type);
|
||||
#else
|
||||
extern char *cplus_demangle ();
|
||||
#endif
|
||||
|
||||
static char **typevec = 0;
|
||||
static int ntypes = 0;
|
||||
static int typevec_size = 0;
|
||||
|
||||
static struct {
|
||||
const char *in;
|
||||
const char *out;
|
||||
} optable[] = {
|
||||
"new", " new",
|
||||
"delete", " delete",
|
||||
"ne", "!=",
|
||||
"eq", "==",
|
||||
"ge", ">=",
|
||||
"gt", ">",
|
||||
"le", "<=",
|
||||
"lt", "<",
|
||||
"plus", "+",
|
||||
"minus", "-",
|
||||
"mult", "*",
|
||||
"convert", "+", /* unary + */
|
||||
"negate", "-", /* unary - */
|
||||
"trunc_mod", "%",
|
||||
"trunc_div", "/",
|
||||
"truth_andif", "&&",
|
||||
"truth_orif", "||",
|
||||
"truth_not", "!",
|
||||
"postincrement", "++",
|
||||
"postdecrement", "--",
|
||||
"bit_ior", "|",
|
||||
"bit_xor", "^",
|
||||
"bit_and", "&",
|
||||
"bit_not", "~",
|
||||
"call", "()",
|
||||
"cond", "?:",
|
||||
"alshift", "<<",
|
||||
"arshift", ">>",
|
||||
"component", "->",
|
||||
"indirect", "*",
|
||||
"method_call", "->()",
|
||||
"addr", "&", /* unary & */
|
||||
"array", "[]",
|
||||
"nop", "", /* for operator= */
|
||||
};
|
||||
|
||||
/* Beware: these aren't '\0' terminated. */
|
||||
|
||||
typedef struct {
|
||||
char *b; /* pointer to start of string */
|
||||
char *p; /* pointer after last character */
|
||||
char *e; /* pointer after end of allocated space */
|
||||
} string;
|
||||
|
||||
#ifdef __STDC__
|
||||
static void string_need (string *s, int n);
|
||||
static void string_delete (string *s);
|
||||
static void string_init (string *s);
|
||||
static void string_clear (string *s);
|
||||
static int string_empty (string *s);
|
||||
static void string_append (string *p, const char *s);
|
||||
static void string_appends (string *p, string *s);
|
||||
static void string_appendn (string *p, const char *s, int n);
|
||||
static void string_prepend (string *p, const char *s);
|
||||
#if 0
|
||||
static void string_prepends (string *p, string *s);
|
||||
#endif
|
||||
static void string_prependn (string *p, const char *s, int n);
|
||||
static int get_count (const char **type, int *count);
|
||||
static int do_args (const char **type, string *decl);
|
||||
static int do_type (const char **type, string *result);
|
||||
static int do_arg (const char **type, string *result);
|
||||
static int do_args (const char **type, string *decl);
|
||||
static void munge_function_name (string *name);
|
||||
#else
|
||||
static void string_need ();
|
||||
static void string_delete ();
|
||||
static void string_init ();
|
||||
static void string_clear ();
|
||||
static int string_empty ();
|
||||
static void string_append ();
|
||||
static void string_appends ();
|
||||
static void string_appendn ();
|
||||
static void string_prepend ();
|
||||
static void string_prepends ();
|
||||
static void string_prependn ();
|
||||
static int get_count ();
|
||||
static int do_args ();
|
||||
static int do_type ();
|
||||
static int do_arg ();
|
||||
static int do_args ();
|
||||
static void munge_function_name ();
|
||||
#endif
|
||||
|
||||
char *
|
||||
cplus_demangle (type)
|
||||
const char *type;
|
||||
{
|
||||
string decl;
|
||||
int n;
|
||||
int success = 0;
|
||||
int constructor = 0;
|
||||
int const_flag = 0;
|
||||
int i;
|
||||
const char *p, *premangle;
|
||||
|
||||
if (type == NULL || *type == '\0')
|
||||
return NULL;
|
||||
#ifndef nounderscore
|
||||
if (*type++ != '_')
|
||||
return NULL;
|
||||
#endif
|
||||
p = type;
|
||||
while (*p != '\0' && !(*p == '_' && p[1] == '_'))
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
{
|
||||
/* destructor */
|
||||
if (type[0] == '_' && type[1] == '$' && type[2] == '_')
|
||||
{
|
||||
unsigned int l = (strlen (type) - 3)*2 + 3 + 2 + 1;
|
||||
char *tem = (char *) xmalloc (l);
|
||||
strcpy (tem, type + 3);
|
||||
strcat (tem, "::~");
|
||||
strcat (tem, type + 3);
|
||||
strcat (tem, "()");
|
||||
return tem;
|
||||
}
|
||||
/* static data member */
|
||||
if (*type != '_' && (p = (char *) strchr (type, '$')) != NULL)
|
||||
{
|
||||
int n = strlen (type) + 2;
|
||||
char *tem = (char *) xmalloc (n);
|
||||
memcpy (tem, type, p - type);
|
||||
strcpy (tem + (p - type), "::");
|
||||
strcpy (tem + (p - type) + 2, p + 1);
|
||||
return tem;
|
||||
}
|
||||
/* virtual table */
|
||||
if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == '$')
|
||||
{
|
||||
int n = strlen (type + 4) + 14 + 1;
|
||||
char *tem = (char *) xmalloc (n);
|
||||
strcpy (tem, type + 4);
|
||||
strcat (tem, " virtual table");
|
||||
return tem;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string_init (&decl);
|
||||
|
||||
if (p == type)
|
||||
{
|
||||
if (!isdigit (p[2]))
|
||||
{
|
||||
string_delete (&decl);
|
||||
return NULL;
|
||||
}
|
||||
constructor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
string_appendn (&decl, type, p - type);
|
||||
munge_function_name (&decl);
|
||||
}
|
||||
p += 2;
|
||||
|
||||
premangle = p;
|
||||
switch (*p)
|
||||
{
|
||||
case 'C':
|
||||
/* a const member function */
|
||||
if (!isdigit (p[1]))
|
||||
{
|
||||
string_delete (&decl);
|
||||
return NULL;
|
||||
}
|
||||
p += 1;
|
||||
const_flag = 1;
|
||||
/* fall through */
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
n *= 10;
|
||||
n += *p - '0';
|
||||
p += 1;
|
||||
}
|
||||
while (isdigit (*p));
|
||||
if (strlen (p) < n)
|
||||
{
|
||||
string_delete (&decl);
|
||||
return NULL;
|
||||
}
|
||||
if (constructor)
|
||||
{
|
||||
string_appendn (&decl, p, n);
|
||||
string_append (&decl, "::");
|
||||
string_appendn (&decl, p, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
string_prepend (&decl, "::");
|
||||
string_prependn (&decl, p, n);
|
||||
}
|
||||
#ifndef LONGERNAMES
|
||||
p = premangle;
|
||||
#else
|
||||
p += n;
|
||||
#endif
|
||||
success = do_args (&p, &decl);
|
||||
if (const_flag)
|
||||
string_append (&decl, " const");
|
||||
break;
|
||||
case 'F':
|
||||
p += 1;
|
||||
success = do_args (&p, &decl);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < ntypes; i++)
|
||||
if (typevec[i] != NULL)
|
||||
free (typevec[i]);
|
||||
ntypes = 0;
|
||||
if (typevec != NULL)
|
||||
{
|
||||
free ((char *)typevec);
|
||||
typevec = NULL;
|
||||
typevec_size = 0;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
string_appendn (&decl, "", 1);
|
||||
return decl.b;
|
||||
}
|
||||
else
|
||||
{
|
||||
string_delete (&decl);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
get_count (type, count)
|
||||
const char **type;
|
||||
int *count;
|
||||
{
|
||||
if (!isdigit (**type))
|
||||
return 0;
|
||||
*count = **type - '0';
|
||||
*type += 1;
|
||||
/* see flush_repeats in cplus-method.c */
|
||||
if (isdigit (**type))
|
||||
{
|
||||
const char *p = *type;
|
||||
int n = *count;
|
||||
do
|
||||
{
|
||||
n *= 10;
|
||||
n += *p - '0';
|
||||
p += 1;
|
||||
}
|
||||
while (isdigit (*p));
|
||||
if (*p == '_')
|
||||
{
|
||||
*type = p + 1;
|
||||
*count = n;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* result will be initialised here; it will be freed on failure */
|
||||
|
||||
static int
|
||||
do_type (type, result)
|
||||
const char **type;
|
||||
string *result;
|
||||
{
|
||||
int n;
|
||||
int done;
|
||||
int non_empty = 0;
|
||||
int success;
|
||||
string decl;
|
||||
const char *remembered_type;
|
||||
|
||||
string_init (&decl);
|
||||
string_init (result);
|
||||
|
||||
done = 0;
|
||||
success = 1;
|
||||
while (success && !done)
|
||||
{
|
||||
int member;
|
||||
switch (**type)
|
||||
{
|
||||
case 'P':
|
||||
*type += 1;
|
||||
string_prepend (&decl, "*");
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
*type += 1;
|
||||
string_prepend (&decl, "&");
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
*type += 1;
|
||||
if (!get_count (type, &n) || n >= ntypes)
|
||||
success = 0;
|
||||
else
|
||||
{
|
||||
remembered_type = typevec[n];
|
||||
type = &remembered_type;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
*type += 1;
|
||||
if (!string_empty (&decl) && decl.b[0] == '*')
|
||||
{
|
||||
string_prepend (&decl, "(");
|
||||
string_append (&decl, ")");
|
||||
}
|
||||
if (!do_args (type, &decl) || **type != '_')
|
||||
success = 0;
|
||||
else
|
||||
*type += 1;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
case 'O':
|
||||
{
|
||||
int constp = 0;
|
||||
int volatilep = 0;
|
||||
|
||||
member = **type == 'M';
|
||||
*type += 1;
|
||||
if (!isdigit (**type))
|
||||
{
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
n *= 10;
|
||||
n += **type - '0';
|
||||
*type += 1;
|
||||
}
|
||||
while (isdigit (**type));
|
||||
if (strlen (*type) < n)
|
||||
{
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
string_append (&decl, ")");
|
||||
string_prepend (&decl, "::");
|
||||
string_prependn (&decl, *type, n);
|
||||
string_prepend (&decl, "(");
|
||||
*type += n;
|
||||
if (member)
|
||||
{
|
||||
if (**type == 'C')
|
||||
{
|
||||
*type += 1;
|
||||
constp = 1;
|
||||
}
|
||||
if (**type == 'V')
|
||||
{
|
||||
*type += 1;
|
||||
volatilep = 1;
|
||||
}
|
||||
if (*(*type)++ != 'F')
|
||||
{
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((member && !do_args (type, &decl)) || **type != '_')
|
||||
{
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
*type += 1;
|
||||
if (constp)
|
||||
{
|
||||
if (non_empty)
|
||||
string_append (&decl, " ");
|
||||
else
|
||||
non_empty = 1;
|
||||
string_append (&decl, "const");
|
||||
}
|
||||
if (volatilep)
|
||||
{
|
||||
if (non_empty)
|
||||
string_append (&decl, " ");
|
||||
else
|
||||
non_empty = 1;
|
||||
string_append (&decl, "volatilep");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'C':
|
||||
if ((*type)[1] == 'P')
|
||||
{
|
||||
*type += 1;
|
||||
if (!string_empty (&decl))
|
||||
string_prepend (&decl, " ");
|
||||
string_prepend (&decl, "const");
|
||||
break;
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
default:
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done = 0;
|
||||
non_empty = 0;
|
||||
while (success && !done)
|
||||
{
|
||||
switch (**type)
|
||||
{
|
||||
case 'C':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
else
|
||||
non_empty = 1;
|
||||
string_append (result, "const");
|
||||
break;
|
||||
case 'U':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
else
|
||||
non_empty = 1;
|
||||
string_append (result, "unsigned");
|
||||
break;
|
||||
case 'V':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
else
|
||||
non_empty = 1;
|
||||
string_append (result, "volatile");
|
||||
break;
|
||||
default:
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
switch (**type)
|
||||
{
|
||||
case '\0':
|
||||
case '_':
|
||||
break;
|
||||
case 'v':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "void");
|
||||
break;
|
||||
case 'l':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "long");
|
||||
break;
|
||||
case 'i':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "int");
|
||||
break;
|
||||
case 's':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "short");
|
||||
break;
|
||||
case 'c':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "char");
|
||||
break;
|
||||
case 'r':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "long double");
|
||||
break;
|
||||
case 'd':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "double");
|
||||
break;
|
||||
case 'f':
|
||||
*type += 1;
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_append (result, "float");
|
||||
break;
|
||||
case 'G':
|
||||
*type += 1;
|
||||
if (!isdigit (**type))
|
||||
{
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
n *= 10;
|
||||
n += **type - '0';
|
||||
*type += 1;
|
||||
}
|
||||
while (isdigit (**type));
|
||||
if (strlen (*type) < n)
|
||||
{
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
if (non_empty)
|
||||
string_append (result, " ");
|
||||
string_appendn (result, *type, n);
|
||||
*type += n;
|
||||
break;
|
||||
default:
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (!string_empty (&decl))
|
||||
{
|
||||
string_append (result, " ");
|
||||
string_appends (result, &decl);
|
||||
}
|
||||
string_delete (&decl);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
string_delete (&decl);
|
||||
string_delete (result);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* `result' will be initialised in do_type; it will be freed on failure */
|
||||
|
||||
static int
|
||||
do_arg (type, result)
|
||||
const char **type;
|
||||
string *result;
|
||||
{
|
||||
char *tem;
|
||||
int len;
|
||||
const char *start;
|
||||
const char *end;
|
||||
|
||||
start = *type;
|
||||
if (!do_type (type, result))
|
||||
return 0;
|
||||
end = *type;
|
||||
if (ntypes >= typevec_size)
|
||||
{
|
||||
if (typevec_size == 0)
|
||||
{
|
||||
typevec_size = 3;
|
||||
typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
typevec_size *= 2;
|
||||
typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
|
||||
}
|
||||
}
|
||||
len = end - start;
|
||||
tem = (char *) xmalloc (len + 1);
|
||||
memcpy (tem, start, len);
|
||||
tem[len] = '\0';
|
||||
typevec[ntypes++] = tem;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* `decl' must be already initialised, usually non-empty;
|
||||
it won't be freed on failure */
|
||||
|
||||
static int
|
||||
do_args (type, decl)
|
||||
const char **type;
|
||||
string *decl;
|
||||
{
|
||||
string arg;
|
||||
int need_comma = 0;
|
||||
int dont_want_first;
|
||||
|
||||
#ifndef LONGERNAMES
|
||||
dont_want_first = 1;
|
||||
#else
|
||||
dont_want_first = 0;
|
||||
#endif
|
||||
|
||||
string_append (decl, "(");
|
||||
|
||||
while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
|
||||
{
|
||||
if (**type == 'N')
|
||||
{
|
||||
int r;
|
||||
int t;
|
||||
*type += 1;
|
||||
if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
|
||||
return 0;
|
||||
while (--r >= 0)
|
||||
{
|
||||
const char *tem = typevec[t];
|
||||
if (need_comma)
|
||||
string_append (decl, ", ");
|
||||
if (!do_arg (&tem, &arg))
|
||||
return 0;
|
||||
string_appends (decl, &arg);
|
||||
string_delete (&arg);
|
||||
need_comma = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (need_comma)
|
||||
string_append (decl, ", ");
|
||||
if (!do_arg (type, &arg))
|
||||
return 0;
|
||||
if (dont_want_first)
|
||||
dont_want_first = 0;
|
||||
else
|
||||
{
|
||||
string_appends (decl, &arg);
|
||||
need_comma = 1;
|
||||
}
|
||||
string_delete (&arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (**type == 'v')
|
||||
*type += 1;
|
||||
else if (**type == 'e')
|
||||
{
|
||||
*type += 1;
|
||||
if (need_comma)
|
||||
string_append (decl, ",");
|
||||
string_append (decl, "...");
|
||||
}
|
||||
|
||||
string_append (decl, ")");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
munge_function_name (name)
|
||||
string *name;
|
||||
{
|
||||
if (!string_empty (name) && name->p - name->b >= 3
|
||||
&& name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$')
|
||||
{
|
||||
unsigned int i;
|
||||
/* see if it's an assignment expression */
|
||||
if (name->p - name->b >= 10 /* op$assign_ */
|
||||
&& memcmp (name->b + 3, "assign_", 7) == 0)
|
||||
{
|
||||
for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
|
||||
{
|
||||
int len = name->p - name->b - 10;
|
||||
if (strlen (optable[i].in) == len
|
||||
&& memcmp (optable[i].in, name->b + 10, len) == 0)
|
||||
{
|
||||
string_clear (name);
|
||||
string_append (name, "operator");
|
||||
string_append (name, optable[i].out);
|
||||
string_append (name, "=");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
|
||||
{
|
||||
int len = name->p - name->b - 3;
|
||||
if (strlen (optable[i].in) == len
|
||||
&& memcmp (optable[i].in, name->b + 3, len) == 0)
|
||||
{
|
||||
string_clear (name);
|
||||
string_append (name, "operator");
|
||||
string_append (name, optable[i].out);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!string_empty (name) && name->p - name->b >= 5
|
||||
&& memcmp (name->b, "type$", 5) == 0)
|
||||
{
|
||||
/* type conversion operator */
|
||||
string type;
|
||||
const char *tem = name->b + 5;
|
||||
if (do_type (&tem, &type))
|
||||
{
|
||||
string_clear (name);
|
||||
string_append (name, "operator ");
|
||||
string_appends (name, &type);
|
||||
string_delete (&type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* a mini string-handling package */
|
||||
|
||||
static void
|
||||
string_need (s, n)
|
||||
string *s;
|
||||
int n;
|
||||
{
|
||||
if (s->b == NULL)
|
||||
{
|
||||
if (n < 32)
|
||||
n = 32;
|
||||
s->p = s->b = (char *) xmalloc (n);
|
||||
s->e = s->b + n;
|
||||
}
|
||||
else if (s->e - s->p < n)
|
||||
{
|
||||
int tem = s->p - s->b;
|
||||
n += tem;
|
||||
n *= 2;
|
||||
s->b = (char *) xrealloc (s->b, n);
|
||||
s->p = s->b + tem;
|
||||
s->e = s->b + n;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
string_delete (s)
|
||||
string *s;
|
||||
{
|
||||
if (s->b != NULL)
|
||||
{
|
||||
free (s->b);
|
||||
s->b = s->e = s->p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
string_init (s)
|
||||
string *s;
|
||||
{
|
||||
s->b = s->p = s->e = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
string_clear (s)
|
||||
string *s;
|
||||
{
|
||||
s->p = s->b;
|
||||
}
|
||||
|
||||
static int
|
||||
string_empty (s)
|
||||
string *s;
|
||||
{
|
||||
return s->b == s->p;
|
||||
}
|
||||
|
||||
static void
|
||||
string_append (p, s)
|
||||
string *p;
|
||||
const char *s;
|
||||
{
|
||||
int n;
|
||||
if (s == NULL || *s == '\0')
|
||||
return;
|
||||
n = strlen (s);
|
||||
string_need (p, n);
|
||||
memcpy (p->p, s, n);
|
||||
p->p += n;
|
||||
}
|
||||
|
||||
static void
|
||||
string_appends (p, s)
|
||||
string *p, *s;
|
||||
{
|
||||
int n;
|
||||
if (s->b == s->p)
|
||||
return;
|
||||
n = s->p - s->b;
|
||||
string_need (p, n);
|
||||
memcpy (p->p, s->b, n);
|
||||
p->p += n;
|
||||
}
|
||||
|
||||
static void
|
||||
string_appendn (p, s, n)
|
||||
string *p;
|
||||
const char *s;
|
||||
int n;
|
||||
{
|
||||
if (n == 0)
|
||||
return;
|
||||
string_need (p, n);
|
||||
memcpy (p->p, s, n);
|
||||
p->p += n;
|
||||
}
|
||||
|
||||
static void
|
||||
string_prepend (p, s)
|
||||
string *p;
|
||||
const char *s;
|
||||
{
|
||||
if (s == NULL || *s == '\0')
|
||||
return;
|
||||
string_prependn (p, s, strlen (s));
|
||||
}
|
||||
|
||||
static void
|
||||
string_prependn (p, s, n)
|
||||
string *p;
|
||||
const char *s;
|
||||
int n;
|
||||
{
|
||||
char *q;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
string_need (p, n);
|
||||
for (q = p->p - 1; q >= p->b; q--)
|
||||
q[n] = q[0];
|
||||
memcpy (p->b, s, n);
|
||||
p->p += n;
|
||||
}
|
Binary file not shown.
@ -1,417 +0,0 @@
|
||||
/* strip certain symbols from a rel file.
|
||||
Copyright (C) 1986, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "getopt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
enum strip_action {
|
||||
strip_undef,
|
||||
strip_all, /* strip all symbols */
|
||||
strip_debug, /* strip all debugger symbols */
|
||||
};
|
||||
|
||||
/* Which symbols to remove. */
|
||||
enum strip_action strip_symbols;
|
||||
|
||||
enum locals_action {
|
||||
locals_undef,
|
||||
locals_start_L, /* discard locals starting with L */
|
||||
locals_all, /* discard all locals */
|
||||
};
|
||||
|
||||
/* Which local symbols to remove. */
|
||||
enum locals_action discard_locals;
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
struct option long_options[] = {
|
||||
{"strip-all", 0, 0, 's'},
|
||||
{"strip-debug", 0, 0, 'S'},
|
||||
{"discard-all", 0, 0, 'x'},
|
||||
{"discard-locals", 0, 0, 'X'},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static char *target = NULL;
|
||||
|
||||
static int fatal_error;
|
||||
|
||||
extern char *malloc();
|
||||
extern char *mktemp();
|
||||
extern char *realloc();
|
||||
extern char *strcpy();
|
||||
extern int exit();
|
||||
extern int fprintf();
|
||||
extern int free();
|
||||
extern int getpid();
|
||||
extern int kill();
|
||||
extern int perror();
|
||||
extern int sprintf();
|
||||
extern int unlink();
|
||||
|
||||
#ifdef __STDC__
|
||||
static int strip_bfd(bfd *ibfd, bfd *obfd);
|
||||
static int strip_file(char *filetostrip);
|
||||
static void usage(void);
|
||||
#else
|
||||
static int strip_bfd();
|
||||
static int strip_file();
|
||||
static void usage();
|
||||
#endif /* __STDC__ */
|
||||
static void copy_sections ();
|
||||
static void setup_sections ();
|
||||
|
||||
int main(argc, argv)
|
||||
char **argv;
|
||||
int argc;
|
||||
{
|
||||
int ind;
|
||||
int c;
|
||||
program_name = argv[0];
|
||||
|
||||
strip_symbols = strip_undef; /* default is to strip everything. */
|
||||
discard_locals = locals_undef;
|
||||
|
||||
while ((c = getopt_long (argc, argv, "gsST:xX", long_options, &ind)) != EOF) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 's':
|
||||
strip_symbols = strip_all;
|
||||
break;
|
||||
case 'g':
|
||||
case 'S':
|
||||
strip_symbols = strip_debug;
|
||||
break;
|
||||
case 'T':
|
||||
target = optarg;
|
||||
break;
|
||||
case 'x':
|
||||
discard_locals = locals_all;
|
||||
break;
|
||||
case 'X':
|
||||
discard_locals = locals_start_L;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
} /* switch on option */
|
||||
} /* for each option */
|
||||
|
||||
if (strip_symbols == strip_undef && discard_locals == locals_undef) {
|
||||
strip_symbols = strip_all;
|
||||
} /* Default is to strip all symbols. */
|
||||
|
||||
|
||||
if (argc == optind) {
|
||||
return(strip_file("a.out"));
|
||||
} else {
|
||||
int retval = 0;
|
||||
|
||||
for ( ; optind < argc; ++optind) {
|
||||
retval &= strip_file(argv[optind]);
|
||||
} /* for each file to strip */
|
||||
|
||||
return(retval);
|
||||
} /* if no arguments given */
|
||||
|
||||
} /* main() */
|
||||
|
||||
static int delayed_signal;
|
||||
|
||||
void delay_signal(signo)
|
||||
int signo;
|
||||
{
|
||||
delayed_signal = signo;
|
||||
signal(signo, delay_signal);
|
||||
} /* delay_signal() */
|
||||
|
||||
static int sigint_handled = 0;
|
||||
static int sighup_handled = 0;
|
||||
static int sigterm_handled = 0;
|
||||
|
||||
void handle_sigs() {
|
||||
/* Effectively defer handling of asynchronous kill signals. */
|
||||
delayed_signal = 0;
|
||||
|
||||
if (signal (SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
sigint_handled = 1;
|
||||
signal(SIGINT, delay_signal);
|
||||
} /* if not ignored */
|
||||
|
||||
if (signal (SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
sighup_handled = 1;
|
||||
signal(SIGHUP, delay_signal);
|
||||
} /* if not ignored */
|
||||
|
||||
if (signal (SIGTERM, SIG_IGN) != SIG_IGN) {
|
||||
sigterm_handled = 1;
|
||||
signal(SIGTERM, delay_signal);
|
||||
} /* if not ignored */
|
||||
|
||||
return;
|
||||
} /* handle_sigs() */
|
||||
|
||||
void unhandle_sigs() {
|
||||
/* Effectively undefer handling. */
|
||||
if (sigint_handled)
|
||||
signal (SIGINT, SIG_DFL);
|
||||
if (sighup_handled)
|
||||
signal (SIGHUP, SIG_DFL);
|
||||
if (sigterm_handled)
|
||||
signal (SIGTERM, SIG_DFL);
|
||||
|
||||
/* Handle any signal that came in while they were deferred. */
|
||||
if (delayed_signal)
|
||||
kill (getpid (), delayed_signal);
|
||||
|
||||
return;
|
||||
} /* unhandle_sigs() */
|
||||
|
||||
static int strip_file(filetostrip)
|
||||
char *filetostrip;
|
||||
{
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
char tmpfilename[] = "stXXXXXX";
|
||||
|
||||
if ((ibfd = bfd_openr(filetostrip, (char *)NULL)) == NULL) {
|
||||
bfd_perror(filetostrip);
|
||||
return(1);
|
||||
} /* on error opening input */
|
||||
|
||||
obfd = bfd_openw(mktemp(tmpfilename),
|
||||
target? target: bfd_get_target (ibfd));
|
||||
if (obfd == NULL) {
|
||||
bfd_perror(tmpfilename);
|
||||
|
||||
if (bfd_close(ibfd) == false) {
|
||||
bfd_perror(bfd_get_filename(ibfd));
|
||||
} /* on close error */
|
||||
|
||||
return(1);
|
||||
} /* on error opening output */
|
||||
|
||||
handle_sigs();
|
||||
|
||||
if (bfd_check_format(ibfd, bfd_object) != false) {
|
||||
if (bfd_set_format(obfd, bfd_get_format(ibfd)) != false) {
|
||||
if (!strip_bfd(ibfd, obfd)) {
|
||||
/* success */
|
||||
|
||||
if (bfd_close(ibfd) == false) {
|
||||
bfd_perror(bfd_get_filename(ibfd));
|
||||
} /* on close error */
|
||||
|
||||
if (bfd_close(obfd) == false) {
|
||||
bfd_perror(bfd_get_filename(obfd));
|
||||
} /* on close error */
|
||||
|
||||
rename(tmpfilename, filetostrip);
|
||||
unhandle_sigs();
|
||||
return(0);
|
||||
} /* strip_bfd prints it's own failing messages */
|
||||
} else {
|
||||
bfd_perror(filetostrip);
|
||||
} /* can't set format */
|
||||
} else {
|
||||
/* not an object file */
|
||||
(void) fprintf(stderr, "File %s has format 0x%x that will not be stripped.\n",
|
||||
filetostrip, (unsigned) bfd_get_format(ibfd));
|
||||
} /* if anything fails along the way */
|
||||
|
||||
|
||||
if (bfd_close(ibfd) == false) {
|
||||
bfd_perror(bfd_get_filename(ibfd));
|
||||
} /* on close error */
|
||||
|
||||
if (bfd_close(obfd) == false) {
|
||||
bfd_perror(bfd_get_filename(obfd));
|
||||
} /* on close error */
|
||||
|
||||
if (unlink(tmpfilename)) {
|
||||
perror(tmpfilename);
|
||||
} /* on error */
|
||||
|
||||
unhandle_sigs();
|
||||
|
||||
return(1);
|
||||
} /* strip_file() */
|
||||
|
||||
|
||||
boolean
|
||||
bfd_set_start_address (abfd, new_address)
|
||||
bfd *abfd;
|
||||
bfd_vma new_address;
|
||||
{
|
||||
bfd_get_start_address (abfd) = new_address;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
strip_bfd(ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
if (bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false
|
||||
|| bfd_set_file_flags(obfd, bfd_get_file_flags(ibfd) & ~(HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS)) == false
|
||||
|| bfd_set_start_address(obfd, bfd_get_start_address(ibfd)) == false) {
|
||||
bfd_perror(bfd_get_filename(ibfd));
|
||||
return(1);
|
||||
} /* on error setting file attributes */
|
||||
|
||||
/* bfd mandates that all output sections be created and sizes set before
|
||||
any output is done. Thus, we traverse all sections twice. */
|
||||
|
||||
fatal_error = 0;
|
||||
bfd_map_over_sections (ibfd, setup_sections, (void *)obfd);
|
||||
if (!fatal_error)
|
||||
bfd_map_over_sections (ibfd, copy_sections, (void *)obfd);
|
||||
return fatal_error;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_sections(ibfd, isection, obfd)
|
||||
bfd *ibfd;
|
||||
sec_ptr isection;
|
||||
bfd *obfd;
|
||||
{
|
||||
sec_ptr osection;
|
||||
char *err;
|
||||
|
||||
do {
|
||||
err = "making";
|
||||
osection = bfd_make_section(obfd, bfd_section_name(ibfd, isection));
|
||||
if (osection == NULL)
|
||||
break;
|
||||
err = "size";
|
||||
if (!bfd_set_section_size(obfd, osection,
|
||||
bfd_section_size(ibfd, isection)))
|
||||
break;
|
||||
err = "vma";
|
||||
if (!bfd_set_section_vma(obfd, osection,
|
||||
bfd_section_vma(ibfd, isection)))
|
||||
break;
|
||||
err = "alignment";
|
||||
if (!bfd_set_section_alignment(obfd, osection,
|
||||
bfd_section_alignment(ibfd, isection)))
|
||||
break;
|
||||
err = "flags";
|
||||
if (!bfd_set_section_flags(obfd, osection,
|
||||
bfd_get_section_flags(ibfd, isection)))
|
||||
break;
|
||||
return;
|
||||
} while (0);
|
||||
|
||||
(void) fprintf(stderr, "file \"%s\", section \"%s\": error in %s: ",
|
||||
bfd_get_filename(ibfd),
|
||||
bfd_section_name(ibfd, isection),
|
||||
err);
|
||||
|
||||
bfd_perror("");
|
||||
fatal_error = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_sections(ibfd, isection, obfd)
|
||||
bfd *ibfd;
|
||||
sec_ptr isection;
|
||||
bfd *obfd;
|
||||
{
|
||||
static char *memhunk = NULL;
|
||||
static unsigned memhunksize = 0;
|
||||
|
||||
sec_ptr osection;
|
||||
unsigned long size;
|
||||
flagword iflg;
|
||||
char *temp;
|
||||
|
||||
osection = bfd_get_section_by_name (obfd,
|
||||
bfd_section_name(ibfd, isection));
|
||||
|
||||
size = bfd_section_size(ibfd, isection);
|
||||
iflg = bfd_get_section_flags(ibfd, isection);
|
||||
|
||||
/* either:
|
||||
we don't need any memory because there's nothing in this section,
|
||||
we had no memory so we got some,
|
||||
we had some memory but not enough so we got more,
|
||||
or we fail to allocat. */
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
if (memhunk == NULL) {
|
||||
memhunk = malloc (size);
|
||||
memhunksize = size;
|
||||
}
|
||||
|
||||
if (size > memhunksize) {
|
||||
temp = realloc (memhunk, size);
|
||||
memhunksize = size;
|
||||
if (!temp) /* If realloc failed, blow away our mem */
|
||||
free (memhunk);
|
||||
memhunk = temp;
|
||||
}
|
||||
|
||||
if (memhunk == NULL) {
|
||||
/* failed to allocate or reallocate */
|
||||
/* FIXME, we should just copy in pieces. */
|
||||
(void) fprintf(stderr,
|
||||
"Could not allocate %lu bytes in which to copy section.\n", size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now we have enough memory */
|
||||
|
||||
if (!bfd_get_section_contents(ibfd, isection, memhunk, 0, size)) {
|
||||
bfd_perror(bfd_get_filename(ibfd));
|
||||
fatal_error = 1;
|
||||
return;
|
||||
}
|
||||
if (!bfd_set_section_contents(obfd, osection, memhunk, 0, size)) {
|
||||
bfd_perror(bfd_get_filename(obfd));
|
||||
fatal_error = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage ()
|
||||
{
|
||||
fprintf (stderr, "\
|
||||
Usage: %s [-gsxSX] [+strip-all] [+strip-debug] [+discard-all]\n\
|
||||
[+discard-locals] file...\n", program_name);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* comment-column: 0
|
||||
* fill-column: 131
|
||||
* End:
|
||||
*/
|
||||
|
||||
/* end of strip.c */
|
362
binutils/strip.c
362
binutils/strip.c
@ -1,362 +0,0 @@
|
||||
/* strip.c -- strip certain symbols from a rel file.
|
||||
Copyright (C) 1986, 1990, 1991 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* BUGS: When there's not enough memory, this should do the copy
|
||||
in pieces rather than just fail as it does now */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "getopt.h"
|
||||
#include <signal.h>
|
||||
|
||||
/* Various program options */
|
||||
|
||||
int show_version = 0;
|
||||
|
||||
/* Which symbols to remove. */
|
||||
enum strip_action {
|
||||
strip_undef,
|
||||
strip_all, /* strip all symbols */
|
||||
strip_debug, /* strip all debugger symbols */
|
||||
} strip_symbols;
|
||||
|
||||
/* Which local symbols to remove. */
|
||||
enum {
|
||||
locals_undef,
|
||||
locals_start_L, /* discard locals starting with L */
|
||||
locals_all, /* discard all locals */
|
||||
} discard_locals;
|
||||
|
||||
extern char *mktemp();
|
||||
|
||||
/* IMPORTS */
|
||||
extern char *program_version;
|
||||
extern char *program_name;
|
||||
extern char *target;
|
||||
extern char *xmalloc();
|
||||
|
||||
PROTO(static boolean, strip_file, (char *filetostrip));
|
||||
PROTO(static void, copy_sections, (bfd *ibfd, sec_ptr isection, bfd *obfd));
|
||||
PROTO(static void, setup_sections, (bfd *ibfd, sec_ptr isection, bfd *obfd));
|
||||
|
||||
/** main, etc */
|
||||
|
||||
static void
|
||||
usage ()
|
||||
{
|
||||
fprintf (stderr, "strip %s\nUsage: %s [-gsxSX] files ...\n",
|
||||
program_version, program_name);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
struct option long_options[] = {{"strip-all", 0, 0, 's'},
|
||||
{"strip-debug", 0, 0, 'S'},
|
||||
{"discard-all", 0, 0, 'x'},
|
||||
{"discard-locals", 0, 0, 'X'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
char **argv;
|
||||
int argc;
|
||||
{
|
||||
int ind;
|
||||
int c;
|
||||
program_name = argv[0];
|
||||
|
||||
bfd_init();
|
||||
|
||||
strip_symbols = strip_undef; /* default is to strip everything. */
|
||||
discard_locals = locals_undef;
|
||||
|
||||
while ((c = getopt_long (argc, argv, "gsST:xX", long_options, &ind)) != EOF) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 's':
|
||||
strip_symbols = strip_all;
|
||||
break;
|
||||
case 'g':
|
||||
case 'S':
|
||||
strip_symbols = strip_debug;
|
||||
break;
|
||||
case 'T':
|
||||
target = optarg;
|
||||
break;
|
||||
case 'x':
|
||||
discard_locals = locals_all;
|
||||
break;
|
||||
case 'X':
|
||||
discard_locals = locals_start_L;
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Default is to strip all symbols: */
|
||||
if (strip_symbols == strip_undef && discard_locals == locals_undef) {
|
||||
strip_symbols = strip_all;
|
||||
}
|
||||
|
||||
/* OK, all options now parsed. If no filename specified, do a.out. */
|
||||
if (optind == argc) return !strip_file ("a.out");
|
||||
|
||||
/* We were given several filenames to do: */
|
||||
while (optind < argc)
|
||||
if (!strip_file (argv[optind++])) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Hack signals */
|
||||
|
||||
/* Why does strip need to do this, and anyway, if it does shouldn't this be
|
||||
handled by bfd? */
|
||||
|
||||
static int delayed_signal;
|
||||
|
||||
static int sigint_handled = 0;
|
||||
static int sighup_handled = 0;
|
||||
static int sigterm_handled = 0;
|
||||
|
||||
void
|
||||
delay_signal (signo)
|
||||
int signo;
|
||||
{
|
||||
delayed_signal = signo;
|
||||
signal (signo, delay_signal);
|
||||
}
|
||||
|
||||
/* Effectively defer handling of asynchronous kill signals. */
|
||||
void
|
||||
handle_sigs () /* puff puff */
|
||||
{
|
||||
delayed_signal = 0;
|
||||
|
||||
if (signal (SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
sigint_handled = 1;
|
||||
signal (SIGINT, delay_signal);
|
||||
}
|
||||
|
||||
if (signal (SIGHUP, SIG_IGN) != SIG_IGN) {
|
||||
sighup_handled = 1;
|
||||
signal (SIGHUP, delay_signal);
|
||||
}
|
||||
|
||||
if (signal (SIGTERM, SIG_IGN) != SIG_IGN) {
|
||||
sigterm_handled = 1;
|
||||
signal (SIGTERM, delay_signal);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Effectively undefer handling. */
|
||||
void
|
||||
unhandle_sigs () /* put them down */
|
||||
{
|
||||
if (sigint_handled) signal (SIGINT, SIG_DFL);
|
||||
|
||||
if (sighup_handled) signal (SIGHUP, SIG_DFL);
|
||||
|
||||
if (sigterm_handled) signal (SIGTERM, SIG_DFL);
|
||||
|
||||
/* Handle any signal that came in while they were deferred. */
|
||||
if (delayed_signal)
|
||||
kill (getpid (), delayed_signal);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
strip_file (filetostrip)
|
||||
char *filetostrip;
|
||||
{
|
||||
static char template[] = "stXXXXXX";
|
||||
char *slash;
|
||||
char *tmpname;
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
|
||||
ibfd = bfd_openr (filetostrip, target);
|
||||
|
||||
if (ibfd == NULL) bfd_fatal (filetostrip);
|
||||
|
||||
handle_sigs (); /* light up */
|
||||
|
||||
if (!bfd_check_format (ibfd, bfd_object)) {
|
||||
fprintf (stderr, "Can't strip %s file %s.\n",
|
||||
bfd_format_string (bfd_get_format (ibfd)), filetostrip);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
slash = strrchr( filetostrip, '/' );
|
||||
if ( slash ){
|
||||
*slash = 0;
|
||||
tmpname = xmalloc( strlen(filetostrip) + sizeof(template) + 1 );
|
||||
strcpy( tmpname, filetostrip );
|
||||
strcat( tmpname, "/" );
|
||||
strcat( tmpname, template );
|
||||
mktemp( tmpname );
|
||||
*slash = '/';
|
||||
} else {
|
||||
tmpname = xmalloc( sizeof(template) );
|
||||
strcpy( tmpname, template );
|
||||
mktemp( tmpname );
|
||||
}
|
||||
|
||||
obfd = bfd_openw (mktemp(tmpname), (target ? target : bfd_get_target (ibfd)));
|
||||
if (obfd == NULL) bfd_fatal (tmpname);
|
||||
|
||||
if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
|
||||
bfd_fatal (tmpname);
|
||||
|
||||
|
||||
if ((bfd_set_start_address (obfd, bfd_get_start_address (ibfd)) == false) ||
|
||||
(bfd_set_file_flags (obfd, (bfd_get_file_flags (ibfd) &
|
||||
~(HAS_LINENO | HAS_DEBUG | HAS_SYMS |
|
||||
HAS_LOCALS))) == false) ||
|
||||
bfd_set_start_address (obfd, bfd_get_start_address (ibfd)) == false)
|
||||
bfd_fatal (bfd_get_filename (ibfd));
|
||||
|
||||
/* Copy architecture of input file to output file */
|
||||
if (!bfd_set_arch_mach (obfd, bfd_get_architecture (ibfd),
|
||||
bfd_get_machine (ibfd))) {
|
||||
fprintf(stderr, "Output file cannot represent architecture %s",
|
||||
bfd_printable_arch_mach (bfd_get_architecture(ibfd),
|
||||
bfd_get_machine (ibfd)));
|
||||
}
|
||||
|
||||
|
||||
/* bfd mandates that all output sections be created and sizes set before
|
||||
any output is done. Thus, we traverse all sections twice. */
|
||||
bfd_map_over_sections (ibfd, setup_sections, (void *)obfd);
|
||||
bfd_map_over_sections (ibfd, copy_sections, (void *)obfd);
|
||||
|
||||
if (!bfd_close (obfd)) bfd_fatal (filetostrip);
|
||||
if (!bfd_close (ibfd)) bfd_fatal (filetostrip);
|
||||
|
||||
rename(tmpname, filetostrip);
|
||||
free(tmpname);
|
||||
|
||||
unhandle_sigs();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Actually do the work */
|
||||
static void
|
||||
setup_sections (ibfd, isection, obfd)
|
||||
bfd *ibfd;
|
||||
sec_ptr isection;
|
||||
bfd *obfd;
|
||||
{
|
||||
sec_ptr osection;
|
||||
char *err;
|
||||
|
||||
osection = bfd_make_section (obfd, bfd_section_name (ibfd, isection));
|
||||
if (osection == NULL) {
|
||||
err = "making";
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (!bfd_set_section_size(obfd, osection, bfd_section_size(ibfd, isection))) {
|
||||
err = "size";
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (!bfd_set_section_vma (obfd, osection, bfd_section_vma (ibfd, isection))) {
|
||||
err = "vma";
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (bfd_set_section_alignment (obfd, osection,
|
||||
bfd_section_alignment (ibfd, isection))
|
||||
!= true) {
|
||||
err = "alignment";
|
||||
goto loser;
|
||||
} /* on error, I presume. */
|
||||
|
||||
if (!bfd_set_section_flags (obfd, osection,
|
||||
bfd_get_section_flags (ibfd, isection))) {
|
||||
err = "flags";
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* All went well */
|
||||
return;
|
||||
|
||||
loser:
|
||||
fprintf (stderr, "%s: file \"%s\", section \"%s\": error in %s: %s\n",
|
||||
program_name,
|
||||
bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
|
||||
err, bfd_errmsg (bfd_error));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_sections (ibfd, isection, obfd)
|
||||
bfd *ibfd;
|
||||
sec_ptr isection;
|
||||
bfd *obfd;
|
||||
{
|
||||
static unsigned char *memhunk = NULL;
|
||||
static unsigned memhunksize = 0;
|
||||
|
||||
sec_ptr osection;
|
||||
unsigned long size;
|
||||
flagword iflg;
|
||||
unsigned char *temp;
|
||||
|
||||
osection = bfd_get_section_by_name (obfd, bfd_section_name (ibfd, isection));
|
||||
|
||||
size = bfd_section_size (ibfd, isection);
|
||||
iflg = bfd_get_section_flags (ibfd, isection);
|
||||
|
||||
/* either:
|
||||
we don't need any memory because there's nothing in this section,
|
||||
we had no memory so we got some,
|
||||
we had some memory but not enough so we got more,
|
||||
or we fail to allocat. */
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
if ((iflg & SEC_HAS_CONTENTS) == 0)
|
||||
return;
|
||||
|
||||
if (memhunk == NULL) {
|
||||
memhunk = (unsigned char *) xmalloc (size);
|
||||
memhunksize = size;
|
||||
}
|
||||
|
||||
if (size > memhunksize) {
|
||||
temp = (unsigned char *) xrealloc ((char *) memhunk, size);
|
||||
memhunksize = size;
|
||||
memhunk = temp;
|
||||
}
|
||||
|
||||
/* now we have enough memory, just do it: */
|
||||
if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
|
||||
bfd_fatal (bfd_get_filename (ibfd));
|
||||
|
||||
if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
|
||||
bfd_fatal (bfd_get_filename (obfd));
|
||||
}
|
Reference in New Issue
Block a user