2005-02-09 Andrew Cagney <cagney@gnu.org>
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call) (convert_code_addr_to_desc_addr): Convert any function code address to the corresponding function's descriptor. (ppc64_sysv_abi_return_value): have TYPE_CODE_ENUM and TYPE_CODE_INT use the same code paths as TYPE_CODE_INT. When writing, convert any function code address to the corresponding descriptor.
This commit is contained in:
parent
dbdfa66c30
commit
b6e1c0277f
2 changed files with 85 additions and 44 deletions
|
@ -1,10 +1,13 @@
|
|||
2005-02-09 Corinna Vinschen <vinschen@redhat.com>
|
||||
|
||||
* symmisc.c: Include gdb_stat.h.
|
||||
(maintenance_print_msymbols): Use inode numbers to compare files.
|
||||
|
||||
2005-02-09 Andrew Cagney <cagney@gnu.org>
|
||||
|
||||
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call)
|
||||
(convert_code_addr_to_desc_addr): Convert any function code
|
||||
address to the corresponding function's descriptor.
|
||||
(ppc64_sysv_abi_return_value): have TYPE_CODE_ENUM and
|
||||
TYPE_CODE_INT use the same code paths as TYPE_CODE_INT. When
|
||||
writing, convert any function code address to the corresponding
|
||||
descriptor.
|
||||
|
||||
* config/sh/linux.mt (TDEPFILES): Add symfile-mem.o.
|
||||
* config/powerpc/linux.mt (TDEPFILES): Ditto.
|
||||
* config/pa/linux.mt (TDEPFILES): Ditto.
|
||||
|
@ -14,6 +17,11 @@
|
|||
* config/ia64/linux.mt (TDEPFILES): Ditto.
|
||||
* config/arm/linux.mt (TDEPFILES): Ditto.
|
||||
|
||||
2005-02-09 Corinna Vinschen <vinschen@redhat.com>
|
||||
|
||||
* symmisc.c: Include gdb_stat.h.
|
||||
(maintenance_print_msymbols): Use inode numbers to compare files.
|
||||
|
||||
2005-02-08 Andrew Cagney <cagney@gnu.org>
|
||||
|
||||
* value.h (METHOD_PTR_IS_VIRTUAL, METHOD_PTR_FROM_VOFFSET)
|
||||
|
|
|
@ -534,6 +534,47 @@ ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch,
|
|||
writebuf, 1);
|
||||
}
|
||||
|
||||
/* The helper function for 64-bit SYSV push_dummy_call. Converts the
|
||||
function's code address back into the function's descriptor
|
||||
address.
|
||||
|
||||
Find a value for the TOC register. Every symbol should have both
|
||||
".FN" and "FN" in the minimal symbol table. "FN" points at the
|
||||
FN's descriptor, while ".FN" points at the entry point (which
|
||||
matches FUNC_ADDR). Need to reverse from FUNC_ADDR back to the
|
||||
FN's descriptor address (while at the same time being careful to
|
||||
find "FN" in the same object file as ".FN"). */
|
||||
|
||||
static int
|
||||
convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr)
|
||||
{
|
||||
struct obj_section *dot_fn_section;
|
||||
struct minimal_symbol *dot_fn;
|
||||
struct minimal_symbol *fn;
|
||||
CORE_ADDR toc;
|
||||
/* Find the minimal symbol that corresponds to CODE_ADDR (should
|
||||
have a name of the form ".FN"). */
|
||||
dot_fn = lookup_minimal_symbol_by_pc (code_addr);
|
||||
if (dot_fn == NULL || SYMBOL_LINKAGE_NAME (dot_fn)[0] != '.')
|
||||
return 0;
|
||||
/* Get the section that contains CODE_ADDR. Need this for the
|
||||
"objfile" that it contains. */
|
||||
dot_fn_section = find_pc_section (code_addr);
|
||||
if (dot_fn_section == NULL || dot_fn_section->objfile == NULL)
|
||||
return 0;
|
||||
/* Now find the corresponding "FN" (dropping ".") minimal symbol's
|
||||
address. Only look for the minimal symbol in ".FN"'s object file
|
||||
- avoids problems when two object files (i.e., shared libraries)
|
||||
contain a minimal symbol with the same name. */
|
||||
fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL,
|
||||
dot_fn_section->objfile);
|
||||
if (fn == NULL)
|
||||
return 0;
|
||||
/* Found a descriptor. */
|
||||
(*desc_addr) = SYMBOL_VALUE_ADDRESS (fn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Pass the arguments in either registers, or in the stack. Using the
|
||||
ppc 64 bit SysV ABI.
|
||||
|
||||
|
@ -704,15 +745,25 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||
}
|
||||
}
|
||||
else if ((TYPE_CODE (type) == TYPE_CODE_INT
|
||||
|| TYPE_CODE (type) == TYPE_CODE_ENUM)
|
||||
|| TYPE_CODE (type) == TYPE_CODE_ENUM
|
||||
|| TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||
&& TYPE_LENGTH (type) <= 8)
|
||||
{
|
||||
/* Scalars get sign[un]extended and go in gpr3 .. gpr10.
|
||||
They can also end up in memory. */
|
||||
/* Scalars and Pointers get sign[un]extended and go in
|
||||
gpr3 .. gpr10. They can also end up in memory. */
|
||||
if (write_pass)
|
||||
{
|
||||
/* Sign extend the value, then store it unsigned. */
|
||||
ULONGEST word = unpack_long (type, val);
|
||||
/* Convert any function code addresses into
|
||||
descriptors. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_PTR
|
||||
&& TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
|
||||
{
|
||||
CORE_ADDR desc = word;
|
||||
convert_code_addr_to_desc_addr (word, &desc);
|
||||
word = desc;
|
||||
}
|
||||
if (greg <= 10)
|
||||
regcache_cooked_write_unsigned (regcache,
|
||||
tdep->ppc_gp0_regnum +
|
||||
|
@ -765,6 +816,11 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||
value to memory. Fortunately, doing this
|
||||
simplifies the code. */
|
||||
write_memory (gparam, val, TYPE_LENGTH (type));
|
||||
if (write_pass)
|
||||
/* WARNING: cagney/2004-06-20: It appears that GCC
|
||||
likes to put structures containing a single
|
||||
floating-point member in an FP register instead of
|
||||
general general purpose. */
|
||||
/* Always consume parameter stack space. */
|
||||
gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
|
||||
}
|
||||
|
@ -793,43 +849,18 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||
breakpoint. */
|
||||
regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
|
||||
|
||||
/* Find a value for the TOC register. Every symbol should have both
|
||||
".FN" and "FN" in the minimal symbol table. "FN" points at the
|
||||
FN's descriptor, while ".FN" points at the entry point (which
|
||||
matches FUNC_ADDR). Need to reverse from FUNC_ADDR back to the
|
||||
FN's descriptor address (while at the same time being careful to
|
||||
find "FN" in the same object file as ".FN"). */
|
||||
/* Use the func_addr to find the descriptor, and use that to find
|
||||
the TOC. */
|
||||
{
|
||||
/* Find the minimal symbol that corresponds to FUNC_ADDR (should
|
||||
have the name ".FN"). */
|
||||
struct minimal_symbol *dot_fn = lookup_minimal_symbol_by_pc (func_addr);
|
||||
if (dot_fn != NULL && SYMBOL_LINKAGE_NAME (dot_fn)[0] == '.')
|
||||
CORE_ADDR desc_addr;
|
||||
if (convert_code_addr_to_desc_addr (func_addr, &desc_addr))
|
||||
{
|
||||
/* Get the section that contains FUNC_ADR. Need this for the
|
||||
"objfile" that it contains. */
|
||||
struct obj_section *dot_fn_section = find_pc_section (func_addr);
|
||||
if (dot_fn_section != NULL && dot_fn_section->objfile != NULL)
|
||||
{
|
||||
/* Now find the corresponding "FN" (dropping ".") minimal
|
||||
symbol's address. Only look for the minimal symbol in
|
||||
".FN"'s object file - avoids problems when two object
|
||||
files (i.e., shared libraries) contain a minimal symbol
|
||||
with the same name. */
|
||||
struct minimal_symbol *fn =
|
||||
lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL,
|
||||
dot_fn_section->objfile);
|
||||
if (fn != NULL)
|
||||
{
|
||||
/* Got the address of that descriptor. The TOC is the
|
||||
second double word. */
|
||||
CORE_ADDR toc =
|
||||
read_memory_unsigned_integer (SYMBOL_VALUE_ADDRESS (fn)
|
||||
+ tdep->wordsize,
|
||||
tdep->wordsize);
|
||||
regcache_cooked_write_unsigned (regcache,
|
||||
tdep->ppc_gp0_regnum + 2, toc);
|
||||
}
|
||||
}
|
||||
/* The TOC is the second double word in the descriptor. */
|
||||
CORE_ADDR toc =
|
||||
read_memory_unsigned_integer (desc_addr + tdep->wordsize,
|
||||
tdep->wordsize);
|
||||
regcache_cooked_write_unsigned (regcache,
|
||||
tdep->ppc_gp0_regnum + 2, toc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -876,7 +907,9 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
|
|||
}
|
||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||
}
|
||||
if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 8)
|
||||
if ((TYPE_CODE (valtype) == TYPE_CODE_INT
|
||||
|| TYPE_CODE (valtype) == TYPE_CODE_ENUM)
|
||||
&& TYPE_LENGTH (valtype) <= 8)
|
||||
{
|
||||
/* Integers in r3. */
|
||||
if (writebuf != NULL)
|
||||
|
|
Loading…
Reference in a new issue