* xcofflink.c (struct xcoff_final_link_info): Add new line_filepos
field. (xcoff_find_reloc): New static function. (xcoff_link_add_symbols): Use it. (_bfd_xcoff_bfd_final_link): Set finfo.line_filepos. (xcoff_link_input_bfd): Handle C_BINCL and C_EINCL. Don't relocate the value of C_DECL.
This commit is contained in:
parent
91123dbe02
commit
f630a0a41a
|
@ -1,5 +1,13 @@
|
||||||
Mon Oct 30 14:53:48 1995 Ian Lance Taylor <ian@cygnus.com>
|
Mon Oct 30 14:53:48 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* xcofflink.c (struct xcoff_final_link_info): Add new line_filepos
|
||||||
|
field.
|
||||||
|
(xcoff_find_reloc): New static function.
|
||||||
|
(xcoff_link_add_symbols): Use it.
|
||||||
|
(_bfd_xcoff_bfd_final_link): Set finfo.line_filepos.
|
||||||
|
(xcoff_link_input_bfd): Handle C_BINCL and C_EINCL. Don't
|
||||||
|
relocate the value of C_DECL.
|
||||||
|
|
||||||
* elf.c (elf_fake_sections): Remove bogus BFD_ASSERT.
|
* elf.c (elf_fake_sections): Remove bogus BFD_ASSERT.
|
||||||
|
|
||||||
Sat Oct 28 01:25:34 1995 steve chamberlain <sac@slash.cygnus.com>
|
Sat Oct 28 01:25:34 1995 steve chamberlain <sac@slash.cygnus.com>
|
||||||
|
|
187
bfd/xcofflink.c
187
bfd/xcofflink.c
|
@ -390,6 +390,8 @@ struct xcoff_final_link_info
|
||||||
struct external_ldsym *ldsym;
|
struct external_ldsym *ldsym;
|
||||||
/* Next .loader reloc to swap out. */
|
/* Next .loader reloc to swap out. */
|
||||||
struct external_ldrel *ldrel;
|
struct external_ldrel *ldrel;
|
||||||
|
/* File position of start of line numbers. */
|
||||||
|
file_ptr line_filepos;
|
||||||
/* Buffer large enough to hold swapped symbols of any input file. */
|
/* Buffer large enough to hold swapped symbols of any input file. */
|
||||||
struct internal_syment *internal_syms;
|
struct internal_syment *internal_syms;
|
||||||
/* Buffer large enough to hold output indices of symbols of any
|
/* Buffer large enough to hold output indices of symbols of any
|
||||||
|
@ -423,6 +425,8 @@ static boolean xcoff_link_check_archive_element
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
||||||
static boolean xcoff_link_check_ar_symbols
|
static boolean xcoff_link_check_ar_symbols
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
PARAMS ((bfd *, struct bfd_link_info *, boolean *));
|
||||||
|
static bfd_size_type xcoff_find_reloc
|
||||||
|
PARAMS ((struct internal_reloc *, bfd_size_type, bfd_vma));
|
||||||
static boolean xcoff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
|
static boolean xcoff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
|
||||||
static boolean xcoff_link_add_dynamic_symbols
|
static boolean xcoff_link_add_dynamic_symbols
|
||||||
PARAMS ((bfd *, struct bfd_link_info *));
|
PARAMS ((bfd *, struct bfd_link_info *));
|
||||||
|
@ -786,6 +790,51 @@ xcoff_link_check_ar_symbols (abfd, info, pneeded)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the index of reloc in RELOCS with the least address greater
|
||||||
|
than or equal to ADDRESS. The relocs are sorted by address. */
|
||||||
|
|
||||||
|
static bfd_size_type
|
||||||
|
xcoff_find_reloc (relocs, count, address)
|
||||||
|
struct internal_reloc *relocs;
|
||||||
|
bfd_size_type count;
|
||||||
|
bfd_vma address;
|
||||||
|
{
|
||||||
|
bfd_size_type min, max, this;
|
||||||
|
|
||||||
|
if (count < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
min = 0;
|
||||||
|
max = count;
|
||||||
|
|
||||||
|
/* Do a binary search over (min,max]. */
|
||||||
|
while (min + 1 < max)
|
||||||
|
{
|
||||||
|
bfd_vma raddr;
|
||||||
|
|
||||||
|
this = (max + min) / 2;
|
||||||
|
raddr = relocs[this].r_vaddr;
|
||||||
|
if (raddr > address)
|
||||||
|
max = this;
|
||||||
|
else if (raddr < address)
|
||||||
|
min = this;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min = this;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relocs[min].r_vaddr < address)
|
||||||
|
return min + 1;
|
||||||
|
|
||||||
|
while (min > 0
|
||||||
|
&& relocs[min - 1].r_vaddr == address)
|
||||||
|
--min;
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add all the symbols from an object file to the hash table.
|
/* Add all the symbols from an object file to the hash table.
|
||||||
|
|
||||||
XCOFF is a weird format. A normal XCOFF .o files will have three
|
XCOFF is a weird format. A normal XCOFF .o files will have three
|
||||||
|
@ -1197,29 +1246,22 @@ xcoff_link_add_symbols (abfd, info)
|
||||||
&& info->hash->creator == abfd->xvec)
|
&& info->hash->creator == abfd->xvec)
|
||||||
{
|
{
|
||||||
asection *enclosing;
|
asection *enclosing;
|
||||||
|
struct internal_reloc *relocs;
|
||||||
bfd_size_type relindx;
|
bfd_size_type relindx;
|
||||||
struct internal_reloc *rel;
|
struct internal_reloc *rel;
|
||||||
asection **rel_csect;
|
|
||||||
|
|
||||||
enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum);
|
enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum);
|
||||||
if (enclosing == NULL)
|
if (enclosing == NULL)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
/* XCOFF requires that relocs be sorted by address, so
|
relocs = reloc_info[enclosing->target_index].relocs;
|
||||||
we could do a binary search here. FIXME. */
|
relindx = xcoff_find_reloc (relocs, enclosing->reloc_count,
|
||||||
rel = reloc_info[enclosing->target_index].relocs;
|
sym.n_value);
|
||||||
rel_csect = reloc_info[enclosing->target_index].csects;
|
rel = relocs + relindx;
|
||||||
for (relindx = 0;
|
if (relindx < enclosing->reloc_count
|
||||||
relindx < enclosing->reloc_count;
|
&& rel->r_vaddr == (bfd_vma) sym.n_value
|
||||||
relindx++, rel++, rel_csect++)
|
&& rel->r_size == 31
|
||||||
{
|
&& rel->r_type == R_POS)
|
||||||
if (*rel_csect == NULL
|
|
||||||
&& rel->r_vaddr == (bfd_vma) sym.n_value
|
|
||||||
&& rel->r_size == 31
|
|
||||||
&& rel->r_type == R_POS)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (relindx < enclosing->reloc_count)
|
|
||||||
{
|
{
|
||||||
bfd_byte *erelsym;
|
bfd_byte *erelsym;
|
||||||
struct internal_syment relsym;
|
struct internal_syment relsym;
|
||||||
|
@ -1270,10 +1312,14 @@ xcoff_link_add_symbols (abfd, info)
|
||||||
|
|
||||||
if (h->toc_section != NULL)
|
if (h->toc_section != NULL)
|
||||||
{
|
{
|
||||||
|
asection **rel_csects;
|
||||||
|
|
||||||
/* We already have a TOC entry for this
|
/* We already have a TOC entry for this
|
||||||
symbol, so we can just ignore this
|
symbol, so we can just ignore this
|
||||||
one. */
|
one. */
|
||||||
*rel_csect = bfd_und_section_ptr;
|
rel_csects =
|
||||||
|
reloc_info[enclosing->target_index].csects;
|
||||||
|
rel_csects[relindx] = bfd_und_section_ptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1297,9 +1343,6 @@ xcoff_link_add_symbols (abfd, info)
|
||||||
};
|
};
|
||||||
const char *csect_name;
|
const char *csect_name;
|
||||||
asection *enclosing;
|
asection *enclosing;
|
||||||
struct internal_reloc *rel;
|
|
||||||
bfd_size_type relindx;
|
|
||||||
asection **rel_csect;
|
|
||||||
|
|
||||||
if ((aux.x_csect.x_smclas >=
|
if ((aux.x_csect.x_smclas >=
|
||||||
sizeof csect_name_by_class / sizeof csect_name_by_class[0])
|
sizeof csect_name_by_class / sizeof csect_name_by_class[0])
|
||||||
|
@ -1359,31 +1402,23 @@ xcoff_link_add_symbols (abfd, info)
|
||||||
xcoff_section_data (abfd, csect)->lineno_count =
|
xcoff_section_data (abfd, csect)->lineno_count =
|
||||||
enclosing->lineno_count;
|
enclosing->lineno_count;
|
||||||
|
|
||||||
/* XCOFF requires that relocs be sorted by address, so we
|
|
||||||
could do a binary search here. FIXME. (XCOFF
|
|
||||||
unfortunately does not require that symbols be sorted
|
|
||||||
by address, or this would be a simple merge). */
|
|
||||||
if (enclosing->owner == abfd)
|
if (enclosing->owner == abfd)
|
||||||
{
|
{
|
||||||
rel = reloc_info[enclosing->target_index].relocs;
|
struct internal_reloc *relocs;
|
||||||
rel_csect = reloc_info[enclosing->target_index].csects;
|
bfd_size_type relindx;
|
||||||
for (relindx = 0;
|
struct internal_reloc *rel;
|
||||||
relindx < enclosing->reloc_count;
|
asection **rel_csect;
|
||||||
relindx++, rel++, rel_csect++)
|
|
||||||
{
|
relocs = reloc_info[enclosing->target_index].relocs;
|
||||||
if (*rel_csect == NULL
|
relindx = xcoff_find_reloc (relocs, enclosing->reloc_count,
|
||||||
&& rel->r_vaddr >= csect->vma
|
csect->vma);
|
||||||
&& rel->r_vaddr < csect->vma + csect->_raw_size)
|
rel = relocs + relindx;
|
||||||
{
|
rel_csect = (reloc_info[enclosing->target_index].csects
|
||||||
csect->rel_filepos = (enclosing->rel_filepos
|
+ relindx);
|
||||||
+ (relindx
|
csect->rel_filepos = (enclosing->rel_filepos
|
||||||
* bfd_coff_relsz (abfd)));
|
+ relindx * bfd_coff_relsz (abfd));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (relindx < enclosing->reloc_count
|
while (relindx < enclosing->reloc_count
|
||||||
&& *rel_csect == NULL
|
&& *rel_csect == NULL
|
||||||
&& rel->r_vaddr >= csect->vma
|
|
||||||
&& rel->r_vaddr < csect->vma + csect->_raw_size)
|
&& rel->r_vaddr < csect->vma + csect->_raw_size)
|
||||||
{
|
{
|
||||||
*rel_csect = csect;
|
*rel_csect = csect;
|
||||||
|
@ -3044,6 +3079,7 @@ _bfd_xcoff_bfd_final_link (abfd, info)
|
||||||
/* We now know the size of the relocs, so we can determine the file
|
/* We now know the size of the relocs, so we can determine the file
|
||||||
positions of the line numbers. */
|
positions of the line numbers. */
|
||||||
line_filepos = rel_filepos;
|
line_filepos = rel_filepos;
|
||||||
|
finfo.line_filepos = line_filepos;
|
||||||
linesz = bfd_coff_linesz (abfd);
|
linesz = bfd_coff_linesz (abfd);
|
||||||
max_output_reloc_count = 0;
|
max_output_reloc_count = 0;
|
||||||
for (o = abfd->sections; o != NULL; o = o->next)
|
for (o = abfd->sections; o != NULL; o = o->next)
|
||||||
|
@ -3444,6 +3480,7 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||||
long *indexp;
|
long *indexp;
|
||||||
unsigned long output_index;
|
unsigned long output_index;
|
||||||
bfd_byte *outsym;
|
bfd_byte *outsym;
|
||||||
|
unsigned int incls;
|
||||||
asection *oline;
|
asection *oline;
|
||||||
boolean keep_syms;
|
boolean keep_syms;
|
||||||
asection *o;
|
asection *o;
|
||||||
|
@ -3489,6 +3526,7 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||||
indexp = finfo->sym_indices;
|
indexp = finfo->sym_indices;
|
||||||
output_index = syment_base;
|
output_index = syment_base;
|
||||||
outsym = finfo->outsyms;
|
outsym = finfo->outsyms;
|
||||||
|
incls = 0;
|
||||||
oline = NULL;
|
oline = NULL;
|
||||||
|
|
||||||
while (esym < esym_end)
|
while (esym < esym_end)
|
||||||
|
@ -3750,6 +3788,7 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||||
|
|
||||||
if (isym.n_sclass != C_BSTAT
|
if (isym.n_sclass != C_BSTAT
|
||||||
&& isym.n_sclass != C_ESTAT
|
&& isym.n_sclass != C_ESTAT
|
||||||
|
&& isym.n_sclass != C_DECL
|
||||||
&& isym.n_scnum > 0)
|
&& isym.n_scnum > 0)
|
||||||
{
|
{
|
||||||
isym.n_scnum = (*csectpp)->output_section->target_index;
|
isym.n_scnum = (*csectpp)->output_section->target_index;
|
||||||
|
@ -3802,6 +3841,16 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||||
finfo->last_file = isym;
|
finfo->last_file = isym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The value of a C_BINCL or C_EINCL symbol is a file offset
|
||||||
|
into the line numbers. We update the symbol values when
|
||||||
|
we handle the line numbers. */
|
||||||
|
if (isym.n_sclass == C_BINCL
|
||||||
|
|| isym.n_sclass == C_EINCL)
|
||||||
|
{
|
||||||
|
isym.n_value = finfo->line_filepos;
|
||||||
|
++incls;
|
||||||
|
}
|
||||||
|
|
||||||
/* Output the symbol. */
|
/* Output the symbol. */
|
||||||
|
|
||||||
bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
|
bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
|
||||||
|
@ -3872,21 +3921,23 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||||
|
|
||||||
if (isymp->n_sclass == C_BSTAT)
|
if (isymp->n_sclass == C_BSTAT)
|
||||||
{
|
{
|
||||||
|
struct internal_syment isym;
|
||||||
unsigned long indx;
|
unsigned long indx;
|
||||||
|
|
||||||
/* The value of a C_BSTAT symbol is the symbol table
|
/* The value of a C_BSTAT symbol is the symbol table
|
||||||
index of the containing csect. */
|
index of the containing csect. */
|
||||||
indx = isymp->n_value;
|
bfd_coff_swap_sym_in (output_bfd, (PTR) outsym, (PTR) &isym);
|
||||||
|
indx = isym.n_value;
|
||||||
if (indx < obj_raw_syment_count (input_bfd))
|
if (indx < obj_raw_syment_count (input_bfd))
|
||||||
{
|
{
|
||||||
long symindx;
|
long symindx;
|
||||||
|
|
||||||
symindx = finfo->sym_indices[indx];
|
symindx = finfo->sym_indices[indx];
|
||||||
if (symindx < 0)
|
if (symindx < 0)
|
||||||
isymp->n_value = 0;
|
isym.n_value = 0;
|
||||||
else
|
else
|
||||||
isymp->n_value = symindx;
|
isym.n_value = symindx;
|
||||||
bfd_coff_swap_sym_out (output_bfd, (PTR) isymp,
|
bfd_coff_swap_sym_out (output_bfd, (PTR) &isym,
|
||||||
(PTR) outsym);
|
(PTR) outsym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4091,6 +4142,52 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
o->output_section->lineno_count += count;
|
o->output_section->lineno_count += count;
|
||||||
|
|
||||||
|
if (incls > 0)
|
||||||
|
{
|
||||||
|
struct internal_syment *iisp, *iispend;
|
||||||
|
long *iindp;
|
||||||
|
bfd_byte *oos;
|
||||||
|
|
||||||
|
/* Update any C_BINCL or C_EINCL symbols
|
||||||
|
that refer to a line number in the
|
||||||
|
range we just output. */
|
||||||
|
iisp = finfo->internal_syms;
|
||||||
|
iispend = (iisp
|
||||||
|
+ obj_raw_syment_count (input_bfd));
|
||||||
|
iindp = finfo->sym_indices;
|
||||||
|
oos = finfo->outsyms;
|
||||||
|
while (iisp < iispend)
|
||||||
|
{
|
||||||
|
if ((iisp->n_sclass == C_BINCL
|
||||||
|
|| iisp->n_sclass == C_EINCL)
|
||||||
|
&& ((bfd_size_type) iisp->n_value
|
||||||
|
>= enclosing->line_filepos + linoff)
|
||||||
|
&& ((bfd_size_type) iisp->n_value
|
||||||
|
< (enclosing->line_filepos
|
||||||
|
+ enc_count * linesz)))
|
||||||
|
{
|
||||||
|
struct internal_syment iis;
|
||||||
|
|
||||||
|
bfd_coff_swap_sym_in (output_bfd,
|
||||||
|
(PTR) oos,
|
||||||
|
(PTR) &iis);
|
||||||
|
iis.n_value =
|
||||||
|
(iisp->n_value
|
||||||
|
- enclosing->line_filepos
|
||||||
|
- linoff
|
||||||
|
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr);
|
||||||
|
bfd_coff_swap_sym_out (output_bfd,
|
||||||
|
(PTR) &iis,
|
||||||
|
(PTR) oos);
|
||||||
|
--incls;
|
||||||
|
}
|
||||||
|
|
||||||
|
iisp += iisp->n_numaux + 1;
|
||||||
|
iindp += iisp->n_numaux + 1;
|
||||||
|
oos += (iisp->n_numaux + 1) * osymesz;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue