* osfsolib.c (solib_map_sections, first_link_map_member,
next_link_map_member, xfer_link_map_member): Retrieve and use shared library relocation offset from runtime loader structures. Use libxproc.a routines to get a working version if USE_LDR_ROUTINES is defined. * README: Remove item about shared library relocation for Alpha OSF/1.
This commit is contained in:
parent
a8d23c7364
commit
17d347bd60
2 changed files with 159 additions and 21 deletions
|
@ -1,3 +1,13 @@
|
|||
Thu Nov 3 01:23:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||
|
||||
* osfsolib.c (solib_map_sections, first_link_map_member,
|
||||
next_link_map_member, xfer_link_map_member): Retrieve and use
|
||||
shared library relocation offset from runtime loader structures.
|
||||
Use libxproc.a routines to get a working version if
|
||||
USE_LDR_ROUTINES is defined.
|
||||
* README: Remove item about shared library relocation for
|
||||
Alpha OSF/1.
|
||||
|
||||
Wed Nov 2 15:05:39 1994 Kung Hsu (kung@mexican.cygnus.com)
|
||||
|
||||
* c-exp.y (yylex): scan template names, and scan nested class
|
||||
|
|
170
gdb/osfsolib.c
170
gdb/osfsolib.c
|
@ -39,26 +39,58 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "inferior.h"
|
||||
#include "language.h"
|
||||
|
||||
#define MAX_PATH_SIZE 256 /* FIXME: Should be dynamic */
|
||||
#define MAX_PATH_SIZE 1024 /* FIXME: Should be dynamic */
|
||||
|
||||
/* FIXME: This is a terrible hack for shared library support under OSF/1.
|
||||
The main problem is that the needed definitions are not contained in
|
||||
the system header files.
|
||||
The ldr_* routines described in loader(3) would be the way to go here.
|
||||
But they do not work for arbitrary target processes (as documented). */
|
||||
/* When handling shared libraries, GDB has to find out the pathnames
|
||||
of all shared libraries that are currently loaded (to read in their
|
||||
symbols) and where the shared libraries are loaded in memory
|
||||
(to relocate them properly from their prelinked addresses to the
|
||||
current load address).
|
||||
|
||||
Under OSF/1 there are two possibilities to get at this information:
|
||||
1) Peek around in the runtime loader structures.
|
||||
These are not documented, and they are not defined in the system
|
||||
header files. The definitions below were obtained by experimentation,
|
||||
but they seem stable enough.
|
||||
2) Use the undocumented libxproc.a library, which contains the
|
||||
equivalent ldr_* routines.
|
||||
This approach is somewhat cleaner, but it requires that the GDB
|
||||
executable is dynamically linked. In addition it requires a
|
||||
NAT_CLIBS= -lxproc -Wl,-expect_unresolved,ldr_process_context
|
||||
linker specification for GDB and all applications that are using
|
||||
libgdb.
|
||||
We will use the peeking approach until it becomes unwieldy. */
|
||||
|
||||
#ifndef USE_LDR_ROUTINES
|
||||
|
||||
/* Definition of runtime loader structures, found by experimentation. */
|
||||
#define RLD_CONTEXT_ADDRESS 0x3ffc0000000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CORE_ADDR next;
|
||||
CORE_ADDR previous;
|
||||
CORE_ADDR unknown;
|
||||
CORE_ADDR unknown1;
|
||||
char *module_name;
|
||||
CORE_ADDR modinfo_addr;
|
||||
long module_id;
|
||||
CORE_ADDR unknown2;
|
||||
CORE_ADDR unknown3;
|
||||
long region_count;
|
||||
CORE_ADDR regioninfo_addr;
|
||||
} ldr_module_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long unknown1;
|
||||
CORE_ADDR regionname_addr;
|
||||
long protection;
|
||||
CORE_ADDR vaddr;
|
||||
CORE_ADDR mapaddr;
|
||||
long size;
|
||||
long unknown2[5];
|
||||
} ldr_region_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CORE_ADDR unknown1;
|
||||
|
@ -68,20 +100,53 @@ typedef struct
|
|||
} ldr_context_t;
|
||||
|
||||
static ldr_context_t ldr_context;
|
||||
|
||||
#else
|
||||
|
||||
#include <loader.h>
|
||||
static ldr_process_t fake_ldr_process;
|
||||
|
||||
/* Called by ldr_* routines to read memory from the current target. */
|
||||
|
||||
static int ldr_read_memory PARAMS ((CORE_ADDR, char *, int, int));
|
||||
|
||||
static int
|
||||
ldr_read_memory (memaddr, myaddr, len, readstring)
|
||||
CORE_ADDR memaddr;
|
||||
char *myaddr;
|
||||
int len;
|
||||
int readstring;
|
||||
{
|
||||
int result;
|
||||
char *buffer;
|
||||
|
||||
if (readstring)
|
||||
{
|
||||
target_read_string (memaddr, &buffer, len, &result);
|
||||
if (result == 0)
|
||||
strcpy (myaddr, buffer);
|
||||
free (buffer);
|
||||
}
|
||||
else
|
||||
result = target_read_memory (memaddr, myaddr, len);
|
||||
|
||||
if (result != 0)
|
||||
result = -result;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Define our own link_map structure.
|
||||
This will help to share code with solib.c. */
|
||||
|
||||
struct link_map {
|
||||
CORE_ADDR l_addr; /* address at which object mapped */
|
||||
CORE_ADDR l_offset; /* prelink to load address offset */
|
||||
char *l_name; /* full name of loaded object */
|
||||
ldr_module_info_t module_info; /* corresponding module info */
|
||||
};
|
||||
|
||||
#define LM_ADDR(so) ((so) -> lm.l_addr)
|
||||
#define LM_OFFSET(so) ((so) -> lm.l_offset)
|
||||
#define LM_NAME(so) ((so) -> lm.l_name)
|
||||
|
||||
struct so_list {
|
||||
|
@ -209,10 +274,10 @@ solib_map_sections (so)
|
|||
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 += LM_OFFSET (so);
|
||||
p -> endaddr += LM_OFFSET (so);
|
||||
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
|
||||
if (STREQ (p -> the_bfd_section -> name, ".text"))
|
||||
{
|
||||
|
@ -251,9 +316,13 @@ first_link_map_member ()
|
|||
ldr_module_t mod_id = LDR_NULL_MODULE;
|
||||
size_t retsize;
|
||||
|
||||
if (ldr_next_module(inferior_pid, &mod_id) != 0
|
||||
fake_ldr_process = ldr_core_process ();
|
||||
ldr_set_core_reader (ldr_read_memory);
|
||||
ldr_xdetach (fake_ldr_process);
|
||||
if (ldr_xattach (fake_ldr_process) != 0
|
||||
|| ldr_next_module(fake_ldr_process, &mod_id) != 0
|
||||
|| mod_id == LDR_NULL_MODULE
|
||||
|| ldr_inq_module(inferior_pid, mod_id,
|
||||
|| ldr_inq_module(fake_ldr_process, mod_id,
|
||||
&first_lm.module_info, sizeof(ldr_module_info_t),
|
||||
&retsize) != 0)
|
||||
return lm;
|
||||
|
@ -287,12 +356,12 @@ next_link_map_member (so_list_ptr)
|
|||
struct link_map *lm = NULL;
|
||||
static struct link_map next_lm;
|
||||
#ifdef USE_LDR_ROUTINES
|
||||
ldr_module_t mod_id = lm->module_info.lmi_modid;
|
||||
ldr_module_t mod_id = so_list_ptr->lm.module_info.lmi_modid;
|
||||
size_t retsize;
|
||||
|
||||
if (ldr_next_module(inferior_pid, &mod_id) != 0
|
||||
if (ldr_next_module(fake_ldr_process, &mod_id) != 0
|
||||
|| mod_id == LDR_NULL_MODULE
|
||||
|| ldr_inq_module(inferior_pid, mod_id,
|
||||
|| ldr_inq_module(fake_ldr_process, mod_id,
|
||||
&next_lm.module_info, sizeof(ldr_module_info_t),
|
||||
&retsize) != 0)
|
||||
return lm;
|
||||
|
@ -327,10 +396,21 @@ xfer_link_map_member (so_list_ptr, lm)
|
|||
struct so_list *so_list_ptr;
|
||||
struct link_map *lm;
|
||||
{
|
||||
int i;
|
||||
so_list_ptr->lm = *lm;
|
||||
|
||||
/* OSF/1 has absolute addresses in shared libraries. */
|
||||
LM_ADDR (so_list_ptr) = 0;
|
||||
/* OSF/1 shared libraries are pre-linked to particular addresses,
|
||||
but the runtime loader may have to relocate them if the
|
||||
address ranges of the libraries used by the target executable clash,
|
||||
or if the target executable is linked with the -taso option.
|
||||
The offset is the difference between the address where the shared
|
||||
library is mapped and the pre-linked address of the shared library.
|
||||
|
||||
FIXME: GDB is currently unable to relocate the shared library
|
||||
sections by different offsets. If sections are relocated by
|
||||
different offsets, put out a warning and use the offset of the
|
||||
first section for all remaining sections. */
|
||||
LM_OFFSET (so_list_ptr) = 0;
|
||||
|
||||
/* There is one entry that has no name (for the inferior executable)
|
||||
since it is not a shared object. */
|
||||
|
@ -343,6 +423,26 @@ xfer_link_map_member (so_list_ptr, lm)
|
|||
if (len > MAX_PATH_SIZE)
|
||||
len = MAX_PATH_SIZE;
|
||||
strncpy (so_list_ptr->so_name, LM_NAME (so_list_ptr), MAX_PATH_SIZE);
|
||||
so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0';
|
||||
|
||||
for (i = 0; i < lm->module_info.lmi_nregion; i++)
|
||||
{
|
||||
ldr_region_info_t region_info;
|
||||
size_t retsize;
|
||||
CORE_ADDR region_offset;
|
||||
|
||||
if (ldr_inq_region (fake_ldr_process, lm->module_info.lmi_modid,
|
||||
i, ®ion_info, sizeof (region_info),
|
||||
&retsize) != 0)
|
||||
break;
|
||||
region_offset = (CORE_ADDR) region_info.lri_mapaddr
|
||||
- (CORE_ADDR) region_info.lri_vaddr;
|
||||
if (i == 0)
|
||||
LM_OFFSET (so_list_ptr) = region_offset;
|
||||
else if (LM_OFFSET (so_list_ptr) != region_offset)
|
||||
warning ("cannot handle shared library relocation for %s (%s)",
|
||||
so_list_ptr->so_name, region_info.lri_name);
|
||||
}
|
||||
#else
|
||||
int errcode;
|
||||
char *buffer;
|
||||
|
@ -353,9 +453,37 @@ xfer_link_map_member (so_list_ptr, lm)
|
|||
safe_strerror (errcode));
|
||||
strncpy (so_list_ptr->so_name, buffer, MAX_PATH_SIZE - 1);
|
||||
free (buffer);
|
||||
#endif
|
||||
so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0';
|
||||
|
||||
for (i = 0; i < lm->module_info.region_count; i++)
|
||||
{
|
||||
ldr_region_info_t region_info;
|
||||
CORE_ADDR region_offset;
|
||||
|
||||
if (target_read_memory (lm->module_info.regioninfo_addr
|
||||
+ i * sizeof (region_info),
|
||||
(char *) ®ion_info,
|
||||
sizeof (region_info)) != 0)
|
||||
break;
|
||||
region_offset = region_info.mapaddr - region_info.vaddr;
|
||||
if (i == 0)
|
||||
LM_OFFSET (so_list_ptr) = region_offset;
|
||||
else if (LM_OFFSET (so_list_ptr) != region_offset)
|
||||
{
|
||||
char *region_name;
|
||||
target_read_string (region_info.regionname_addr, &buffer,
|
||||
MAX_PATH_SIZE - 1, &errcode);
|
||||
if (errcode == 0)
|
||||
region_name = buffer;
|
||||
else
|
||||
region_name = "??";
|
||||
warning ("cannot handle shared library relocation for %s (%s)",
|
||||
so_list_ptr->so_name, region_name);
|
||||
free (buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
solib_map_sections (so_list_ptr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue