/* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1992, 1994, 1995, 1996
+ Copyright 1986, 1987, 1989, 1991, 1992, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
register struct vmap *vp;
{
register struct objfile *objfile;
- CORE_ADDR text_delta;
- CORE_ADDR data_delta;
- CORE_ADDR bss_delta;
struct section_offsets *new_offsets;
int i;
for (i = 0; i < objfile->num_sections; ++i)
ANOFFSET (new_offsets, i) = ANOFFSET (objfile->section_offsets, i);
- text_delta =
- vp->tstart - ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
- ANOFFSET (new_offsets, SECT_OFF_TEXT) = vp->tstart;
-
- data_delta =
- vp->dstart - ANOFFSET (objfile->section_offsets, SECT_OFF_DATA);
- ANOFFSET (new_offsets, SECT_OFF_DATA) = vp->dstart;
-
- bss_delta =
- vp->dstart - ANOFFSET (objfile->section_offsets, SECT_OFF_BSS);
- ANOFFSET (new_offsets, SECT_OFF_BSS) = vp->dstart;
+ /* The symbols in the object file are linked to the VMA of the section,
+ relocate them VMA relative. */
+ ANOFFSET (new_offsets, SECT_OFF_TEXT) = vp->tstart - vp->tvma;
+ ANOFFSET (new_offsets, SECT_OFF_DATA) = vp->dstart - vp->dvma;
+ ANOFFSET (new_offsets, SECT_OFF_BSS) = vp->dstart - vp->dvma;
objfile_relocate (objfile, new_offsets);
}
vp->dstart = (CORE_ADDR) ldi->ldinfo_dataorg;
vp->dend = vp->dstart + ldi->ldinfo_datasize;
- if (vp->tadj)
- {
- vp->tstart += vp->tadj;
- vp->tend += vp->tadj;
- }
+ /* The run time loader maps the file header in addition to the text
+ section and returns a pointer to the header in ldinfo_textorg.
+ Adjust the text start address to point to the real start address
+ of the text section. */
+ vp->tstart += vp->toffs;
/* The objfile is only NULL for the exec file. */
if (vp->objfile == NULL)
got_exec_file = 1;
-#ifdef DONT_RELOCATE_SYMFILE_OBJFILE
- if (vp->objfile == symfile_objfile
- || vp->objfile == NULL)
- {
- ldi->ldinfo_dataorg = 0;
- vp->dstart = (CORE_ADDR) 0;
- vp->dend = ldi->ldinfo_datasize;
- }
-#endif
-
/* relocate symbol table(s). */
vmap_symtab (vp);
{
if (STREQ(".text", exec_ops.to_sections[i].the_bfd_section->name))
{
- exec_ops.to_sections[i].addr += vmap->tstart;
- exec_ops.to_sections[i].endaddr += vmap->tstart;
+ exec_ops.to_sections[i].addr += vmap->tstart - vmap->tvma;
+ exec_ops.to_sections[i].endaddr += vmap->tstart - vmap->tvma;
}
else if (STREQ(".data", exec_ops.to_sections[i].the_bfd_section->name))
{
- exec_ops.to_sections[i].addr += vmap->dstart;
- exec_ops.to_sections[i].endaddr += vmap->dstart;
+ exec_ops.to_sections[i].addr += vmap->dstart - vmap->dvma;
+ exec_ops.to_sections[i].endaddr += vmap->dstart - vmap->dvma;
+ }
+ else if (STREQ(".bss", exec_ops.to_sections[i].the_bfd_section->name))
+ {
+ exec_ops.to_sections[i].addr += vmap->dstart - vmap->dvma;
+ exec_ops.to_sections[i].endaddr += vmap->dstart - vmap->dvma;
}
}
}
vp->dstart = (CORE_ADDR) ldip->ldinfo_dataorg;
vp->dend = vp->dstart + ldip->ldinfo_datasize;
-#ifdef DONT_RELOCATE_SYMFILE_OBJFILE
- if (vp == vmap)
- {
- vp->dstart = (CORE_ADDR) 0;
- vp->dend = ldip->ldinfo_datasize;
- }
-#endif
-
- if (vp->tadj != 0)
- {
- vp->tstart += vp->tadj;
- vp->tend += vp->tadj;
- }
+ /* The run time loader maps the file header in addition to the text
+ section and returns a pointer to the header in ldinfo_textorg.
+ Adjust the text start address to point to the real start address
+ of the text section. */
+ vp->tstart += vp->toffs;
/* Unless this is the exec file,
add our sections to the section table for the core target. */
}
stp = target->to_sections_end - 2;
- /* "Why do we add bfd_section_vma?", I hear you cry.
- Well, the start of the section in the file is actually
- that far into the section as the struct vmap understands it.
- So for text sections, bfd_section_vma tends to be 0x200,
- and if vp->tstart is 0xd0002000, then the first byte of
- the text section on disk corresponds to address 0xd0002200. */
stp->bfd = vp->bfd;
stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text");
- stp->addr = bfd_section_vma (stp->bfd, stp->the_bfd_section) + vp->tstart;
- stp->endaddr = bfd_section_vma (stp->bfd, stp->the_bfd_section) + vp->tend;
+ stp->addr = vp->tstart;
+ stp->endaddr = vp->tend;
stp++;
stp->bfd = vp->bfd;
stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".data");
- stp->addr = bfd_section_vma (stp->bfd, stp->the_bfd_section) + vp->dstart;
- stp->endaddr = bfd_section_vma (stp->bfd, stp->the_bfd_section) + vp->dend;
+ stp->addr = vp->dstart;
+ stp->endaddr = vp->dend;
}
vmap_symtab (vp);
}
\f
-/* Find which partial symtab on contains PC. Return 0 if none. */
+
+struct symbol * fixup_symbol_section PARAMS ((struct symbol *,
+ struct objfile *));
+struct partial_symbol * fixup_psymbol_section PARAMS ((struct partial_symbol *,
+ struct objfile *));
+
+
+/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
struct partial_symtab *
-find_pc_psymtab (pc)
- register CORE_ADDR pc;
+find_pc_sect_psymtab (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register struct partial_symtab *pst;
register struct objfile *objfile;
many partial symbol tables containing the PC, but
we want the partial symbol table that contains the
function containing the PC. */
- if (!(objfile->flags & OBJF_REORDERED))
+ if (!(objfile->flags & OBJF_REORDERED) &&
+ section == 0) /* can't validate section this way */
return (pst);
- msymbol = lookup_minimal_symbol_by_pc (pc);
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
if (msymbol == NULL)
return (pst);
{
struct partial_symbol *p;
- p = find_pc_psymbol (tpst, pc);
+ p = find_pc_sect_psymbol (tpst, pc, section);
if (p != NULL
&& SYMBOL_VALUE_ADDRESS(p)
== SYMBOL_VALUE_ADDRESS (msymbol))
return (NULL);
}
-/* Find which partial symbol within a psymtab contains PC. Return 0
- if none. Check all psymtabs if PSYMTAB is 0. */
+/* Find which partial symtab contains PC. Return 0 if none.
+ Backward compatibility, no section */
+
+struct partial_symtab *
+find_pc_psymtab (pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_psymtab (pc, find_pc_mapped_section (pc));
+}
+
+/* Find which partial symbol within a psymtab matches PC and SECTION.
+ Return 0 if none. Check all psymtabs if PSYMTAB is 0. */
+
struct partial_symbol *
-find_pc_psymbol (psymtab, pc)
+find_pc_sect_psymbol (psymtab, pc, section)
struct partial_symtab *psymtab;
CORE_ADDR pc;
+ asection *section;
{
struct partial_symbol *best = NULL, *p, **pp;
CORE_ADDR best_pc;
if (!psymtab)
- psymtab = find_pc_psymtab (pc);
+ psymtab = find_pc_sect_psymtab (pc, section);
if (!psymtab)
return 0;
&& pc >= SYMBOL_VALUE_ADDRESS (p)
&& SYMBOL_VALUE_ADDRESS (p) > best_pc)
{
+ if (section) /* match on a specific section */
+ {
+ fixup_psymbol_section (p, psymtab->objfile);
+ if (SYMBOL_BFD_SECTION (p) != section)
+ continue;
+ }
best_pc = SYMBOL_VALUE_ADDRESS (p);
best = p;
}
&& pc >= SYMBOL_VALUE_ADDRESS (p)
&& SYMBOL_VALUE_ADDRESS (p) > best_pc)
{
+ if (section) /* match on a specific section */
+ {
+ fixup_psymbol_section (p, psymtab->objfile);
+ if (SYMBOL_BFD_SECTION (p) != section)
+ continue;
+ }
best_pc = SYMBOL_VALUE_ADDRESS (p);
best = p;
}
return best;
}
+/* Find which partial symbol within a psymtab matches PC. Return 0 if none.
+ Check all psymtabs if PSYMTAB is 0. Backwards compatibility, no section. */
+
+struct partial_symbol *
+find_pc_psymbol (psymtab, pc)
+ struct partial_symtab *psymtab;
+ CORE_ADDR pc;
+{
+ return find_pc_sect_psymbol (psymtab, pc, find_pc_mapped_section (pc));
+}
+\f
/* Debug symbols usually don't have section information. We need to dig that
out of the minimal symbols and stash that in the debug symbol. */
-static
-struct symbol * fixup_symbol_section PARAMS ((struct symbol *sym,
- struct objfile *objfile));
-static struct symbol *
+static void
+fixup_section (ginfo, objfile)
+ struct general_symbol_info *ginfo;
+ struct objfile *objfile;
+{
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
+
+ if (msym)
+ ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
+}
+
+struct symbol *
fixup_symbol_section (sym, objfile)
struct symbol *sym;
struct objfile *objfile;
if (SYMBOL_BFD_SECTION (sym))
return sym;
- msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
-
- if (msym)
- SYMBOL_BFD_SECTION (sym) = SYMBOL_BFD_SECTION (msym);
+ fixup_section (&sym->ginfo, objfile);
return sym;
}
-\f
+struct partial_symbol *
+fixup_psymbol_section (psym, objfile)
+ struct partial_symbol *psym;
+ struct objfile *objfile;
+{
+ struct minimal_symbol *msym;
+
+ if (!psym)
+ return NULL;
+
+ if (SYMBOL_BFD_SECTION (psym))
+ return psym;
+
+ fixup_section (&psym->ginfo, objfile);
+
+ return psym;
+}
+
/* Find the definition for a specified symbol name NAME
in namespace NAMESPACE, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
msymbol = lookup_minimal_symbol (name, NULL, NULL);
if (msymbol != NULL)
{
- s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol));
+ s = find_pc_sect_symtab (SYMBOL_VALUE_ADDRESS (msymbol),
+ SYMBOL_BFD_SECTION (msymbol));
if (s != NULL)
{
/* This is a function which has a symtab for its address. */
{
/* This is a mangled variable, look it up by its
mangled name. */
- return fixup_symbol_section
- (lookup_symbol (SYMBOL_NAME (msymbol), block,
- namespace, is_a_field_of_this, symtab),
- NULL);
+ return lookup_symbol (SYMBOL_NAME (msymbol), block,
+ namespace, is_a_field_of_this, symtab);
}
/* There are no debug symbols for this file, or we are looking
for an unmangled variable.
return BLOCK_FUNCTION (bl);
}
-/* Find the symtab associated with PC. Look through the psymtabs and read in
- another symtab if necessary. */
+/* Find the symtab associated with PC and SECTION. Look through the
+ psymtabs and read in another symtab if necessary. */
struct symtab *
-find_pc_symtab (pc)
- register CORE_ADDR pc;
+find_pc_sect_symtab (pc, section)
+ CORE_ADDR pc;
+ asection *section;
{
register struct block *b;
struct blockvector *bv;
/* For an objfile that has its functions reordered,
find_pc_psymtab will find the proper partial symbol table
and we simply return its corresponding symtab. */
+ /* In order to better support objfiles that contain both
+ stabs and coff debugging info, we continue on if a psymtab
+ can't be found. */
if ((objfile->flags & OBJF_REORDERED) && objfile->psymtabs)
{
- ps = find_pc_psymtab (pc);
+ ps = find_pc_sect_psymtab (pc, section);
if (ps)
- s = PSYMTAB_TO_SYMTAB (ps);
- else
- s = NULL;
- return (s);
+ return PSYMTAB_TO_SYMTAB (ps);
+ }
+ if (section != 0)
+ {
+ int i;
+
+ for (i = 0; i < b->nsyms; i++)
+ {
+ fixup_symbol_section (b->sym[i], objfile);
+ if (section == SYMBOL_BFD_SECTION (b->sym[i]))
+ break;
+ }
+ if (i >= b->nsyms)
+ continue; /* no symbol in this symtab matches section */
}
distance = BLOCK_END (b) - BLOCK_START (b);
best_s = s;
return(best_s);
s = NULL;
- ps = find_pc_psymtab (pc);
+ ps = find_pc_sect_psymtab (pc, section);
if (ps)
{
if (ps->readin)
}
return (s);
}
+
+/* Find the symtab associated with PC. Look through the psymtabs and
+ read in another symtab if necessary. Backward compatibility, no section */
+
+struct symtab *
+find_pc_symtab (pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_symtab (pc, find_pc_mapped_section (pc));
+}
+
\f
#if 0
}
#endif /* 0 */
-/* Find the source file and line number for a given PC value.
+/* Find the source file and line number for a given PC value and section.
Return a structure containing a symtab pointer, a line number,
and a pc range for the entire source line.
The value's .pc field is NOT the specified pc.
/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
-find_pc_line (pc, notcurrent)
+find_pc_sect_line (pc, section, notcurrent)
CORE_ADDR pc;
+ struct sec *section;
int notcurrent;
{
struct symtab *s;
INIT_SAL (&val); /* initialize to zeroes */
- if (notcurrent)
+ if (notcurrent)
pc -= 1;
- s = find_pc_symtab (pc);
+ s = find_pc_sect_symtab (pc, section);
if (!s)
{
val.pc = pc;
else
val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
}
+ val.section = section;
return val;
}
+
+/* Backward compatibility (no section) */
+
+struct symtab_and_line
+find_pc_line (pc, notcurrent)
+ CORE_ADDR pc;
+ int notcurrent;
+{
+ asection *section;
+
+ section = find_pc_overlay (pc);
+ if (pc_in_unmapped_range (pc, section))
+ pc = overlay_mapped_address (pc, section);
+ return find_pc_sect_line (pc, section, notcurrent);
+}
+
\f
static int find_line_symtab PARAMS ((struct symtab *, int, struct linetable **,
int *, int *));
This also insures that we never give a range like "starts at 0x134
and ends at 0x12c". */
- found_sal = find_pc_line (startaddr, 0);
+ found_sal = find_pc_sect_line (startaddr, sal.section, 0);
if (found_sal.line != sal.line)
{
/* The specified line (sal) has zero bytes. */
struct symtab_and_line sal;
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ fixup_symbol_section (sym, NULL);
if (funfirstline)
- {
+ { /* skip "first line" of function (which is actually its prologue) */
+ asection *section = SYMBOL_BFD_SECTION (sym);
+ /* If function is in an unmapped overlay, use its unmapped LMA
+ address, so that SKIP_PROLOGUE has something unique to work on */
+ if (section_is_overlay (section) &&
+ !section_is_mapped (section))
+ pc = overlay_unmapped_address (pc, section);
+
pc += FUNCTION_START_OFFSET;
SKIP_PROLOGUE (pc);
+
+ /* For overlays, map pc back into its mapped VMA range */
+ pc = overlay_mapped_address (pc, section);
}
- sal = find_pc_line (pc, 0);
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
#ifdef PROLOGUE_FIRSTLINE_OVERLAP
/* Convex: no need to suppress code on first line, if any */
/* First pc of next line */
pc = sal.end;
/* Recalculate the line number (might not be N+1). */
- sal = find_pc_line (pc, 0);
+ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
}
sal.pc = pc;
#endif
int count;
CHECK_TYPEDEF (type);
+ if (TYPE_CPLUS_SPECIFIC (type) == NULL)
+ return 0;
count = TYPE_NFN_FIELDS_TOTAL (type);
for (n = 0; n < TYPE_N_BASECLASSES (type); n++)
xmalloc (sizeof (struct symtab_and_line));
values.nelts = 1;
values.sals[0] = find_pc_line (pc, 0);
- values.sals[0].pc = pc;
return values;
}
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
values.nelts = 1;
values.sals[0] = find_function_start_sal (sym,
funfirstline);
s = default_symtab;
val.symtab = s;
val.pc = 0;
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
values.sals[0] = val;
values.nelts = 1;
if (need_canonical)
if (SYMBOL_CLASS (sym) == LOC_BLOCK)
{
/* Arg is the name of a function */
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
values.sals[0] = find_function_start_sal (sym, funfirstline);
values.nelts = 1;
msymbol = lookup_minimal_symbol (copy, NULL, NULL);
if (msymbol != NULL)
{
- val.pc = SYMBOL_VALUE_ADDRESS (msymbol);
+ val.pc = SYMBOL_VALUE_ADDRESS (msymbol);
+ val.section = SYMBOL_BFD_SECTION (msymbol);
if (funfirstline)
{
val.pc += FUNCTION_START_OFFSET;
struct cleanup *old_chain;
char **canonical_arr = (char **)NULL;
- values.sals = (struct symtab_and_line *) alloca (nelts * sizeof(struct symtab_and_line));
- return_values.sals = (struct symtab_and_line *) xmalloc (nelts * sizeof(struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ alloca (nelts * sizeof(struct symtab_and_line));
+ return_values.sals = (struct symtab_and_line *)
+ xmalloc (nelts * sizeof(struct symtab_and_line));
old_chain = make_cleanup (free, return_values.sals);
if (canonical)
between the first instruction of a function, and the first executable line.
Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
- If non-zero, func_start is where we thing the prologue starts, possibly
+ If non-zero, func_start is where we think the prologue starts, possibly
by previous examination of symbol table information.
*/
/* Read AIX xcoff symbol tables and convert to internal format, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
Free Software Foundation, Inc.
Derived from coffread.c, dbxread.c, and a lot of hacking.
Contributed by IBM Corporation.
/* Translate from a COFF section number (target_index) to a SECT_OFF_*
code. */
static int secnum_to_section PARAMS ((int, struct objfile *));
+static asection * secnum_to_bfd_section PARAMS ((int, struct objfile *));
struct find_targ_sec_arg {
int targ_index;
int *resultp;
+ asection **bfd_sect;
};
static void find_targ_sec PARAMS ((bfd *, asection *, void *));
*args->resultp = SECT_OFF_DATA;
else
*args->resultp = SECT_OFF_BSS;
+ *args->bfd_sect = sect;
}
}
struct objfile *objfile;
{
int off = SECT_OFF_TEXT;
+ asection *sect = NULL;
struct find_targ_sec_arg args;
args.targ_index = secnum;
args.resultp = &off;
+ args.bfd_sect = §
bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
return off;
}
+
+/* Return the BFD section that CS points to. */
+static asection *
+secnum_to_bfd_section (secnum, objfile)
+ int secnum;
+ struct objfile *objfile;
+{
+ int off = SECT_OFF_TEXT;
+ asection *sect = NULL;
+ struct find_targ_sec_arg args;
+ args.targ_index = secnum;
+ args.resultp = &off;
+ args.bfd_sect = §
+ bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+ return sect;
+}
\f
/* add a given stab string into given stab vector. */
struct section_offsets *section_offsets;
struct objfile *objfile;
{
- int toc_offset = 0; /* toc offset value in data section. */
+ CORE_ADDR toc_offset = 0; /* toc offset value in data section. */
char *filestring = NULL;
char *namestring;
int past_first_source_file = 0;
bfd *abfd;
+ asection *bfd_sect;
unsigned int nsyms;
/* Current partial symtab */
if (toc_offset)
warning ("More than one XMC_TC0 symbol found.");
toc_offset = symbol.n_value;
+
+ /* Make TOC offset relative to start address of section. */
+ bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile);
+ if (bfd_sect)
+ toc_offset -= bfd_section_vma (objfile->obfd, bfd_sect);
break;
case XMC_TC: