Based on patches from Donn Terry <donn@interix.com>:
* coffcode.h (enum coff_symbol_classification): Define. (bfd_coff_backend_data): Rename _bfd_coff_sym_is_global to _bfd_coff_classify_symbol. Change return type. (bfd_coff_classify_symbol): Rename from bfd_coff_sym_is_global. (coff_slurp_symbol_table): Use coff_classify_symbol. (coff_classify_symbol): New static function. (coff_sym_is_global): Never define. (bfd_coff_std_swap_table): Initialize with coff_classify_symbol. * cofflink.c (coff_link_check_ar_symbols): Use bfd_coff_classify_symbol rather than bfd_coff_sym_is_global. (coff_link_add_symbols): Likewise. (_bfd_coff_link_input_bfd): Likewise. * coff-sh.c (bfd_coff_small_swap_table): Initialize with coff_classify_symbol. * libcoff.h: Rebuild.
This commit is contained in:
parent
1198f921ae
commit
5d54c62870
@ -1,3 +1,22 @@
|
||||
1999-08-05 Ian Lance Taylor <ian@zembu.com>
|
||||
|
||||
Based on patches from Donn Terry <donn@interix.com>:
|
||||
* coffcode.h (enum coff_symbol_classification): Define.
|
||||
(bfd_coff_backend_data): Rename _bfd_coff_sym_is_global to
|
||||
_bfd_coff_classify_symbol. Change return type.
|
||||
(bfd_coff_classify_symbol): Rename from bfd_coff_sym_is_global.
|
||||
(coff_slurp_symbol_table): Use coff_classify_symbol.
|
||||
(coff_classify_symbol): New static function.
|
||||
(coff_sym_is_global): Never define.
|
||||
(bfd_coff_std_swap_table): Initialize with coff_classify_symbol.
|
||||
* cofflink.c (coff_link_check_ar_symbols): Use
|
||||
bfd_coff_classify_symbol rather than bfd_coff_sym_is_global.
|
||||
(coff_link_add_symbols): Likewise.
|
||||
(_bfd_coff_link_input_bfd): Likewise.
|
||||
* coff-sh.c (bfd_coff_small_swap_table): Initialize with
|
||||
coff_classify_symbol.
|
||||
* libcoff.h: Rebuild.
|
||||
|
||||
Wed Aug 4 18:08:07 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* libhppa.h (R_HPPA_LTPSEL, R_HPPA_RTPSEL): New field selectors
|
||||
|
@ -2765,7 +2765,7 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table =
|
||||
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
|
||||
coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
|
||||
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
|
||||
coff_sym_is_global, coff_compute_section_file_positions,
|
||||
coff_classify_symbol, coff_compute_section_file_positions,
|
||||
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
|
||||
coff_adjust_symndx, coff_link_add_one_symbol,
|
||||
coff_link_output_has_begun, coff_final_link_postscript
|
||||
|
213
bfd/coffcode.h
213
bfd/coffcode.h
@ -329,6 +329,8 @@ static boolean coff_set_section_contents
|
||||
static PTR buy_and_read PARAMS ((bfd *, file_ptr, int, size_t));
|
||||
static boolean coff_slurp_line_table PARAMS ((bfd *, asection *));
|
||||
static boolean coff_slurp_symbol_table PARAMS ((bfd *));
|
||||
static enum coff_symbol_classification coff_classify_symbol
|
||||
PARAMS ((bfd *, struct internal_syment *));
|
||||
static boolean coff_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **));
|
||||
static long coff_canonicalize_reloc
|
||||
PARAMS ((bfd *, asection *, arelent **, asymbol **));
|
||||
@ -709,6 +711,22 @@ INTERNAL_DEFINITION
|
||||
|
||||
CODE_FRAGMENT
|
||||
|
||||
.{* COFF symbol classifications. *}
|
||||
.
|
||||
.enum coff_symbol_classification
|
||||
.{
|
||||
. {* Global symbol. *}
|
||||
. COFF_SYMBOL_GLOBAL,
|
||||
. {* Common symbol. *}
|
||||
. COFF_SYMBOL_COMMON,
|
||||
. {* Undefined symbol. *}
|
||||
. COFF_SYMBOL_UNDEFINED,
|
||||
. {* Local symbol. *}
|
||||
. COFF_SYMBOL_LOCAL,
|
||||
. {* PE section symbol. *}
|
||||
. COFF_SYMBOL_PE_SECTION
|
||||
.};
|
||||
.
|
||||
Special entry points for gdb to swap in coff symbol table parts:
|
||||
.typedef struct
|
||||
.{
|
||||
@ -853,7 +871,7 @@ dependent COFF routines:
|
||||
. arelent *r,
|
||||
. unsigned int shrink,
|
||||
. struct bfd_link_info *link_info));
|
||||
. boolean (*_bfd_coff_sym_is_global) PARAMS ((
|
||||
. enum coff_symbol_classification (*_bfd_coff_classify_symbol) PARAMS ((
|
||||
. bfd *abfd,
|
||||
. struct internal_syment *));
|
||||
. boolean (*_bfd_coff_compute_section_file_positions) PARAMS ((
|
||||
@ -993,8 +1011,8 @@ dependent COFF routines:
|
||||
. ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
|
||||
. (abfd, section, reloc, shrink, link_info))
|
||||
.
|
||||
.#define bfd_coff_sym_is_global(abfd, sym)\
|
||||
. ((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\
|
||||
.#define bfd_coff_classify_symbol(abfd, sym)\
|
||||
. ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
|
||||
. (abfd, sym))
|
||||
.
|
||||
.#define bfd_coff_compute_section_file_positions(abfd)\
|
||||
@ -3569,31 +3587,15 @@ coff_slurp_symbol_table (abfd)
|
||||
case C_SYSTEM: /* System Wide variable */
|
||||
#endif
|
||||
#ifdef COFF_WITH_PE
|
||||
/* PE uses storage class 0x68 to denote a section symbol */
|
||||
/* In PE, 0x68 (104) denotes a section symbol */
|
||||
case C_SECTION:
|
||||
/* PE uses storage class 0x69 for a weak external symbol. */
|
||||
/* In PE, 0x69 (105) denotes a weak external symbol. */
|
||||
case C_NT_WEAK:
|
||||
#endif
|
||||
if ((src->u.syment.n_scnum) == 0)
|
||||
switch (coff_classify_symbol (abfd, &src->u.syment))
|
||||
{
|
||||
if ((src->u.syment.n_value) == 0)
|
||||
{
|
||||
dst->symbol.section = bfd_und_section_ptr;
|
||||
dst->symbol.value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst->symbol.section = bfd_com_section_ptr;
|
||||
dst->symbol.value = (src->u.syment.n_value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Base the value as an index from the base of the
|
||||
section */
|
||||
|
||||
case COFF_SYMBOL_GLOBAL:
|
||||
dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
|
||||
|
||||
#if defined COFF_WITH_PE
|
||||
/* PE sets the symbol to a value relative to the
|
||||
start of the section. */
|
||||
@ -3602,19 +3604,45 @@ coff_slurp_symbol_table (abfd)
|
||||
dst->symbol.value = (src->u.syment.n_value
|
||||
- dst->symbol.section->vma);
|
||||
#endif
|
||||
|
||||
if (ISFCN ((src->u.syment.n_type)))
|
||||
{
|
||||
/* A function ext does not go at the end of a
|
||||
file. */
|
||||
dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
|
||||
}
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_COMMON:
|
||||
dst->symbol.section = bfd_com_section_ptr;
|
||||
dst->symbol.value = src->u.syment.n_value;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_UNDEFINED:
|
||||
dst->symbol.section = bfd_und_section_ptr;
|
||||
dst->symbol.value = 0;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_PE_SECTION:
|
||||
dst->symbol.flags |= BSF_EXPORT | BSF_SECTION_SYM;
|
||||
dst->symbol.value = 0;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_LOCAL:
|
||||
dst->symbol.flags = BSF_LOCAL;
|
||||
#if defined COFF_WITH_PE
|
||||
/* PE sets the symbol to a value relative to the
|
||||
start of the section. */
|
||||
dst->symbol.value = src->u.syment.n_value;
|
||||
#else
|
||||
dst->symbol.value = (src->u.syment.n_value
|
||||
- dst->symbol.section->vma);
|
||||
#endif
|
||||
if (ISFCN ((src->u.syment.n_type)))
|
||||
dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef RS6000COFF_C
|
||||
/* A C_HIDEXT symbol is not global. */
|
||||
if (src->u.syment.n_sclass == C_HIDEXT)
|
||||
dst->symbol.flags = BSF_LOCAL;
|
||||
/* A symbol with a csect entry should not go at the end. */
|
||||
if (src->u.syment.n_numaux > 0)
|
||||
dst->symbol.flags |= BSF_NOT_AT_END;
|
||||
@ -3830,47 +3858,102 @@ coff_slurp_symbol_table (abfd)
|
||||
return true;
|
||||
} /* coff_slurp_symbol_table() */
|
||||
|
||||
/* Check whether a symbol is globally visible. This is used by the
|
||||
COFF backend linker code in cofflink.c, since a couple of targets
|
||||
have globally visible symbols which are not class C_EXT. This
|
||||
function need not handle the case of n_class == C_EXT. */
|
||||
/* Classify a COFF symbol. A couple of targets have globally visible
|
||||
symbols which are not class C_EXT, and this handles those. It also
|
||||
recognizes some special PE cases. */
|
||||
|
||||
#undef OTHER_GLOBAL_CLASS
|
||||
|
||||
#ifdef I960
|
||||
#define OTHER_GLOBAL_CLASS C_LEAFEXT
|
||||
#endif
|
||||
|
||||
#ifdef COFFARM
|
||||
#define OTHER_GLOBAL_CLASS C_THUMBEXT || syment->n_sclass == C_THUMBEXTFUNC
|
||||
#else
|
||||
#ifdef COFF_WITH_PE
|
||||
#define OTHER_GLOBAL_CLASS C_SECTION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef OTHER_GLOBAL_CLASS
|
||||
|
||||
static boolean coff_sym_is_global PARAMS ((bfd *, struct internal_syment *));
|
||||
|
||||
static boolean
|
||||
coff_sym_is_global (abfd, syment)
|
||||
bfd * abfd ATTRIBUTE_UNUSED;
|
||||
struct internal_syment * syment;
|
||||
static enum coff_symbol_classification
|
||||
coff_classify_symbol (abfd, syment)
|
||||
bfd *abfd;
|
||||
struct internal_syment *syment;
|
||||
{
|
||||
return (syment->n_sclass == OTHER_GLOBAL_CLASS);
|
||||
/* FIXME: This partially duplicates the switch in
|
||||
coff_slurp_symbol_table. */
|
||||
switch (syment->n_sclass)
|
||||
{
|
||||
case C_EXT:
|
||||
case C_WEAKEXT:
|
||||
#ifdef I960
|
||||
case C_LEAFEXT:
|
||||
#endif
|
||||
#ifdef ARM
|
||||
case C_THUMBEXT:
|
||||
case C_THUMBEXTFUNC:
|
||||
#endif
|
||||
#ifdef C_SYSTEM
|
||||
case C_SYSTEM:
|
||||
#endif
|
||||
#ifdef COFF_WITH_PE
|
||||
case C_NT_WEAK:
|
||||
#endif
|
||||
if (syment->n_scnum == 0)
|
||||
{
|
||||
if (syment->n_value == 0)
|
||||
return COFF_SYMBOL_UNDEFINED;
|
||||
else
|
||||
return COFF_SYMBOL_COMMON;
|
||||
}
|
||||
return COFF_SYMBOL_GLOBAL;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef COFF_WITH_PE
|
||||
if (syment->n_sclass == C_STAT)
|
||||
{
|
||||
if (syment->n_scnum == 0)
|
||||
{
|
||||
/* The Microsoft compiler sometimes generates these if a
|
||||
small static function is inlined every time it is used.
|
||||
The function is discarded, but the symbol table entry
|
||||
remains. */
|
||||
return COFF_SYMBOL_LOCAL;
|
||||
}
|
||||
|
||||
if (syment->n_value == 0)
|
||||
{
|
||||
asection *sec;
|
||||
char buf[SYMNMLEN + 1];
|
||||
|
||||
sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
|
||||
if (sec != NULL
|
||||
&& (strcmp (bfd_get_section_name (abfd, sec),
|
||||
_bfd_coff_internal_syment_name (abfd, syment, buf))
|
||||
== 0))
|
||||
return COFF_SYMBOL_PE_SECTION;
|
||||
}
|
||||
|
||||
return COFF_SYMBOL_LOCAL;
|
||||
}
|
||||
|
||||
if (syment->n_sclass == C_SECTION)
|
||||
{
|
||||
/* In some cases in a DLL generated by the Microsoft linker, the
|
||||
n_value field will contain garbage. FIXME: This should
|
||||
probably be handled by the swapping function instead. */
|
||||
syment->n_value = 0;
|
||||
if (syment->n_scnum == 0)
|
||||
return COFF_SYMBOL_UNDEFINED;
|
||||
return COFF_SYMBOL_PE_SECTION;
|
||||
}
|
||||
#endif /* COFF_WITH_PE */
|
||||
|
||||
/* If it is not a global symbol, we presume it is a local symbol. */
|
||||
|
||||
if (syment->n_scnum == 0)
|
||||
{
|
||||
char buf[SYMNMLEN + 1];
|
||||
|
||||
(*_bfd_error_handler)
|
||||
(_("warning: %s: local symbol `%s' has no section"),
|
||||
bfd_get_filename (abfd),
|
||||
_bfd_coff_internal_syment_name (abfd, syment, buf));
|
||||
}
|
||||
|
||||
return COFF_SYMBOL_LOCAL;
|
||||
}
|
||||
|
||||
#undef OTHER_GLOBAL_CLASS
|
||||
|
||||
#else /* ! defined (OTHER_GLOBAL_CLASS) */
|
||||
|
||||
/* sym_is_global should not be defined if it has nothing to do. */
|
||||
|
||||
#define coff_sym_is_global 0
|
||||
|
||||
#endif /* ! defined (OTHER_GLOBAL_CLASS) */
|
||||
|
||||
/*
|
||||
SUBSUBSECTION
|
||||
Reading relocations
|
||||
@ -4291,7 +4374,7 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table =
|
||||
coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
|
||||
coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
|
||||
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
|
||||
coff_sym_is_global, coff_compute_section_file_positions,
|
||||
coff_classify_symbol, coff_compute_section_file_positions,
|
||||
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
|
||||
coff_adjust_symndx, coff_link_add_one_symbol,
|
||||
coff_link_output_has_begun, coff_final_link_postscript
|
||||
|
136
bfd/cofflink.c
136
bfd/cofflink.c
@ -225,32 +225,25 @@ coff_link_check_ar_symbols (abfd, info, pneeded)
|
||||
struct bfd_link_info *info;
|
||||
boolean *pneeded;
|
||||
{
|
||||
boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *));
|
||||
bfd_size_type symesz;
|
||||
bfd_byte *esym;
|
||||
bfd_byte *esym_end;
|
||||
|
||||
*pneeded = false;
|
||||
|
||||
sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global;
|
||||
|
||||
symesz = bfd_coff_symesz (abfd);
|
||||
esym = (bfd_byte *) obj_coff_external_syms (abfd);
|
||||
esym_end = esym + obj_raw_syment_count (abfd) * symesz;
|
||||
while (esym < esym_end)
|
||||
{
|
||||
struct internal_syment sym;
|
||||
enum coff_symbol_classification classification;
|
||||
|
||||
bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
|
||||
|
||||
if ((sym.n_sclass == C_EXT
|
||||
|| sym.n_sclass == C_WEAKEXT
|
||||
|| (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK)
|
||||
#ifdef C_SYSTEM
|
||||
|| sym.n_sclass == C_SYSTEM
|
||||
#endif
|
||||
|| (sym_is_global && (*sym_is_global) (abfd, &sym)))
|
||||
&& (sym.n_scnum != 0 || sym.n_value != 0))
|
||||
classification = bfd_coff_classify_symbol (abfd, &sym);
|
||||
if (classification == COFF_SYMBOL_GLOBAL
|
||||
|| classification == COFF_SYMBOL_COMMON)
|
||||
{
|
||||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
@ -292,7 +285,6 @@ coff_link_add_symbols (abfd, info)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *));
|
||||
boolean keep_syms;
|
||||
boolean default_copy;
|
||||
bfd_size_type symcount;
|
||||
@ -306,8 +298,6 @@ coff_link_add_symbols (abfd, info)
|
||||
keep_syms = obj_coff_keep_syms (abfd);
|
||||
obj_coff_keep_syms (abfd) = true;
|
||||
|
||||
sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global;
|
||||
|
||||
if (info->keep_memory)
|
||||
default_copy = false;
|
||||
else
|
||||
@ -334,17 +324,13 @@ coff_link_add_symbols (abfd, info)
|
||||
while (esym < esym_end)
|
||||
{
|
||||
struct internal_syment sym;
|
||||
enum coff_symbol_classification classification;
|
||||
boolean copy;
|
||||
|
||||
bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
|
||||
|
||||
if (sym.n_sclass == C_EXT
|
||||
|| sym.n_sclass == C_WEAKEXT
|
||||
|| (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK)
|
||||
#ifdef C_SYSTEM
|
||||
|| sym.n_sclass == C_SYSTEM
|
||||
#endif
|
||||
|| (sym_is_global && (*sym_is_global) (abfd, &sym)))
|
||||
classification = bfd_coff_classify_symbol (abfd, &sym);
|
||||
if (classification != COFF_SYMBOL_LOCAL)
|
||||
{
|
||||
const char *name;
|
||||
char buf[SYMNMLEN + 1];
|
||||
@ -368,25 +354,32 @@ coff_link_add_symbols (abfd, info)
|
||||
|
||||
value = sym.n_value;
|
||||
|
||||
if (sym.n_scnum == 0)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
flags = 0;
|
||||
section = bfd_und_section_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = BSF_GLOBAL;
|
||||
section = bfd_com_section_ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
switch (classification)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
|
||||
case COFF_SYMBOL_GLOBAL:
|
||||
flags = BSF_EXPORT | BSF_GLOBAL;
|
||||
section = coff_section_from_bfd_index (abfd, sym.n_scnum);
|
||||
if (! obj_pe (abfd))
|
||||
value -= section->vma;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_UNDEFINED:
|
||||
flags = 0;
|
||||
section = bfd_und_section_ptr;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_COMMON:
|
||||
flags = BSF_GLOBAL;
|
||||
section = bfd_com_section_ptr;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_PE_SECTION:
|
||||
flags = BSF_SECTION_SYM | BSF_GLOBAL;
|
||||
section = coff_section_from_bfd_index (abfd, sym.n_scnum);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sym.n_sclass == C_WEAKEXT
|
||||
@ -481,6 +474,26 @@ coff_link_add_symbols (abfd, info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classification == COFF_SYMBOL_PE_SECTION
|
||||
&& (*sym_hash)->numaux != 0)
|
||||
{
|
||||
/* Some PE sections (such as .bss) have a zero size in
|
||||
the section header, but a non-zero size in the AUX
|
||||
record. Correct that here.
|
||||
|
||||
FIXME: This is not at all the right place to do this.
|
||||
For example, it won't help objdump. This needs to be
|
||||
done when we swap in the section header. */
|
||||
|
||||
BFD_ASSERT ((*sym_hash)->numaux == 1);
|
||||
if (section->_raw_size == 0)
|
||||
section->_raw_size = (*sym_hash)->aux[0].x_scn.x_scnlen;
|
||||
|
||||
/* FIXME: We could test whether the section sizes
|
||||
matches the size in the aux entry, but apparently
|
||||
that sometimes fails unexpectedly. */
|
||||
}
|
||||
}
|
||||
|
||||
esym += (sym.n_numaux + 1) * symesz;
|
||||
@ -1243,7 +1256,6 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
|
||||
struct coff_final_link_info *finfo;
|
||||
bfd *input_bfd;
|
||||
{
|
||||
boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *));
|
||||
boolean (*adjust_symndx) PARAMS ((bfd *, struct bfd_link_info *, bfd *,
|
||||
asection *, struct internal_reloc *,
|
||||
boolean *));
|
||||
@ -1269,7 +1281,6 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
|
||||
/* Move all the symbols to the output file. */
|
||||
|
||||
output_bfd = finfo->output_bfd;
|
||||
sym_is_global = coff_backend_info (input_bfd)->_bfd_coff_sym_is_global;
|
||||
strings = NULL;
|
||||
syment_base = obj_raw_syment_count (output_bfd);
|
||||
isymesz = bfd_coff_symesz (input_bfd);
|
||||
@ -1324,6 +1335,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
|
||||
while (esym < esym_end)
|
||||
{
|
||||
struct internal_syment isym;
|
||||
enum coff_symbol_classification classification;
|
||||
boolean skip;
|
||||
boolean global;
|
||||
boolean dont_skip_symbol;
|
||||
@ -1337,14 +1349,22 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
|
||||
the symbol. */
|
||||
isym = *isymp;
|
||||
|
||||
if (isym.n_scnum != 0)
|
||||
*secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
|
||||
else
|
||||
classification = bfd_coff_classify_symbol (input_bfd, &isym);
|
||||
switch (classification)
|
||||
{
|
||||
if (isym.n_value == 0)
|
||||
*secpp = bfd_und_section_ptr;
|
||||
else
|
||||
*secpp = bfd_com_section_ptr;
|
||||
default:
|
||||
abort ();
|
||||
case COFF_SYMBOL_GLOBAL:
|
||||
case COFF_SYMBOL_PE_SECTION:
|
||||
case COFF_SYMBOL_LOCAL:
|
||||
*secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
|
||||
break;
|
||||
case COFF_SYMBOL_COMMON:
|
||||
*secpp = bfd_com_section_ptr;
|
||||
break;
|
||||
case COFF_SYMBOL_UNDEFINED:
|
||||
*secpp = bfd_und_section_ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Extract the flag indicating if this symbol is used by a
|
||||
@ -1368,28 +1388,34 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
|
||||
|
||||
if (! skip)
|
||||
{
|
||||
if (isym.n_sclass == C_EXT
|
||||
|| isym.n_sclass == C_WEAKEXT
|
||||
|| (obj_pe (input_bfd) && isym.n_sclass == C_NT_WEAK)
|
||||
#ifdef C_SYSTEM
|
||||
|| isym.n_sclass == C_SYSTEM
|
||||
#endif
|
||||
|| (sym_is_global && (*sym_is_global) (input_bfd, &isym)))
|
||||
switch (classification)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
case COFF_SYMBOL_GLOBAL:
|
||||
case COFF_SYMBOL_COMMON:
|
||||
case COFF_SYMBOL_PE_SECTION:
|
||||
/* This is a global symbol. Global symbols come at the
|
||||
end of the symbol table, so skip them for now.
|
||||
Locally defined function symbols, however, are an
|
||||
exception, and are not moved to the end. */
|
||||
global = true;
|
||||
if (! ISFCN (isym.n_type) || isym.n_scnum == 0)
|
||||
if (! ISFCN (isym.n_type))
|
||||
skip = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_UNDEFINED:
|
||||
/* Undefined symbols are left for the end. */
|
||||
global = true;
|
||||
skip = true;
|
||||
break;
|
||||
|
||||
case COFF_SYMBOL_LOCAL:
|
||||
/* This is a local symbol. Skip it if we are discarding
|
||||
local symbols. */
|
||||
if (finfo->info->discard == discard_all && ! dont_skip_symbol)
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,6 +586,22 @@ struct lineno_cache_entry *lineno;
|
||||
/* Have the line numbers been relocated yet ? */
|
||||
boolean done_lineno;
|
||||
} coff_symbol_type;
|
||||
/* COFF symbol classifications. */
|
||||
|
||||
enum coff_symbol_classification
|
||||
{
|
||||
/* Global symbol. */
|
||||
COFF_SYMBOL_GLOBAL,
|
||||
/* Common symbol. */
|
||||
COFF_SYMBOL_COMMON,
|
||||
/* Undefined symbol. */
|
||||
COFF_SYMBOL_UNDEFINED,
|
||||
/* Local symbol. */
|
||||
COFF_SYMBOL_LOCAL,
|
||||
/* PE section symbol. */
|
||||
COFF_SYMBOL_PE_SECTION
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*_bfd_coff_swap_aux_in) PARAMS ((
|
||||
@ -722,7 +738,7 @@ typedef struct
|
||||
arelent *r,
|
||||
unsigned int shrink,
|
||||
struct bfd_link_info *link_info));
|
||||
boolean (*_bfd_coff_sym_is_global) PARAMS ((
|
||||
enum coff_symbol_classification (*_bfd_coff_classify_symbol) PARAMS ((
|
||||
bfd *abfd,
|
||||
struct internal_syment *));
|
||||
boolean (*_bfd_coff_compute_section_file_positions) PARAMS ((
|
||||
@ -862,8 +878,8 @@ typedef struct
|
||||
((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
|
||||
(abfd, section, reloc, shrink, link_info))
|
||||
|
||||
#define bfd_coff_sym_is_global(abfd, sym)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\
|
||||
#define bfd_coff_classify_symbol(abfd, sym)\
|
||||
((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
|
||||
(abfd, sym))
|
||||
|
||||
#define bfd_coff_compute_section_file_positions(abfd)\
|
||||
|
Loading…
Reference in New Issue
Block a user