|
|
|
@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
|
|
#include "libbfd.h" |
|
|
|
#include "aout/ar.h" |
|
|
|
#include "aout/ranlib.h" |
|
|
|
#include "aout/stab_gnu.h" |
|
|
|
|
|
|
|
/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines
|
|
|
|
some other stuff which we don't want and which conflicts with stuff |
|
|
|
@ -152,14 +153,17 @@ _bfd_ecoff_new_section_hook (abfd, section) |
|
|
|
asection *section; |
|
|
|
{ |
|
|
|
/* For the .pdata section, which has a special meaning on the Alpha,
|
|
|
|
we set the alignment to 8. We correct this later in |
|
|
|
we set the alignment power to 3. We correct this later in |
|
|
|
ecoff_compute_section_file_positions. We do this hackery because |
|
|
|
we need to know the exact unaligned size of the .pdata section in |
|
|
|
order to set the lnnoptr field correctly. */ |
|
|
|
order to set the lnnoptr field correctly. For every other |
|
|
|
section we use an alignment power of 4; this could be made target |
|
|
|
dependent by adding a field to ecoff_backend_data, but 4 appears |
|
|
|
to be correct for both the MIPS and the Alpha. */ |
|
|
|
if (strcmp (section->name, _PDATA) == 0) |
|
|
|
section->alignment_power = 3; |
|
|
|
else |
|
|
|
section->alignment_power = abfd->xvec->align_power_min; |
|
|
|
section->alignment_power = 4; |
|
|
|
|
|
|
|
if (strcmp (section->name, _TEXT) == 0) |
|
|
|
section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; |
|
|
|
@ -340,9 +344,10 @@ ecoff_sec_to_styp_flags (name, flags) |
|
|
|
|
|
|
|
/*ARGSUSED*/ |
|
|
|
flagword |
|
|
|
_bfd_ecoff_styp_to_sec_flags (abfd, hdr) |
|
|
|
_bfd_ecoff_styp_to_sec_flags (abfd, hdr, name) |
|
|
|
bfd *abfd; |
|
|
|
PTR hdr; |
|
|
|
const char *name; |
|
|
|
{ |
|
|
|
struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; |
|
|
|
long styp_flags = internal_s->s_flags; |
|
|
|
@ -871,7 +876,7 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) |
|
|
|
(*indirect_ptr_ptr)->value = (bfd_vma) asym; |
|
|
|
|
|
|
|
asym->flags = BSF_DEBUGGING; |
|
|
|
asym->section = &bfd_und_section; |
|
|
|
asym->section = bfd_und_section_ptr; |
|
|
|
*indirect_ptr_ptr = NULL; |
|
|
|
return true; |
|
|
|
} |
|
|
|
@ -880,7 +885,7 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) |
|
|
|
&& (ECOFF_UNMARK_STAB (ecoff_sym->index) | N_EXT) == (N_INDR | N_EXT)) |
|
|
|
{ |
|
|
|
asym->flags = BSF_DEBUGGING | BSF_INDIRECT; |
|
|
|
asym->section = &bfd_ind_section; |
|
|
|
asym->section = bfd_ind_section_ptr; |
|
|
|
/* Pass this symbol on to the next call to this function. */ |
|
|
|
*indirect_ptr_ptr = asym; |
|
|
|
return true; |
|
|
|
@ -910,7 +915,18 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) |
|
|
|
if (ext) |
|
|
|
asym->flags = BSF_EXPORT | BSF_GLOBAL; |
|
|
|
else |
|
|
|
asym->flags = BSF_LOCAL; |
|
|
|
{ |
|
|
|
asym->flags = BSF_LOCAL; |
|
|
|
/* Normally, a local stProc symbol will have a corresponding
|
|
|
|
external symbol. We mark the local symbol as a debugging |
|
|
|
symbol, in order to prevent nm from printing both out. |
|
|
|
Similarly, we mark stLabel fields as debugging symbols. In |
|
|
|
both cases, we do want to set the value correctly based on |
|
|
|
the symbol class. */ |
|
|
|
if (ecoff_sym->st == stProc |
|
|
|
|| ecoff_sym->st == stLabel) |
|
|
|
asym->flags |= BSF_DEBUGGING; |
|
|
|
} |
|
|
|
switch (ecoff_sym->sc) |
|
|
|
{ |
|
|
|
case scNil: |
|
|
|
@ -936,10 +952,10 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) |
|
|
|
asym->flags = BSF_DEBUGGING; |
|
|
|
break; |
|
|
|
case scAbs: |
|
|
|
asym->section = &bfd_abs_section; |
|
|
|
asym->section = bfd_abs_section_ptr; |
|
|
|
break; |
|
|
|
case scUndefined: |
|
|
|
asym->section = &bfd_und_section; |
|
|
|
asym->section = bfd_und_section_ptr; |
|
|
|
asym->flags = 0; |
|
|
|
asym->value = 0; |
|
|
|
break; |
|
|
|
@ -969,7 +985,7 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) |
|
|
|
case scCommon: |
|
|
|
if (asym->value > ecoff_data (abfd)->gp_size) |
|
|
|
{ |
|
|
|
asym->section = &bfd_com_section; |
|
|
|
asym->section = bfd_com_section_ptr; |
|
|
|
asym->flags = 0; |
|
|
|
break; |
|
|
|
} |
|
|
|
@ -996,7 +1012,7 @@ ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) |
|
|
|
asym->flags = BSF_DEBUGGING; |
|
|
|
break; |
|
|
|
case scSUndefined: |
|
|
|
asym->section = &bfd_und_section; |
|
|
|
asym->section = bfd_und_section_ptr; |
|
|
|
asym->flags = 0; |
|
|
|
asym->value = 0; |
|
|
|
break; |
|
|
|
@ -1895,7 +1911,7 @@ ecoff_slurp_reloc_table (abfd, section, symbols) |
|
|
|
else if (intern.r_symndx == RELOC_SECTION_NONE |
|
|
|
|| intern.r_symndx == RELOC_SECTION_ABS) |
|
|
|
{ |
|
|
|
rptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; |
|
|
|
rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; |
|
|
|
rptr->addend = 0; |
|
|
|
} |
|
|
|
else |
|
|
|
@ -2003,18 +2019,12 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset, |
|
|
|
{ |
|
|
|
const struct ecoff_debug_swap * const debug_swap |
|
|
|
= &ecoff_backend (abfd)->debug_swap; |
|
|
|
struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; |
|
|
|
FDR *fdr_ptr; |
|
|
|
FDR *fdr_start; |
|
|
|
FDR *fdr_end; |
|
|
|
FDR *fdr_hold; |
|
|
|
bfd_size_type external_pdr_size; |
|
|
|
char *pdr_ptr; |
|
|
|
char *pdr_end; |
|
|
|
PDR pdr; |
|
|
|
bfd_vma first_off; |
|
|
|
unsigned char *line_ptr; |
|
|
|
unsigned char *line_end; |
|
|
|
int lineno; |
|
|
|
boolean stabs; |
|
|
|
|
|
|
|
/* If we're not in the .text section, we don't have any line
|
|
|
|
numbers. */ |
|
|
|
@ -2024,8 +2034,7 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset, |
|
|
|
return false; |
|
|
|
|
|
|
|
/* Make sure we have the FDR's. */ |
|
|
|
if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, |
|
|
|
&ecoff_data (abfd)->debug_info) |
|
|
|
if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info) |
|
|
|
|| bfd_get_symcount (abfd) == 0) |
|
|
|
return false; |
|
|
|
|
|
|
|
@ -2034,8 +2043,8 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset, |
|
|
|
memory order. If speed is ever important, this can become a |
|
|
|
binary search. We must ignore FDR's with no PDR entries; they |
|
|
|
will have the adr of the FDR before or after them. */ |
|
|
|
fdr_start = ecoff_data (abfd)->debug_info.fdr; |
|
|
|
fdr_end = fdr_start + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax; |
|
|
|
fdr_start = debug_info->fdr; |
|
|
|
fdr_end = fdr_start + debug_info->symbolic_header.ifdMax; |
|
|
|
fdr_hold = (FDR *) NULL; |
|
|
|
for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++) |
|
|
|
{ |
|
|
|
@ -2049,112 +2058,289 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset, |
|
|
|
return false; |
|
|
|
fdr_ptr = fdr_hold; |
|
|
|
|
|
|
|
/* Each FDR has a list of procedure descriptors (PDR). PDR's also
|
|
|
|
have an address, which is relative to the FDR address, and are |
|
|
|
also stored in increasing memory order. */ |
|
|
|
offset -= fdr_ptr->adr; |
|
|
|
external_pdr_size = debug_swap->external_pdr_size; |
|
|
|
pdr_ptr = ((char *) ecoff_data (abfd)->debug_info.external_pdr |
|
|
|
+ fdr_ptr->ipdFirst * external_pdr_size); |
|
|
|
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size; |
|
|
|
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); |
|
|
|
if (offset < pdr.adr) |
|
|
|
return false; |
|
|
|
/* Check whether this file has stabs debugging information. In a
|
|
|
|
file with stabs debugging information, the second local symbol is |
|
|
|
named @stabs. */ |
|
|
|
stabs = false; |
|
|
|
if (fdr_ptr->csym >= 2) |
|
|
|
{ |
|
|
|
char *sym_ptr; |
|
|
|
SYMR sym; |
|
|
|
|
|
|
|
/* The address of the first PDR is an offset which applies to the
|
|
|
|
addresses of all the PDR's. */ |
|
|
|
first_off = pdr.adr; |
|
|
|
sym_ptr = ((char *) debug_info->external_sym |
|
|
|
+ (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size); |
|
|
|
(*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym); |
|
|
|
if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss, |
|
|
|
STABS_SYMBOL) == 0) |
|
|
|
stabs = true; |
|
|
|
} |
|
|
|
|
|
|
|
for (pdr_ptr += external_pdr_size; |
|
|
|
pdr_ptr < pdr_end; |
|
|
|
pdr_ptr += external_pdr_size) |
|
|
|
if (! stabs) |
|
|
|
{ |
|
|
|
bfd_size_type external_pdr_size; |
|
|
|
char *pdr_ptr; |
|
|
|
char *pdr_end; |
|
|
|
PDR pdr; |
|
|
|
bfd_vma first_off; |
|
|
|
unsigned char *line_ptr; |
|
|
|
unsigned char *line_end; |
|
|
|
int lineno; |
|
|
|
|
|
|
|
/* This file uses ECOFF debugging information. Each FDR has a
|
|
|
|
list of procedure descriptors (PDR). PDR's also have an |
|
|
|
address, which is relative to the FDR address, and are also |
|
|
|
stored in increasing memory order. */ |
|
|
|
offset -= fdr_ptr->adr; |
|
|
|
external_pdr_size = debug_swap->external_pdr_size; |
|
|
|
pdr_ptr = ((char *) debug_info->external_pdr |
|
|
|
+ fdr_ptr->ipdFirst * external_pdr_size); |
|
|
|
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size; |
|
|
|
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); |
|
|
|
if (offset < pdr.adr) |
|
|
|
break; |
|
|
|
} |
|
|
|
return false; |
|
|
|
|
|
|
|
/* Now we can look for the actual line number. The line numbers are
|
|
|
|
stored in a very funky format, which I won't try to describe. |
|
|
|
Note that right here pdr_ptr and pdr hold the PDR *after* the one |
|
|
|
we want; we need this to compute line_end. */ |
|
|
|
line_end = ecoff_data (abfd)->debug_info.line; |
|
|
|
if (pdr_ptr == pdr_end) |
|
|
|
line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine; |
|
|
|
else |
|
|
|
line_end += fdr_ptr->cbLineOffset + pdr.cbLineOffset; |
|
|
|
|
|
|
|
/* Now change pdr and pdr_ptr to the one we want. */ |
|
|
|
pdr_ptr -= external_pdr_size; |
|
|
|
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); |
|
|
|
|
|
|
|
offset -= pdr.adr - first_off; |
|
|
|
lineno = pdr.lnLow; |
|
|
|
line_ptr = (ecoff_data (abfd)->debug_info.line |
|
|
|
+ fdr_ptr->cbLineOffset |
|
|
|
+ pdr.cbLineOffset); |
|
|
|
while (line_ptr < line_end) |
|
|
|
{ |
|
|
|
int delta; |
|
|
|
int count; |
|
|
|
|
|
|
|
delta = *line_ptr >> 4; |
|
|
|
if (delta >= 0x8) |
|
|
|
delta -= 0x10; |
|
|
|
count = (*line_ptr & 0xf) + 1; |
|
|
|
++line_ptr; |
|
|
|
if (delta == -8) |
|
|
|
/* The address of the first PDR is an offset which applies to
|
|
|
|
the addresses of all the PDR's. */ |
|
|
|
first_off = pdr.adr; |
|
|
|
|
|
|
|
for (pdr_ptr += external_pdr_size; |
|
|
|
pdr_ptr < pdr_end; |
|
|
|
pdr_ptr += external_pdr_size) |
|
|
|
{ |
|
|
|
delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff); |
|
|
|
if (delta >= 0x8000) |
|
|
|
delta -= 0x10000; |
|
|
|
line_ptr += 2; |
|
|
|
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); |
|
|
|
if (offset < pdr.adr) |
|
|
|
break; |
|
|
|
} |
|
|
|
lineno += delta; |
|
|
|
if (offset < count * 4) |
|
|
|
break; |
|
|
|
offset -= count * 4; |
|
|
|
} |
|
|
|
|
|
|
|
/* If fdr_ptr->rss is -1, then this file does not have full symbols,
|
|
|
|
at least according to gdb/mipsread.c. */ |
|
|
|
if (fdr_ptr->rss == -1) |
|
|
|
{ |
|
|
|
*filename_ptr = NULL; |
|
|
|
if (pdr.isym == -1) |
|
|
|
*functionname_ptr = NULL; |
|
|
|
/* Now we can look for the actual line number. The line numbers
|
|
|
|
are stored in a very funky format, which I won't try to |
|
|
|
describe. Note that right here pdr_ptr and pdr hold the PDR |
|
|
|
*after* the one we want; we need this to compute line_end. */ |
|
|
|
line_end = debug_info->line; |
|
|
|
if (pdr_ptr == pdr_end) |
|
|
|
line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine; |
|
|
|
else |
|
|
|
line_end += fdr_ptr->cbLineOffset + pdr.cbLineOffset; |
|
|
|
|
|
|
|
/* Now change pdr and pdr_ptr to the one we want. */ |
|
|
|
pdr_ptr -= external_pdr_size; |
|
|
|
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); |
|
|
|
|
|
|
|
offset -= pdr.adr - first_off; |
|
|
|
lineno = pdr.lnLow; |
|
|
|
line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset; |
|
|
|
while (line_ptr < line_end) |
|
|
|
{ |
|
|
|
int delta; |
|
|
|
int count; |
|
|
|
|
|
|
|
delta = *line_ptr >> 4; |
|
|
|
if (delta >= 0x8) |
|
|
|
delta -= 0x10; |
|
|
|
count = (*line_ptr & 0xf) + 1; |
|
|
|
++line_ptr; |
|
|
|
if (delta == -8) |
|
|
|
{ |
|
|
|
delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff); |
|
|
|
if (delta >= 0x8000) |
|
|
|
delta -= 0x10000; |
|
|
|
line_ptr += 2; |
|
|
|
} |
|
|
|
lineno += delta; |
|
|
|
if (offset < count * 4) |
|
|
|
break; |
|
|
|
offset -= count * 4; |
|
|
|
} |
|
|
|
|
|
|
|
/* If fdr_ptr->rss is -1, then this file does not have full
|
|
|
|
symbols, at least according to gdb/mipsread.c. */ |
|
|
|
if (fdr_ptr->rss == -1) |
|
|
|
{ |
|
|
|
*filename_ptr = NULL; |
|
|
|
if (pdr.isym == -1) |
|
|
|
*functionname_ptr = NULL; |
|
|
|
else |
|
|
|
{ |
|
|
|
EXTR proc_ext; |
|
|
|
|
|
|
|
(*debug_swap->swap_ext_in) |
|
|
|
(abfd, |
|
|
|
((char *) debug_info->external_ext |
|
|
|
+ pdr.isym * debug_swap->external_ext_size), |
|
|
|
&proc_ext); |
|
|
|
*functionname_ptr = debug_info->ssext + proc_ext.asym.iss; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
EXTR proc_ext; |
|
|
|
SYMR proc_sym; |
|
|
|
|
|
|
|
(*debug_swap->swap_ext_in) |
|
|
|
*filename_ptr = debug_info->ss + fdr_ptr->issBase + fdr_ptr->rss; |
|
|
|
(*debug_swap->swap_sym_in) |
|
|
|
(abfd, |
|
|
|
((char *) ecoff_data (abfd)->debug_info.external_ext |
|
|
|
+ pdr.isym * debug_swap->external_ext_size), |
|
|
|
&proc_ext); |
|
|
|
*functionname_ptr = (ecoff_data (abfd)->debug_info.ssext |
|
|
|
+ proc_ext.asym.iss); |
|
|
|
((char *) debug_info->external_sym |
|
|
|
+ (fdr_ptr->isymBase + pdr.isym) * debug_swap->external_sym_size), |
|
|
|
&proc_sym); |
|
|
|
*functionname_ptr = debug_info->ss + fdr_ptr->issBase + proc_sym.iss; |
|
|
|
} |
|
|
|
if (lineno == ilineNil) |
|
|
|
lineno = 0; |
|
|
|
*retline_ptr = lineno; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
SYMR proc_sym; |
|
|
|
|
|
|
|
*filename_ptr = (ecoff_data (abfd)->debug_info.ss |
|
|
|
+ fdr_ptr->issBase |
|
|
|
+ fdr_ptr->rss); |
|
|
|
(*debug_swap->swap_sym_in) |
|
|
|
(abfd, |
|
|
|
((char *) ecoff_data (abfd)->debug_info.external_sym |
|
|
|
+ (fdr_ptr->isymBase + pdr.isym) * debug_swap->external_sym_size), |
|
|
|
&proc_sym); |
|
|
|
*functionname_ptr = (ecoff_data (abfd)->debug_info.ss |
|
|
|
+ fdr_ptr->issBase |
|
|
|
+ proc_sym.iss); |
|
|
|
bfd_size_type external_sym_size; |
|
|
|
const char *directory_name; |
|
|
|
const char *main_file_name; |
|
|
|
const char *current_file_name; |
|
|
|
const char *function_name; |
|
|
|
const char *line_file_name; |
|
|
|
bfd_vma low_func_vma; |
|
|
|
bfd_vma low_line_vma; |
|
|
|
char *sym_ptr, *sym_ptr_end; |
|
|
|
size_t len, funclen; |
|
|
|
char *buffer = NULL; |
|
|
|
|
|
|
|
/* This file uses stabs debugging information. */ |
|
|
|
|
|
|
|
*filename_ptr = NULL; |
|
|
|
*functionname_ptr = NULL; |
|
|
|
*retline_ptr = 0; |
|
|
|
|
|
|
|
directory_name = NULL; |
|
|
|
main_file_name = NULL; |
|
|
|
current_file_name = NULL; |
|
|
|
function_name = NULL; |
|
|
|
line_file_name = NULL; |
|
|
|
low_func_vma = 0; |
|
|
|
low_line_vma = 0; |
|
|
|
|
|
|
|
external_sym_size = debug_swap->external_sym_size; |
|
|
|
|
|
|
|
sym_ptr = ((char *) debug_info->external_sym |
|
|
|
+ (fdr_ptr->isymBase + 2) * external_sym_size); |
|
|
|
sym_ptr_end = sym_ptr + fdr_ptr->csym * external_sym_size; |
|
|
|
for (; sym_ptr < sym_ptr_end; sym_ptr += external_sym_size) |
|
|
|
{ |
|
|
|
SYMR sym; |
|
|
|
|
|
|
|
(*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym); |
|
|
|
|
|
|
|
if (ECOFF_IS_STAB (&sym)) |
|
|
|
{ |
|
|
|
switch (ECOFF_UNMARK_STAB (sym.index)) |
|
|
|
{ |
|
|
|
case N_SO: |
|
|
|
main_file_name = current_file_name = |
|
|
|
debug_info->ss + fdr_ptr->issBase + sym.iss; |
|
|
|
|
|
|
|
/* Check the next symbol to see if it is also an
|
|
|
|
N_SO symbol. */ |
|
|
|
if (sym_ptr + external_sym_size < sym_ptr_end) |
|
|
|
{ |
|
|
|
SYMR nextsym; |
|
|
|
|
|
|
|
(*debug_swap->swap_sym_in) (abfd, |
|
|
|
sym_ptr + external_sym_size, |
|
|
|
&nextsym); |
|
|
|
if (ECOFF_IS_STAB (&nextsym) |
|
|
|
&& ECOFF_UNMARK_STAB (nextsym.index) == N_SO) |
|
|
|
{ |
|
|
|
directory_name = current_file_name; |
|
|
|
main_file_name = current_file_name = |
|
|
|
debug_info->ss + fdr_ptr->issBase + sym.iss; |
|
|
|
sym_ptr += external_sym_size; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
case N_SOL: |
|
|
|
current_file_name = |
|
|
|
debug_info->ss + fdr_ptr->issBase + sym.iss; |
|
|
|
break; |
|
|
|
|
|
|
|
case N_FUN: |
|
|
|
if (sym.value >= low_func_vma |
|
|
|
&& sym.value <= offset + section->vma) |
|
|
|
{ |
|
|
|
low_func_vma = sym.value; |
|
|
|
function_name = |
|
|
|
debug_info->ss + fdr_ptr->issBase + sym.iss; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (sym.st == stLabel && sym.index != indexNil) |
|
|
|
{ |
|
|
|
if (sym.value > offset + section->vma) |
|
|
|
{ |
|
|
|
/* We have passed the location in the file we are
|
|
|
|
looking for, so we can get out of the loop. */ |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (sym.value >= low_line_vma) |
|
|
|
{ |
|
|
|
low_line_vma = sym.value; |
|
|
|
line_file_name = current_file_name; |
|
|
|
*retline_ptr = sym.index; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (*retline_ptr != 0) |
|
|
|
main_file_name = line_file_name; |
|
|
|
|
|
|
|
/* We need to remove the stuff after the colon in the function
|
|
|
|
name. We also need to put the directory name and the file |
|
|
|
name together. */ |
|
|
|
if (function_name == NULL) |
|
|
|
len = funclen = 0; |
|
|
|
else |
|
|
|
len = funclen = strlen (function_name) + 1; |
|
|
|
|
|
|
|
if (main_file_name != NULL |
|
|
|
&& directory_name != NULL |
|
|
|
&& main_file_name[0] != '/') |
|
|
|
len += strlen (directory_name) + strlen (main_file_name) + 1; |
|
|
|
|
|
|
|
if (len != 0) |
|
|
|
{ |
|
|
|
if (ecoff_data (abfd)->find_buffer != NULL) |
|
|
|
free (ecoff_data (abfd)->find_buffer); |
|
|
|
buffer = (char *) malloc (len); |
|
|
|
if (buffer == NULL) |
|
|
|
{ |
|
|
|
bfd_set_error (bfd_error_no_memory); |
|
|
|
return false; |
|
|
|
} |
|
|
|
ecoff_data (abfd)->find_buffer = buffer; |
|
|
|
} |
|
|
|
|
|
|
|
if (function_name != NULL) |
|
|
|
{ |
|
|
|
char *colon; |
|
|
|
|
|
|
|
strcpy (buffer, function_name); |
|
|
|
colon = strchr (buffer, ':'); |
|
|
|
if (colon != NULL) |
|
|
|
*colon = '\0'; |
|
|
|
*functionname_ptr = buffer; |
|
|
|
} |
|
|
|
|
|
|
|
if (main_file_name != NULL) |
|
|
|
{ |
|
|
|
if (directory_name == NULL || main_file_name[0] == '/') |
|
|
|
*filename_ptr = main_file_name; |
|
|
|
else |
|
|
|
{ |
|
|
|
sprintf (buffer + funclen, "%s%s", directory_name, |
|
|
|
main_file_name); |
|
|
|
*filename_ptr = buffer + funclen; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (lineno == ilineNil) |
|
|
|
lineno = 0; |
|
|
|
*retline_ptr = lineno; |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
@ -2617,7 +2803,7 @@ ecoff_get_extr (sym, esym) |
|
|
|
symbol. */ |
|
|
|
if ((esym->asym.sc == scUndefined |
|
|
|
|| esym->asym.sc == scSUndefined) |
|
|
|
&& bfd_get_section (sym) != &bfd_und_section) |
|
|
|
&& ! bfd_is_und_section (bfd_get_section (sym))) |
|
|
|
esym->asym.sc = scAbs; |
|
|
|
|
|
|
|
/* Adjust the FDR index for the symbol by that used for the input
|
|
|
|
@ -4099,10 +4285,10 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext) |
|
|
|
value -= section->vma; |
|
|
|
break; |
|
|
|
case scAbs: |
|
|
|
section = &bfd_abs_section; |
|
|
|
section = bfd_abs_section_ptr; |
|
|
|
break; |
|
|
|
case scUndefined: |
|
|
|
section = &bfd_und_section; |
|
|
|
section = bfd_und_section_ptr; |
|
|
|
break; |
|
|
|
case scSData: |
|
|
|
section = bfd_make_section_old_way (abfd, ".sdata"); |
|
|
|
@ -4119,7 +4305,7 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext) |
|
|
|
case scCommon: |
|
|
|
if (value > ecoff_data (abfd)->gp_size) |
|
|
|
{ |
|
|
|
section = &bfd_com_section; |
|
|
|
section = bfd_com_section_ptr; |
|
|
|
break; |
|
|
|
} |
|
|
|
/* Fall through. */ |
|
|
|
@ -4140,7 +4326,7 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext) |
|
|
|
section = &ecoff_scom_section; |
|
|
|
break; |
|
|
|
case scSUndefined: |
|
|
|
section = &bfd_und_section; |
|
|
|
section = bfd_und_section_ptr; |
|
|
|
break; |
|
|
|
case scInit: |
|
|
|
section = bfd_make_section_old_way (abfd, ".init"); |
|
|
|
@ -4171,7 +4357,7 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext) |
|
|
|
if (info->hash->creator->flavour == bfd_get_flavour (abfd)) |
|
|
|
{ |
|
|
|
if (h->abfd == (bfd *) NULL |
|
|
|
|| (section != &bfd_und_section |
|
|
|
|| (! bfd_is_und_section (section) |
|
|
|
&& (! bfd_is_com_section (section) |
|
|
|
|| h->root.type != bfd_link_hash_defined))) |
|
|
|
{ |
|
|
|
|