Mostly merged in changes from IBM (Metin); see ChangeLog.

This commit is contained in:
Per Bothner 1992-03-13 01:42:25 +00:00
parent 8a62f15528
commit 507e40040c
5 changed files with 388 additions and 90 deletions

View File

@ -116,7 +116,7 @@ iterate_over_msymbols (func, arg1, arg2, arg3)
particular objfile and the search is limited to that objfile. Returns
a pointer to the minimal symbol that matches, or NULL if no match is found.
Note: One instance where their may be duplicate minimal symbols with
Note: One instance where there may be duplicate minimal symbols with
the same name is when the symbol tables for a shared library and the
symbol tables for an executable contain global symbols with the same
names (the dynamic linker deals with the duplication). */
@ -129,6 +129,9 @@ lookup_minimal_symbol (name, objf)
struct objfile *objfile;
struct minimal_symbol *msymbol;
struct minimal_symbol *found_symbol = NULL;
#ifdef IBM6000
struct minimal_symbol *trampoline_symbol = NULL;
#endif
for (objfile = object_files;
objfile != NULL && found_symbol == NULL;
@ -143,11 +146,36 @@ lookup_minimal_symbol (name, objf)
{
if (strcmp (msymbol -> name, name) == 0)
{
/* I *think* all platforms using shared libraries (and trampoline code)
* will suffer this problem. Consider a case where there are 5 shared
* libraries, each referencing `foo' with a trampoline entry. When someone
* wants to put a breakpoint on `foo' and the only info we have is minimal
* symbol vector, we want to use the real `foo', rather than one of those
* trampoline entries. MGO */
#ifdef IBM6000
/* If a trampoline symbol is found, we prefer to keep looking
for the *real* symbol. If the actual symbol not found,
then we'll use the trampoline entry. Sorry for the machine
dependent code here, but I hope this will benefit other
platforms as well. For trampoline entries, we used mst_unknown
earlier. Perhaps we should define a `mst_trampoline' type?? */
if (msymbol->type != mst_unknown)
found_symbol = msymbol;
else if (msymbol->type == mst_unknown && !trampoline_symbol)
trampoline_symbol = msymbol;
#else
found_symbol = msymbol;
#endif
}
}
}
}
#ifdef IBM6000
return found_symbol ? found_symbol : trampoline_symbol;
#endif
return (found_symbol);
}

View File

@ -44,6 +44,7 @@ extern int attach_flag;
/* Nonzero if we just simulated a single step break. */
int one_stepped;
/* Breakpoint shadows for the single step instructions will be kept here. */
static struct sstep_breaks {
@ -188,13 +189,6 @@ int pc;
op = read_memory_integer (pc, 4);
}
#if 0
if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
pc += 4; /* store floating register double */
op = read_memory_integer (pc, 4);
}
#endif
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
pc += 4;
op = read_memory_integer (pc, 4);
@ -213,7 +207,7 @@ int pc;
op = read_memory_integer (pc, 4);
}
/* store parameters into stack */
/* store parameters into stack */
while(
(op & 0xfc1f0000) == 0xd8010000 || /* stfd Rx,NUM(r1) */
(op & 0xfc1f0000) == 0x90010000 || /* st r?, NUM(r1) */
@ -235,6 +229,33 @@ int pc;
tmp += 0x20;
}
}
#if 0
/* I have problems with skipping over __main() that I need to address
* sometime. Previously, I used to use misc_function_vector which
* didn't work as well as I wanted to be. -MGO */
/* If the first thing after skipping a prolog is a branch to a function,
this might be a call to an initializer in main(), introduced by gcc2.
We'd like to skip over it as well. Fortunately, xlc does some extra
work before calling a function right after a prologue, thus we can
single out such gcc2 behaviour. */
if ((op & 0xfc000001) == 0x48000001) { /* bl foo, an initializer function? */
op = read_memory_integer (pc+4, 4);
if (op == 0x4def7b82) { /* cror 0xf, 0xf, 0xf (nop) */
/* check and see if we are in main. If so, skip over this initializer
function as well. */
tmp = find_pc_misc_function (pc);
if (tmp >= 0 && !strcmp (misc_function_vector [tmp].name, "main"))
return pc + 8;
}
}
#endif /* 0 */
return pc;
}
@ -244,6 +265,7 @@ int pc;
CORE_ADDR text_start;
CORE_ADDR text_end;
/*************************************************************************
Support for creating pushind a dummy frame into the stack, and popping
frames, etc.

View File

@ -333,7 +333,7 @@ frame_initial_stack_address (fi)
return fi->initial_sp = read_register (fdata.alloca_reg);
/* Otherwise, this is a caller frame. Callee has usually already saved
registers, but there are are exceptions (such as when the callee
registers, but there are exceptions (such as when the callee
has no parameters). Find the address in which caller's alloca
register is saved. */

View File

@ -124,7 +124,16 @@ exec_close(quitting)
}
vmap = 0;
exec_bfd = 0;
if (exec_bfd) {
bfd_close (exec_bfd);
exec_bfd = NULL;
}
if (exec_ops.to_sections) {
free (exec_ops.to_sections);
exec_ops.to_sections = NULL;
exec_ops.to_sections_end = NULL;
}
}
/*
@ -134,9 +143,9 @@ void
exec_file_command(filename, from_tty)
char *filename;
{
bfd *bfd;
target_preopen(from_tty);
/* Remove any previous exec file. */
unpush_target(&exec_ops);
/* Now open and digest the file the user requested, if any. */
@ -148,33 +157,33 @@ char *filename;
filename = tilde_expand(filename);
make_cleanup (free, filename);
scratch_chan = openp(getenv("PATH"), 1, filename, O_RDONLY, 0
, &scratch_pathname);
scratch_chan = openp(getenv("PATH"), 1, filename,
write_files? O_RDWR: O_RDONLY, 0,
&scratch_pathname);
if (scratch_chan < 0)
perror_with_name(filename);
bfd = bfd_fdopenr(scratch_pathname, NULL, scratch_chan);
if (!bfd)
exec_bfd = bfd_fdopenr(scratch_pathname, NULL, scratch_chan);
if (!exec_bfd)
error("Could not open `%s' as an executable file: %s"
, scratch_pathname, bfd_errmsg(bfd_error));
/* make sure we have an object file */
if (!bfd_check_format(bfd, bfd_object))
error("\"%s\": not in executable format: %s."
, scratch_pathname, bfd_errmsg(bfd_error));
if (!bfd_check_format(exec_bfd, bfd_object))
error("\"%s\": not in executable format: %s.",
scratch_pathname, bfd_errmsg(bfd_error));
/* setup initial vmap */
map_vmap (bfd, 0);
map_vmap (exec_bfd, 0);
if (!vmap)
error("Can't find the file sections in `%s': %s"
, bfd->filename, bfd_errmsg(bfd_error));
error("Can't find the file sections in `%s': %s",
exec_bfd->filename, bfd_errmsg(bfd_error));
exec_bfd = bfd;
if (build_section_table (exec_bfd, &exec_sections, &exec_sections_end))
if (build_section_table (exec_bfd, &exec_ops.to_sections,
&exec_ops.to_sections_end))
error ("Can't find the file sections in `%s': %s",
exec_bfd->filename, bfd_errmsg (bfd_error));
@ -224,6 +233,9 @@ add_to_section_table (abfd, asect, table_pp_char)
/* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */
if (!(aflag & SEC_LOAD))
return;
if (0 == bfd_section_size (abfd, asect))
return;
(*table_pp)->bfd = abfd;
(*table_pp)->sec_ptr = asect;
(*table_pp)->addr = bfd_section_vma (abfd, asect);
(*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
@ -280,12 +292,12 @@ sex_to_vmap(bfd *bf, sec_ptr sex, struct vmap_and_bfd *vmap_bfd)
vp->tstart = 0;
vp->tend = vp->tstart + bfd_section_size(bf, sex);
/* This is quite a tacky way to recognize the `exec' load segment (rather
than shared libraries. You should use `arch' instead. FIXMEmgo */
if (!vmap)
vp->tadj = sex->filepos - bfd_section_vma(bf, sex);
else
vp->tadj = 0;
/* When it comes to this adjustment value, in contrast to our previous
belief shared objects should behave the same as the main load segment.
This is the offset from the beginning of text section to the first
real instruction. */
vp->tadj = sex->filepos - bfd_section_vma(bf, sex);
}
else if (!strcmp(bfd_section_name(bf, sex), ".data")) {
@ -328,9 +340,33 @@ map_vmap (bfd *bf, bfd *arch)
*vpp = vp;
}
#define FASTER_MSYMBOL_RELOCATION 1
#ifdef FASTER_MSYMBOL_RELOCATION
/* Used to relocate an object file's minimal symbols. */
static void
reloc_objfile_msymbols (objf, addr)
struct objfile *objf;
CORE_ADDR addr;
{
register struct minimal_symbol *msymbol;
int ii;
for (msymbol = objf->msymbols, ii=0;
msymbol && ii < objf->minimal_symbol_count; ++msymbol, ++ii)
if (msymbol->address < TEXT_SEGMENT_BASE)
msymbol->address += addr;
}
#else /* !FASTER_MSYMBOL_RELOCATION */
/* Called via iterate_over_msymbols to relocate minimal symbols */
static PTR
static int
relocate_minimal_symbol (objfile, msymbol, arg1, arg2, arg3)
struct objfile *objfile;
struct minimal_symbol *msymbol;
@ -340,8 +376,12 @@ relocate_minimal_symbol (objfile, msymbol, arg1, arg2, arg3)
{
if (msymbol->address < TEXT_SEGMENT_BASE)
msymbol -> address += (int) arg1;
return (NULL);
/* return 0, otherwise `iterate_over_msymbols()' will stop at the
first iteration. */
return 0;
}
#endif /* FASTER_MSYMBOL_RELOCATION */
/* true, if symbol table and minimal symbol table are relocated. */
@ -400,14 +440,34 @@ struct stat *vip;
continue;
}
if (vp->tstart != old_start)
vmap_symtab_1(s, vp, old_start);
if (vp->tstart != old_start) {
/* Once we find a relocation base address for one of the symtabs
in this objfile, it will be the same for all symtabs in this
objfile. Clean this algorithm. FIXME. */
for (; s; s = s->next)
if (!s->nonreloc || LINETABLE(s))
vmap_symtab_1(s, vp, old_start);
#ifdef FASTER_MSYMBOL_RELOCATION
/* we can rely on the fact that at least one symtab in this objfile
will get relocated. Thus, we can be sure that minimal symbol
vector is guaranteed for relocation. */
reloc_objfile_msymbols (objfile, vp->tstart - old_start);
#endif
break;
}
}
}
if (vp->tstart != old_start) {
#ifndef FASTER_MSYMBOL_RELOCATION
(void) iterate_over_msymbols (relocate_minimal_symbol,
(PTR) (vp->tstart - old_start),
(PTR) NULL, (PTR) NULL);
#endif
/* breakpoints need to be relocated as well. */
fixup_breakpoints (0, TEXT_SEGMENT_BASE, vp->tstart - old_start);
@ -416,6 +476,7 @@ struct stat *vip;
symtab_relocated = 1;
}
vmap_symtab_1(s, vp, old_start)
register struct symtab *s;
register struct vmap *vp;
@ -515,19 +576,26 @@ CORE_ADDR old_start;
add_vmap(ldi)
register struct ld_info *ldi; {
bfd *bfd, *last;
register char *mem;
register char *mem, *objname;
/* This ldi structure was allocated using alloca() in
aixcoff_relocate_symtab(). Now we need to have persistent object
and member names, so we should save them. */
mem = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1;
bfd = bfd_fdopenr(ldi->ldinfo_filename, NULL, ldi->ldinfo_fd);
mem = savestring (mem, strlen (mem));
objname = savestring (ldi->ldinfo_filename, strlen (ldi->ldinfo_filename));
bfd = bfd_fdopenr(objname, NULL, ldi->ldinfo_fd);
if (!bfd)
error("Could not open `%s' as an executable file: %s"
, ldi->ldinfo_filename, bfd_errmsg(bfd_error));
error("Could not open `%s' as an executable file: %s",
objname, bfd_errmsg(bfd_error));
/* make sure we have an object file */
if (bfd_check_format(bfd, bfd_object))
map_vmap (bfd, 0);
map_vmap (bfd, 0);
else if (bfd_check_format(bfd, bfd_archive)) {
last = 0;
@ -539,11 +607,10 @@ register struct ld_info *ldi; {
break;
if (!last) {
bfd_close(bfd);
/* FIXME -- should be error */
warning("\"%s\": member \"%s\" missing.",
bfd->filename, mem);
return;
bfd_close(bfd);
/* FIXME -- should be error */
warning("\"%s\": member \"%s\" missing.", bfd->filename, mem);
return;
}
if (!bfd_check_format(last, bfd_object)) {
@ -558,18 +625,20 @@ register struct ld_info *ldi; {
bfd_close(bfd);
/* FIXME -- should be error */
warning("\"%s\": not in executable format: %s."
, ldi->ldinfo_filename, bfd_errmsg(bfd_error));
, objname, bfd_errmsg(bfd_error));
return;
}
}
/* As well as symbol tables, exec_sections need relocation. Otherwise after
the inferior process terminates, symbol table is relocated but there is
no inferior process. Thus, we have to use `exec' bfd, rather than the inferior
process's memory space, when lookipng at symbols.
`exec_sections' need to be relocated only once though, as long as the exec
file was not changed.
/* As well as symbol tables, exec_sections need relocation. After
the inferior process' termination, there will be a relocated symbol
table exist with no corresponding inferior process. At that time, we
need to use `exec' bfd, rather than the inferior process's memory space
to look up symbols.
`exec_sections' need to be relocated only once, as long as the exec
file remains unchanged.
*/
vmap_exec ()
{
@ -579,17 +648,19 @@ vmap_exec ()
execbfd = exec_bfd;
if (!vmap || !exec_sections) {
printf ("WARNING: vmap not found in vmap_exec()!\n");
return;
}
/* First exec section is `.text', second is `.data'. If this is changed,
then this routine will choke. Better you should check section names,
FIXMEmgo. */
exec_sections [0].addr += vmap->tstart;
exec_sections [0].endaddr += vmap->tstart;
exec_sections [1].addr += vmap->dstart;
exec_sections [1].endaddr += vmap->dstart;
then this routine will choke. */
if (!vmap || !exec_ops.to_sections ||
strcmp (exec_ops.to_sections[0].sec_ptr->name, ".text") ||
strcmp (exec_ops.to_sections[1].sec_ptr->name, ".data"))
fatal ("aix: Improper exec_ops sections.");
exec_ops.to_sections [0].addr += vmap->tstart;
exec_ops.to_sections [0].endaddr += vmap->tstart;
exec_ops.to_sections [1].addr += vmap->dstart;
exec_ops.to_sections [1].endaddr += vmap->dstart;
}
@ -710,10 +781,9 @@ retry:
vmap_inferior() {
if (inferior_pid == 0)
return 0; /* normal processing */
return 0; /* normal processing */
exec_files_info();
return 1;
}
@ -791,7 +861,6 @@ print_section_info (t, abfd)
struct target_ops *t;
bfd *abfd;
{
#if 1
struct section_table *p;
printf_filtered ("\t`%s', ", bfd_get_filename(abfd));
@ -810,32 +879,32 @@ print_section_info (t, abfd)
}
printf_filtered ("\n");
}
#else
register struct vmap *vp = vmap;
if (!vp)
return;
printf("\tMapping info for file `%s'.\n", vp->name);
printf("\t %8.8s %8.8s %8.8s %s\n"
, "start", "end", "section", "file(member)");
for (; vp; vp = vp->nxt)
printf("\t0x%8.8x 0x%8.8x %s%s%s%s\n"
, vp->tstart
, vp->tend
, vp->name
, *vp->member ? "(" : ""
, vp->member
, *vp->member ? ")" : "");
#endif
}
static void
exec_files_info (t)
struct target_ops *t;
{
register struct vmap *vp = vmap;
print_section_info (t, exec_bfd);
if (!vp)
return;
printf("\n\tMapping info for file `%s'.\n", vp->name);
printf("\t %8.8s %8.8s %8.8s %s\n",
"start", "end", "section", "file(member)");
for (; vp; vp = vp->nxt)
printf("\t0x%8.8x 0x%8.8x %s%s%s%s\n",
vp->tstart,
vp->tend,
vp->name,
vp->member ? "(" : "",
vp->member,
vp->member ? ")" : "");
}
#ifdef DAMON
@ -909,13 +978,14 @@ set_section_command (args, from_tty)
/* Parse out new virtual address */
secaddr = parse_and_eval_address (args);
for (p = exec_sections; p < exec_sections_end; p++) {
for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) {
if (!strncmp (secname, bfd_section_name (exec_bfd, p->sec_ptr), seclen)
&& bfd_section_name (exec_bfd, p->sec_ptr)[seclen] == '\0') {
offset = secaddr - p->addr;
p->addr += offset;
p->endaddr += offset;
exec_files_info();
if (from_tty)
exec_files_info(&exec_ops);
return;
}
}

