* 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)
|
Wed Nov 2 15:05:39 1994 Kung Hsu (kung@mexican.cygnus.com)
|
||||||
|
|
||||||
* c-exp.y (yylex): scan template names, and scan nested class
|
* 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 "inferior.h"
|
||||||
#include "language.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.
|
/* When handling shared libraries, GDB has to find out the pathnames
|
||||||
The main problem is that the needed definitions are not contained in
|
of all shared libraries that are currently loaded (to read in their
|
||||||
the system header files.
|
symbols) and where the shared libraries are loaded in memory
|
||||||
The ldr_* routines described in loader(3) would be the way to go here.
|
(to relocate them properly from their prelinked addresses to the
|
||||||
But they do not work for arbitrary target processes (as documented). */
|
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
|
#ifndef USE_LDR_ROUTINES
|
||||||
|
|
||||||
|
/* Definition of runtime loader structures, found by experimentation. */
|
||||||
#define RLD_CONTEXT_ADDRESS 0x3ffc0000000
|
#define RLD_CONTEXT_ADDRESS 0x3ffc0000000
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CORE_ADDR next;
|
CORE_ADDR next;
|
||||||
CORE_ADDR previous;
|
CORE_ADDR previous;
|
||||||
CORE_ADDR unknown;
|
CORE_ADDR unknown1;
|
||||||
char *module_name;
|
char *module_name;
|
||||||
CORE_ADDR modinfo_addr;
|
CORE_ADDR modinfo_addr;
|
||||||
|
long module_id;
|
||||||
|
CORE_ADDR unknown2;
|
||||||
|
CORE_ADDR unknown3;
|
||||||
|
long region_count;
|
||||||
|
CORE_ADDR regioninfo_addr;
|
||||||
} ldr_module_info_t;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
CORE_ADDR unknown1;
|
CORE_ADDR unknown1;
|
||||||
|
@ -68,20 +100,53 @@ typedef struct
|
||||||
} ldr_context_t;
|
} ldr_context_t;
|
||||||
|
|
||||||
static ldr_context_t ldr_context;
|
static ldr_context_t ldr_context;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <loader.h>
|
#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
|
#endif
|
||||||
|
|
||||||
/* Define our own link_map structure.
|
/* Define our own link_map structure.
|
||||||
This will help to share code with solib.c. */
|
This will help to share code with solib.c. */
|
||||||
|
|
||||||
struct link_map {
|
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 */
|
char *l_name; /* full name of loaded object */
|
||||||
ldr_module_info_t module_info; /* corresponding module info */
|
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)
|
#define LM_NAME(so) ((so) -> lm.l_name)
|
||||||
|
|
||||||
struct so_list {
|
struct so_list {
|
||||||
|
@ -209,10 +274,10 @@ solib_map_sections (so)
|
||||||
for (p = so -> sections; p < so -> sections_end; p++)
|
for (p = so -> sections; p < so -> sections_end; p++)
|
||||||
{
|
{
|
||||||
/* Relocate the section binding addresses as recorded in the shared
|
/* Relocate the section binding addresses as recorded in the shared
|
||||||
object's file by the base address to which the object was actually
|
object's file by the offset to get the address to which the
|
||||||
mapped. */
|
object was actually mapped. */
|
||||||
p -> addr += (CORE_ADDR) LM_ADDR (so);
|
p -> addr += LM_OFFSET (so);
|
||||||
p -> endaddr += (CORE_ADDR) LM_ADDR (so);
|
p -> endaddr += LM_OFFSET (so);
|
||||||
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
|
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
|
||||||
if (STREQ (p -> the_bfd_section -> name, ".text"))
|
if (STREQ (p -> the_bfd_section -> name, ".text"))
|
||||||
{
|
{
|
||||||
|
@ -251,9 +316,13 @@ first_link_map_member ()
|
||||||
ldr_module_t mod_id = LDR_NULL_MODULE;
|
ldr_module_t mod_id = LDR_NULL_MODULE;
|
||||||
size_t retsize;
|
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
|
|| 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),
|
&first_lm.module_info, sizeof(ldr_module_info_t),
|
||||||
&retsize) != 0)
|
&retsize) != 0)
|
||||||
return lm;
|
return lm;
|
||||||
|
@ -287,12 +356,12 @@ next_link_map_member (so_list_ptr)
|
||||||
struct link_map *lm = NULL;
|
struct link_map *lm = NULL;
|
||||||
static struct link_map next_lm;
|
static struct link_map next_lm;
|
||||||
#ifdef USE_LDR_ROUTINES
|
#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;
|
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
|
|| 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),
|
&next_lm.module_info, sizeof(ldr_module_info_t),
|
||||||
&retsize) != 0)
|
&retsize) != 0)
|
||||||
return lm;
|
return lm;
|
||||||
|
@ -327,10 +396,21 @@ xfer_link_map_member (so_list_ptr, lm)
|
||||||
struct so_list *so_list_ptr;
|
struct so_list *so_list_ptr;
|
||||||
struct link_map *lm;
|
struct link_map *lm;
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
so_list_ptr->lm = *lm;
|
so_list_ptr->lm = *lm;
|
||||||
|
|
||||||
/* OSF/1 has absolute addresses in shared libraries. */
|
/* OSF/1 shared libraries are pre-linked to particular addresses,
|
||||||
LM_ADDR (so_list_ptr) = 0;
|
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)
|
/* There is one entry that has no name (for the inferior executable)
|
||||||
since it is not a shared object. */
|
since it is not a shared object. */
|
||||||
|
@ -343,6 +423,26 @@ xfer_link_map_member (so_list_ptr, lm)
|
||||||
if (len > MAX_PATH_SIZE)
|
if (len > MAX_PATH_SIZE)
|
||||||
len = MAX_PATH_SIZE;
|
len = MAX_PATH_SIZE;
|
||||||
strncpy (so_list_ptr->so_name, LM_NAME (so_list_ptr), 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
|
#else
|
||||||
int errcode;
|
int errcode;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
@ -353,9 +453,37 @@ xfer_link_map_member (so_list_ptr, lm)
|
||||||
safe_strerror (errcode));
|
safe_strerror (errcode));
|
||||||
strncpy (so_list_ptr->so_name, buffer, MAX_PATH_SIZE - 1);
|
strncpy (so_list_ptr->so_name, buffer, MAX_PATH_SIZE - 1);
|
||||||
free (buffer);
|
free (buffer);
|
||||||
#endif
|
|
||||||
so_list_ptr->so_name[MAX_PATH_SIZE - 1] = '\0';
|
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);
|
solib_map_sections (so_list_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue