15796c8dcSSimon Schubert /* Generic symbol-table support for the BFD library.
25796c8dcSSimon Schubert Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3*ef5ccd6cSJohn Marino 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2012
45796c8dcSSimon Schubert Free Software Foundation, Inc.
55796c8dcSSimon Schubert Written by Cygnus Support.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This file is part of BFD, the Binary File Descriptor library.
85796c8dcSSimon Schubert
95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert (at your option) any later version.
135796c8dcSSimon Schubert
145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
175796c8dcSSimon Schubert GNU General Public License for more details.
185796c8dcSSimon Schubert
195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert along with this program; if not, write to the Free Software
215796c8dcSSimon Schubert Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
225796c8dcSSimon Schubert MA 02110-1301, USA. */
235796c8dcSSimon Schubert
245796c8dcSSimon Schubert /*
255796c8dcSSimon Schubert SECTION
265796c8dcSSimon Schubert Symbols
275796c8dcSSimon Schubert
285796c8dcSSimon Schubert BFD tries to maintain as much symbol information as it can when
295796c8dcSSimon Schubert it moves information from file to file. BFD passes information
305796c8dcSSimon Schubert to applications though the <<asymbol>> structure. When the
315796c8dcSSimon Schubert application requests the symbol table, BFD reads the table in
325796c8dcSSimon Schubert the native form and translates parts of it into the internal
335796c8dcSSimon Schubert format. To maintain more than the information passed to
345796c8dcSSimon Schubert applications, some targets keep some information ``behind the
355796c8dcSSimon Schubert scenes'' in a structure only the particular back end knows
365796c8dcSSimon Schubert about. For example, the coff back end keeps the original
375796c8dcSSimon Schubert symbol table structure as well as the canonical structure when
385796c8dcSSimon Schubert a BFD is read in. On output, the coff back end can reconstruct
395796c8dcSSimon Schubert the output symbol table so that no information is lost, even
405796c8dcSSimon Schubert information unique to coff which BFD doesn't know or
415796c8dcSSimon Schubert understand. If a coff symbol table were read, but were written
425796c8dcSSimon Schubert through an a.out back end, all the coff specific information
435796c8dcSSimon Schubert would be lost. The symbol table of a BFD
445796c8dcSSimon Schubert is not necessarily read in until a canonicalize request is
455796c8dcSSimon Schubert made. Then the BFD back end fills in a table provided by the
465796c8dcSSimon Schubert application with pointers to the canonical information. To
475796c8dcSSimon Schubert output symbols, the application provides BFD with a table of
485796c8dcSSimon Schubert pointers to pointers to <<asymbol>>s. This allows applications
495796c8dcSSimon Schubert like the linker to output a symbol as it was read, since the ``behind
505796c8dcSSimon Schubert the scenes'' information will be still available.
515796c8dcSSimon Schubert @menu
525796c8dcSSimon Schubert @* Reading Symbols::
535796c8dcSSimon Schubert @* Writing Symbols::
545796c8dcSSimon Schubert @* Mini Symbols::
555796c8dcSSimon Schubert @* typedef asymbol::
565796c8dcSSimon Schubert @* symbol handling functions::
575796c8dcSSimon Schubert @end menu
585796c8dcSSimon Schubert
595796c8dcSSimon Schubert INODE
605796c8dcSSimon Schubert Reading Symbols, Writing Symbols, Symbols, Symbols
615796c8dcSSimon Schubert SUBSECTION
625796c8dcSSimon Schubert Reading symbols
635796c8dcSSimon Schubert
645796c8dcSSimon Schubert There are two stages to reading a symbol table from a BFD:
655796c8dcSSimon Schubert allocating storage, and the actual reading process. This is an
665796c8dcSSimon Schubert excerpt from an application which reads the symbol table:
675796c8dcSSimon Schubert
685796c8dcSSimon Schubert | long storage_needed;
695796c8dcSSimon Schubert | asymbol **symbol_table;
705796c8dcSSimon Schubert | long number_of_symbols;
715796c8dcSSimon Schubert | long i;
725796c8dcSSimon Schubert |
735796c8dcSSimon Schubert | storage_needed = bfd_get_symtab_upper_bound (abfd);
745796c8dcSSimon Schubert |
755796c8dcSSimon Schubert | if (storage_needed < 0)
765796c8dcSSimon Schubert | FAIL
775796c8dcSSimon Schubert |
785796c8dcSSimon Schubert | if (storage_needed == 0)
795796c8dcSSimon Schubert | return;
805796c8dcSSimon Schubert |
815796c8dcSSimon Schubert | symbol_table = xmalloc (storage_needed);
825796c8dcSSimon Schubert | ...
835796c8dcSSimon Schubert | number_of_symbols =
845796c8dcSSimon Schubert | bfd_canonicalize_symtab (abfd, symbol_table);
855796c8dcSSimon Schubert |
865796c8dcSSimon Schubert | if (number_of_symbols < 0)
875796c8dcSSimon Schubert | FAIL
885796c8dcSSimon Schubert |
895796c8dcSSimon Schubert | for (i = 0; i < number_of_symbols; i++)
905796c8dcSSimon Schubert | process_symbol (symbol_table[i]);
915796c8dcSSimon Schubert
925796c8dcSSimon Schubert All storage for the symbols themselves is in an objalloc
935796c8dcSSimon Schubert connected to the BFD; it is freed when the BFD is closed.
945796c8dcSSimon Schubert
955796c8dcSSimon Schubert INODE
965796c8dcSSimon Schubert Writing Symbols, Mini Symbols, Reading Symbols, Symbols
975796c8dcSSimon Schubert SUBSECTION
985796c8dcSSimon Schubert Writing symbols
995796c8dcSSimon Schubert
1005796c8dcSSimon Schubert Writing of a symbol table is automatic when a BFD open for
1015796c8dcSSimon Schubert writing is closed. The application attaches a vector of
1025796c8dcSSimon Schubert pointers to pointers to symbols to the BFD being written, and
1035796c8dcSSimon Schubert fills in the symbol count. The close and cleanup code reads
1045796c8dcSSimon Schubert through the table provided and performs all the necessary
1055796c8dcSSimon Schubert operations. The BFD output code must always be provided with an
1065796c8dcSSimon Schubert ``owned'' symbol: one which has come from another BFD, or one
1075796c8dcSSimon Schubert which has been created using <<bfd_make_empty_symbol>>. Here is an
1085796c8dcSSimon Schubert example showing the creation of a symbol table with only one element:
1095796c8dcSSimon Schubert
110*ef5ccd6cSJohn Marino | #include "sysdep.h"
1115796c8dcSSimon Schubert | #include "bfd.h"
1125796c8dcSSimon Schubert | int main (void)
1135796c8dcSSimon Schubert | {
1145796c8dcSSimon Schubert | bfd *abfd;
1155796c8dcSSimon Schubert | asymbol *ptrs[2];
1165796c8dcSSimon Schubert | asymbol *new;
1175796c8dcSSimon Schubert |
1185796c8dcSSimon Schubert | abfd = bfd_openw ("foo","a.out-sunos-big");
1195796c8dcSSimon Schubert | bfd_set_format (abfd, bfd_object);
1205796c8dcSSimon Schubert | new = bfd_make_empty_symbol (abfd);
1215796c8dcSSimon Schubert | new->name = "dummy_symbol";
1225796c8dcSSimon Schubert | new->section = bfd_make_section_old_way (abfd, ".text");
1235796c8dcSSimon Schubert | new->flags = BSF_GLOBAL;
1245796c8dcSSimon Schubert | new->value = 0x12345;
1255796c8dcSSimon Schubert |
1265796c8dcSSimon Schubert | ptrs[0] = new;
1275796c8dcSSimon Schubert | ptrs[1] = 0;
1285796c8dcSSimon Schubert |
1295796c8dcSSimon Schubert | bfd_set_symtab (abfd, ptrs, 1);
1305796c8dcSSimon Schubert | bfd_close (abfd);
1315796c8dcSSimon Schubert | return 0;
1325796c8dcSSimon Schubert | }
1335796c8dcSSimon Schubert |
1345796c8dcSSimon Schubert | ./makesym
1355796c8dcSSimon Schubert | nm foo
1365796c8dcSSimon Schubert | 00012345 A dummy_symbol
1375796c8dcSSimon Schubert
1385796c8dcSSimon Schubert Many formats cannot represent arbitrary symbol information; for
1395796c8dcSSimon Schubert instance, the <<a.out>> object format does not allow an
1405796c8dcSSimon Schubert arbitrary number of sections. A symbol pointing to a section
1415796c8dcSSimon Schubert which is not one of <<.text>>, <<.data>> or <<.bss>> cannot
1425796c8dcSSimon Schubert be described.
1435796c8dcSSimon Schubert
1445796c8dcSSimon Schubert INODE
1455796c8dcSSimon Schubert Mini Symbols, typedef asymbol, Writing Symbols, Symbols
1465796c8dcSSimon Schubert SUBSECTION
1475796c8dcSSimon Schubert Mini Symbols
1485796c8dcSSimon Schubert
1495796c8dcSSimon Schubert Mini symbols provide read-only access to the symbol table.
1505796c8dcSSimon Schubert They use less memory space, but require more time to access.
1515796c8dcSSimon Schubert They can be useful for tools like nm or objdump, which may
1525796c8dcSSimon Schubert have to handle symbol tables of extremely large executables.
1535796c8dcSSimon Schubert
1545796c8dcSSimon Schubert The <<bfd_read_minisymbols>> function will read the symbols
1555796c8dcSSimon Schubert into memory in an internal form. It will return a <<void *>>
1565796c8dcSSimon Schubert pointer to a block of memory, a symbol count, and the size of
1575796c8dcSSimon Schubert each symbol. The pointer is allocated using <<malloc>>, and
1585796c8dcSSimon Schubert should be freed by the caller when it is no longer needed.
1595796c8dcSSimon Schubert
1605796c8dcSSimon Schubert The function <<bfd_minisymbol_to_symbol>> will take a pointer
1615796c8dcSSimon Schubert to a minisymbol, and a pointer to a structure returned by
1625796c8dcSSimon Schubert <<bfd_make_empty_symbol>>, and return a <<asymbol>> structure.
1635796c8dcSSimon Schubert The return value may or may not be the same as the value from
1645796c8dcSSimon Schubert <<bfd_make_empty_symbol>> which was passed in.
1655796c8dcSSimon Schubert
1665796c8dcSSimon Schubert */
1675796c8dcSSimon Schubert
1685796c8dcSSimon Schubert /*
1695796c8dcSSimon Schubert DOCDD
1705796c8dcSSimon Schubert INODE
1715796c8dcSSimon Schubert typedef asymbol, symbol handling functions, Mini Symbols, Symbols
1725796c8dcSSimon Schubert
1735796c8dcSSimon Schubert */
1745796c8dcSSimon Schubert /*
1755796c8dcSSimon Schubert SUBSECTION
1765796c8dcSSimon Schubert typedef asymbol
1775796c8dcSSimon Schubert
1785796c8dcSSimon Schubert An <<asymbol>> has the form:
1795796c8dcSSimon Schubert
1805796c8dcSSimon Schubert */
1815796c8dcSSimon Schubert
1825796c8dcSSimon Schubert /*
1835796c8dcSSimon Schubert CODE_FRAGMENT
1845796c8dcSSimon Schubert
1855796c8dcSSimon Schubert .
1865796c8dcSSimon Schubert .typedef struct bfd_symbol
1875796c8dcSSimon Schubert .{
1885796c8dcSSimon Schubert . {* A pointer to the BFD which owns the symbol. This information
1895796c8dcSSimon Schubert . is necessary so that a back end can work out what additional
1905796c8dcSSimon Schubert . information (invisible to the application writer) is carried
1915796c8dcSSimon Schubert . with the symbol.
1925796c8dcSSimon Schubert .
1935796c8dcSSimon Schubert . This field is *almost* redundant, since you can use section->owner
1945796c8dcSSimon Schubert . instead, except that some symbols point to the global sections
1955796c8dcSSimon Schubert . bfd_{abs,com,und}_section. This could be fixed by making
1965796c8dcSSimon Schubert . these globals be per-bfd (or per-target-flavor). FIXME. *}
1975796c8dcSSimon Schubert . struct bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *}
1985796c8dcSSimon Schubert .
1995796c8dcSSimon Schubert . {* The text of the symbol. The name is left alone, and not copied; the
2005796c8dcSSimon Schubert . application may not alter it. *}
2015796c8dcSSimon Schubert . const char *name;
2025796c8dcSSimon Schubert .
2035796c8dcSSimon Schubert . {* The value of the symbol. This really should be a union of a
2045796c8dcSSimon Schubert . numeric value with a pointer, since some flags indicate that
2055796c8dcSSimon Schubert . a pointer to another symbol is stored here. *}
2065796c8dcSSimon Schubert . symvalue value;
2075796c8dcSSimon Schubert .
2085796c8dcSSimon Schubert . {* Attributes of a symbol. *}
2095796c8dcSSimon Schubert .#define BSF_NO_FLAGS 0x00
2105796c8dcSSimon Schubert .
2115796c8dcSSimon Schubert . {* The symbol has local scope; <<static>> in <<C>>. The value
2125796c8dcSSimon Schubert . is the offset into the section of the data. *}
2135796c8dcSSimon Schubert .#define BSF_LOCAL (1 << 0)
2145796c8dcSSimon Schubert .
2155796c8dcSSimon Schubert . {* The symbol has global scope; initialized data in <<C>>. The
2165796c8dcSSimon Schubert . value is the offset into the section of the data. *}
2175796c8dcSSimon Schubert .#define BSF_GLOBAL (1 << 1)
2185796c8dcSSimon Schubert .
2195796c8dcSSimon Schubert . {* The symbol has global scope and is exported. The value is
2205796c8dcSSimon Schubert . the offset into the section of the data. *}
2215796c8dcSSimon Schubert .#define BSF_EXPORT BSF_GLOBAL {* No real difference. *}
2225796c8dcSSimon Schubert .
2235796c8dcSSimon Schubert . {* A normal C symbol would be one of:
2245796c8dcSSimon Schubert . <<BSF_LOCAL>>, <<BSF_COMMON>>, <<BSF_UNDEFINED>> or
2255796c8dcSSimon Schubert . <<BSF_GLOBAL>>. *}
2265796c8dcSSimon Schubert .
2275796c8dcSSimon Schubert . {* The symbol is a debugging record. The value has an arbitrary
2285796c8dcSSimon Schubert . meaning, unless BSF_DEBUGGING_RELOC is also set. *}
2295796c8dcSSimon Schubert .#define BSF_DEBUGGING (1 << 2)
2305796c8dcSSimon Schubert .
2315796c8dcSSimon Schubert . {* The symbol denotes a function entry point. Used in ELF,
2325796c8dcSSimon Schubert . perhaps others someday. *}
2335796c8dcSSimon Schubert .#define BSF_FUNCTION (1 << 3)
2345796c8dcSSimon Schubert .
2355796c8dcSSimon Schubert . {* Used by the linker. *}
2365796c8dcSSimon Schubert .#define BSF_KEEP (1 << 5)
2375796c8dcSSimon Schubert .#define BSF_KEEP_G (1 << 6)
2385796c8dcSSimon Schubert .
2395796c8dcSSimon Schubert . {* A weak global symbol, overridable without warnings by
2405796c8dcSSimon Schubert . a regular global symbol of the same name. *}
2415796c8dcSSimon Schubert .#define BSF_WEAK (1 << 7)
2425796c8dcSSimon Schubert .
2435796c8dcSSimon Schubert . {* This symbol was created to point to a section, e.g. ELF's
2445796c8dcSSimon Schubert . STT_SECTION symbols. *}
2455796c8dcSSimon Schubert .#define BSF_SECTION_SYM (1 << 8)
2465796c8dcSSimon Schubert .
2475796c8dcSSimon Schubert . {* The symbol used to be a common symbol, but now it is
2485796c8dcSSimon Schubert . allocated. *}
2495796c8dcSSimon Schubert .#define BSF_OLD_COMMON (1 << 9)
2505796c8dcSSimon Schubert .
2515796c8dcSSimon Schubert . {* In some files the type of a symbol sometimes alters its
2525796c8dcSSimon Schubert . location in an output file - ie in coff a <<ISFCN>> symbol
2535796c8dcSSimon Schubert . which is also <<C_EXT>> symbol appears where it was
2545796c8dcSSimon Schubert . declared and not at the end of a section. This bit is set
2555796c8dcSSimon Schubert . by the target BFD part to convey this information. *}
2565796c8dcSSimon Schubert .#define BSF_NOT_AT_END (1 << 10)
2575796c8dcSSimon Schubert .
2585796c8dcSSimon Schubert . {* Signal that the symbol is the label of constructor section. *}
2595796c8dcSSimon Schubert .#define BSF_CONSTRUCTOR (1 << 11)
2605796c8dcSSimon Schubert .
2615796c8dcSSimon Schubert . {* Signal that the symbol is a warning symbol. The name is a
2625796c8dcSSimon Schubert . warning. The name of the next symbol is the one to warn about;
2635796c8dcSSimon Schubert . if a reference is made to a symbol with the same name as the next
2645796c8dcSSimon Schubert . symbol, a warning is issued by the linker. *}
2655796c8dcSSimon Schubert .#define BSF_WARNING (1 << 12)
2665796c8dcSSimon Schubert .
2675796c8dcSSimon Schubert . {* Signal that the symbol is indirect. This symbol is an indirect
2685796c8dcSSimon Schubert . pointer to the symbol with the same name as the next symbol. *}
2695796c8dcSSimon Schubert .#define BSF_INDIRECT (1 << 13)
2705796c8dcSSimon Schubert .
2715796c8dcSSimon Schubert . {* BSF_FILE marks symbols that contain a file name. This is used
2725796c8dcSSimon Schubert . for ELF STT_FILE symbols. *}
2735796c8dcSSimon Schubert .#define BSF_FILE (1 << 14)
2745796c8dcSSimon Schubert .
2755796c8dcSSimon Schubert . {* Symbol is from dynamic linking information. *}
2765796c8dcSSimon Schubert .#define BSF_DYNAMIC (1 << 15)
2775796c8dcSSimon Schubert .
2785796c8dcSSimon Schubert . {* The symbol denotes a data object. Used in ELF, and perhaps
2795796c8dcSSimon Schubert . others someday. *}
2805796c8dcSSimon Schubert .#define BSF_OBJECT (1 << 16)
2815796c8dcSSimon Schubert .
2825796c8dcSSimon Schubert . {* This symbol is a debugging symbol. The value is the offset
2835796c8dcSSimon Schubert . into the section of the data. BSF_DEBUGGING should be set
2845796c8dcSSimon Schubert . as well. *}
2855796c8dcSSimon Schubert .#define BSF_DEBUGGING_RELOC (1 << 17)
2865796c8dcSSimon Schubert .
2875796c8dcSSimon Schubert . {* This symbol is thread local. Used in ELF. *}
2885796c8dcSSimon Schubert .#define BSF_THREAD_LOCAL (1 << 18)
2895796c8dcSSimon Schubert .
2905796c8dcSSimon Schubert . {* This symbol represents a complex relocation expression,
2915796c8dcSSimon Schubert . with the expression tree serialized in the symbol name. *}
2925796c8dcSSimon Schubert .#define BSF_RELC (1 << 19)
2935796c8dcSSimon Schubert .
2945796c8dcSSimon Schubert . {* This symbol represents a signed complex relocation expression,
2955796c8dcSSimon Schubert . with the expression tree serialized in the symbol name. *}
2965796c8dcSSimon Schubert .#define BSF_SRELC (1 << 20)
2975796c8dcSSimon Schubert .
2985796c8dcSSimon Schubert . {* This symbol was created by bfd_get_synthetic_symtab. *}
2995796c8dcSSimon Schubert .#define BSF_SYNTHETIC (1 << 21)
3005796c8dcSSimon Schubert .
3015796c8dcSSimon Schubert . {* This symbol is an indirect code object. Unrelated to BSF_INDIRECT.
3025796c8dcSSimon Schubert . The dynamic linker will compute the value of this symbol by
3035796c8dcSSimon Schubert . calling the function that it points to. BSF_FUNCTION must
3045796c8dcSSimon Schubert . also be also set. *}
3055796c8dcSSimon Schubert .#define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
3065796c8dcSSimon Schubert . {* This symbol is a globally unique data object. The dynamic linker
3075796c8dcSSimon Schubert . will make sure that in the entire process there is just one symbol
3085796c8dcSSimon Schubert . with this name and type in use. BSF_OBJECT must also be set. *}
3095796c8dcSSimon Schubert .#define BSF_GNU_UNIQUE (1 << 23)
3105796c8dcSSimon Schubert .
3115796c8dcSSimon Schubert . flagword flags;
3125796c8dcSSimon Schubert .
3135796c8dcSSimon Schubert . {* A pointer to the section to which this symbol is
3145796c8dcSSimon Schubert . relative. This will always be non NULL, there are special
3155796c8dcSSimon Schubert . sections for undefined and absolute symbols. *}
3165796c8dcSSimon Schubert . struct bfd_section *section;
3175796c8dcSSimon Schubert .
3185796c8dcSSimon Schubert . {* Back end special data. *}
3195796c8dcSSimon Schubert . union
3205796c8dcSSimon Schubert . {
3215796c8dcSSimon Schubert . void *p;
3225796c8dcSSimon Schubert . bfd_vma i;
3235796c8dcSSimon Schubert . }
3245796c8dcSSimon Schubert . udata;
3255796c8dcSSimon Schubert .}
3265796c8dcSSimon Schubert .asymbol;
3275796c8dcSSimon Schubert .
3285796c8dcSSimon Schubert */
3295796c8dcSSimon Schubert
3305796c8dcSSimon Schubert #include "sysdep.h"
3315796c8dcSSimon Schubert #include "bfd.h"
3325796c8dcSSimon Schubert #include "libbfd.h"
3335796c8dcSSimon Schubert #include "safe-ctype.h"
3345796c8dcSSimon Schubert #include "bfdlink.h"
3355796c8dcSSimon Schubert #include "aout/stab_gnu.h"
3365796c8dcSSimon Schubert
3375796c8dcSSimon Schubert /*
3385796c8dcSSimon Schubert DOCDD
3395796c8dcSSimon Schubert INODE
3405796c8dcSSimon Schubert symbol handling functions, , typedef asymbol, Symbols
3415796c8dcSSimon Schubert SUBSECTION
3425796c8dcSSimon Schubert Symbol handling functions
3435796c8dcSSimon Schubert */
3445796c8dcSSimon Schubert
3455796c8dcSSimon Schubert /*
3465796c8dcSSimon Schubert FUNCTION
3475796c8dcSSimon Schubert bfd_get_symtab_upper_bound
3485796c8dcSSimon Schubert
3495796c8dcSSimon Schubert DESCRIPTION
3505796c8dcSSimon Schubert Return the number of bytes required to store a vector of pointers
3515796c8dcSSimon Schubert to <<asymbols>> for all the symbols in the BFD @var{abfd},
3525796c8dcSSimon Schubert including a terminal NULL pointer. If there are no symbols in
3535796c8dcSSimon Schubert the BFD, then return 0. If an error occurs, return -1.
3545796c8dcSSimon Schubert
3555796c8dcSSimon Schubert .#define bfd_get_symtab_upper_bound(abfd) \
3565796c8dcSSimon Schubert . BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
3575796c8dcSSimon Schubert .
3585796c8dcSSimon Schubert */
3595796c8dcSSimon Schubert
3605796c8dcSSimon Schubert /*
3615796c8dcSSimon Schubert FUNCTION
3625796c8dcSSimon Schubert bfd_is_local_label
3635796c8dcSSimon Schubert
3645796c8dcSSimon Schubert SYNOPSIS
3655796c8dcSSimon Schubert bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym);
3665796c8dcSSimon Schubert
3675796c8dcSSimon Schubert DESCRIPTION
3685796c8dcSSimon Schubert Return TRUE if the given symbol @var{sym} in the BFD @var{abfd} is
3695796c8dcSSimon Schubert a compiler generated local label, else return FALSE.
3705796c8dcSSimon Schubert */
3715796c8dcSSimon Schubert
3725796c8dcSSimon Schubert bfd_boolean
bfd_is_local_label(bfd * abfd,asymbol * sym)3735796c8dcSSimon Schubert bfd_is_local_label (bfd *abfd, asymbol *sym)
3745796c8dcSSimon Schubert {
3755796c8dcSSimon Schubert /* The BSF_SECTION_SYM check is needed for IA-64, where every label that
3765796c8dcSSimon Schubert starts with '.' is local. This would accidentally catch section names
3775796c8dcSSimon Schubert if we didn't reject them here. */
3785796c8dcSSimon Schubert if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_FILE | BSF_SECTION_SYM)) != 0)
3795796c8dcSSimon Schubert return FALSE;
3805796c8dcSSimon Schubert if (sym->name == NULL)
3815796c8dcSSimon Schubert return FALSE;
3825796c8dcSSimon Schubert return bfd_is_local_label_name (abfd, sym->name);
3835796c8dcSSimon Schubert }
3845796c8dcSSimon Schubert
3855796c8dcSSimon Schubert /*
3865796c8dcSSimon Schubert FUNCTION
3875796c8dcSSimon Schubert bfd_is_local_label_name
3885796c8dcSSimon Schubert
3895796c8dcSSimon Schubert SYNOPSIS
3905796c8dcSSimon Schubert bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name);
3915796c8dcSSimon Schubert
3925796c8dcSSimon Schubert DESCRIPTION
3935796c8dcSSimon Schubert Return TRUE if a symbol with the name @var{name} in the BFD
3945796c8dcSSimon Schubert @var{abfd} is a compiler generated local label, else return
3955796c8dcSSimon Schubert FALSE. This just checks whether the name has the form of a
3965796c8dcSSimon Schubert local label.
3975796c8dcSSimon Schubert
3985796c8dcSSimon Schubert .#define bfd_is_local_label_name(abfd, name) \
3995796c8dcSSimon Schubert . BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
4005796c8dcSSimon Schubert .
4015796c8dcSSimon Schubert */
4025796c8dcSSimon Schubert
4035796c8dcSSimon Schubert /*
4045796c8dcSSimon Schubert FUNCTION
4055796c8dcSSimon Schubert bfd_is_target_special_symbol
4065796c8dcSSimon Schubert
4075796c8dcSSimon Schubert SYNOPSIS
4085796c8dcSSimon Schubert bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);
4095796c8dcSSimon Schubert
4105796c8dcSSimon Schubert DESCRIPTION
4115796c8dcSSimon Schubert Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something
4125796c8dcSSimon Schubert special to the particular target represented by the BFD. Such symbols
4135796c8dcSSimon Schubert should normally not be mentioned to the user.
4145796c8dcSSimon Schubert
4155796c8dcSSimon Schubert .#define bfd_is_target_special_symbol(abfd, sym) \
4165796c8dcSSimon Schubert . BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
4175796c8dcSSimon Schubert .
4185796c8dcSSimon Schubert */
4195796c8dcSSimon Schubert
4205796c8dcSSimon Schubert /*
4215796c8dcSSimon Schubert FUNCTION
4225796c8dcSSimon Schubert bfd_canonicalize_symtab
4235796c8dcSSimon Schubert
4245796c8dcSSimon Schubert DESCRIPTION
4255796c8dcSSimon Schubert Read the symbols from the BFD @var{abfd}, and fills in
4265796c8dcSSimon Schubert the vector @var{location} with pointers to the symbols and
4275796c8dcSSimon Schubert a trailing NULL.
4285796c8dcSSimon Schubert Return the actual number of symbol pointers, not
4295796c8dcSSimon Schubert including the NULL.
4305796c8dcSSimon Schubert
4315796c8dcSSimon Schubert .#define bfd_canonicalize_symtab(abfd, location) \
4325796c8dcSSimon Schubert . BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location))
4335796c8dcSSimon Schubert .
4345796c8dcSSimon Schubert */
4355796c8dcSSimon Schubert
4365796c8dcSSimon Schubert /*
4375796c8dcSSimon Schubert FUNCTION
4385796c8dcSSimon Schubert bfd_set_symtab
4395796c8dcSSimon Schubert
4405796c8dcSSimon Schubert SYNOPSIS
4415796c8dcSSimon Schubert bfd_boolean bfd_set_symtab
4425796c8dcSSimon Schubert (bfd *abfd, asymbol **location, unsigned int count);
4435796c8dcSSimon Schubert
4445796c8dcSSimon Schubert DESCRIPTION
4455796c8dcSSimon Schubert Arrange that when the output BFD @var{abfd} is closed,
4465796c8dcSSimon Schubert the table @var{location} of @var{count} pointers to symbols
4475796c8dcSSimon Schubert will be written.
4485796c8dcSSimon Schubert */
4495796c8dcSSimon Schubert
4505796c8dcSSimon Schubert bfd_boolean
bfd_set_symtab(bfd * abfd,asymbol ** location,unsigned int symcount)4515796c8dcSSimon Schubert bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int symcount)
4525796c8dcSSimon Schubert {
4535796c8dcSSimon Schubert if (abfd->format != bfd_object || bfd_read_p (abfd))
4545796c8dcSSimon Schubert {
4555796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation);
4565796c8dcSSimon Schubert return FALSE;
4575796c8dcSSimon Schubert }
4585796c8dcSSimon Schubert
4595796c8dcSSimon Schubert bfd_get_outsymbols (abfd) = location;
4605796c8dcSSimon Schubert bfd_get_symcount (abfd) = symcount;
4615796c8dcSSimon Schubert return TRUE;
4625796c8dcSSimon Schubert }
4635796c8dcSSimon Schubert
4645796c8dcSSimon Schubert /*
4655796c8dcSSimon Schubert FUNCTION
4665796c8dcSSimon Schubert bfd_print_symbol_vandf
4675796c8dcSSimon Schubert
4685796c8dcSSimon Schubert SYNOPSIS
4695796c8dcSSimon Schubert void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol);
4705796c8dcSSimon Schubert
4715796c8dcSSimon Schubert DESCRIPTION
4725796c8dcSSimon Schubert Print the value and flags of the @var{symbol} supplied to the
4735796c8dcSSimon Schubert stream @var{file}.
4745796c8dcSSimon Schubert */
4755796c8dcSSimon Schubert void
bfd_print_symbol_vandf(bfd * abfd,void * arg,asymbol * symbol)4765796c8dcSSimon Schubert bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
4775796c8dcSSimon Schubert {
4785796c8dcSSimon Schubert FILE *file = (FILE *) arg;
4795796c8dcSSimon Schubert
4805796c8dcSSimon Schubert flagword type = symbol->flags;
4815796c8dcSSimon Schubert
4825796c8dcSSimon Schubert if (symbol->section != NULL)
4835796c8dcSSimon Schubert bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma);
4845796c8dcSSimon Schubert else
4855796c8dcSSimon Schubert bfd_fprintf_vma (abfd, file, symbol->value);
4865796c8dcSSimon Schubert
4875796c8dcSSimon Schubert /* This presumes that a symbol can not be both BSF_DEBUGGING and
4885796c8dcSSimon Schubert BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and
4895796c8dcSSimon Schubert BSF_OBJECT. */
4905796c8dcSSimon Schubert fprintf (file, " %c%c%c%c%c%c%c",
4915796c8dcSSimon Schubert ((type & BSF_LOCAL)
4925796c8dcSSimon Schubert ? (type & BSF_GLOBAL) ? '!' : 'l'
4935796c8dcSSimon Schubert : (type & BSF_GLOBAL) ? 'g'
4945796c8dcSSimon Schubert : (type & BSF_GNU_UNIQUE) ? 'u' : ' '),
4955796c8dcSSimon Schubert (type & BSF_WEAK) ? 'w' : ' ',
4965796c8dcSSimon Schubert (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
4975796c8dcSSimon Schubert (type & BSF_WARNING) ? 'W' : ' ',
4985796c8dcSSimon Schubert (type & BSF_INDIRECT) ? 'I' : (type & BSF_GNU_INDIRECT_FUNCTION) ? 'i' : ' ',
4995796c8dcSSimon Schubert (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
5005796c8dcSSimon Schubert ((type & BSF_FUNCTION)
5015796c8dcSSimon Schubert ? 'F'
5025796c8dcSSimon Schubert : ((type & BSF_FILE)
5035796c8dcSSimon Schubert ? 'f'
5045796c8dcSSimon Schubert : ((type & BSF_OBJECT) ? 'O' : ' '))));
5055796c8dcSSimon Schubert }
5065796c8dcSSimon Schubert
5075796c8dcSSimon Schubert /*
5085796c8dcSSimon Schubert FUNCTION
5095796c8dcSSimon Schubert bfd_make_empty_symbol
5105796c8dcSSimon Schubert
5115796c8dcSSimon Schubert DESCRIPTION
5125796c8dcSSimon Schubert Create a new <<asymbol>> structure for the BFD @var{abfd}
5135796c8dcSSimon Schubert and return a pointer to it.
5145796c8dcSSimon Schubert
5155796c8dcSSimon Schubert This routine is necessary because each back end has private
5165796c8dcSSimon Schubert information surrounding the <<asymbol>>. Building your own
5175796c8dcSSimon Schubert <<asymbol>> and pointing to it will not create the private
5185796c8dcSSimon Schubert information, and will cause problems later on.
5195796c8dcSSimon Schubert
5205796c8dcSSimon Schubert .#define bfd_make_empty_symbol(abfd) \
5215796c8dcSSimon Schubert . BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
5225796c8dcSSimon Schubert .
5235796c8dcSSimon Schubert */
5245796c8dcSSimon Schubert
5255796c8dcSSimon Schubert /*
5265796c8dcSSimon Schubert FUNCTION
5275796c8dcSSimon Schubert _bfd_generic_make_empty_symbol
5285796c8dcSSimon Schubert
5295796c8dcSSimon Schubert SYNOPSIS
5305796c8dcSSimon Schubert asymbol *_bfd_generic_make_empty_symbol (bfd *);
5315796c8dcSSimon Schubert
5325796c8dcSSimon Schubert DESCRIPTION
5335796c8dcSSimon Schubert Create a new <<asymbol>> structure for the BFD @var{abfd}
5345796c8dcSSimon Schubert and return a pointer to it. Used by core file routines,
5355796c8dcSSimon Schubert binary back-end and anywhere else where no private info
5365796c8dcSSimon Schubert is needed.
5375796c8dcSSimon Schubert */
5385796c8dcSSimon Schubert
5395796c8dcSSimon Schubert asymbol *
_bfd_generic_make_empty_symbol(bfd * abfd)5405796c8dcSSimon Schubert _bfd_generic_make_empty_symbol (bfd *abfd)
5415796c8dcSSimon Schubert {
5425796c8dcSSimon Schubert bfd_size_type amt = sizeof (asymbol);
5435796c8dcSSimon Schubert asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);
5445796c8dcSSimon Schubert if (new_symbol)
5455796c8dcSSimon Schubert new_symbol->the_bfd = abfd;
5465796c8dcSSimon Schubert return new_symbol;
5475796c8dcSSimon Schubert }
5485796c8dcSSimon Schubert
5495796c8dcSSimon Schubert /*
5505796c8dcSSimon Schubert FUNCTION
5515796c8dcSSimon Schubert bfd_make_debug_symbol
5525796c8dcSSimon Schubert
5535796c8dcSSimon Schubert DESCRIPTION
5545796c8dcSSimon Schubert Create a new <<asymbol>> structure for the BFD @var{abfd},
5555796c8dcSSimon Schubert to be used as a debugging symbol. Further details of its use have
5565796c8dcSSimon Schubert yet to be worked out.
5575796c8dcSSimon Schubert
5585796c8dcSSimon Schubert .#define bfd_make_debug_symbol(abfd,ptr,size) \
5595796c8dcSSimon Schubert . BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
5605796c8dcSSimon Schubert .
5615796c8dcSSimon Schubert */
5625796c8dcSSimon Schubert
5635796c8dcSSimon Schubert struct section_to_type
5645796c8dcSSimon Schubert {
5655796c8dcSSimon Schubert const char *section;
5665796c8dcSSimon Schubert char type;
5675796c8dcSSimon Schubert };
5685796c8dcSSimon Schubert
5695796c8dcSSimon Schubert /* Map section names to POSIX/BSD single-character symbol types.
5705796c8dcSSimon Schubert This table is probably incomplete. It is sorted for convenience of
5715796c8dcSSimon Schubert adding entries. Since it is so short, a linear search is used. */
5725796c8dcSSimon Schubert static const struct section_to_type stt[] =
5735796c8dcSSimon Schubert {
5745796c8dcSSimon Schubert {".bss", 'b'},
5755796c8dcSSimon Schubert {"code", 't'}, /* MRI .text */
5765796c8dcSSimon Schubert {".data", 'd'},
5775796c8dcSSimon Schubert {"*DEBUG*", 'N'},
5785796c8dcSSimon Schubert {".debug", 'N'}, /* MSVC's .debug (non-standard debug syms) */
5795796c8dcSSimon Schubert {".drectve", 'i'}, /* MSVC's .drective section */
5805796c8dcSSimon Schubert {".edata", 'e'}, /* MSVC's .edata (export) section */
5815796c8dcSSimon Schubert {".fini", 't'}, /* ELF fini section */
5825796c8dcSSimon Schubert {".idata", 'i'}, /* MSVC's .idata (import) section */
5835796c8dcSSimon Schubert {".init", 't'}, /* ELF init section */
5845796c8dcSSimon Schubert {".pdata", 'p'}, /* MSVC's .pdata (stack unwind) section */
5855796c8dcSSimon Schubert {".rdata", 'r'}, /* Read only data. */
5865796c8dcSSimon Schubert {".rodata", 'r'}, /* Read only data. */
5875796c8dcSSimon Schubert {".sbss", 's'}, /* Small BSS (uninitialized data). */
5885796c8dcSSimon Schubert {".scommon", 'c'}, /* Small common. */
5895796c8dcSSimon Schubert {".sdata", 'g'}, /* Small initialized data. */
5905796c8dcSSimon Schubert {".text", 't'},
5915796c8dcSSimon Schubert {"vars", 'd'}, /* MRI .data */
5925796c8dcSSimon Schubert {"zerovars", 'b'}, /* MRI .bss */
5935796c8dcSSimon Schubert {0, 0}
5945796c8dcSSimon Schubert };
5955796c8dcSSimon Schubert
5965796c8dcSSimon Schubert /* Return the single-character symbol type corresponding to
5975796c8dcSSimon Schubert section S, or '?' for an unknown COFF section.
5985796c8dcSSimon Schubert
5995796c8dcSSimon Schubert Check for any leading string which matches, so .text5 returns
6005796c8dcSSimon Schubert 't' as well as .text */
6015796c8dcSSimon Schubert
6025796c8dcSSimon Schubert static char
coff_section_type(const char * s)6035796c8dcSSimon Schubert coff_section_type (const char *s)
6045796c8dcSSimon Schubert {
6055796c8dcSSimon Schubert const struct section_to_type *t;
6065796c8dcSSimon Schubert
6075796c8dcSSimon Schubert for (t = &stt[0]; t->section; t++)
6085796c8dcSSimon Schubert if (!strncmp (s, t->section, strlen (t->section)))
6095796c8dcSSimon Schubert return t->type;
6105796c8dcSSimon Schubert
6115796c8dcSSimon Schubert return '?';
6125796c8dcSSimon Schubert }
6135796c8dcSSimon Schubert
6145796c8dcSSimon Schubert /* Return the single-character symbol type corresponding to section
6155796c8dcSSimon Schubert SECTION, or '?' for an unknown section. This uses section flags to
6165796c8dcSSimon Schubert identify sections.
6175796c8dcSSimon Schubert
6185796c8dcSSimon Schubert FIXME These types are unhandled: c, i, e, p. If we handled these also,
6195796c8dcSSimon Schubert we could perhaps obsolete coff_section_type. */
6205796c8dcSSimon Schubert
6215796c8dcSSimon Schubert static char
decode_section_type(const struct bfd_section * section)6225796c8dcSSimon Schubert decode_section_type (const struct bfd_section *section)
6235796c8dcSSimon Schubert {
6245796c8dcSSimon Schubert if (section->flags & SEC_CODE)
6255796c8dcSSimon Schubert return 't';
6265796c8dcSSimon Schubert if (section->flags & SEC_DATA)
6275796c8dcSSimon Schubert {
6285796c8dcSSimon Schubert if (section->flags & SEC_READONLY)
6295796c8dcSSimon Schubert return 'r';
6305796c8dcSSimon Schubert else if (section->flags & SEC_SMALL_DATA)
6315796c8dcSSimon Schubert return 'g';
6325796c8dcSSimon Schubert else
6335796c8dcSSimon Schubert return 'd';
6345796c8dcSSimon Schubert }
6355796c8dcSSimon Schubert if ((section->flags & SEC_HAS_CONTENTS) == 0)
6365796c8dcSSimon Schubert {
6375796c8dcSSimon Schubert if (section->flags & SEC_SMALL_DATA)
6385796c8dcSSimon Schubert return 's';
6395796c8dcSSimon Schubert else
6405796c8dcSSimon Schubert return 'b';
6415796c8dcSSimon Schubert }
6425796c8dcSSimon Schubert if (section->flags & SEC_DEBUGGING)
6435796c8dcSSimon Schubert return 'N';
6445796c8dcSSimon Schubert if ((section->flags & SEC_HAS_CONTENTS) && (section->flags & SEC_READONLY))
6455796c8dcSSimon Schubert return 'n';
6465796c8dcSSimon Schubert
6475796c8dcSSimon Schubert return '?';
6485796c8dcSSimon Schubert }
6495796c8dcSSimon Schubert
6505796c8dcSSimon Schubert /*
6515796c8dcSSimon Schubert FUNCTION
6525796c8dcSSimon Schubert bfd_decode_symclass
6535796c8dcSSimon Schubert
6545796c8dcSSimon Schubert DESCRIPTION
6555796c8dcSSimon Schubert Return a character corresponding to the symbol
6565796c8dcSSimon Schubert class of @var{symbol}, or '?' for an unknown class.
6575796c8dcSSimon Schubert
6585796c8dcSSimon Schubert SYNOPSIS
6595796c8dcSSimon Schubert int bfd_decode_symclass (asymbol *symbol);
6605796c8dcSSimon Schubert */
6615796c8dcSSimon Schubert int
bfd_decode_symclass(asymbol * symbol)6625796c8dcSSimon Schubert bfd_decode_symclass (asymbol *symbol)
6635796c8dcSSimon Schubert {
6645796c8dcSSimon Schubert char c;
6655796c8dcSSimon Schubert
6665796c8dcSSimon Schubert if (symbol->section && bfd_is_com_section (symbol->section))
6675796c8dcSSimon Schubert return 'C';
6685796c8dcSSimon Schubert if (bfd_is_und_section (symbol->section))
6695796c8dcSSimon Schubert {
6705796c8dcSSimon Schubert if (symbol->flags & BSF_WEAK)
6715796c8dcSSimon Schubert {
6725796c8dcSSimon Schubert /* If weak, determine if it's specifically an object
6735796c8dcSSimon Schubert or non-object weak. */
6745796c8dcSSimon Schubert if (symbol->flags & BSF_OBJECT)
6755796c8dcSSimon Schubert return 'v';
6765796c8dcSSimon Schubert else
6775796c8dcSSimon Schubert return 'w';
6785796c8dcSSimon Schubert }
6795796c8dcSSimon Schubert else
6805796c8dcSSimon Schubert return 'U';
6815796c8dcSSimon Schubert }
6825796c8dcSSimon Schubert if (bfd_is_ind_section (symbol->section))
6835796c8dcSSimon Schubert return 'I';
6845796c8dcSSimon Schubert if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION)
6855796c8dcSSimon Schubert return 'i';
6865796c8dcSSimon Schubert if (symbol->flags & BSF_WEAK)
6875796c8dcSSimon Schubert {
6885796c8dcSSimon Schubert /* If weak, determine if it's specifically an object
6895796c8dcSSimon Schubert or non-object weak. */
6905796c8dcSSimon Schubert if (symbol->flags & BSF_OBJECT)
6915796c8dcSSimon Schubert return 'V';
6925796c8dcSSimon Schubert else
6935796c8dcSSimon Schubert return 'W';
6945796c8dcSSimon Schubert }
6955796c8dcSSimon Schubert if (symbol->flags & BSF_GNU_UNIQUE)
6965796c8dcSSimon Schubert return 'u';
6975796c8dcSSimon Schubert if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
6985796c8dcSSimon Schubert return '?';
6995796c8dcSSimon Schubert
7005796c8dcSSimon Schubert if (bfd_is_abs_section (symbol->section))
7015796c8dcSSimon Schubert c = 'a';
7025796c8dcSSimon Schubert else if (symbol->section)
7035796c8dcSSimon Schubert {
7045796c8dcSSimon Schubert c = coff_section_type (symbol->section->name);
7055796c8dcSSimon Schubert if (c == '?')
7065796c8dcSSimon Schubert c = decode_section_type (symbol->section);
7075796c8dcSSimon Schubert }
7085796c8dcSSimon Schubert else
7095796c8dcSSimon Schubert return '?';
7105796c8dcSSimon Schubert if (symbol->flags & BSF_GLOBAL)
7115796c8dcSSimon Schubert c = TOUPPER (c);
7125796c8dcSSimon Schubert return c;
7135796c8dcSSimon Schubert
7145796c8dcSSimon Schubert /* We don't have to handle these cases just yet, but we will soon:
7155796c8dcSSimon Schubert N_SETV: 'v';
7165796c8dcSSimon Schubert N_SETA: 'l';
7175796c8dcSSimon Schubert N_SETT: 'x';
7185796c8dcSSimon Schubert N_SETD: 'z';
7195796c8dcSSimon Schubert N_SETB: 's';
7205796c8dcSSimon Schubert N_INDR: 'i';
7215796c8dcSSimon Schubert */
7225796c8dcSSimon Schubert }
7235796c8dcSSimon Schubert
7245796c8dcSSimon Schubert /*
7255796c8dcSSimon Schubert FUNCTION
7265796c8dcSSimon Schubert bfd_is_undefined_symclass
7275796c8dcSSimon Schubert
7285796c8dcSSimon Schubert DESCRIPTION
7295796c8dcSSimon Schubert Returns non-zero if the class symbol returned by
7305796c8dcSSimon Schubert bfd_decode_symclass represents an undefined symbol.
7315796c8dcSSimon Schubert Returns zero otherwise.
7325796c8dcSSimon Schubert
7335796c8dcSSimon Schubert SYNOPSIS
7345796c8dcSSimon Schubert bfd_boolean bfd_is_undefined_symclass (int symclass);
7355796c8dcSSimon Schubert */
7365796c8dcSSimon Schubert
7375796c8dcSSimon Schubert bfd_boolean
bfd_is_undefined_symclass(int symclass)7385796c8dcSSimon Schubert bfd_is_undefined_symclass (int symclass)
7395796c8dcSSimon Schubert {
7405796c8dcSSimon Schubert return symclass == 'U' || symclass == 'w' || symclass == 'v';
7415796c8dcSSimon Schubert }
7425796c8dcSSimon Schubert
7435796c8dcSSimon Schubert /*
7445796c8dcSSimon Schubert FUNCTION
7455796c8dcSSimon Schubert bfd_symbol_info
7465796c8dcSSimon Schubert
7475796c8dcSSimon Schubert DESCRIPTION
7485796c8dcSSimon Schubert Fill in the basic info about symbol that nm needs.
7495796c8dcSSimon Schubert Additional info may be added by the back-ends after
7505796c8dcSSimon Schubert calling this function.
7515796c8dcSSimon Schubert
7525796c8dcSSimon Schubert SYNOPSIS
7535796c8dcSSimon Schubert void bfd_symbol_info (asymbol *symbol, symbol_info *ret);
7545796c8dcSSimon Schubert */
7555796c8dcSSimon Schubert
7565796c8dcSSimon Schubert void
bfd_symbol_info(asymbol * symbol,symbol_info * ret)7575796c8dcSSimon Schubert bfd_symbol_info (asymbol *symbol, symbol_info *ret)
7585796c8dcSSimon Schubert {
7595796c8dcSSimon Schubert ret->type = bfd_decode_symclass (symbol);
7605796c8dcSSimon Schubert
7615796c8dcSSimon Schubert if (bfd_is_undefined_symclass (ret->type))
7625796c8dcSSimon Schubert ret->value = 0;
7635796c8dcSSimon Schubert else
7645796c8dcSSimon Schubert ret->value = symbol->value + symbol->section->vma;
7655796c8dcSSimon Schubert
7665796c8dcSSimon Schubert ret->name = symbol->name;
7675796c8dcSSimon Schubert }
7685796c8dcSSimon Schubert
7695796c8dcSSimon Schubert /*
7705796c8dcSSimon Schubert FUNCTION
7715796c8dcSSimon Schubert bfd_copy_private_symbol_data
7725796c8dcSSimon Schubert
7735796c8dcSSimon Schubert SYNOPSIS
7745796c8dcSSimon Schubert bfd_boolean bfd_copy_private_symbol_data
7755796c8dcSSimon Schubert (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
7765796c8dcSSimon Schubert
7775796c8dcSSimon Schubert DESCRIPTION
7785796c8dcSSimon Schubert Copy private symbol information from @var{isym} in the BFD
7795796c8dcSSimon Schubert @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}.
7805796c8dcSSimon Schubert Return <<TRUE>> on success, <<FALSE>> on error. Possible error
7815796c8dcSSimon Schubert returns are:
7825796c8dcSSimon Schubert
7835796c8dcSSimon Schubert o <<bfd_error_no_memory>> -
7845796c8dcSSimon Schubert Not enough memory exists to create private data for @var{osec}.
7855796c8dcSSimon Schubert
7865796c8dcSSimon Schubert .#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
7875796c8dcSSimon Schubert . BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
7885796c8dcSSimon Schubert . (ibfd, isymbol, obfd, osymbol))
7895796c8dcSSimon Schubert .
7905796c8dcSSimon Schubert */
7915796c8dcSSimon Schubert
7925796c8dcSSimon Schubert /* The generic version of the function which returns mini symbols.
7935796c8dcSSimon Schubert This is used when the backend does not provide a more efficient
7945796c8dcSSimon Schubert version. It just uses BFD asymbol structures as mini symbols. */
7955796c8dcSSimon Schubert
7965796c8dcSSimon Schubert long
_bfd_generic_read_minisymbols(bfd * abfd,bfd_boolean dynamic,void ** minisymsp,unsigned int * sizep)7975796c8dcSSimon Schubert _bfd_generic_read_minisymbols (bfd *abfd,
7985796c8dcSSimon Schubert bfd_boolean dynamic,
7995796c8dcSSimon Schubert void **minisymsp,
8005796c8dcSSimon Schubert unsigned int *sizep)
8015796c8dcSSimon Schubert {
8025796c8dcSSimon Schubert long storage;
8035796c8dcSSimon Schubert asymbol **syms = NULL;
8045796c8dcSSimon Schubert long symcount;
8055796c8dcSSimon Schubert
8065796c8dcSSimon Schubert if (dynamic)
8075796c8dcSSimon Schubert storage = bfd_get_dynamic_symtab_upper_bound (abfd);
8085796c8dcSSimon Schubert else
8095796c8dcSSimon Schubert storage = bfd_get_symtab_upper_bound (abfd);
8105796c8dcSSimon Schubert if (storage < 0)
8115796c8dcSSimon Schubert goto error_return;
8125796c8dcSSimon Schubert if (storage == 0)
8135796c8dcSSimon Schubert return 0;
8145796c8dcSSimon Schubert
8155796c8dcSSimon Schubert syms = (asymbol **) bfd_malloc (storage);
8165796c8dcSSimon Schubert if (syms == NULL)
8175796c8dcSSimon Schubert goto error_return;
8185796c8dcSSimon Schubert
8195796c8dcSSimon Schubert if (dynamic)
8205796c8dcSSimon Schubert symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
8215796c8dcSSimon Schubert else
8225796c8dcSSimon Schubert symcount = bfd_canonicalize_symtab (abfd, syms);
8235796c8dcSSimon Schubert if (symcount < 0)
8245796c8dcSSimon Schubert goto error_return;
8255796c8dcSSimon Schubert
8265796c8dcSSimon Schubert *minisymsp = syms;
8275796c8dcSSimon Schubert *sizep = sizeof (asymbol *);
8285796c8dcSSimon Schubert return symcount;
8295796c8dcSSimon Schubert
8305796c8dcSSimon Schubert error_return:
8315796c8dcSSimon Schubert bfd_set_error (bfd_error_no_symbols);
8325796c8dcSSimon Schubert if (syms != NULL)
8335796c8dcSSimon Schubert free (syms);
8345796c8dcSSimon Schubert return -1;
8355796c8dcSSimon Schubert }
8365796c8dcSSimon Schubert
8375796c8dcSSimon Schubert /* The generic version of the function which converts a minisymbol to
8385796c8dcSSimon Schubert an asymbol. We don't worry about the sym argument we are passed;
8395796c8dcSSimon Schubert we just return the asymbol the minisymbol points to. */
8405796c8dcSSimon Schubert
8415796c8dcSSimon Schubert asymbol *
_bfd_generic_minisymbol_to_symbol(bfd * abfd ATTRIBUTE_UNUSED,bfd_boolean dynamic ATTRIBUTE_UNUSED,const void * minisym,asymbol * sym ATTRIBUTE_UNUSED)8425796c8dcSSimon Schubert _bfd_generic_minisymbol_to_symbol (bfd *abfd ATTRIBUTE_UNUSED,
8435796c8dcSSimon Schubert bfd_boolean dynamic ATTRIBUTE_UNUSED,
8445796c8dcSSimon Schubert const void *minisym,
8455796c8dcSSimon Schubert asymbol *sym ATTRIBUTE_UNUSED)
8465796c8dcSSimon Schubert {
8475796c8dcSSimon Schubert return *(asymbol **) minisym;
8485796c8dcSSimon Schubert }
8495796c8dcSSimon Schubert
8505796c8dcSSimon Schubert /* Look through stabs debugging information in .stab and .stabstr
8515796c8dcSSimon Schubert sections to find the source file and line closest to a desired
8525796c8dcSSimon Schubert location. This is used by COFF and ELF targets. It sets *pfound
8535796c8dcSSimon Schubert to TRUE if it finds some information. The *pinfo field is used to
8545796c8dcSSimon Schubert pass cached information in and out of this routine; this first time
8555796c8dcSSimon Schubert the routine is called for a BFD, *pinfo should be NULL. The value
8565796c8dcSSimon Schubert placed in *pinfo should be saved with the BFD, and passed back each
8575796c8dcSSimon Schubert time this function is called. */
8585796c8dcSSimon Schubert
8595796c8dcSSimon Schubert /* We use a cache by default. */
8605796c8dcSSimon Schubert
8615796c8dcSSimon Schubert #define ENABLE_CACHING
8625796c8dcSSimon Schubert
8635796c8dcSSimon Schubert /* We keep an array of indexentry structures to record where in the
8645796c8dcSSimon Schubert stabs section we should look to find line number information for a
8655796c8dcSSimon Schubert particular address. */
8665796c8dcSSimon Schubert
8675796c8dcSSimon Schubert struct indexentry
8685796c8dcSSimon Schubert {
8695796c8dcSSimon Schubert bfd_vma val;
8705796c8dcSSimon Schubert bfd_byte *stab;
8715796c8dcSSimon Schubert bfd_byte *str;
8725796c8dcSSimon Schubert char *directory_name;
8735796c8dcSSimon Schubert char *file_name;
8745796c8dcSSimon Schubert char *function_name;
8755796c8dcSSimon Schubert };
8765796c8dcSSimon Schubert
8775796c8dcSSimon Schubert /* Compare two indexentry structures. This is called via qsort. */
8785796c8dcSSimon Schubert
8795796c8dcSSimon Schubert static int
cmpindexentry(const void * a,const void * b)8805796c8dcSSimon Schubert cmpindexentry (const void *a, const void *b)
8815796c8dcSSimon Schubert {
8825796c8dcSSimon Schubert const struct indexentry *contestantA = (const struct indexentry *) a;
8835796c8dcSSimon Schubert const struct indexentry *contestantB = (const struct indexentry *) b;
8845796c8dcSSimon Schubert
8855796c8dcSSimon Schubert if (contestantA->val < contestantB->val)
8865796c8dcSSimon Schubert return -1;
8875796c8dcSSimon Schubert else if (contestantA->val > contestantB->val)
8885796c8dcSSimon Schubert return 1;
8895796c8dcSSimon Schubert else
8905796c8dcSSimon Schubert return 0;
8915796c8dcSSimon Schubert }
8925796c8dcSSimon Schubert
8935796c8dcSSimon Schubert /* A pointer to this structure is stored in *pinfo. */
8945796c8dcSSimon Schubert
8955796c8dcSSimon Schubert struct stab_find_info
8965796c8dcSSimon Schubert {
8975796c8dcSSimon Schubert /* The .stab section. */
8985796c8dcSSimon Schubert asection *stabsec;
8995796c8dcSSimon Schubert /* The .stabstr section. */
9005796c8dcSSimon Schubert asection *strsec;
9015796c8dcSSimon Schubert /* The contents of the .stab section. */
9025796c8dcSSimon Schubert bfd_byte *stabs;
9035796c8dcSSimon Schubert /* The contents of the .stabstr section. */
9045796c8dcSSimon Schubert bfd_byte *strs;
9055796c8dcSSimon Schubert
9065796c8dcSSimon Schubert /* A table that indexes stabs by memory address. */
9075796c8dcSSimon Schubert struct indexentry *indextable;
9085796c8dcSSimon Schubert /* The number of entries in indextable. */
9095796c8dcSSimon Schubert int indextablesize;
9105796c8dcSSimon Schubert
9115796c8dcSSimon Schubert #ifdef ENABLE_CACHING
9125796c8dcSSimon Schubert /* Cached values to restart quickly. */
9135796c8dcSSimon Schubert struct indexentry *cached_indexentry;
9145796c8dcSSimon Schubert bfd_vma cached_offset;
9155796c8dcSSimon Schubert bfd_byte *cached_stab;
9165796c8dcSSimon Schubert char *cached_file_name;
9175796c8dcSSimon Schubert #endif
9185796c8dcSSimon Schubert
9195796c8dcSSimon Schubert /* Saved ptr to malloc'ed filename. */
9205796c8dcSSimon Schubert char *filename;
9215796c8dcSSimon Schubert };
9225796c8dcSSimon Schubert
9235796c8dcSSimon Schubert bfd_boolean
_bfd_stab_section_find_nearest_line(bfd * abfd,asymbol ** symbols,asection * section,bfd_vma offset,bfd_boolean * pfound,const char ** pfilename,const char ** pfnname,unsigned int * pline,void ** pinfo)9245796c8dcSSimon Schubert _bfd_stab_section_find_nearest_line (bfd *abfd,
9255796c8dcSSimon Schubert asymbol **symbols,
9265796c8dcSSimon Schubert asection *section,
9275796c8dcSSimon Schubert bfd_vma offset,
9285796c8dcSSimon Schubert bfd_boolean *pfound,
9295796c8dcSSimon Schubert const char **pfilename,
9305796c8dcSSimon Schubert const char **pfnname,
9315796c8dcSSimon Schubert unsigned int *pline,
9325796c8dcSSimon Schubert void **pinfo)
9335796c8dcSSimon Schubert {
9345796c8dcSSimon Schubert struct stab_find_info *info;
9355796c8dcSSimon Schubert bfd_size_type stabsize, strsize;
9365796c8dcSSimon Schubert bfd_byte *stab, *str;
9375796c8dcSSimon Schubert bfd_byte *last_stab = NULL;
9385796c8dcSSimon Schubert bfd_size_type stroff;
9395796c8dcSSimon Schubert struct indexentry *indexentry;
9405796c8dcSSimon Schubert char *file_name;
9415796c8dcSSimon Schubert char *directory_name;
9425796c8dcSSimon Schubert int saw_fun;
9435796c8dcSSimon Schubert bfd_boolean saw_line, saw_func;
9445796c8dcSSimon Schubert
9455796c8dcSSimon Schubert *pfound = FALSE;
9465796c8dcSSimon Schubert *pfilename = bfd_get_filename (abfd);
9475796c8dcSSimon Schubert *pfnname = NULL;
9485796c8dcSSimon Schubert *pline = 0;
9495796c8dcSSimon Schubert
9505796c8dcSSimon Schubert /* Stabs entries use a 12 byte format:
9515796c8dcSSimon Schubert 4 byte string table index
9525796c8dcSSimon Schubert 1 byte stab type
9535796c8dcSSimon Schubert 1 byte stab other field
9545796c8dcSSimon Schubert 2 byte stab desc field
9555796c8dcSSimon Schubert 4 byte stab value
9565796c8dcSSimon Schubert FIXME: This will have to change for a 64 bit object format.
9575796c8dcSSimon Schubert
9585796c8dcSSimon Schubert The stabs symbols are divided into compilation units. For the
9595796c8dcSSimon Schubert first entry in each unit, the type of 0, the value is the length
9605796c8dcSSimon Schubert of the string table for this unit, and the desc field is the
9615796c8dcSSimon Schubert number of stabs symbols for this unit. */
9625796c8dcSSimon Schubert
9635796c8dcSSimon Schubert #define STRDXOFF (0)
9645796c8dcSSimon Schubert #define TYPEOFF (4)
9655796c8dcSSimon Schubert #define OTHEROFF (5)
9665796c8dcSSimon Schubert #define DESCOFF (6)
9675796c8dcSSimon Schubert #define VALOFF (8)
9685796c8dcSSimon Schubert #define STABSIZE (12)
9695796c8dcSSimon Schubert
9705796c8dcSSimon Schubert info = (struct stab_find_info *) *pinfo;
9715796c8dcSSimon Schubert if (info != NULL)
9725796c8dcSSimon Schubert {
9735796c8dcSSimon Schubert if (info->stabsec == NULL || info->strsec == NULL)
9745796c8dcSSimon Schubert {
9755796c8dcSSimon Schubert /* No stabs debugging information. */
9765796c8dcSSimon Schubert return TRUE;
9775796c8dcSSimon Schubert }
9785796c8dcSSimon Schubert
9795796c8dcSSimon Schubert stabsize = (info->stabsec->rawsize
9805796c8dcSSimon Schubert ? info->stabsec->rawsize
9815796c8dcSSimon Schubert : info->stabsec->size);
9825796c8dcSSimon Schubert strsize = (info->strsec->rawsize
9835796c8dcSSimon Schubert ? info->strsec->rawsize
9845796c8dcSSimon Schubert : info->strsec->size);
9855796c8dcSSimon Schubert }
9865796c8dcSSimon Schubert else
9875796c8dcSSimon Schubert {
9885796c8dcSSimon Schubert long reloc_size, reloc_count;
9895796c8dcSSimon Schubert arelent **reloc_vector;
9905796c8dcSSimon Schubert int i;
9915796c8dcSSimon Schubert char *name;
9925796c8dcSSimon Schubert char *function_name;
9935796c8dcSSimon Schubert bfd_size_type amt = sizeof *info;
9945796c8dcSSimon Schubert
9955796c8dcSSimon Schubert info = (struct stab_find_info *) bfd_zalloc (abfd, amt);
9965796c8dcSSimon Schubert if (info == NULL)
9975796c8dcSSimon Schubert return FALSE;
9985796c8dcSSimon Schubert
9995796c8dcSSimon Schubert /* FIXME: When using the linker --split-by-file or
10005796c8dcSSimon Schubert --split-by-reloc options, it is possible for the .stab and
10015796c8dcSSimon Schubert .stabstr sections to be split. We should handle that. */
10025796c8dcSSimon Schubert
10035796c8dcSSimon Schubert info->stabsec = bfd_get_section_by_name (abfd, ".stab");
10045796c8dcSSimon Schubert info->strsec = bfd_get_section_by_name (abfd, ".stabstr");
10055796c8dcSSimon Schubert
10065796c8dcSSimon Schubert if (info->stabsec == NULL || info->strsec == NULL)
10075796c8dcSSimon Schubert {
10085796c8dcSSimon Schubert /* Try SOM section names. */
10095796c8dcSSimon Schubert info->stabsec = bfd_get_section_by_name (abfd, "$GDB_SYMBOLS$");
10105796c8dcSSimon Schubert info->strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
10115796c8dcSSimon Schubert
10125796c8dcSSimon Schubert if (info->stabsec == NULL || info->strsec == NULL)
10135796c8dcSSimon Schubert {
10145796c8dcSSimon Schubert /* No stabs debugging information. Set *pinfo so that we
10155796c8dcSSimon Schubert can return quickly in the info != NULL case above. */
10165796c8dcSSimon Schubert *pinfo = info;
10175796c8dcSSimon Schubert return TRUE;
10185796c8dcSSimon Schubert }
10195796c8dcSSimon Schubert }
10205796c8dcSSimon Schubert
10215796c8dcSSimon Schubert stabsize = (info->stabsec->rawsize
10225796c8dcSSimon Schubert ? info->stabsec->rawsize
10235796c8dcSSimon Schubert : info->stabsec->size);
10245796c8dcSSimon Schubert strsize = (info->strsec->rawsize
10255796c8dcSSimon Schubert ? info->strsec->rawsize
10265796c8dcSSimon Schubert : info->strsec->size);
10275796c8dcSSimon Schubert
10285796c8dcSSimon Schubert info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize);
10295796c8dcSSimon Schubert info->strs = (bfd_byte *) bfd_alloc (abfd, strsize);
10305796c8dcSSimon Schubert if (info->stabs == NULL || info->strs == NULL)
10315796c8dcSSimon Schubert return FALSE;
10325796c8dcSSimon Schubert
10335796c8dcSSimon Schubert if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs,
10345796c8dcSSimon Schubert 0, stabsize)
10355796c8dcSSimon Schubert || ! bfd_get_section_contents (abfd, info->strsec, info->strs,
10365796c8dcSSimon Schubert 0, strsize))
10375796c8dcSSimon Schubert return FALSE;
10385796c8dcSSimon Schubert
10395796c8dcSSimon Schubert /* If this is a relocatable object file, we have to relocate
10405796c8dcSSimon Schubert the entries in .stab. This should always be simple 32 bit
10415796c8dcSSimon Schubert relocations against symbols defined in this object file, so
10425796c8dcSSimon Schubert this should be no big deal. */
10435796c8dcSSimon Schubert reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
10445796c8dcSSimon Schubert if (reloc_size < 0)
10455796c8dcSSimon Schubert return FALSE;
10465796c8dcSSimon Schubert reloc_vector = (arelent **) bfd_malloc (reloc_size);
10475796c8dcSSimon Schubert if (reloc_vector == NULL && reloc_size != 0)
10485796c8dcSSimon Schubert return FALSE;
10495796c8dcSSimon Schubert reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
10505796c8dcSSimon Schubert symbols);
10515796c8dcSSimon Schubert if (reloc_count < 0)
10525796c8dcSSimon Schubert {
10535796c8dcSSimon Schubert if (reloc_vector != NULL)
10545796c8dcSSimon Schubert free (reloc_vector);
10555796c8dcSSimon Schubert return FALSE;
10565796c8dcSSimon Schubert }
10575796c8dcSSimon Schubert if (reloc_count > 0)
10585796c8dcSSimon Schubert {
10595796c8dcSSimon Schubert arelent **pr;
10605796c8dcSSimon Schubert
10615796c8dcSSimon Schubert for (pr = reloc_vector; *pr != NULL; pr++)
10625796c8dcSSimon Schubert {
10635796c8dcSSimon Schubert arelent *r;
10645796c8dcSSimon Schubert unsigned long val;
10655796c8dcSSimon Schubert asymbol *sym;
10665796c8dcSSimon Schubert
10675796c8dcSSimon Schubert r = *pr;
10685796c8dcSSimon Schubert /* Ignore R_*_NONE relocs. */
10695796c8dcSSimon Schubert if (r->howto->dst_mask == 0)
10705796c8dcSSimon Schubert continue;
10715796c8dcSSimon Schubert
10725796c8dcSSimon Schubert if (r->howto->rightshift != 0
10735796c8dcSSimon Schubert || r->howto->size != 2
10745796c8dcSSimon Schubert || r->howto->bitsize != 32
10755796c8dcSSimon Schubert || r->howto->pc_relative
10765796c8dcSSimon Schubert || r->howto->bitpos != 0
10775796c8dcSSimon Schubert || r->howto->dst_mask != 0xffffffff)
10785796c8dcSSimon Schubert {
10795796c8dcSSimon Schubert (*_bfd_error_handler)
10805796c8dcSSimon Schubert (_("Unsupported .stab relocation"));
10815796c8dcSSimon Schubert bfd_set_error (bfd_error_invalid_operation);
10825796c8dcSSimon Schubert if (reloc_vector != NULL)
10835796c8dcSSimon Schubert free (reloc_vector);
10845796c8dcSSimon Schubert return FALSE;
10855796c8dcSSimon Schubert }
10865796c8dcSSimon Schubert
10875796c8dcSSimon Schubert val = bfd_get_32 (abfd, info->stabs + r->address);
10885796c8dcSSimon Schubert val &= r->howto->src_mask;
10895796c8dcSSimon Schubert sym = *r->sym_ptr_ptr;
10905796c8dcSSimon Schubert val += sym->value + sym->section->vma + r->addend;
10915796c8dcSSimon Schubert bfd_put_32 (abfd, (bfd_vma) val, info->stabs + r->address);
10925796c8dcSSimon Schubert }
10935796c8dcSSimon Schubert }
10945796c8dcSSimon Schubert
10955796c8dcSSimon Schubert if (reloc_vector != NULL)
10965796c8dcSSimon Schubert free (reloc_vector);
10975796c8dcSSimon Schubert
10985796c8dcSSimon Schubert /* First time through this function, build a table matching
10995796c8dcSSimon Schubert function VM addresses to stabs, then sort based on starting
11005796c8dcSSimon Schubert VM address. Do this in two passes: once to count how many
11015796c8dcSSimon Schubert table entries we'll need, and a second to actually build the
11025796c8dcSSimon Schubert table. */
11035796c8dcSSimon Schubert
11045796c8dcSSimon Schubert info->indextablesize = 0;
11055796c8dcSSimon Schubert saw_fun = 1;
11065796c8dcSSimon Schubert for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
11075796c8dcSSimon Schubert {
11085796c8dcSSimon Schubert if (stab[TYPEOFF] == (bfd_byte) N_SO)
11095796c8dcSSimon Schubert {
11105796c8dcSSimon Schubert /* N_SO with null name indicates EOF */
11115796c8dcSSimon Schubert if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
11125796c8dcSSimon Schubert continue;
11135796c8dcSSimon Schubert
11145796c8dcSSimon Schubert /* if we did not see a function def, leave space for one. */
11155796c8dcSSimon Schubert if (saw_fun == 0)
11165796c8dcSSimon Schubert ++info->indextablesize;
11175796c8dcSSimon Schubert
11185796c8dcSSimon Schubert saw_fun = 0;
11195796c8dcSSimon Schubert
11205796c8dcSSimon Schubert /* two N_SO's in a row is a filename and directory. Skip */
11215796c8dcSSimon Schubert if (stab + STABSIZE < info->stabs + stabsize
11225796c8dcSSimon Schubert && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
11235796c8dcSSimon Schubert {
11245796c8dcSSimon Schubert stab += STABSIZE;
11255796c8dcSSimon Schubert }
11265796c8dcSSimon Schubert }
11275796c8dcSSimon Schubert else if (stab[TYPEOFF] == (bfd_byte) N_FUN)
11285796c8dcSSimon Schubert {
11295796c8dcSSimon Schubert saw_fun = 1;
11305796c8dcSSimon Schubert ++info->indextablesize;
11315796c8dcSSimon Schubert }
11325796c8dcSSimon Schubert }
11335796c8dcSSimon Schubert
11345796c8dcSSimon Schubert if (saw_fun == 0)
11355796c8dcSSimon Schubert ++info->indextablesize;
11365796c8dcSSimon Schubert
11375796c8dcSSimon Schubert if (info->indextablesize == 0)
11385796c8dcSSimon Schubert return TRUE;
11395796c8dcSSimon Schubert ++info->indextablesize;
11405796c8dcSSimon Schubert
11415796c8dcSSimon Schubert amt = info->indextablesize;
11425796c8dcSSimon Schubert amt *= sizeof (struct indexentry);
11435796c8dcSSimon Schubert info->indextable = (struct indexentry *) bfd_alloc (abfd, amt);
11445796c8dcSSimon Schubert if (info->indextable == NULL)
11455796c8dcSSimon Schubert return FALSE;
11465796c8dcSSimon Schubert
11475796c8dcSSimon Schubert file_name = NULL;
11485796c8dcSSimon Schubert directory_name = NULL;
11495796c8dcSSimon Schubert saw_fun = 1;
11505796c8dcSSimon Schubert
11515796c8dcSSimon Schubert for (i = 0, stroff = 0, stab = info->stabs, str = info->strs;
11525796c8dcSSimon Schubert i < info->indextablesize && stab < info->stabs + stabsize;
11535796c8dcSSimon Schubert stab += STABSIZE)
11545796c8dcSSimon Schubert {
11555796c8dcSSimon Schubert switch (stab[TYPEOFF])
11565796c8dcSSimon Schubert {
11575796c8dcSSimon Schubert case 0:
11585796c8dcSSimon Schubert /* This is the first entry in a compilation unit. */
11595796c8dcSSimon Schubert if ((bfd_size_type) ((info->strs + strsize) - str) < stroff)
11605796c8dcSSimon Schubert break;
11615796c8dcSSimon Schubert str += stroff;
11625796c8dcSSimon Schubert stroff = bfd_get_32 (abfd, stab + VALOFF);
11635796c8dcSSimon Schubert break;
11645796c8dcSSimon Schubert
11655796c8dcSSimon Schubert case N_SO:
11665796c8dcSSimon Schubert /* The main file name. */
11675796c8dcSSimon Schubert
11685796c8dcSSimon Schubert /* The following code creates a new indextable entry with
11695796c8dcSSimon Schubert a NULL function name if there were no N_FUNs in a file.
11705796c8dcSSimon Schubert Note that a N_SO without a file name is an EOF and
11715796c8dcSSimon Schubert there could be 2 N_SO following it with the new filename
11725796c8dcSSimon Schubert and directory. */
11735796c8dcSSimon Schubert if (saw_fun == 0)
11745796c8dcSSimon Schubert {
11755796c8dcSSimon Schubert info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
11765796c8dcSSimon Schubert info->indextable[i].stab = last_stab;
11775796c8dcSSimon Schubert info->indextable[i].str = str;
11785796c8dcSSimon Schubert info->indextable[i].directory_name = directory_name;
11795796c8dcSSimon Schubert info->indextable[i].file_name = file_name;
11805796c8dcSSimon Schubert info->indextable[i].function_name = NULL;
11815796c8dcSSimon Schubert ++i;
11825796c8dcSSimon Schubert }
11835796c8dcSSimon Schubert saw_fun = 0;
11845796c8dcSSimon Schubert
11855796c8dcSSimon Schubert file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
11865796c8dcSSimon Schubert if (*file_name == '\0')
11875796c8dcSSimon Schubert {
11885796c8dcSSimon Schubert directory_name = NULL;
11895796c8dcSSimon Schubert file_name = NULL;
11905796c8dcSSimon Schubert saw_fun = 1;
11915796c8dcSSimon Schubert }
11925796c8dcSSimon Schubert else
11935796c8dcSSimon Schubert {
11945796c8dcSSimon Schubert last_stab = stab;
11955796c8dcSSimon Schubert if (stab + STABSIZE >= info->stabs + stabsize
11965796c8dcSSimon Schubert || *(stab + STABSIZE + TYPEOFF) != (bfd_byte) N_SO)
11975796c8dcSSimon Schubert {
11985796c8dcSSimon Schubert directory_name = NULL;
11995796c8dcSSimon Schubert }
12005796c8dcSSimon Schubert else
12015796c8dcSSimon Schubert {
12025796c8dcSSimon Schubert /* Two consecutive N_SOs are a directory and a
12035796c8dcSSimon Schubert file name. */
12045796c8dcSSimon Schubert stab += STABSIZE;
12055796c8dcSSimon Schubert directory_name = file_name;
12065796c8dcSSimon Schubert file_name = ((char *) str
12075796c8dcSSimon Schubert + bfd_get_32 (abfd, stab + STRDXOFF));
12085796c8dcSSimon Schubert }
12095796c8dcSSimon Schubert }
12105796c8dcSSimon Schubert break;
12115796c8dcSSimon Schubert
12125796c8dcSSimon Schubert case N_SOL:
12135796c8dcSSimon Schubert /* The name of an include file. */
12145796c8dcSSimon Schubert file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
12155796c8dcSSimon Schubert break;
12165796c8dcSSimon Schubert
12175796c8dcSSimon Schubert case N_FUN:
12185796c8dcSSimon Schubert /* A function name. */
12195796c8dcSSimon Schubert saw_fun = 1;
12205796c8dcSSimon Schubert name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
12215796c8dcSSimon Schubert
12225796c8dcSSimon Schubert if (*name == '\0')
12235796c8dcSSimon Schubert name = NULL;
12245796c8dcSSimon Schubert
12255796c8dcSSimon Schubert function_name = name;
12265796c8dcSSimon Schubert
12275796c8dcSSimon Schubert if (name == NULL)
12285796c8dcSSimon Schubert continue;
12295796c8dcSSimon Schubert
12305796c8dcSSimon Schubert info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
12315796c8dcSSimon Schubert info->indextable[i].stab = stab;
12325796c8dcSSimon Schubert info->indextable[i].str = str;
12335796c8dcSSimon Schubert info->indextable[i].directory_name = directory_name;
12345796c8dcSSimon Schubert info->indextable[i].file_name = file_name;
12355796c8dcSSimon Schubert info->indextable[i].function_name = function_name;
12365796c8dcSSimon Schubert ++i;
12375796c8dcSSimon Schubert break;
12385796c8dcSSimon Schubert }
12395796c8dcSSimon Schubert }
12405796c8dcSSimon Schubert
12415796c8dcSSimon Schubert if (saw_fun == 0)
12425796c8dcSSimon Schubert {
12435796c8dcSSimon Schubert info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
12445796c8dcSSimon Schubert info->indextable[i].stab = last_stab;
12455796c8dcSSimon Schubert info->indextable[i].str = str;
12465796c8dcSSimon Schubert info->indextable[i].directory_name = directory_name;
12475796c8dcSSimon Schubert info->indextable[i].file_name = file_name;
12485796c8dcSSimon Schubert info->indextable[i].function_name = NULL;
12495796c8dcSSimon Schubert ++i;
12505796c8dcSSimon Schubert }
12515796c8dcSSimon Schubert
12525796c8dcSSimon Schubert info->indextable[i].val = (bfd_vma) -1;
12535796c8dcSSimon Schubert info->indextable[i].stab = info->stabs + stabsize;
12545796c8dcSSimon Schubert info->indextable[i].str = str;
12555796c8dcSSimon Schubert info->indextable[i].directory_name = NULL;
12565796c8dcSSimon Schubert info->indextable[i].file_name = NULL;
12575796c8dcSSimon Schubert info->indextable[i].function_name = NULL;
12585796c8dcSSimon Schubert ++i;
12595796c8dcSSimon Schubert
12605796c8dcSSimon Schubert info->indextablesize = i;
12615796c8dcSSimon Schubert qsort (info->indextable, (size_t) i, sizeof (struct indexentry),
12625796c8dcSSimon Schubert cmpindexentry);
12635796c8dcSSimon Schubert
12645796c8dcSSimon Schubert *pinfo = info;
12655796c8dcSSimon Schubert }
12665796c8dcSSimon Schubert
12675796c8dcSSimon Schubert /* We are passed a section relative offset. The offsets in the
12685796c8dcSSimon Schubert stabs information are absolute. */
12695796c8dcSSimon Schubert offset += bfd_get_section_vma (abfd, section);
12705796c8dcSSimon Schubert
12715796c8dcSSimon Schubert #ifdef ENABLE_CACHING
12725796c8dcSSimon Schubert if (info->cached_indexentry != NULL
12735796c8dcSSimon Schubert && offset >= info->cached_offset
12745796c8dcSSimon Schubert && offset < (info->cached_indexentry + 1)->val)
12755796c8dcSSimon Schubert {
12765796c8dcSSimon Schubert stab = info->cached_stab;
12775796c8dcSSimon Schubert indexentry = info->cached_indexentry;
12785796c8dcSSimon Schubert file_name = info->cached_file_name;
12795796c8dcSSimon Schubert }
12805796c8dcSSimon Schubert else
12815796c8dcSSimon Schubert #endif
12825796c8dcSSimon Schubert {
12835796c8dcSSimon Schubert long low, high;
12845796c8dcSSimon Schubert long mid = -1;
12855796c8dcSSimon Schubert
12865796c8dcSSimon Schubert /* Cache non-existent or invalid. Do binary search on
12875796c8dcSSimon Schubert indextable. */
12885796c8dcSSimon Schubert indexentry = NULL;
12895796c8dcSSimon Schubert
12905796c8dcSSimon Schubert low = 0;
12915796c8dcSSimon Schubert high = info->indextablesize - 1;
12925796c8dcSSimon Schubert while (low != high)
12935796c8dcSSimon Schubert {
12945796c8dcSSimon Schubert mid = (high + low) / 2;
12955796c8dcSSimon Schubert if (offset >= info->indextable[mid].val
12965796c8dcSSimon Schubert && offset < info->indextable[mid + 1].val)
12975796c8dcSSimon Schubert {
12985796c8dcSSimon Schubert indexentry = &info->indextable[mid];
12995796c8dcSSimon Schubert break;
13005796c8dcSSimon Schubert }
13015796c8dcSSimon Schubert
13025796c8dcSSimon Schubert if (info->indextable[mid].val > offset)
13035796c8dcSSimon Schubert high = mid;
13045796c8dcSSimon Schubert else
13055796c8dcSSimon Schubert low = mid + 1;
13065796c8dcSSimon Schubert }
13075796c8dcSSimon Schubert
13085796c8dcSSimon Schubert if (indexentry == NULL)
13095796c8dcSSimon Schubert return TRUE;
13105796c8dcSSimon Schubert
13115796c8dcSSimon Schubert stab = indexentry->stab + STABSIZE;
13125796c8dcSSimon Schubert file_name = indexentry->file_name;
13135796c8dcSSimon Schubert }
13145796c8dcSSimon Schubert
13155796c8dcSSimon Schubert directory_name = indexentry->directory_name;
13165796c8dcSSimon Schubert str = indexentry->str;
13175796c8dcSSimon Schubert
13185796c8dcSSimon Schubert saw_line = FALSE;
13195796c8dcSSimon Schubert saw_func = FALSE;
13205796c8dcSSimon Schubert for (; stab < (indexentry+1)->stab; stab += STABSIZE)
13215796c8dcSSimon Schubert {
13225796c8dcSSimon Schubert bfd_boolean done;
13235796c8dcSSimon Schubert bfd_vma val;
13245796c8dcSSimon Schubert
13255796c8dcSSimon Schubert done = FALSE;
13265796c8dcSSimon Schubert
13275796c8dcSSimon Schubert switch (stab[TYPEOFF])
13285796c8dcSSimon Schubert {
13295796c8dcSSimon Schubert case N_SOL:
13305796c8dcSSimon Schubert /* The name of an include file. */
13315796c8dcSSimon Schubert val = bfd_get_32 (abfd, stab + VALOFF);
13325796c8dcSSimon Schubert if (val <= offset)
13335796c8dcSSimon Schubert {
13345796c8dcSSimon Schubert file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
13355796c8dcSSimon Schubert *pline = 0;
13365796c8dcSSimon Schubert }
13375796c8dcSSimon Schubert break;
13385796c8dcSSimon Schubert
13395796c8dcSSimon Schubert case N_SLINE:
13405796c8dcSSimon Schubert case N_DSLINE:
13415796c8dcSSimon Schubert case N_BSLINE:
13425796c8dcSSimon Schubert /* A line number. If the function was specified, then the value
13435796c8dcSSimon Schubert is relative to the start of the function. Otherwise, the
13445796c8dcSSimon Schubert value is an absolute address. */
13455796c8dcSSimon Schubert val = ((indexentry->function_name ? indexentry->val : 0)
13465796c8dcSSimon Schubert + bfd_get_32 (abfd, stab + VALOFF));
13475796c8dcSSimon Schubert /* If this line starts before our desired offset, or if it's
13485796c8dcSSimon Schubert the first line we've been able to find, use it. The
13495796c8dcSSimon Schubert !saw_line check works around a bug in GCC 2.95.3, which emits
13505796c8dcSSimon Schubert the first N_SLINE late. */
13515796c8dcSSimon Schubert if (!saw_line || val <= offset)
13525796c8dcSSimon Schubert {
13535796c8dcSSimon Schubert *pline = bfd_get_16 (abfd, stab + DESCOFF);
13545796c8dcSSimon Schubert
13555796c8dcSSimon Schubert #ifdef ENABLE_CACHING
13565796c8dcSSimon Schubert info->cached_stab = stab;
13575796c8dcSSimon Schubert info->cached_offset = val;
13585796c8dcSSimon Schubert info->cached_file_name = file_name;
13595796c8dcSSimon Schubert info->cached_indexentry = indexentry;
13605796c8dcSSimon Schubert #endif
13615796c8dcSSimon Schubert }
13625796c8dcSSimon Schubert if (val > offset)
13635796c8dcSSimon Schubert done = TRUE;
13645796c8dcSSimon Schubert saw_line = TRUE;
13655796c8dcSSimon Schubert break;
13665796c8dcSSimon Schubert
13675796c8dcSSimon Schubert case N_FUN:
13685796c8dcSSimon Schubert case N_SO:
13695796c8dcSSimon Schubert if (saw_func || saw_line)
13705796c8dcSSimon Schubert done = TRUE;
13715796c8dcSSimon Schubert saw_func = TRUE;
13725796c8dcSSimon Schubert break;
13735796c8dcSSimon Schubert }
13745796c8dcSSimon Schubert
13755796c8dcSSimon Schubert if (done)
13765796c8dcSSimon Schubert break;
13775796c8dcSSimon Schubert }
13785796c8dcSSimon Schubert
13795796c8dcSSimon Schubert *pfound = TRUE;
13805796c8dcSSimon Schubert
13815796c8dcSSimon Schubert if (file_name == NULL || IS_ABSOLUTE_PATH (file_name)
13825796c8dcSSimon Schubert || directory_name == NULL)
13835796c8dcSSimon Schubert *pfilename = file_name;
13845796c8dcSSimon Schubert else
13855796c8dcSSimon Schubert {
13865796c8dcSSimon Schubert size_t dirlen;
13875796c8dcSSimon Schubert
13885796c8dcSSimon Schubert dirlen = strlen (directory_name);
13895796c8dcSSimon Schubert if (info->filename == NULL
1390c50c785cSJohn Marino || filename_ncmp (info->filename, directory_name, dirlen) != 0
1391c50c785cSJohn Marino || filename_cmp (info->filename + dirlen, file_name) != 0)
13925796c8dcSSimon Schubert {
13935796c8dcSSimon Schubert size_t len;
13945796c8dcSSimon Schubert
13955796c8dcSSimon Schubert /* Don't free info->filename here. objdump and other
13965796c8dcSSimon Schubert apps keep a copy of a previously returned file name
13975796c8dcSSimon Schubert pointer. */
13985796c8dcSSimon Schubert len = strlen (file_name) + 1;
13995796c8dcSSimon Schubert info->filename = (char *) bfd_alloc (abfd, dirlen + len);
14005796c8dcSSimon Schubert if (info->filename == NULL)
14015796c8dcSSimon Schubert return FALSE;
14025796c8dcSSimon Schubert memcpy (info->filename, directory_name, dirlen);
14035796c8dcSSimon Schubert memcpy (info->filename + dirlen, file_name, len);
14045796c8dcSSimon Schubert }
14055796c8dcSSimon Schubert
14065796c8dcSSimon Schubert *pfilename = info->filename;
14075796c8dcSSimon Schubert }
14085796c8dcSSimon Schubert
14095796c8dcSSimon Schubert if (indexentry->function_name != NULL)
14105796c8dcSSimon Schubert {
14115796c8dcSSimon Schubert char *s;
14125796c8dcSSimon Schubert
14135796c8dcSSimon Schubert /* This will typically be something like main:F(0,1), so we want
14145796c8dcSSimon Schubert to clobber the colon. It's OK to change the name, since the
14155796c8dcSSimon Schubert string is in our own local storage anyhow. */
14165796c8dcSSimon Schubert s = strchr (indexentry->function_name, ':');
14175796c8dcSSimon Schubert if (s != NULL)
14185796c8dcSSimon Schubert *s = '\0';
14195796c8dcSSimon Schubert
14205796c8dcSSimon Schubert *pfnname = indexentry->function_name;
14215796c8dcSSimon Schubert }
14225796c8dcSSimon Schubert
14235796c8dcSSimon Schubert return TRUE;
14245796c8dcSSimon Schubert }
1425