* ecoff.c (_bfd_ecoff_write_armap): give the symtab element a
reasonable mode until "ar x" is smart enough to skip it (fixes gcc/libgcc.a builds on mips-ecoff targets * coffcode.h (styp_to_sec_flags): Explain how COMDATs are supposed to work. Hack to support MS import libraries, which use different COMDAT types than GNU. (coff_slurp_symbol_table): C_SECTION symbols are local; they refer to implied zero-length sections (see peicode below) * coffgen.c (coff_get_normalized_symtab): Properly read long MS filename symbols, which use one *or more* auxents. * coffswap.h (coff_swap_aux_in): ditto * peicode.h (coff_swap_sym_in): Build the implied zero-length sections
This commit is contained in:
parent
69f868fa5d
commit
ec0ef80e9f
6 changed files with 125 additions and 4 deletions
|
@ -1,3 +1,20 @@
|
|||
1999-05-10 DJ Delorie <dj@cygnus.com>
|
||||
|
||||
* ecoff.c (_bfd_ecoff_write_armap): give the symtab element a
|
||||
reasonable mode until "ar x" is smart enough to skip it (fixes
|
||||
gcc/libgcc.a builds on mips-ecoff targets
|
||||
|
||||
* coffcode.h (styp_to_sec_flags): Explain how COMDATs are supposed
|
||||
to work. Hack to support MS import libraries, which use different
|
||||
COMDAT types than GNU.
|
||||
(coff_slurp_symbol_table): C_SECTION symbols are local; they refer
|
||||
to implied zero-length sections (see peicode below)
|
||||
* coffgen.c (coff_get_normalized_symtab): Properly read long MS
|
||||
filename symbols, which use one *or more* auxents.
|
||||
* coffswap.h (coff_swap_aux_in): ditto
|
||||
* peicode.h (coff_swap_sym_in): Build the implied zero-length
|
||||
sections
|
||||
|
||||
Tue May 11 15:51:58 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* elf32-v850.c (v850_elf_howto_table): Make partial_inplace false
|
||||
|
|
|
@ -588,6 +588,12 @@ styp_to_sec_flags (abfd, hdr, name)
|
|||
can't call slurp_symtab, because the linker doesn't want the
|
||||
swapped symbols. */
|
||||
|
||||
/* COMDAT sections are special. The first symbol is the section
|
||||
symbol, which tells what kind of COMDAT section it is. The
|
||||
*second* symbol is the "comdat symbol" - the one with the
|
||||
unique name. GNU uses the section symbol for the unique
|
||||
name; MS uses ".text" for every comdat section. Sigh. - DJ */
|
||||
|
||||
if (_bfd_coff_get_external_symbols (abfd))
|
||||
{
|
||||
bfd_byte *esym, *esymend;
|
||||
|
@ -629,10 +635,23 @@ styp_to_sec_flags (abfd, hdr, name)
|
|||
isym.n_type, isym.n_sclass,
|
||||
0, isym.n_numaux, (PTR) &aux);
|
||||
|
||||
/* FIXME: Microsoft uses NODUPLICATES and
|
||||
ASSOCIATIVE, but gnu uses ANY and SAME_SIZE.
|
||||
Unfortunately, gnu doesn't do the comdat
|
||||
symbols right. So, until we can fix it to do
|
||||
the right thing, we are temporarily disabling
|
||||
comdats for the MS types (they're used in
|
||||
DLLs and C++, but we don't support *their*
|
||||
C++ libraries anyway - DJ */
|
||||
|
||||
switch (aux.x_scn.x_comdat)
|
||||
{
|
||||
case IMAGE_COMDAT_SELECT_NODUPLICATES:
|
||||
#if 0
|
||||
sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
|
||||
#else
|
||||
sec_flags &= ~SEC_LINK_ONCE;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -649,8 +668,12 @@ styp_to_sec_flags (abfd, hdr, name)
|
|||
break;
|
||||
|
||||
case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
|
||||
#if 0
|
||||
/* FIXME: This is not currently implemented. */
|
||||
sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
|
||||
#else
|
||||
sec_flags &= ~SEC_LINK_ONCE;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3581,6 +3604,11 @@ coff_slurp_symbol_table (abfd)
|
|||
#ifdef COFF_WITH_PE
|
||||
if (src->u.syment.n_sclass == C_NT_WEAK)
|
||||
dst->symbol.flags = BSF_WEAK;
|
||||
if (src->u.syment.n_sclass == C_SECTION
|
||||
&& src->u.syment.n_scnum > 0)
|
||||
{
|
||||
dst->symbol.flags = BSF_LOCAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (src->u.syment.n_sclass == C_WEAKEXT)
|
||||
|
|
|
@ -1747,9 +1747,19 @@ coff_get_normalized_symtab (abfd)
|
|||
else
|
||||
{
|
||||
/* ordinary short filename, put into memory anyway */
|
||||
internal_ptr->u.syment._n._n_n._n_offset = (long)
|
||||
copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
|
||||
FILNMLEN);
|
||||
if (internal_ptr->u.syment.n_numaux > 1
|
||||
&& coff_data (abfd)->pe)
|
||||
{
|
||||
internal_ptr->u.syment._n._n_n._n_offset = (long)
|
||||
copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
|
||||
internal_ptr->u.syment.n_numaux * symesz);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_ptr->u.syment._n._n_n._n_offset = (long)
|
||||
copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
|
||||
FILNMLEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -422,7 +422,16 @@ coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
|
|||
#if FILNMLEN != E_FILNMLEN
|
||||
-> Error, we need to cope with truncating or extending FILNMLEN!;
|
||||
#else
|
||||
memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
|
||||
if (numaux > 1)
|
||||
{
|
||||
if (indx == 0)
|
||||
memcpy (in->x_file.x_fname, ext->x_file.x_fname,
|
||||
numaux * sizeof (AUXENT));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
goto end;
|
||||
|
|
|
@ -3181,7 +3181,14 @@ _bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx)
|
|||
armap. */
|
||||
hdr.ar_uid[0] = '0';
|
||||
hdr.ar_gid[0] = '0';
|
||||
#if 0
|
||||
hdr.ar_mode[0] = '0';
|
||||
#else
|
||||
/* Building gcc ends up extracting the armap as a file - twice. */
|
||||
hdr.ar_mode[0] = '6';
|
||||
hdr.ar_mode[1] = '4';
|
||||
hdr.ar_mode[2] = '4';
|
||||
#endif
|
||||
|
||||
sprintf (hdr.ar_size, "%-10d", (int) mapsize);
|
||||
|
||||
|
|
|
@ -504,6 +504,7 @@ coff_swap_sym_in (abfd, ext1, in1)
|
|||
{
|
||||
in->n_value = 0x0;
|
||||
|
||||
#if 0
|
||||
/* FIXME: This is clearly wrong. The problem seems to be that
|
||||
undefined C_SECTION symbols appear in the first object of a
|
||||
MS generated .lib file, and the symbols are not defined
|
||||
|
@ -518,6 +519,55 @@ coff_swap_sym_in (abfd, ext1, in1)
|
|||
/* in->n_scnum = 3; */
|
||||
/* else */
|
||||
/* in->n_scnum = 2; */
|
||||
#else
|
||||
/* Create synthetic empty sections as needed. DJ */
|
||||
if (in->n_scnum == 0)
|
||||
{
|
||||
asection *sec;
|
||||
for (sec=abfd->sections; sec; sec=sec->next)
|
||||
{
|
||||
if (strcmp (sec->name, in->n_name) == 0)
|
||||
{
|
||||
in->n_scnum = sec->target_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (in->n_scnum == 0)
|
||||
{
|
||||
int unused_section_number = 0;
|
||||
asection *sec;
|
||||
char *name;
|
||||
for (sec=abfd->sections; sec; sec=sec->next)
|
||||
if (unused_section_number <= sec->target_index)
|
||||
unused_section_number = sec->target_index+1;
|
||||
|
||||
name = bfd_alloc (abfd, strlen (in->n_name) + 10);
|
||||
if (name == NULL)
|
||||
return;
|
||||
strcpy (name, in->n_name);
|
||||
sec = bfd_make_section_anyway (abfd, name);
|
||||
|
||||
sec->vma = 0;
|
||||
sec->lma = 0;
|
||||
sec->_cooked_size = 0;
|
||||
sec->_raw_size = 0;
|
||||
sec->filepos = 0;
|
||||
sec->rel_filepos = 0;
|
||||
sec->reloc_count = 0;
|
||||
sec->line_filepos = 0;
|
||||
sec->lineno_count = 0;
|
||||
sec->userdata = NULL;
|
||||
sec->next = (asection *) NULL;
|
||||
sec->flags = 0;
|
||||
sec->alignment_power = 2;
|
||||
sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
|
||||
|
||||
sec->target_index = unused_section_number;
|
||||
|
||||
in->n_scnum = unused_section_number;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef coff_swap_sym_in_hook
|
||||
|
|
Loading…
Reference in a new issue