View File

@ -1285,7 +1285,11 @@ function_entry_point:
}
/* shared library function trampoline code entry point. */
else if (CSECT_SCLAS (main_aux) == XMC_GL) {
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text,
/* record trampoline code entries as mst_unknown symbol. When we
lookup mst symbols, we will choose mst_text over mst_unknown. */
RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_unknown,
symname_alloced);
continue;
}
@ -1622,11 +1626,12 @@ process_xcoff_symbol (cs, objfile)
char *tmp_pp = pp;
read_type_number (&tmp_pp, typenums);
tmp_type = dbx_alloc_type (typenums);
tmp_type = dbx_alloc_type (typenums, objfile);
if (tmp_type && !TYPE_NAME (tmp_type) && !nameless)
TYPE_NAME (tmp_type) = SYMBOL_NAME (sym) =
obsavestring (name, qq-name);
obsavestring (name, qq-name,
&objfile->symbol_obstack);
}
ttype = SYMBOL_TYPE (sym) = read_type (&pp, objfile);
@ -2264,3 +2269,176 @@ char **pp;
fatal ("internals eror: builtin_type called!");
}
#endif /* IBM6000 */
#define DEBUG 1
#ifdef DEBUG
void
dump_strtbl ()
{
int ii;
printf ("===STRING TABLE DUMP...\n\n");
for ( ii=0; ii < strtbl_len; ++ii )
printf ("%c", isprint (*(strtbl+ii)) ? *(strtbl+ii) : ' ');
printf ("\n");
}
void
dump_linetable (ltb)
struct linetable *ltb;
{
int ii;
for (ii=0; ii < ltb->nitems; ++ii)
printf ("line: %d, addr: 0x%x\n", ltb->item[ii].line, ltb->item[ii].pc);
}
void
dump_type (typeP)
struct type *typeP;
{
printf ("0x%x: name: %s\n", typeP, typeP->name ? typeP->name : "(nil)");
}
char *dump_namespace ();
char *dump_addrclass ();
void
dump_symbol (pp)
struct symbol *pp;
{
printf (" sym: %s\t%s,\t%s\ttype: 0x%x, val: 0x%x end: 0x%x\n",
pp->name, dump_namespace (pp->namespace),
dump_addrclass (pp->class), pp->type,
SYMBOL_CLASS(pp) == LOC_BLOCK ? BLOCK_START(SYMBOL_BLOCK_VALUE(pp))
: pp->value.value,
SYMBOL_CLASS(pp) == LOC_BLOCK ? BLOCK_END(SYMBOL_BLOCK_VALUE(pp)) : 0);
}
char *
dump_namespace (ns)
int ns;
{
static char *ns_name [] = {
"UNDEF_NS", "VAR_NS", "STRUCT_NS", "LABEL_NS"};
switch (ns) {
case UNDEF_NAMESPACE:
case VAR_NAMESPACE:
case STRUCT_NAMESPACE:
case LABEL_NAMESPACE:
return ns_name[ns];
}
return "***ERROR***";
}
char *
dump_addrclass (ac)
int ac; /* address class */
{
static char *ac_name [] = {
"LOC_UNDEF",
"LOC_CONST",
"LOC_STATIC",
"LOC_REGISTER",
"LOC_ARG",
"LOC_REF_ARG",
"LOC_REGPARM",
"LOC_LOCAL",
"LOC_TYPEDEF",
"LOC_LABEL",
"LOC_BLOCK",
"LOC_CONST_BYTES",
"LOC_LOCAL_ARG",
};
switch (ac) {
case LOC_UNDEF:
case LOC_CONST:
case LOC_STATIC:
case LOC_REGISTER:
case LOC_ARG:
case LOC_REF_ARG:
case LOC_REGPARM:
case LOC_LOCAL:
case LOC_TYPEDEF:
case LOC_LABEL:
case LOC_BLOCK:
case LOC_CONST_BYTES:
case LOC_LOCAL_ARG:
return ac_name [ac];
}
return "***ERROR***";
}
void
dump_block (pp)
struct block *pp;
{
int ii;
printf ("BLOCK..: start: 0x%x, end: 0x%x\n", pp->startaddr, pp->endaddr);
for (ii=0; ii < pp->nsyms; ++ii)
dump_symbol (pp->sym[ii]);
}
void
dump_blockvector (pp)
struct blockvector *pp;
{
int ii;
for (ii=0; ii < pp->nblocks; ++ii)
dump_block (pp->block [ii]);
}
void
dump_last_symtab (pp)
struct symtab *pp;
{
for ( ; pp; pp = pp->next) {
if ( pp->next == 0 ) {
printf ("SYMTAB NAME: %s\n", pp->filename);
dump_blockvector (pp->blockvector);
}
}
}
void
dump_symtabs (pp)
struct symtab *pp;
{
for ( ; pp; pp = pp->next) {
printf ("SYMTAB NAME: %s\n", pp->filename ? pp->filename : "(nil)");
/* if (pp->linetable)
dump_linetable (pp->linetable); */
dump_blockvector (pp->blockvector);
}
}
void
dump_symtab_lines (pp)
struct symtab *pp;
{
for ( ; pp; pp = pp->next) {
printf ("SYMTAB NAME: %s\n", pp->filename ? pp->filename : "(nil)");
if (pp->linetable)
dump_linetable (pp->linetable);
/* dump_blockvector (pp->blockvector); */
}
}
void
dump_msymbols (of)
struct objfile *of;
{
int ii;
for (ii=0; ii < of->minimal_symbol_count; ++ii)
printf ("name: %s, addr: 0x%x, info: 0x%x\n",
of->msymbols[ii].name,
of->msymbols[ii].address,
of->msymbols[ii].info );
}
#endif /* DEBUG */