/* Native support for the SGI Iris running IRIX version 5, for GDB.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
Implemented for Irix 4.x by Garrett A. Wollman.
#define DEBUG_BASE "__rld_obj_head"
/* How to get the loaded address of a shared library. */
-#define LM_ADDR(so) ((so)->lm.o_base_address)
+#define LM_ADDR(so) ((so)->lm.o_praw)
char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
struct section_table *p;
struct cleanup *old_chain;
bfd *abfd;
+ CORE_ADDR offset;
filename = tilde_expand (so -> lm.o_path);
old_chain = make_cleanup (free, filename);
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
}
+ /* Irix 5 shared objects are pre-linked to particular addresses
+ although the dynamic linker may have to relocate them if the
+ address ranges of the libraries used by the main program clash.
+ The offset is the difference between the address where the object
+ is mapped and the binding address of the shared library. */
+ offset = (CORE_ADDR) LM_ADDR (so) - so -> lm.o_base_address;
+
for (p = so -> sections; p < so -> sections_end; p++)
{
/* Relocate the section binding addresses as recorded in the shared
- object's file by the base address to which the object was actually
- mapped. */
- p -> addr += (CORE_ADDR) LM_ADDR (so);
- p -> endaddr += (CORE_ADDR) LM_ADDR (so);
+ object's file by the offset to get the address to which the
+ object was actually mapped. */
+ p -> addr += offset;
+ p -> endaddr += offset;
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
if (STREQ (p -> the_bfd_section -> name, ".text"))
{
{
if (so -> lm.o_path[0])
{
- if ((address >= (CORE_ADDR) so->lm.o_base_address) &&
+ if ((address >= (CORE_ADDR) LM_ADDR (so)) &&
(address < (CORE_ADDR) so -> lmend))
{
return (1);
switch (sh->sc)
{
case scText:
- sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ /* The value of a stEnd symbol is the displacement from the
+ corresponding start symbol value, do not relocate it. */
+ if (sh->st != stEnd)
+ sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
break;
case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA);
break;
case scBss:
+ case scSBss:
sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS);
break;
}
Just ignore it. */
break;
+ case stIndirect:
+ /* Irix5 cc puts out a stIndirect for struct x if it is not
+ yet defined when it encounters
+ struct y { struct x *xp; };
+ Just ignore it. */
+ break;
+
default:
complain (&block_member_complaint, tsym.st);
}
f->bitsize = bitsize;
break;
+ case stIndirect: /* forward declaration on Irix5 */
+ /* Forward declarations from Irix5 cc are handled by cross_ref,
+ skip them. */
+ break;
+
case stTypedef: /* type definition */
/* Typedefs for forward declarations and opaque structs from alpha cc
are handled by cross_ref, skip them. */
generates a cross referencing stTypedef for x and xx.
The user visible effect of this is that the type of a pointer
to struct foo sometimes is given as `foo *' instead of `struct foo *'.
- The problem is fixed with alpha cc. */
+ The problem is fixed with alpha cc and Irix5 cc. */
/* However if the typedef cross references to an opaque aggregate, it
is safe to omit it from the symbol table. */
in question, or NULL to use top_stack->cur_block. */
static void parse_procedure PARAMS ((PDR *, struct symtab *, unsigned long,
- struct section_offsets *));
+ struct partial_symtab *));
static void
-parse_procedure (pr, search_symtab, first_off, section_offsets)
+parse_procedure (pr, search_symtab, first_off, pst)
PDR *pr;
struct symtab *search_symtab;
unsigned long first_off;
- struct section_offsets *section_offsets;
+ struct partial_symtab *pst;
{
struct symbol *s, *i;
struct block *b;
e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
e->pdr = *pr;
e->pdr.isym = (long) s;
- e->pdr.adr += cur_fdr->adr - first_off
- + ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ e->pdr.adr += pst->textlow - first_off;
/* Correct incorrect setjmp procedure descriptor from the library
to make backtrace through setjmp work. */
numbers can go back and forth, apparently we can live
with that and do not need to reorder our linetables */
+static void parse_lines PARAMS ((FDR *, PDR *, struct linetable *, int,
+ struct partial_symtab *));
+
static void
-parse_lines (fh, pr, lt, maxlines, section_offsets)
+parse_lines (fh, pr, lt, maxlines, pst)
FDR *fh;
PDR *pr;
struct linetable *lt;
int maxlines;
- struct section_offsets *section_offsets;
+ struct partial_symtab *pst;
{
unsigned char *base;
int j, k;
halt = base + fh->cbLine;
base += pr->cbLineOffset;
- adr = fh->adr + pr->adr - first_off
- + ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ adr = pst->textlow + pr->adr - first_off;
l = adr >> 2; /* in words */
for (lineno = pr->lnLow; base < halt; )
struct cleanup *old_chain;
char *name;
enum language prev_language;
+ asection *text_sect;
+ int relocatable = 0;
+
+ /* Irix 5.2 shared libraries have a fh->adr field of zero, but
+ the shared libraries are prelinked at a high memory address.
+ We have to adjust the start address of the object file for this case,
+ by setting it to the start address of the first procedure in the file.
+ But we should do no adjustments if we are debugging a .o file, where
+ the text section (and fh->adr) really starts at zero. */
+ text_sect = bfd_get_section_by_name (cur_bfd, ".text");
+ if (text_sect != NULL
+ && (bfd_get_section_flags (cur_bfd, text_sect) & SEC_RELOC))
+ relocatable = 1;
extern_tab = (EXTR *) obstack_alloc (&objfile->psymbol_obstack,
sizeof (EXTR) * hdr->iextMax);
for (; ext_in < ext_in_end; ext_in++)
{
enum minimal_symbol_type ms_type = mst_text;
+ CORE_ADDR svalue = ext_in->asym.value;
/* The Irix 5 native tools seem to sometimes generate bogus
external symbols. */
switch (ext_in->asym.st)
{
case stProc:
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
break;
case stStaticProc:
ms_type = mst_file_text;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
break;
case stGlobal:
if (ext_in->asym.sc == scCommon)
|| ext_in->asym.sc == scRData
|| ext_in->asym.sc == scPData
|| ext_in->asym.sc == scXData)
- ms_type = mst_data;
+ {
+ ms_type = mst_data;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
+ }
else
- ms_type = mst_bss;
+ {
+ ms_type = mst_bss;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
+ }
break;
case stLabel:
if (ext_in->asym.sc == scAbs)
else if (ext_in->asym.sc == scText
|| ext_in->asym.sc == scInit
|| ext_in->asym.sc == scFini)
- ms_type = mst_file_text;
+ {
+ ms_type = mst_file_text;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ }
else if (ext_in->asym.sc == scData
|| ext_in->asym.sc == scSData
|| ext_in->asym.sc == scRData
|| ext_in->asym.sc == scPData
|| ext_in->asym.sc == scXData)
- ms_type = mst_file_data;
+ {
+ ms_type = mst_file_data;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
+ }
else
- ms_type = mst_file_bss;
+ {
+ ms_type = mst_file_bss;
+ svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
+ }
break;
case stLocal:
/* The alpha has the section start addresses in stLocal symbols
ms_type = mst_unknown;
complain (&unknown_ext_complaint, name);
}
- prim_record_minimal_symbol (name, ext_in->asym.value, ms_type, objfile);
+ prim_record_minimal_symbol (name, svalue, ms_type, objfile);
}
/* Pass 3 over files, over local syms: fill in static symbols */
{
struct partial_symtab *save_pst;
EXTR *ext_ptr;
+ CORE_ADDR textlow;
cur_fdr = fh = debug_info->fdr + f_idx;
fdr_to_pst[f_idx].pst = NULL;
continue;
}
+
+ /* Determine the start address for this object file from the
+ file header and relocate it, except for Irix 5.2 zero fh->adr. */
+ if (fh->cpd)
+ {
+ textlow = fh->adr;
+ if (relocatable || textlow != 0)
+ textlow += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ }
+ else
+ textlow = 0;
pst = start_psymtab_common (objfile, section_offsets,
fdr_name (fh),
- fh->cpd ? fh->adr : 0,
+ textlow,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
pst->read_symtab_private = ((char *)
if (sh.st == stEnd)
{
long high = procaddr + sh.value;
+
+ /* Kludge for Irix 5.2 zero fh->adr. */
+ if (!relocatable
+ && (pst->textlow == 0 || procaddr < pst->textlow))
+ pst->textlow = procaddr;
if (high > pst->texthigh)
pst->texthigh = high;
}
name = debug_info->ss + fh->issBase + sh.iss;
+ switch (sh.sc)
+ {
+ case scText:
+ /* The value of a stEnd symbol is the displacement from the
+ corresponding start symbol value, do not relocate it. */
+ if (sh.st != stEnd)
+ sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ break;
+ case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
+ sh.value += ANOFFSET (section_offsets, SECT_OFF_DATA);
+ break;
+ case scBss:
+ case scSBss:
+ sh.value += ANOFFSET (section_offsets, SECT_OFF_BSS);
+ break;
+ }
+
switch (sh.st)
{
long high;
&sh);
if (sh.st != stEnd)
continue;
+
+ /* Kludge for Irix 5.2 zero fh->adr. */
+ if (!relocatable
+ && (pst->textlow == 0 || procaddr < pst->textlow))
+ pst->textlow = procaddr;
+
high = procaddr + sh.value;
if (high > pst->texthigh)
pst->texthigh = high;
class = LOC_STATIC;
break;
+ case stIndirect:/* Irix5 forward declaration */
+ /* Skip forward declarations from Irix5 cc */
+ goto skip;
+
case stTypedef:/* Typedef */
/* Skip typedefs for forward declarations and opaque
structs from alpha and mips cc. */
enum address_class class;
SYMR *psh;
char *name;
+ CORE_ADDR svalue;
if (ext_ptr->ifd != f_idx)
abort ();
if (psh->sc == scUndefined || psh->sc == scNil)
continue;
+ svalue = psh->value;
+ switch (psh->sc)
+ {
+ case scText:
+ svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ break;
+ case scData:
+ case scSData:
+ case scRData:
+ case scPData:
+ case scXData:
+ svalue += ANOFFSET (section_offsets, SECT_OFF_DATA);
+ break;
+ case scBss:
+ case scSBss:
+ svalue += ANOFFSET (section_offsets, SECT_OFF_BSS);
+ break;
+ }
+
switch (psh->st)
{
case stNil:
ADD_PSYMBOL_ADDR_TO_LIST (name, strlen (name),
VAR_NAMESPACE, class,
objfile->global_psymbols,
- (CORE_ADDR) psh->value,
+ svalue,
psymtab_language, objfile);
}
}
first_off = pr.adr;
first_pdr = 0;
}
- parse_procedure (&pr, st, first_off, pst->section_offsets);
+ parse_procedure (&pr, st, first_off, pst);
}
}
else
top_stack->cur_st = st;
top_stack->cur_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (st),
STATIC_BLOCK);
- BLOCK_START (top_stack->cur_block) = fh ? fh->adr : 0;
+ BLOCK_START (top_stack->cur_block) = pst->textlow;
BLOCK_END (top_stack->cur_block) = 0;
top_stack->blocktype = stFile;
top_stack->maxsyms = 2 * f_max;
pdr_ptr += external_pdr_size, pdr_in++)
(*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
- parse_lines (fh, pr_block, lines, maxlines,
- pst->section_offsets);
+ parse_lines (fh, pr_block, lines, maxlines, pst);
if (lines->nitems < fh->cline)
lines = shrink_linetable (lines);
pdr_in = pr_block;
pdr_in_end = pdr_in + fh->cpd;
for (; pdr_in < pdr_in_end; pdr_in++)
- parse_procedure (pdr_in, 0, pr_block->adr,
- pst->section_offsets);
+ parse_procedure (pdr_in, 0, pr_block->adr, pst);
do_cleanups (old_chain);
}
/* Make sure that this type of cross reference can be handled. */
if ((sh.sc != scInfo
- || (sh.st != stBlock && sh.st != stTypedef
+ || (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
&& sh.st != stStruct && sh.st != stUnion
&& sh.st != stEnum))
&& (sh.sc != scCommon || sh.st != stBlock))
{
/* We have not yet seen this type. */
- if (sh.iss == 0 && sh.st == stTypedef)
+ if ((sh.iss == 0 && sh.st == stTypedef) || sh.st == stIndirect)
{
TIR tir;
due to the missing name.
b) forward declarations of structs/unions/enums which are defined
later in this file or in another file in the same compilation
- unit. Simply cross reference those again to get the
- true type.
+ unit. Irix5 cc uses a stIndirect symbol for this.
+ Simply cross reference those again to get the true type.
The forward references are not entered in the pending list and
in the symbol table. */