Shared object support for Haiku. Currently only working as part of a native debugger.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12028 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ffe68e41fb
commit
d92911c6c3
318
src/bin/gdb/gdb/solib-haiku.c
Normal file
318
src/bin/gdb/gdb/solib-haiku.c
Normal file
@ -0,0 +1,318 @@
|
||||
/* Shared library support for Haiku.
|
||||
|
||||
Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "haiku-nat.h" // TODO: Needs to be removed. See there!
|
||||
#include "inferior.h"
|
||||
#include "objfiles.h"
|
||||
#include "solib-haiku.h"
|
||||
#include "solist.h"
|
||||
#include "symfile.h"
|
||||
#include "symtab.h"
|
||||
#include "target.h"
|
||||
#include "elf/common.h"
|
||||
#include "elf/internal.h"
|
||||
|
||||
//#define TRACE_SOLIB_HAIKU
|
||||
#ifdef TRACE_SOLIB_HAIKU
|
||||
#define TRACE(x) printf x
|
||||
#else
|
||||
#define TRACE(x) while (false) {}
|
||||
#endif
|
||||
|
||||
|
||||
struct lm_info {
|
||||
CORE_ADDR text_address;
|
||||
CORE_ADDR unrelocated_text_address;
|
||||
bool unrelocated_text_address_initialized;
|
||||
};
|
||||
|
||||
|
||||
static haiku_image_info *
|
||||
haiku_get_app_image()
|
||||
{
|
||||
haiku_image_info *image;
|
||||
int lastID = -1;
|
||||
|
||||
while ((image = haiku_get_next_image_info(lastID)) != NULL) {
|
||||
if (image->is_app_image)
|
||||
return image;
|
||||
|
||||
lastID = image->id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static Elf_Internal_Phdr *
|
||||
read_phdrs(bfd *abfd, int *_count)
|
||||
{
|
||||
long size;
|
||||
int count;
|
||||
Elf_Internal_Phdr *phdrs;
|
||||
|
||||
// get the phdrs size
|
||||
size = bfd_get_elf_phdr_upper_bound(abfd);
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
// alloc memory
|
||||
phdrs = (Elf_Internal_Phdr *)xmalloc(size);
|
||||
if (!phdrs)
|
||||
return NULL;
|
||||
|
||||
// read the phdrs
|
||||
count = bfd_get_elf_phdrs(abfd, phdrs);
|
||||
if (count < 0) {
|
||||
xfree(phdrs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*_count = count;
|
||||
return phdrs;
|
||||
}
|
||||
|
||||
|
||||
static CORE_ADDR
|
||||
get_bfd_vma(bfd *abfd)
|
||||
{
|
||||
int count;
|
||||
Elf_Internal_Phdr *phdrs;
|
||||
int i;
|
||||
CORE_ADDR result = 0;
|
||||
|
||||
// get the phdrs array
|
||||
phdrs = read_phdrs(abfd, &count);
|
||||
if (!phdrs)
|
||||
return 0;
|
||||
|
||||
// iterate through phdrs array and find the first one to load
|
||||
for (i = 0; i < count; i++) {
|
||||
Elf_Internal_Phdr *phdr = phdrs + i;
|
||||
if (phdr->p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
// found the first segment to load
|
||||
result = phdr->p_vaddr & ~(B_PAGE_SIZE - 1);
|
||||
TRACE(("get_bfd_vma(): found first segment: %p\n", (void*)result));
|
||||
break;
|
||||
}
|
||||
|
||||
xfree(phdrs);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CORE_ADDR
|
||||
get_unrelocated_text_address(struct so_list *so)
|
||||
{
|
||||
if (!so->lm_info->unrelocated_text_address_initialized) {
|
||||
so->lm_info->unrelocated_text_address = get_bfd_vma(so->abfd);
|
||||
so->lm_info->unrelocated_text_address_initialized = true;
|
||||
}
|
||||
|
||||
return so->lm_info->unrelocated_text_address;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
static void
|
||||
haiku_relocate_section_addresses (struct so_list *so, struct section_table *sec)
|
||||
{
|
||||
CORE_ADDR unrelocatedAddress = get_unrelocated_text_address(so);
|
||||
long relocation = so->lm_info->text_address - unrelocatedAddress;
|
||||
|
||||
sec->addr += relocation;
|
||||
sec->endaddr += relocation;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
haiku_free_so (struct so_list *so)
|
||||
{
|
||||
xfree (so->lm_info);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
haiku_clear_solib (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
haiku_solib_create_inferior_hook (void)
|
||||
{
|
||||
haiku_image_info *appImageInfo = haiku_get_app_image();
|
||||
|
||||
TRACE(("haiku_solib_create_inferior_hook()\n"));
|
||||
|
||||
TRACE(("haiku_solib_create_inferior_hook(): symfile_objfile: %p\n",
|
||||
symfile_objfile));
|
||||
TRACE(("haiku_solib_create_inferior_hook(): symfile_objfile->obfd: %p\n",
|
||||
symfile_objfile->obfd));
|
||||
TRACE(("haiku_solib_create_inferior_hook(): app image: %p\n", appImageInfo));
|
||||
|
||||
// Relocate the executable here.
|
||||
if (symfile_objfile && symfile_objfile->obfd && appImageInfo) {
|
||||
CORE_ADDR unrelocatedAddress = get_bfd_vma(symfile_objfile->obfd);
|
||||
CORE_ADDR displacement = (CORE_ADDR)appImageInfo->text_address
|
||||
- unrelocatedAddress;
|
||||
|
||||
TRACE(("haiku_solib_create_inferior_hook(): image text address: %p, "
|
||||
"unrelocated address: %p\n", (void*)appImageInfo->text_address,
|
||||
(void*)unrelocatedAddress));
|
||||
|
||||
if (displacement != 0) {
|
||||
struct cleanup *old_chain;
|
||||
struct section_offsets *new_offsets;
|
||||
int i, changed;
|
||||
|
||||
changed = 0;
|
||||
|
||||
new_offsets = xcalloc (symfile_objfile->num_sections,
|
||||
sizeof (struct section_offsets));
|
||||
old_chain = make_cleanup (xfree, new_offsets);
|
||||
|
||||
for (i = 0; i < symfile_objfile->num_sections; i++) {
|
||||
if (displacement
|
||||
!= ANOFFSET (symfile_objfile->section_offsets, i)) {
|
||||
changed = 1;
|
||||
}
|
||||
new_offsets->offsets[i] = displacement;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
objfile_relocate (symfile_objfile, new_offsets);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
haiku_special_symbol_handling (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static struct so_list *
|
||||
haiku_current_sos (void)
|
||||
{
|
||||
int lastID = -1;
|
||||
haiku_image_info *image;
|
||||
struct so_list *head = 0;
|
||||
struct so_list **link_ptr = &head;
|
||||
|
||||
TRACE(("haiku_current_sos()\n"));
|
||||
|
||||
while ((image = haiku_get_next_image_info(lastID)) != NULL) {
|
||||
struct so_list *object
|
||||
= (struct so_list *) xmalloc (sizeof (struct so_list));
|
||||
struct cleanup *old_chain = make_cleanup (xfree, object);
|
||||
|
||||
lastID = image->id;
|
||||
|
||||
memset (object, 0, sizeof (*object));
|
||||
|
||||
object->lm_info = XMALLOC(struct lm_info);
|
||||
make_cleanup (xfree, object->lm_info);
|
||||
object->lm_info->text_address = image->text_address;
|
||||
object->lm_info->unrelocated_text_address = 0;
|
||||
object->lm_info->unrelocated_text_address_initialized = false;
|
||||
|
||||
// Note: I don't know why, but the other solib implementations seem
|
||||
// to ignore the executable's shared object. We'll just do the same
|
||||
// here.
|
||||
if (image->is_app_image) {
|
||||
free_so (object);
|
||||
} else {
|
||||
strncpy (object->so_name, image->path, SO_NAME_MAX_PATH_SIZE);
|
||||
object->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
|
||||
strncpy (object->so_original_name, image->name,
|
||||
SO_NAME_MAX_PATH_SIZE);
|
||||
object->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
|
||||
|
||||
object->next = 0;
|
||||
*link_ptr = object;
|
||||
link_ptr = &object->next;
|
||||
}
|
||||
|
||||
discard_cleanups (old_chain);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
haiku_open_symbol_file_object (void *from_ttyp)
|
||||
{
|
||||
haiku_image_info *appImage = haiku_get_app_image();
|
||||
|
||||
TRACE(("haiku_open_symbol_file_object(%p)\n", from_ttyp));
|
||||
|
||||
if (!appImage) {
|
||||
TRACE(("haiku_open_symbol_file_object(): No app image!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
symbol_file_add_main (appImage->path, *(int *)from_ttyp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
haiku_in_dynsym_resolve_code (CORE_ADDR pc)
|
||||
{
|
||||
// No dynamic resolving implemented in Haiku yet.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
static struct target_so_ops haiku_so_ops;
|
||||
|
||||
extern initialize_file_ftype _initialize_haiku_solib;
|
||||
|
||||
void
|
||||
_initialize_haiku_solib (void)
|
||||
{
|
||||
haiku_so_ops.relocate_section_addresses = haiku_relocate_section_addresses;
|
||||
haiku_so_ops.free_so = haiku_free_so;
|
||||
haiku_so_ops.clear_solib = haiku_clear_solib;
|
||||
haiku_so_ops.solib_create_inferior_hook = haiku_solib_create_inferior_hook;
|
||||
haiku_so_ops.special_symbol_handling = haiku_special_symbol_handling;
|
||||
haiku_so_ops.current_sos = haiku_current_sos;
|
||||
haiku_so_ops.open_symbol_file_object = haiku_open_symbol_file_object;
|
||||
haiku_so_ops.in_dynsym_resolve_code = haiku_in_dynsym_resolve_code;
|
||||
|
||||
/* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
|
||||
current_target_so_ops = &haiku_so_ops;
|
||||
}
|
34
src/bin/gdb/gdb/solib-haiku.h
Normal file
34
src/bin/gdb/gdb/solib-haiku.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* Shared library support for Haiku.
|
||||
|
||||
Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
typedef struct haiku_image_info {
|
||||
int id;
|
||||
char name[256];
|
||||
char path[1024];
|
||||
CORE_ADDR text_address;
|
||||
int text_size;
|
||||
CORE_ADDR data_address;
|
||||
int data_size;
|
||||
bool is_app_image;
|
||||
} haiku_image_info;
|
||||
|
Loading…
Reference in New Issue
Block a user