HaikuPorts
  • Login
  • Preferences
  • Help/Guide
  • Wiki
  • Timeline
  • Roadmap
  • View Tickets
  • Search
  • Port Log
  • Blog

Context Navigation

  • Back to Ticket #534

Ticket #534: gdb-7.2.patch

File gdb-7.2.patch, 80.2 KB (added by korli, 4 years ago)

WIP 7.2 patch

  • bfd/config.bfd

    diff -ruN gdb-7.2-orig/bfd/config.bfd gdb-7.2/bfd/config.bfd
    old new  
    670670    targ_defvec=bfd_elf32_i386_vec 
    671671    targ_selvecs="i386pe_vec i386pei_vec" 
    672672    ;; 
     673  i[3-7]86-*-haiku*) 
     674        targ_defvec=bfd_elf32_i386_vec 
     675    targ_selvecs="i386pe_vec i386pei_vec" 
     676    ;; 
    673677  i[3-7]86-*-interix*) 
    674678    targ_defvec=i386pei_vec 
    675679    targ_selvecs="i386pe_vec" 
  • config.sub

    diff -ruN gdb-7.2-orig/config.sub gdb-7.2/config.sub
    old new  
    14501450        -dicos*) 
    14511451                os=-dicos 
    14521452                ;; 
    1453         -nacl*) 
    1454                 ;; 
     1453        -nacl*) 
     1454                ;; 
     1455        -haiku*) 
     1456                os=-haiku 
     1457                ;; 
    14551458        -none) 
    14561459                ;; 
    14571460        *) 
  • gdb/config/i386/haiku.mh

    diff -ruN gdb-7.2-orig/gdb/config/i386/haiku.mh gdb-7.2/gdb/config/i386/haiku.mh
    old new  
     1# Host: Intel 586 running Haiku 
     2 
     3NAT_FILE= nm-haiku.h 
     4NATDEPFILES= haiku-nat.o i386-haiku-nat.o inf-child.o fork-child.o 
     5 
     6# No core file support yet. 
     7# corelow.o core-aout.o 
  • gdb/config/i386/haiku.mt

    diff -ruN gdb-7.2-orig/gdb/config/i386/haiku.mt gdb-7.2/gdb/config/i386/haiku.mt
    old new  
     1# Target: Intel 586 running Haiku 
     2 
     3TDEPFILES= i386-tdep.o i386-haiku-tdep.o haiku-tdep.o i387-tdep.o \ 
     4        solib.o solib-haiku.o symfile-mem.o 
     5DEPRECATED_TM_FILE= tm-haiku.h 
  • gdb/config/i386/nm-haiku.h

    diff -ruN gdb-7.2-orig/gdb/config/i386/nm-haiku.h gdb-7.2/gdb/config/i386/nm-haiku.h
    old new  
     1/* Native support for Haiku x86. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#ifndef NM_HAIKU_H 
     23#define NM_HAIKU_H 
     24 
     25#include "config/nm-haiku.h" 
     26 
     27#endif /* nm-haiku.h */ 
  • gdb/config/i386/tm-haiku.h

    diff -ruN gdb-7.2-orig/gdb/config/i386/tm-haiku.h gdb-7.2/gdb/config/i386/tm-haiku.h
    old new  
     1/* Definitions to target GDB to Haiku on 386. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#ifndef TM_HAIKU_H 
     23#define TM_HAIKU_H 
     24 
     25#include "config/tm-haiku.h" 
     26 
     27#endif /* #ifndef TM_HAIKU_H */ 
  • gdb/config/nm-haiku.h

    diff -ruN gdb-7.2-orig/gdb/config/nm-haiku.h gdb-7.2/gdb/config/nm-haiku.h
    old new  
     1/* Native support Haiku. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22// #define REALTIME_{LO,HI}? 
     23 
     24/* Support for shared libraries.  */ 
     25#include "solib.h" 
  • gdb/config/tm-haiku.h

    diff -ruN gdb-7.2-orig/gdb/config/tm-haiku.h gdb-7.2/gdb/config/tm-haiku.h
    old new  
     1/* Target support Haiku. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22// #define REALTIME_{LO,HI}? 
     23 
     24/* Support for shared libraries.  */ 
     25#include "solib.h" 
  • gdb/configure.host

    diff -ruN gdb-7.2-orig/gdb/configure.host gdb-7.2/gdb/configure.host
    old new  
    104104                        gdb_host=sol2-64 ;; 
    105105i[34567]86-*-solaris*)  gdb_host=i386sol2 ;; 
    106106i[34567]86-*-cygwin*)   gdb_host=cygwin ;; 
     107i[567]86-*-haiku*)      gdb_host=haiku ;; 
    107108 
    108109ia64-*-linux*)          gdb_host=linux ;; 
    109110 
  • gdb/defs.h

    diff -ruN gdb-7.2-orig/gdb/defs.h gdb-7.2/gdb/defs.h
    old new  
    973973  GDB_OSABI_DICOS, 
    974974  GDB_OSABI_DARWIN, 
    975975  GDB_OSABI_SYMBIAN, 
     976  GDB_OSABI_HAIKU, 
    976977 
    977978  GDB_OSABI_INVALID             /* keep this last */ 
    978979}; 
  • gdb/haiku-nat.c

    diff -ruN gdb-7.2-orig/gdb/haiku-nat.c gdb-7.2/gdb/haiku-nat.c
    old new  
     1/* Haiku native-dependent code common to multiple platforms. 
     2 
     3   Copyright 2011 Jérôme Duval <korli@users.berlios.de>. 
     4   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     5 
     6   This file is part of GDB. 
     7 
     8   This program is free software; you can redistribute it and/or modify 
     9   it under the terms of the GNU General Public License as published by 
     10   the Free Software Foundation; either version 2 of the License, or 
     11   (at your option) any later version. 
     12 
     13   This program is distributed in the hope that it will be useful, 
     14   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     16   GNU General Public License for more details. 
     17 
     18   You should have received a copy of the GNU General Public License 
     19   along with this program; if not, write to the Free Software 
     20   Foundation, Inc., 59 Temple Place - Suite 330, 
     21   Boston, MA 02111-1307, USA.  */ 
     22 
     23#include <stdio.h> 
     24#include <string.h> 
     25 
     26#include <debugger.h> 
     27#include <image.h> 
     28#include <OS.h> 
     29 
     30#include <debug_support.h> 
     31 
     32#include "defs.h"       // include this first -- otherwise "command.h" will choke 
     33#include "command.h" 
     34#include "gdbcore.h" 
     35#include "gdbthread.h" 
     36#include "haiku-nat.h" 
     37#include "inferior.h" 
     38#include "observer.h" 
     39#include "regcache.h" 
     40#include "solib-haiku.h" 
     41#include "symfile.h" 
     42#include "target.h" 
     43 
     44#define TRACE_HAIKU_NAT 
     45#ifdef TRACE_HAIKU_NAT 
     46        #define TRACE(x)        printf x 
     47#else 
     48        #define TRACE(x)        while (false) {} 
     49#endif 
     50 
     51static struct target_ops *sHaikuTarget = NULL; 
     52 
     53typedef struct debug_event { 
     54        struct debug_event                      *next; 
     55        debug_debugger_message          message; 
     56        debug_debugger_message_data     data; 
     57} debug_event; 
     58 
     59typedef struct debug_event_list { 
     60        debug_event             *head; 
     61        debug_event             *tail; 
     62} debug_event_list; 
     63 
     64typedef enum { 
     65        SIGNAL_ARRIVED,         // the signal has actually arrived and is going to be 
     66                                                // handled (in any way) 
     67        SIGNAL_WILL_ARRIVE,     // the signal has not yet been sent, but will be sent 
     68                                                // (e.g. an exception occurred and will cause the 
     69                                                // signal when not being ignored) 
     70        SIGNAL_FAKED,           // the signal didn't arrive and won't arrive, we faked 
     71                                                // it (often in case of SIGTRAP) 
     72} pending_signal_status; 
     73 
     74typedef struct thread_debug_info { 
     75        struct thread_debug_info        *next; 
     76        thread_id                                       thread; 
     77        bool                                            stopped; 
     78        debug_event                                     *last_event;            // last debug message from 
     79                                                                                                        // the thread; valid only, 
     80                                                                                                        // if stopped 
     81        int                                                     reprocess_event;        // > 0, the event 
     82                                                                                                        // shall be processed a 
     83                                                                                                        // that many times, which 
     84                                                                                                        // will probably trigger 
     85                                                                                                        // another target event 
     86        int                                                     signal;                         // only valid, if stopped 
     87        pending_signal_status           signal_status; 
     88} thread_debug_info; 
     89 
     90typedef struct extended_image_info { 
     91        haiku_image_info                        info; 
     92        struct extended_image_info      *next; 
     93} extended_image_info; 
     94 
     95typedef struct team_debug_info { 
     96        team_id                         team; 
     97        port_id                         debugger_port; 
     98        thread_id                       nub_thread; 
     99        debug_context           context; 
     100        thread_debug_info       *threads; 
     101        extended_image_info     *images; 
     102        debug_event_list        events; 
     103} team_debug_info; 
     104 
     105static team_debug_info sTeamDebugInfo; 
     106 
     107 
     108typedef struct signal_map_entry { 
     109        enum target_signal      target; 
     110        int                                     haiku; 
     111} signal_map_entry; 
     112 
     113static const signal_map_entry sSignalMap[] = { 
     114        { TARGET_SIGNAL_0,                      0 }, 
     115        { TARGET_SIGNAL_HUP,            SIGHUP }, 
     116        { TARGET_SIGNAL_INT,            SIGINT }, 
     117        { TARGET_SIGNAL_QUIT,           SIGQUIT }, 
     118        { TARGET_SIGNAL_ILL,            SIGILL }, 
     119        { TARGET_SIGNAL_CHLD,           SIGCHLD }, 
     120        { TARGET_SIGNAL_ABRT,           SIGABRT }, 
     121        { TARGET_SIGNAL_PIPE,           SIGPIPE }, 
     122        { TARGET_SIGNAL_FPE,            SIGFPE }, 
     123        { TARGET_SIGNAL_KILL,           SIGKILL }, 
     124        { TARGET_SIGNAL_STOP,           SIGSTOP }, 
     125        { TARGET_SIGNAL_SEGV,           SIGSEGV }, 
     126        { TARGET_SIGNAL_CONT,           SIGCONT }, 
     127        { TARGET_SIGNAL_TSTP,           SIGTSTP }, 
     128        { TARGET_SIGNAL_ALRM,           SIGALRM }, 
     129        { TARGET_SIGNAL_TERM,           SIGTERM }, 
     130        { TARGET_SIGNAL_TTIN,           SIGTTIN }, 
     131        { TARGET_SIGNAL_TTOU,           SIGTTOU }, 
     132        { TARGET_SIGNAL_USR1,           SIGUSR1 }, 
     133        { TARGET_SIGNAL_USR2,           SIGUSR2 }, 
     134        { TARGET_SIGNAL_WINCH,          SIGWINCH }, 
     135        { TARGET_SIGNAL_TRAP,           SIGTRAP }, 
     136        { TARGET_SIGNAL_0,                      SIGKILLTHR },   // not debuggable anyway 
     137        { -1, -1 } 
     138}; 
     139 
     140 
     141// #pragma mark - 
     142 
     143 
     144static char *haiku_pid_to_str (struct target_ops *ops, ptid_t ptid); 
     145 
     146 
     147static int 
     148target_to_haiku_signal(enum target_signal targetSignal) 
     149{ 
     150        int i; 
     151 
     152        if (targetSignal < 0) 
     153                return -1; 
     154 
     155        for (i = 0; sSignalMap[i].target != -1 || sSignalMap[i].haiku != -1; i++) { 
     156                if (targetSignal == sSignalMap[i].target) 
     157                        return sSignalMap[i].haiku; 
     158        } 
     159 
     160        return -1; 
     161} 
     162 
     163 
     164static enum target_signal 
     165haiku_to_target_signal(int haikuSignal) 
     166{ 
     167        int i; 
     168 
     169        if (haikuSignal < 0) 
     170                return TARGET_SIGNAL_0; 
     171 
     172        for (i = 0; sSignalMap[i].target != -1 || sSignalMap[i].haiku != -1; i++) { 
     173                if (haikuSignal == sSignalMap[i].haiku) 
     174                        return sSignalMap[i].target; 
     175        } 
     176 
     177        return TARGET_SIGNAL_UNKNOWN; 
     178} 
     179 
     180 
     181static thread_debug_info * 
     182haiku_find_thread(team_debug_info *teamDebugInfo, thread_id threadID) 
     183{ 
     184        thread_debug_info *info; 
     185        for (info = teamDebugInfo->threads; info; info = info->next) { 
     186                if (info->thread == threadID) 
     187                        return info; 
     188        } 
     189 
     190        return NULL; 
     191} 
     192 
     193 
     194static thread_debug_info * 
     195haiku_add_thread(team_debug_info *teamDebugInfo, thread_id threadID) 
     196{ 
     197        struct thread_info *gdbThreadInfo; 
     198        thread_debug_info *threadDebugInfo; 
     199 
     200        if (threadID == teamDebugInfo->nub_thread) { 
     201                error("haiku_thread_added(): Trying to add debug nub thread (%ld)\n", 
     202                        threadID); 
     203        } 
     204 
     205        // find the thread first 
     206        threadDebugInfo = haiku_find_thread(teamDebugInfo, threadID); 
     207        if (threadDebugInfo) 
     208                return threadDebugInfo; 
     209 
     210        // allocate a new thread debug info 
     211        threadDebugInfo = XMALLOC(thread_debug_info); 
     212        if (!threadDebugInfo) 
     213                error("haiku_thread_added(): Out of memory!\n"); 
     214 
     215        // init and add it 
     216        threadDebugInfo->thread = threadID; 
     217        threadDebugInfo->next = teamDebugInfo->threads; 
     218        threadDebugInfo->stopped = false; 
     219        threadDebugInfo->last_event = NULL; 
     220        teamDebugInfo->threads = threadDebugInfo; 
     221 
     222        // add it to gdb's thread DB 
     223        gdbThreadInfo = add_thread(ptid_build(teamDebugInfo->team, 0, threadID)); 
     224 
     225        // Note: In theory we could spare us the whole thread list management, since 
     226        // gdb's thread DB is doing exactly the same. We could put our data as 
     227        // thread_info::private. The only catch is that when the thread_info is 
     228        // freed, xfree() is invoked on the private data directly, but there's no 
     229        // callback invoked before that would allow us to do cleanup (e.g. free 
     230        // last_event). 
     231 
     232        TRACE(("haiku_add_thread(): team %ld thread %ld added: " 
     233                "gdb thread info: %p\n", teamDebugInfo->team, threadID, gdbThreadInfo)); 
     234 
     235        return threadDebugInfo; 
     236} 
     237 
     238 
     239static void 
     240haiku_remove_thread(team_debug_info *teamDebugInfo, thread_id threadID) 
     241{ 
     242        thread_debug_info **info; 
     243        for (info = &teamDebugInfo->threads; *info; info = &(*info)->next) { 
     244                if ((*info)->thread == threadID) { 
     245                        thread_debug_info *foundInfo = *info; 
     246                        *info = foundInfo->next; 
     247                        if (foundInfo->last_event) 
     248                                xfree(foundInfo->last_event); 
     249                        xfree(foundInfo); 
     250 
     251                        // remove it from gdb's thread DB 
     252                        delete_thread(ptid_build(teamDebugInfo->team, 0, threadID)); 
     253 
     254                        return; 
     255                } 
     256        } 
     257} 
     258 
     259 
     260static void 
     261haiku_init_thread_list(team_debug_info *teamDebugInfo) 
     262{ 
     263        thread_info threadInfo; 
     264        int32 cookie = 0; 
     265 
     266        // init gdb's thread DB 
     267        init_thread_list(); 
     268 
     269        while (get_next_thread_info(teamDebugInfo->team, &cookie, &threadInfo) 
     270                == B_OK) { 
     271                if (threadInfo.thread != teamDebugInfo->nub_thread) 
     272                        haiku_add_thread(teamDebugInfo, threadInfo.thread); 
     273        } 
     274} 
     275 
     276 
     277static void 
     278haiku_cleanup_thread_list(team_debug_info *teamDebugInfo) 
     279{ 
     280        while (teamDebugInfo->threads) { 
     281                thread_debug_info *thread = teamDebugInfo->threads; 
     282                teamDebugInfo->threads = thread->next; 
     283                xfree(thread); 
     284        } 
     285 
     286        // clear gdb's thread DB 
     287        init_thread_list(); 
     288} 
     289 
     290 
     291// #pragma mark - 
     292 
     293static extended_image_info ** 
     294haiku_find_image_insert_location(team_debug_info *teamDebugInfo, 
     295        image_id imageID) 
     296{ 
     297        extended_image_info **image; 
     298 
     299        for (image = &teamDebugInfo->images; *image; image = &(*image)->next) { 
     300                if ((*image)->info.id >= imageID) 
     301                        return image; 
     302        } 
     303 
     304        return image; 
     305} 
     306 
     307 
     308static extended_image_info * 
     309haiku_find_image(team_debug_info *teamDebugInfo, image_id imageID) 
     310{ 
     311        extended_image_info *image = *haiku_find_image_insert_location( 
     312                teamDebugInfo, imageID); 
     313 
     314        return (image && image->info.id == imageID ? image : NULL); 
     315} 
     316 
     317 
     318static extended_image_info * 
     319haiku_add_image(team_debug_info *teamDebugInfo, image_info *imageInfo) 
     320{ 
     321        extended_image_info **imageP = haiku_find_image_insert_location( 
     322                teamDebugInfo, imageInfo->id); 
     323        extended_image_info *image = *imageP; 
     324 
     325        // already known? 
     326        if (image && image->info.id == imageInfo->id) 
     327                return image; 
     328 
     329        image = XMALLOC(extended_image_info); 
     330        if (!image) 
     331                error("haiku_add_image(): Out of memory!"); 
     332 
     333        image->info.id = imageInfo->id; 
     334        strncpy(image->info.name, imageInfo->name, sizeof(image->info.name)); 
     335        image->info.name[sizeof(image->info.name) - 1] = '\0'; 
     336                // TODO: This should be the shared objects soname, not the path. We 
     337                // probably need to extend the debugger API. 
     338        strncpy(image->info.path, imageInfo->name, sizeof(image->info.path)); 
     339        image->info.path[sizeof(image->info.path) - 1] = '\0'; 
     340        image->info.text_address = (CORE_ADDR)imageInfo->text; 
     341        image->info.text_size = imageInfo->text_size; 
     342        image->info.data_address = (CORE_ADDR)imageInfo->data; 
     343        image->info.data_size = imageInfo->data_size; 
     344        image->info.is_app_image = (imageInfo->type == B_APP_IMAGE); 
     345 
     346        image->next = *imageP; 
     347        *imageP = image; 
     348 
     349        return image; 
     350} 
     351 
     352 
     353static void 
     354haiku_remove_image(team_debug_info *teamDebugInfo, image_id imageID) 
     355{ 
     356        extended_image_info **imageP = haiku_find_image_insert_location( 
     357                teamDebugInfo, imageID); 
     358        extended_image_info *image = *imageP; 
     359 
     360        if (image && image->info.id == imageID) { 
     361                *imageP = image->next; 
     362                xfree(image); 
     363        } 
     364} 
     365 
     366 
     367static void 
     368haiku_init_image_list(team_debug_info *teamDebugInfo) 
     369{ 
     370        int32 cookie = 0; 
     371        image_info info; 
     372        while (get_next_image_info(teamDebugInfo->team, &cookie, &info) == B_OK) 
     373                haiku_add_image(teamDebugInfo, &info); 
     374} 
     375 
     376 
     377static void 
     378haiku_cleanup_image_list(team_debug_info *teamDebugInfo) 
     379{ 
     380        while (teamDebugInfo->images) { 
     381                extended_image_info *image = teamDebugInfo->images; 
     382                teamDebugInfo->images = image->next; 
     383                xfree(image); 
     384        } 
     385} 
     386 
     387 
     388/* 
     389 * Service function. Call with -1 the first time. 
     390 */ 
     391struct haiku_image_info * 
     392haiku_get_next_image_info(int lastID) 
     393{ 
     394        extended_image_info *image = *haiku_find_image_insert_location( 
     395                &sTeamDebugInfo, (lastID >= 0 ? lastID : 0)); 
     396 
     397        if (image && image->info.id == lastID) 
     398                image = image->next; 
     399 
     400        return (image ? &image->info : NULL); 
     401} 
     402 
     403 
     404// #pragma mark - 
     405 
     406static debug_event * 
     407haiku_enqueue_debug_event(debug_event_list *list, int32 message, 
     408        debug_debugger_message_data *data, int32 size) 
     409{ 
     410        debug_event *event = XMALLOC(debug_event); 
     411 
     412        if (!event) 
     413                error("haiku_enqueue_debug_event(): Out of memory!\n"); 
     414 
     415        // init the event 
     416        event->next = NULL; 
     417        event->message = message; 
     418        memcpy(&event->data, data, 
     419                (size >= 0 ? size : sizeof(debug_debugger_message_data))); 
     420 
     421        // add it to the queue 
     422        if (list->tail) { 
     423                list->tail->next = event; 
     424                list->tail = event; 
     425        } else { 
     426                list->head = list->tail = event; 
     427        } 
     428 
     429        return event; 
     430} 
     431 
     432 
     433static debug_event * 
     434haiku_dequeue_next_debug_event(debug_event_list *list) 
     435{ 
     436        debug_event *event = list->head; 
     437 
     438        if (event) { 
     439                // remove it from the queue 
     440                list->head = event->next; 
     441                if (list->tail == event) 
     442                        list->tail = NULL; 
     443 
     444                event->next = NULL;     // just because we're paranoid 
     445        } 
     446 
     447        return event; 
     448} 
     449 
     450 
     451static debug_event * 
     452haiku_remove_debug_event(debug_event_list *list, debug_event *eventToRemove) 
     453{ 
     454        debug_event **event; 
     455 
     456        if (eventToRemove) { 
     457                for (event = &list->head; *event; event = &(*event)->next) { 
     458                        if (*event == eventToRemove) { 
     459                                *event = (*event)->next; 
     460                                if (eventToRemove == list->tail) 
     461                                        list->tail = NULL; 
     462                                return eventToRemove; 
     463                        } 
     464                } 
     465        } 
     466 
     467        error("haiku_remove_debug_event(): event %p not found in list %p\n", 
     468                eventToRemove, list); 
     469 
     470        return NULL; 
     471} 
     472 
     473 
     474static void 
     475haiku_clear_debug_event_list(debug_event_list *list) 
     476{ 
     477        debug_event *event; 
     478 
     479        while ((event = haiku_dequeue_next_debug_event(list))) 
     480                xfree(event); 
     481} 
     482 
     483 
     484static debug_event * 
     485haiku_find_next_debug_event(debug_event_list *list, 
     486        bool (*predicate)(void *closure, debug_event *event), void *closure) 
     487{ 
     488        debug_event *event; 
     489 
     490        for (event = list->head; event; event = event->next) { 
     491                if ((*predicate)(closure, event)) 
     492                        return event; 
     493        } 
     494 
     495        return NULL; 
     496} 
     497 
     498 
     499static void 
     500haiku_read_pending_debug_events(team_debug_info *teamDebugInfo, 
     501        bool block, bool (*block_predicate)(void *closure, debug_event *event), 
     502        void *closure) 
     503{ 
     504        while (true) { 
     505                // read the next message from the debugger port 
     506                debug_debugger_message_data message; 
     507                int32 code; 
     508                ssize_t bytesRead; 
     509                debug_event *event; 
     510 
     511//              TRACE(("haiku_read_pending_debug_events(): reading from debugger port " 
     512//                      "(%sblocking)...\n", (block ? "" : "non-"))); 
     513 
     514                do { 
     515                        bytesRead = read_port_etc(teamDebugInfo->debugger_port, &code, 
     516                                &message, sizeof(message), (block ? 0 : B_RELATIVE_TIMEOUT), 0); 
     517                } while (bytesRead == B_INTERRUPTED); 
     518 
     519                if (bytesRead < 0) { 
     520                        if (bytesRead == B_WOULD_BLOCK && !block) 
     521                                break; 
     522 
     523                        error("Failed to read from debugger port: %s\n", 
     524                                strerror(bytesRead)); 
     525                } 
     526 
     527//              TRACE(("haiku_read_pending_debug_events(): got event: %lu, " 
     528//                      "thread: %ld, team: %ld, nub port: %ld\n", code, 
     529//                      message.origin.thread, message.origin.team, 
     530//                      message.origin.nub_port)); 
     531 
     532                // got a message: queue it 
     533                event = haiku_enqueue_debug_event(&teamDebugInfo->events, code, 
     534                        &message, bytesRead); 
     535 
     536                block = !(*block_predicate)(closure, event); 
     537        } 
     538} 
     539 
     540 
     541typedef struct thread_event_closure { 
     542        team_debug_info *context; 
     543        thread_id               thread; 
     544        debug_event             *event; 
     545} thread_event_closure; 
     546 
     547 
     548static bool 
     549haiku_thread_event_predicate(void *_closure, debug_event *event) 
     550{ 
     551        thread_event_closure *closure = (thread_event_closure*)_closure; 
     552 
     553        if (event->message == B_DEBUGGER_MESSAGE_TEAM_DELETED) { 
     554                if (closure->context->team < 0 
     555                        || event->data.origin.team == closure->context->team) { 
     556                        closure->event = event; 
     557                } 
     558        } 
     559 
     560        if (!closure->event) { 
     561                if (event->data.origin.team == closure->context->team 
     562                        && (closure->thread < 0 
     563                                || closure->thread == event->data.origin.thread)) { 
     564                        closure->event = event; 
     565                } 
     566        } 
     567 
     568        return (closure->event != NULL); 
     569} 
     570 
     571 
     572// #pragma mark - 
     573 
     574static void 
     575haiku_cleanup_team_debug_info() 
     576{ 
     577        destroy_debug_context(&sTeamDebugInfo.context); 
     578        delete_port(sTeamDebugInfo.debugger_port); 
     579        sTeamDebugInfo.debugger_port = -1; 
     580        sTeamDebugInfo.team = -1; 
     581 
     582        haiku_cleanup_thread_list(&sTeamDebugInfo); 
     583        haiku_cleanup_image_list(&sTeamDebugInfo); 
     584} 
     585 
     586 
     587static status_t 
     588haiku_send_debugger_message(team_debug_info *teamDebugInfo, int32 messageCode, 
     589        const void *message, int32 messageSize, void *reply, int32 replySize) 
     590{ 
     591        return send_debug_message(&teamDebugInfo->context, messageCode, 
     592                message, messageSize, reply, replySize); 
     593} 
     594 
     595 
     596static void 
     597haiku_init_child_debugging (thread_id threadID, bool debugThread) 
     598{ 
     599        thread_info threadInfo; 
     600        status_t result; 
     601        port_id nubPort; 
     602 
     603        // get a thread info 
     604        result = get_thread_info(threadID, &threadInfo); 
     605        if (result != B_OK) 
     606                error("Thread with ID %ld not found: %s", threadID, strerror(result)); 
     607 
     608        // init our team debug structure 
     609        sTeamDebugInfo.team = threadInfo.team; 
     610        sTeamDebugInfo.debugger_port = -1; 
     611        sTeamDebugInfo.context.nub_port = -1; 
     612        sTeamDebugInfo.context.reply_port = -1; 
     613        sTeamDebugInfo.threads = NULL; 
     614        sTeamDebugInfo.events.head = NULL; 
     615        sTeamDebugInfo.events.tail = NULL; 
     616 
     617        // create the debugger port 
     618        sTeamDebugInfo.debugger_port = create_port(10, "gdb debug"); 
     619        if (sTeamDebugInfo.debugger_port < 0) { 
     620                error("Failed to create debugger port: %s", 
     621                        strerror(sTeamDebugInfo.debugger_port)); 
     622        } 
     623 
     624        // install ourselves as the team debugger 
     625        nubPort = install_team_debugger(sTeamDebugInfo.team, 
     626                sTeamDebugInfo.debugger_port); 
     627        if (nubPort < 0) { 
     628                error("Failed to install ourselves as debugger for team %ld: %s", 
     629                        sTeamDebugInfo.team, strerror(nubPort)); 
     630        } 
     631 
     632        // get the nub thread 
     633        { 
     634                team_info teamInfo; 
     635                result = get_team_info(sTeamDebugInfo.team, &teamInfo); 
     636                if (result != B_OK) { 
     637                        error("Failed to get info for team %ld: %s\n", 
     638                                sTeamDebugInfo.team, strerror(result)); 
     639                } 
     640 
     641                sTeamDebugInfo.nub_thread = teamInfo.debugger_nub_thread; 
     642        } 
     643 
     644        // init the debug context 
     645        result = init_debug_context(&sTeamDebugInfo.context, sTeamDebugInfo.team, 
     646                nubPort); 
     647        if (result != B_OK) { 
     648                error("Failed to init debug context for team %ld: %s\n", 
     649                        sTeamDebugInfo.team, strerror(result)); 
     650        } 
     651 
     652        // start debugging the thread 
     653        if (debugThread) { 
     654                result = debug_thread(threadID); 
     655                if (result != B_OK) { 
     656                        error("Failed to start debugging thread %ld: %s", threadID, 
     657                                strerror(result)); 
     658                } 
     659        } 
     660 
     661        // set the team debug flags 
     662        { 
     663                debug_nub_set_team_flags message; 
     664                message.flags = B_TEAM_DEBUG_SIGNALS /*| B_TEAM_DEBUG_PRE_SYSCALL 
     665                        | B_TEAM_DEBUG_POST_SYSCALL*/ | B_TEAM_DEBUG_TEAM_CREATION 
     666                        | B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES; 
     667                        // TODO: We probably don't need all events 
     668 
     669                haiku_send_debugger_message(&sTeamDebugInfo, 
     670                        B_DEBUG_MESSAGE_SET_TEAM_FLAGS, &message, sizeof(message), NULL, 0); 
     671        } 
     672 
     673 
     674        // the fun can start: push the target and init the rest 
     675        push_target(sHaikuTarget); 
     676 
     677        haiku_init_thread_list(&sTeamDebugInfo); 
     678        haiku_init_image_list(&sTeamDebugInfo); 
     679 
     680        disable_breakpoints_in_shlibs (); 
     681 
     682//      child_clear_solibs (); 
     683                // TODO: Implement? Do we need this? 
     684 
     685        clear_proceed_status (); 
     686        init_wait_for_inferior (); 
     687 
     688        target_terminal_init (); 
     689        target_terminal_inferior (); 
     690} 
     691 
     692 
     693static void 
     694haiku_continue_thread(team_debug_info *teamDebugInfo, thread_id threadID, 
     695        uint32 handleEvent, bool step) 
     696{ 
     697        debug_nub_continue_thread message; 
     698        status_t err; 
     699 
     700        message.thread = threadID; 
     701        message.handle_event = handleEvent; 
     702        message.single_step = step; 
     703 
     704        err = haiku_send_debugger_message(teamDebugInfo, 
     705                B_DEBUG_MESSAGE_CONTINUE_THREAD, &message, sizeof(message), NULL, 0); 
     706        if (err != B_OK) { 
     707                printf_unfiltered ("Failed to resume thread %ld: %s\n", threadID, 
     708                        strerror(err)); 
     709        } 
     710} 
     711 
     712 
     713static status_t 
     714haiku_stop_thread(team_debug_info *teamDebugInfo, thread_id threadID) 
     715{ 
     716        // check whether we know the thread 
     717        status_t err; 
     718        thread_event_closure threadEventClosure; 
     719 
     720        thread_debug_info *threadInfo = haiku_find_thread(teamDebugInfo, threadID); 
     721        if (!threadInfo) 
     722                return B_BAD_THREAD_ID; 
     723 
     724        // already stopped? 
     725        if (threadInfo->stopped) 
     726                return B_OK; 
     727 
     728        // debug the thread 
     729        err = debug_thread(threadID); 
     730        if (err != B_OK) { 
     731                TRACE(("haiku_stop_thread(): failed to debug thread %ld: %s\n", 
     732                        threadID, strerror(err))); 
     733                return err; 
     734        } 
     735 
     736        // wait for the event to hit our port 
     737 
     738        // TODO: debug_thread() doesn't guarantee that the thread will enter the 
     739        // debug loop any time soon. E.g. a wait_for_thread() is (at the moment) 
     740        // not interruptable, so we block here forever, if we already debug the 
     741        // thread that is being waited for. We should probably limit the time 
     742        // we're waiting, and return the info to the caller, which can then try 
     743        // to deal with the situation in an appropriate way. 
     744 
     745        // prepare closure for finding interesting events 
     746        threadEventClosure.context = teamDebugInfo; 
     747        threadEventClosure.thread = threadID; 
     748        threadEventClosure.event = NULL; 
     749 
     750        // find the first interesting queued event 
     751        threadEventClosure.event = haiku_find_next_debug_event( 
     752                &teamDebugInfo->events, haiku_thread_event_predicate, 
     753                &threadEventClosure); 
     754 
     755        // read all events pending on the port 
     756        haiku_read_pending_debug_events(teamDebugInfo, 
     757                (threadEventClosure.event == NULL), haiku_thread_event_predicate, 
     758                &threadEventClosure); 
     759 
     760        // We should check, whether we really got an event for the thread in 
     761        // question, but the only possible other event is that the team has 
     762        // been delete, which ends the game anyway. 
     763 
     764        // TODO: That's actually not true. We also get messages when an add-on 
     765        // has been loaded/unloaded, a signal arrives, or a thread calls the 
     766        // debugger. 
     767 
     768        return B_OK; 
     769} 
     770 
     771 
     772static status_t 
     773haiku_get_cpu_state(team_debug_info *teamDebugInfo, 
     774        debug_nub_get_cpu_state_reply *reply) 
     775{ 
     776        status_t err; 
     777        thread_id threadID = ptid_get_tid(inferior_ptid); 
     778        debug_nub_get_cpu_state message; 
     779 
     780        // make sure the thread is stopped 
     781        err = haiku_stop_thread(teamDebugInfo, threadID); 
     782        if (err != B_OK) { 
     783                printf_unfiltered ("Failed to stop thread %ld: %s\n", 
     784                        threadID, strerror(err)); 
     785                return err; 
     786        } 
     787 
     788        message.reply_port = teamDebugInfo->context.reply_port; 
     789        message.thread = threadID; 
     790 
     791        err = haiku_send_debugger_message(teamDebugInfo, 
     792                B_DEBUG_MESSAGE_GET_CPU_STATE, &message, sizeof(message), reply, 
     793                sizeof(*reply)); 
     794        if (err == B_OK) 
     795                err = reply->error; 
     796        if (err != B_OK) { 
     797                printf_unfiltered ("Failed to get status of thread %ld: %s\n", 
     798                        threadID, strerror(err)); 
     799        } 
     800 
     801        return err; 
     802} 
     803 
     804 
     805// #pragma mark - 
     806 
     807static void 
     808haiku_child_open (char *arg, int from_tty) 
     809{ 
     810        error ("Use the \"run\" command to start a child process."); 
     811} 
     812 
     813static void 
     814haiku_child_close (int x) 
     815{ 
     816        printf_unfiltered ("gdb: child_close, inferior_ptid=%d\n", 
     817                PIDGET (inferior_ptid)); 
     818} 
     819 
     820 
     821static void 
     822haiku_child_attach (struct target_ops *ops, char *args, int from_tty) 
     823{ 
     824        extern int stop_after_trap; 
     825        thread_id threadID; 
     826        thread_info threadInfo; 
     827        status_t result; 
     828 
     829        TRACE(("haiku_child_attach(`%s', %d)\n", args, from_tty)); 
     830 
     831        if (!args) 
     832                error_no_arg ("thread-id to attach"); 
     833 
     834        // get the thread ID 
     835        threadID = strtoul (args, 0, 0); 
     836        if (threadID <= 0) 
     837                error("The given thread-id %ld is invalid.", threadID); 
     838 
     839        haiku_init_child_debugging(threadID, true); 
     840         
     841        target_terminal_ours (); 
     842 
     843        TRACE(("haiku_child_attach() done\n")); 
     844} 
     845 
     846 
     847static void 
     848haiku_child_detach (struct target_ops *ops, char *args, int from_tty) 
     849{ 
     850        int detached = 1; 
     851        status_t result; 
     852 
     853        TRACE(("haiku_child_detach(`%s', %d)\n", args, from_tty)); 
     854 
     855        result = remove_team_debugger(sTeamDebugInfo.team); 
     856        if (result != B_OK) { 
     857                error("Failed to detach process %ld: %s\n", sTeamDebugInfo.team, 
     858                        strerror(result)); 
     859        } 
     860 
     861        delete_command (NULL, 0); 
     862 
     863        if (from_tty) { 
     864                char *exec_file = get_exec_file (0); 
     865                if (exec_file == 0) 
     866                        exec_file = ""; 
     867                printf_unfiltered ("Detaching from program: %s, Pid %ld\n", exec_file, 
     868                        sTeamDebugInfo.team); 
     869                gdb_flush (gdb_stdout); 
     870        } 
     871 
     872        haiku_cleanup_team_debug_info(); 
     873 
     874        inferior_ptid = null_ptid; 
     875        unpush_target (sHaikuTarget); 
     876} 
     877 
     878 
     879static void 
     880haiku_resume_thread(team_debug_info *teamDebugInfo, thread_debug_info *thread, 
     881        int step, enum target_signal sig) 
     882{ 
     883        thread_id threadID = (thread ? thread->thread : -1); 
     884        int pendingSignal = -1; 
     885        int signalToSend = target_to_haiku_signal(sig); 
     886        uint32 handleEvent = B_THREAD_DEBUG_HANDLE_EVENT; 
     887 
     888        if (!thread || !thread->stopped) { 
     889                TRACE(("haiku_resume_thread(): thread %ld not stopped\n", 
     890                        threadID)); 
     891                return; 
     892        } 
     893 
     894        if (thread->reprocess_event > 0) { 
     895                TRACE(("haiku_resume_thread(): thread %ld is expected to " 
     896                        "reprocess its current event\n", threadID)); 
     897                return; 
     898        } 
     899 
     900        // get the pending signal 
     901        if (thread->last_event) 
     902                pendingSignal = thread->signal; 
     903 
     904        // Decide what to do with the event and the pending and passed signal. 
     905        // We simply adjust signalToSend, pendingSignal and handleEvent. 
     906        // If signalToSend is set afterwards, we need to send it. pendingSignal we 
     907        // need to ignore. handleEvent specifies whether to handle/ignore the event. 
     908        if (signalToSend > 0) { 
     909                if (pendingSignal > 0) { 
     910                        if (signalToSend == pendingSignal) { 
     911                                // signal to send is the pending signal 
     912                                // we don't need to send it 
     913                                signalToSend = -1; 
     914                                if (thread->signal_status != SIGNAL_WILL_ARRIVE) { 
     915                                        // the signal has not yet been sent, so we need to ignore 
     916                                        // it only in this case, but not in the other ones 
     917                                        pendingSignal = -1; 
     918                                } 
     919                        } else { 
     920                                // signal to send is not the pending signal 
     921                                // If the signal has been sent or will be sent, we need to 
     922                                // ignore the event. 
     923                                if (thread->signal_status != SIGNAL_FAKED) 
     924                                        handleEvent = B_THREAD_DEBUG_IGNORE_EVENT; 
     925                                // At any rate we don't need to ignore the signal. 
     926                                pendingSignal = -1; 
     927                                // send the signal 
     928                        } 
     929                } else { 
     930                        // there's a signal to send, but no pending signal 
     931                        // handle the event 
     932                        // ignore the signal 
     933                        // send the signal 
     934                } 
     935        } else { 
     936                if (pendingSignal > 0) { 
     937                        // there's a pending signal, but no signal to send 
     938                        // Ignore the event, if the signal has been sent or will be sent. 
     939                        if (thread->signal_status != SIGNAL_FAKED) 
     940                                handleEvent = B_THREAD_DEBUG_IGNORE_EVENT; 
     941                } else { 
     942                        // there're neither signal to send nor pending signal 
     943                        // handle the event 
     944                } 
     945        } 
     946 
     947        // ignore the pending signal, if necessary 
     948        if (pendingSignal > 0) { 
     949                debug_nub_set_signal_masks message; 
     950                status_t err; 
     951 
     952                message.thread = threadID; 
     953                message.ignore_mask = 0; 
     954                message.ignore_once_mask = B_DEBUG_SIGNAL_TO_MASK(pendingSignal); 
     955                message.ignore_op = B_DEBUG_SIGNAL_MASK_OR; 
     956                message.ignore_once_op = B_DEBUG_SIGNAL_MASK_OR; 
     957 
     958                err = haiku_send_debugger_message(teamDebugInfo, 
     959                        B_DEBUG_MESSAGE_SET_SIGNAL_MASKS, &message, sizeof(message), 
     960                        NULL, 0); 
     961                if (err != B_OK) { 
     962                        printf_unfiltered ("Set signal ignore masks for thread %ld: %s\n", 
     963                                threadID, strerror(err)); 
     964                } 
     965        } 
     966 
     967        // send the signal 
     968        if (signalToSend > 0) { 
     969                if (send_signal(threadID, signalToSend) < 0) { 
     970                        printf_unfiltered ("Failed to send signal %d to thread %ld: %s\n", 
     971                                signalToSend, threadID, strerror(errno)); 
     972                } 
     973        } 
     974 
     975        // resume thread 
     976        haiku_continue_thread(teamDebugInfo, threadID, handleEvent, step); 
     977        thread->stopped = false; 
     978} 
     979 
     980 
     981static void 
     982haiku_child_resume (struct target_ops *ops, ptid_t ptid, int step, 
     983        enum target_signal sig) 
     984{ 
     985        team_id teamID = ptid_get_pid(ptid); 
     986        thread_id threadID = ptid_get_tid(ptid); 
     987        thread_debug_info *thread; 
     988 
     989        TRACE(("haiku_child_resume(`%s', step: %d, signal: %d)\n", 
     990                haiku_pid_to_str(ops, ptid), step, sig)); 
     991 
     992        if (teamID < 0) { 
     993                // resume all stopped threads (at least all haiku_wait_child() has 
     994                // reported to be stopped) 
     995                for (thread = sTeamDebugInfo.threads; thread; thread = thread->next) { 
     996                        if (thread->stopped) 
     997                                haiku_resume_thread(&sTeamDebugInfo, thread, step, sig); 
     998                } 
     999        } else { 
     1000                // resume the thread in question 
     1001                thread = haiku_find_thread(&sTeamDebugInfo, threadID); 
     1002                if (thread) { 
     1003                        haiku_resume_thread(&sTeamDebugInfo, thread, step, sig); 
     1004                } else { 
     1005                        printf_unfiltered ("haiku_child_resume(): unknown thread %ld\n", 
     1006                                threadID); 
     1007                } 
     1008        } 
     1009 
     1010} 
     1011 
     1012 
     1013static ptid_t 
     1014haiku_child_wait_internal (team_debug_info *teamDebugInfo, ptid_t ptid, 
     1015        struct target_waitstatus *ourstatus, bool *ignore, bool *selectThread) 
     1016{ 
     1017        team_id teamID = ptid_get_pid(ptid); 
     1018        team_id threadID = ptid_get_tid(ptid); 
     1019        debug_event *event = NULL; 
     1020        ptid_t retval = pid_to_ptid(-1); 
     1021        struct thread_debug_info *thread; 
     1022        int pendingSignal = -1; 
     1023        pending_signal_status pendingSignalStatus = SIGNAL_FAKED; 
     1024        int reprocessEvent = -1; 
     1025 
     1026        *selectThread = false; 
     1027 
     1028        if (teamID < 0 || threadID == 0) 
     1029                threadID = -1; 
     1030 
     1031        // if we're waiting for any thread, search the thread list for already 
     1032        // stopped threads (needed for reprocessing events) 
     1033        if (threadID < 0) { 
     1034                for (thread = teamDebugInfo->threads; thread; thread = thread->next) { 
     1035                        if (thread->stopped) { 
     1036                                threadID = thread->thread; 
     1037                                break; 
     1038                        } 
     1039                } 
     1040        } 
     1041 
     1042        // check, if the thread exists and is already stopped 
     1043        if (threadID >= 0 
     1044                && (thread = haiku_find_thread(teamDebugInfo, threadID)) != NULL 
     1045                && thread->stopped) { 
     1046                // remove the event that stopped the thread from the thread (we will 
     1047                // add it again, if it shall not be ignored) 
     1048                event = thread->last_event; 
     1049                thread->last_event = NULL; 
     1050                thread->stopped = false; 
     1051                reprocessEvent = thread->reprocess_event; 
     1052 
     1053                TRACE(("haiku_child_wait_internal(): thread %ld already stopped. " 
     1054                        "re-digesting the last event (%p).\n", threadID, event)); 
     1055        } else { 
     1056                // prepare closure for finding interesting events 
     1057                thread_event_closure threadEventClosure; 
     1058                threadEventClosure.context = teamDebugInfo; 
     1059                threadEventClosure.thread = threadID; 
     1060                threadEventClosure.event = NULL; 
     1061 
     1062                // find the first interesting queued event 
     1063                threadEventClosure.event = haiku_find_next_debug_event( 
     1064                        &teamDebugInfo->events, haiku_thread_event_predicate, 
     1065                        &threadEventClosure); 
     1066 
     1067                // read all events pending on the port 
     1068                haiku_read_pending_debug_events(teamDebugInfo, 
     1069                        (threadEventClosure.event == NULL), haiku_thread_event_predicate, 
     1070                        &threadEventClosure); 
     1071 
     1072                // get the event of interest 
     1073                event = haiku_remove_debug_event(&teamDebugInfo->events, 
     1074                        threadEventClosure.event); 
     1075 
     1076                if (!event) { 
     1077                        TRACE(("haiku_child_wait_internal(): got no event!\n")); 
     1078                        return retval; 
     1079                } 
     1080 
     1081                TRACE(("haiku_child_wait_internal(): got event: %u, thread: %ld, " 
     1082                        "team: %ld, nub port: %ld\n", event->message, 
     1083                        event->data.origin.thread, event->data.origin.team, 
     1084                        event->data.origin.nub_port)); 
     1085        } 
     1086 
     1087        if (event->data.origin.team != teamDebugInfo->team) { 
     1088                // Spurious debug message. Doesn't concern our team. Ignore. 
     1089                xfree(event); 
     1090                return retval; 
     1091        } 
     1092 
     1093        retval = ptid_build(event->data.origin.team, 0, event->data.origin.thread); 
     1094 
     1095        *ignore = false; 
     1096 
     1097        switch (event->message) { 
     1098                case B_DEBUGGER_MESSAGE_DEBUGGER_CALL: 
     1099                { 
     1100                        // print the debugger message 
     1101                        char debuggerMessage[1024]; 
     1102                        ssize_t bytesRead = debug_read_string(&teamDebugInfo->context, 
     1103                                event->data.debugger_call.message, debuggerMessage, 
     1104                                sizeof(debuggerMessage)); 
     1105                        if (bytesRead > 0) { 
     1106                                printf_unfiltered ("Thread %ld called debugger(): %s\n", 
     1107                                        event->data.origin.thread, debuggerMessage); 
     1108                        } else { 
     1109                                printf_unfiltered ("Thread %ld called debugger(), but failed" 
     1110                                        "to get the debugger message.\n", 
     1111                                        event->data.origin.thread); 
     1112                        } 
     1113 
     1114                        // fall through... 
     1115                } 
     1116                case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED: 
     1117                case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT: 
     1118                case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT: 
     1119                case B_DEBUGGER_MESSAGE_SINGLE_STEP: 
     1120                        ourstatus->kind = TARGET_WAITKIND_STOPPED; 
     1121                        ourstatus->value.sig = TARGET_SIGNAL_TRAP; 
     1122                        pendingSignal = SIGTRAP; 
     1123                        pendingSignalStatus = SIGNAL_FAKED; 
     1124                        break; 
     1125 
     1126                case B_DEBUGGER_MESSAGE_PRE_SYSCALL: 
     1127                        ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY; 
     1128                        ourstatus->value.syscall_number = event->data.pre_syscall.syscall; 
     1129                        break; 
     1130 
     1131                case B_DEBUGGER_MESSAGE_POST_SYSCALL: 
     1132                        ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN; 
     1133                        ourstatus->value.syscall_number = event->data.post_syscall.syscall; 
     1134                        break; 
     1135 
     1136                case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED: 
     1137                        pendingSignal = event->data.signal_received.signal; 
     1138                        pendingSignalStatus = SIGNAL_ARRIVED; 
     1139                        ourstatus->kind = TARGET_WAITKIND_STOPPED; 
     1140                        ourstatus->value.sig = haiku_to_target_signal(pendingSignal); 
     1141                        break; 
     1142 
     1143                case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED: 
     1144                { 
     1145                        // print the exception message 
     1146                        char exception[1024]; 
     1147                        get_debug_exception_string(event->data.exception_occurred.exception, 
     1148                                exception, sizeof(exception)); 
     1149                        printf_unfiltered ("Thread %ld caused an exception: %s\n", 
     1150                                event->data.origin.thread, exception); 
     1151 
     1152                        pendingSignal = event->data.exception_occurred.signal; 
     1153                        pendingSignalStatus = SIGNAL_WILL_ARRIVE; 
     1154                        ourstatus->kind = TARGET_WAITKIND_STOPPED; 
     1155                        ourstatus->value.sig = haiku_to_target_signal(pendingSignal); 
     1156                        break; 
     1157                } 
     1158 
     1159                case B_DEBUGGER_MESSAGE_TEAM_CREATED: 
     1160                        // ignore 
     1161                        *ignore = true; 
     1162                        break; 
     1163 
     1164                case B_DEBUGGER_MESSAGE_TEAM_DELETED: 
     1165                        ourstatus->kind = TARGET_WAITKIND_EXITED; 
     1166                        ourstatus->value.integer = 0; 
     1167                                // TODO: Extend the debugger interface? 
     1168                        break; 
     1169 
     1170                case B_DEBUGGER_MESSAGE_THREAD_CREATED: 
     1171                { 
     1172                        // internal bookkeeping only 
     1173                        thread_id newThread = event->data.thread_created.new_thread; 
     1174                        if (newThread != teamDebugInfo->nub_thread) 
     1175                                haiku_add_thread(teamDebugInfo, newThread); 
     1176                        *ignore = true; 
     1177                        break; 
     1178                } 
     1179 
     1180                case B_DEBUGGER_MESSAGE_THREAD_DELETED: 
     1181                        // internal bookkeeping 
     1182                        haiku_remove_thread(teamDebugInfo, 
     1183                                event->data.thread_deleted.origin.thread); 
     1184                        *ignore = true; 
     1185 
     1186                        // TODO: What if this is the current thread? 
     1187                        break; 
     1188 
     1189                case B_DEBUGGER_MESSAGE_IMAGE_CREATED: 
     1190                        if (reprocessEvent < 0) { 
     1191                                // first time we see the event: update our image list 
     1192//                              haiku_add_image(teamDebugInfo, 
     1193//                                      &event->data.image_created.info); 
     1194haiku_cleanup_image_list(teamDebugInfo); 
     1195haiku_init_image_list(teamDebugInfo); 
     1196// TODO: We don't get events when images have been removed in preparation of 
     1197// an exec*() yet. 
     1198                        } 
     1199 
     1200                        ourstatus->kind = TARGET_WAITKIND_LOADED; 
     1201                        ourstatus->value.integer = 0; 
     1202                        if (event->data.image_created.info.type == B_APP_IMAGE) { 
     1203                                // An app image has been loaded, i.e. the application is now 
     1204                                // fully loaded. We need to send a TARGET_WAITKIND_LOADED 
     1205                                // first, so that GDB's shared object list is updated correctly. 
     1206                                // But we also need to send an TARGET_WAITKIND_EXECD event. 
     1207                                // We use the reprocessEvent mechanism here. 
     1208 
     1209                                if (reprocessEvent == 2) { 
     1210#if 0                            
     1211                                        // the second time the event is processed: send the `exec' 
     1212                                        // event 
     1213                                        if (inferior_ignoring_startup_exec_events > 0) { 
     1214                                                // we shall not send an exec event, so we skip that 
     1215                                                // and send the `trap' immediately 
     1216TRACE(("haiku_child_wait_internal(): ignoring exec (%d)\n", 
     1217inferior_ignoring_startup_exec_events)); 
     1218                                                inferior_ignoring_startup_exec_events--; 
     1219                                                reprocessEvent = 1; 
     1220                                        } 
     1221#endif                                   
     1222                                } 
     1223 
     1224                                if (reprocessEvent < 0) { 
     1225TRACE(("haiku_child_wait_internal(): B_APP_IMAGE created, reprocess < 0\n")); 
     1226                                        // the first time the event is processed: send the 
     1227                                        // `loaded' event 
     1228                                        reprocessEvent = 2; 
     1229                                } else if (reprocessEvent == 2) { 
     1230TRACE(("haiku_child_wait_internal(): B_APP_IMAGE created, reprocess -> exec\n")); 
     1231                                        // the second time the event is processed: send the `exec' 
     1232                                        // event 
     1233                                        ourstatus->kind = TARGET_WAITKIND_EXECD; 
     1234                                        ourstatus->value.execd_pathname 
     1235                                                = xstrdup(event->data.image_created.info.name); 
     1236                                         
     1237                                        reprocessEvent = 1; 
     1238                                } else if (reprocessEvent <= 1) { 
     1239                                        // the third time the event is processed: send the `trap' 
     1240                                        // event 
     1241                                        ourstatus->kind = TARGET_WAITKIND_STOPPED; 
     1242                                        ourstatus->value.sig = TARGET_SIGNAL_TRAP; 
     1243                                        pendingSignal = SIGTRAP; 
     1244                                        pendingSignalStatus = SIGNAL_FAKED; 
     1245 
     1246                                        reprocessEvent = 0; 
     1247                                } 
     1248                        } 
     1249 
     1250                        // re_enable_breakpoints_in_shlibs (); 
     1251                                // TODO: Needed? 
     1252                        break; 
     1253 
     1254                case B_DEBUGGER_MESSAGE_IMAGE_DELETED: 
     1255                        haiku_remove_image(teamDebugInfo, 
     1256                                event->data.image_deleted.info.id); 
     1257 
     1258                        // send TARGET_WAITKIND_LOADED here too, it causes the shared 
     1259                        // object list to be updated 
     1260                        ourstatus->kind = TARGET_WAITKIND_LOADED; 
     1261                        ourstatus->value.integer = 0; 
     1262                        break; 
     1263 
     1264                case B_DEBUGGER_MESSAGE_HANDED_OVER: 
     1265                { 
     1266TRACE(("haiku_child_wait_internal(): B_DEBUGGER_MESSAGE_HANDED_OVER: causing " 
     1267"thread: %ld\n", event->data.handed_over.causing_thread)); 
     1268                        // The debugged team has been handed over to us by another debugger 
     1269                        // (likely the debug server). This event also tells us, which 
     1270                        // thread has caused the original debugger to be installed (if any). 
     1271                        // So, if we're not looking for any particular thread, select that 
     1272                        // thread. 
     1273                        if (threadID < 0 && event->data.handed_over.causing_thread >= 0) { 
     1274                                *selectThread = true; 
     1275                                retval = ptid_build(event->data.origin.team, 0, 
     1276                                        event->data.handed_over.causing_thread); 
     1277                        } 
     1278                        *ignore = true; 
     1279                } 
     1280 
     1281                default: 
     1282                        // unknown message, ignore 
     1283                        *ignore = true; 
     1284                        break; 
     1285        } 
     1286 
     1287        // make the event the thread's last event or delete it 
     1288        if (!*ignore && event->data.origin.thread >= 0) { 
     1289                struct thread_debug_info *thread = haiku_find_thread(teamDebugInfo, 
     1290                        event->data.origin.thread); 
     1291                if (thread->last_event) 
     1292                        xfree(thread->last_event); 
     1293                        thread->last_event = event; 
     1294                        thread->stopped = true; 
     1295                        thread->signal = pendingSignal; 
     1296                        thread->signal_status = pendingSignalStatus; 
     1297                        thread->reprocess_event 
     1298                                = (reprocessEvent >= 0 ? reprocessEvent : 0); 
     1299        } else { 
     1300                xfree(event); 
     1301 
     1302                // continue the thread 
     1303                if (event->data.origin.thread >= 0) { 
     1304                        haiku_continue_thread(teamDebugInfo, event->data.origin.thread, 
     1305                                B_THREAD_DEBUG_HANDLE_EVENT, false); 
     1306                } 
     1307 
     1308//              *ignore = true; 
     1309// TODO: This should indeed not be needed. It definitely eats the 
     1310// `team deleted' events. 
     1311        } 
     1312 
     1313        return retval; 
     1314} 
     1315 
     1316 
     1317static ptid_t 
     1318haiku_child_wait (struct target_ops *ops, ptid_t ptid, 
     1319        struct target_waitstatus *ourstatus, int options) 
     1320{ 
     1321        ptid_t retval; 
     1322        bool ignore = true; 
     1323        bool selectThread = false; 
     1324 
     1325        TRACE(("haiku_child_wait(`%s', %p)\n", 
     1326                haiku_pid_to_str(ops, ptid), ourstatus)); 
     1327 
     1328        do { 
     1329                retval = haiku_child_wait_internal(&sTeamDebugInfo, ptid, ourstatus, 
     1330                        &ignore, &selectThread); 
     1331                if (selectThread) 
     1332                        ptid = retval; 
     1333        } while (ignore); 
     1334 
     1335        TRACE(("haiku_child_wait() done: `%s'\n", haiku_pid_to_str(ops, retval))); 
     1336 
     1337        return retval; 
     1338} 
     1339 
     1340 
     1341static void 
     1342haiku_child_fetch_inferior_registers (struct target_ops *ops, 
     1343        struct regcache *cache, int reg) 
     1344{ 
     1345        debug_nub_get_cpu_state_reply reply; 
     1346 
     1347        TRACE(("haiku_child_fetch_inferior_registers(%d)\n", reg)); 
     1348 
     1349        // get the CPU state 
     1350        haiku_get_cpu_state(&sTeamDebugInfo, &reply); 
     1351 
     1352// printf("haiku_child_fetch_inferior_registers(): eip: %p, ebp: %p\n", 
     1353// (void*)reply.cpu_state.eip, (void*)reply.cpu_state.ebp); 
     1354 
     1355        // supply the registers (architecture specific) 
     1356        haiku_supply_registers(reg, &reply.cpu_state); 
     1357} 
     1358 
     1359 
     1360static void 
     1361haiku_child_store_inferior_registers (struct target_ops *ops, 
     1362        struct regcache *cache, int reg) 
     1363{ 
     1364        status_t err; 
     1365        thread_id threadID = ptid_get_tid(inferior_ptid); 
     1366        debug_nub_get_cpu_state_reply reply; 
     1367        debug_nub_set_cpu_state message; 
     1368 
     1369        TRACE(("haiku_child_store_inferior_registers(%d)\n", reg)); 
     1370 
     1371        // get the current CPU state 
     1372        haiku_get_cpu_state(&sTeamDebugInfo, &reply); 
     1373 
     1374        // collect the registers (architecture specific) 
     1375        haiku_collect_registers(reg, &reply.cpu_state); 
     1376 
     1377        // set the new CPU state 
     1378        message.thread = threadID; 
     1379        memcpy(&message.cpu_state, &reply.cpu_state, sizeof(debug_cpu_state)); 
     1380        err = haiku_send_debugger_message(&sTeamDebugInfo, 
     1381                B_DEBUG_MESSAGE_SET_CPU_STATE, &message, sizeof(message), NULL, 0); 
     1382        if (err != B_OK) { 
     1383                printf_unfiltered ("Failed to set status of thread %ld: %s\n", 
     1384                        threadID, strerror(err)); 
     1385        } 
     1386} 
     1387 
     1388static void 
     1389haiku_child_prepare_to_store (struct regcache *cache) 
     1390{ 
     1391        // Since we always fetching the current state in 
     1392        // haiku_child_store_inferior_registers(), this should be a no-op. 
     1393} 
     1394 
     1395static int 
     1396haiku_child_deprecated_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, 
     1397        int write, struct mem_attrib *attrib, struct target_ops *target) 
     1398{ 
     1399        TRACE(("haiku_child_deprecated_xfer_memory(0x%8lx, %p, %d, %d, %p, %p)\n", 
     1400                (uint32)memaddr, myaddr, len, write, attrib, target)); 
     1401 
     1402        if (len <= 0) 
     1403                return 0; 
     1404 
     1405        if (write) { 
     1406                // write 
     1407                debug_nub_write_memory message; 
     1408                debug_nub_write_memory_reply reply; 
     1409                status_t err; 
     1410 
     1411                if (len > B_MAX_READ_WRITE_MEMORY_SIZE) 
     1412                        len = B_MAX_READ_WRITE_MEMORY_SIZE; 
     1413 
     1414                message.reply_port = sTeamDebugInfo.context.reply_port; 
     1415                message.address = (void*)memaddr; 
     1416                message.size = len; 
     1417                memcpy(message.data, myaddr, len); 
     1418 
     1419                err = haiku_send_debugger_message(&sTeamDebugInfo, 
     1420                        B_DEBUG_MESSAGE_WRITE_MEMORY, &message, sizeof(message), &reply, 
     1421                        sizeof(reply)); 
     1422                if (err != B_OK || reply.error != B_OK) 
     1423{ 
     1424TRACE(("haiku_child_deprecated_xfer_memory() failed: %lx\n", 
     1425(err != B_OK ? err : reply.error))); 
     1426                        return 0; 
     1427} 
     1428 
     1429TRACE(("haiku_child_deprecated_xfer_memory(): -> %ld\n", reply.size)); 
     1430                return reply.size; 
     1431        } else { 
     1432                // read 
     1433                ssize_t bytesRead = debug_read_memory_partial(&sTeamDebugInfo.context, 
     1434                        (const void *)memaddr, myaddr, len); 
     1435                return (bytesRead < 0 ? 0 : bytesRead); 
     1436        } 
     1437 
     1438        return -1; 
     1439} 
     1440 
     1441LONGEST 
     1442haiku_child_xfer_partial (struct target_ops *ops, enum target_object object, 
     1443        const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, 
     1444        ULONGEST offset, LONGEST len) 
     1445{ 
     1446        if (!readbuf && !writebuf) 
     1447                return -1; 
     1448 
     1449        switch (object) { 
     1450                case TARGET_OBJECT_MEMORY: 
     1451                { 
     1452                        int write = !readbuf; 
     1453                        return haiku_child_deprecated_xfer_memory (offset, 
     1454                                (write ? (void*)writebuf : readbuf), len, write, NULL, ops); 
     1455                } 
     1456        } 
     1457 
     1458        return -1; 
     1459} 
     1460 
     1461static void 
     1462haiku_child_files_info (struct target_ops *ignore) 
     1463{ 
     1464        struct inferior *inf = current_inferior (); 
     1465        printf_unfiltered ("\tUsing the running image of %s %s.\n", 
     1466                inf->attach_flag ? "attached" : "child", 
     1467                target_pid_to_str (inferior_ptid)); 
     1468} 
     1469 
     1470static void 
     1471haiku_child_kill_inferior (struct target_ops * ops) 
     1472{ 
     1473        status_t err; 
     1474        thread_id teamID = ptid_get_pid(inferior_ptid); 
     1475 
     1476        TRACE(("haiku_child_kill_inferior()\n")); 
     1477 
     1478        err = kill_team(teamID); 
     1479        if (err != B_OK) { 
     1480                printf_unfiltered ("Failed to kill team %ld: %s\n", teamID, 
     1481                        strerror(err)); 
     1482                return; 
     1483        } 
     1484 
     1485        target_mourn_inferior(); 
     1486} 
     1487 
     1488static void 
     1489haiku_child_stop_inferior (ptid_t ptid) 
     1490{ 
     1491        status_t err; 
     1492        thread_id threadID = ptid_get_tid(inferior_ptid); 
     1493 
     1494        TRACE(("haiku_child_stop_inferior()\n")); 
     1495 
     1496        err = debug_thread(threadID); 
     1497        if (err != B_OK) { 
     1498                printf_unfiltered ("Failed to stop thread %ld: %s\n", threadID, 
     1499                        strerror(err)); 
     1500                return; 
     1501        } 
     1502} 
     1503 
     1504static void 
     1505haiku_init_debug_create_inferior(int pid) 
     1506{ 
     1507        extern int stop_after_trap; 
     1508        struct inferior *inf = current_inferior (); 
     1509        struct thread_info *tp; 
     1510 
     1511        // fix inferior_ptid -- fork_inferior() sets the process ID only 
     1512        inferior_ptid = ptid_build (pid, 0, pid); 
     1513                // team ID == team main thread ID under Haiku 
     1514 
     1515        haiku_init_child_debugging(pid, false); 
     1516         
     1517        target_terminal_ours (); 
     1518 
     1519        // eat the initial `debugged' event caused by wait_for_inferior() 
     1520// TODO: Maybe we should just dequeue the event and continue the thread instead 
     1521// of using gdb's mechanism, since I don't know what undesired side-effects 
     1522// they may have. 
     1523        clear_proceed_status (); 
     1524        init_wait_for_inferior (); 
     1525         
     1526        inf->stop_soon = STOP_QUIETLY; 
     1527        while (true) { 
     1528                thread_debug_info *thread; 
     1529                stop_after_trap = 1; 
     1530                wait_for_inferior(0); 
     1531                tp = inferior_thread (); 
     1532 
     1533                if (tp->stop_signal == TARGET_SIGNAL_TRAP) { 
     1534                        thread = haiku_find_thread(&sTeamDebugInfo, pid); 
     1535 
     1536                        if (thread && thread->stopped 
     1537                                && thread->last_event->message 
     1538                                        == B_DEBUGGER_MESSAGE_IMAGE_CREATED 
     1539                                && thread->last_event->data.image_created.info.type 
     1540                                        == B_APP_IMAGE 
     1541                                && thread->reprocess_event == 0) { 
     1542                                // This is the trap for the last (second, if started via shell) 
     1543                                // `load app image' event. Be done. 
     1544                                break; 
     1545                        } 
     1546                } 
     1547 
     1548                resume(0, tp->stop_signal); 
     1549        } 
     1550        inf->stop_soon = NO_STOP_QUIETLY; 
     1551 
     1552        // load shared library symbols 
     1553        target_terminal_ours_for_output (); 
     1554#ifdef SOLIB_ADD 
     1555        SOLIB_ADD (NULL, 0, &current_target, auto_solib_add); 
     1556#else 
     1557        solib_add (NULL, 0, &current_target, auto_solib_add); 
     1558#endif 
     1559        target_terminal_inferior (); 
     1560 
     1561//      startup_inferior (START_INFERIOR_TRAPS_EXPECTED); 
     1562 
     1563//while (1) { 
     1564//      stop_after_trap = 1; 
     1565//      wait_for_inferior (); 
     1566//      if (debugThread && stop_signal != TARGET_SIGNAL_TRAP) 
     1567//              resume (0, stop_signal); 
     1568//      else 
     1569//              break; 
     1570//} 
     1571//stop_after_trap = 0; 
     1572 
     1573 
     1574 
     1575//      while (1) { 
     1576//              thread_debug_info *thread; 
     1577// 
     1578//              stop_after_trap = 1; 
     1579//              wait_for_inferior (); 
     1580//// TODO: Catch deadly events, so that we won't block here. 
     1581// 
     1582//              thread = haiku_find_thread(&sTeamDebugInfo, pid); 
     1583//TRACE(("haiku_init_debug_create_inferior(): wait_for_inferior() returned: " 
     1584//"thread: %p (%ld)\n", thread, (thread ? thread->thread : -1))); 
     1585//              if (thread && thread->stopped 
     1586//                      && thread->last_event->message 
     1587//                              == B_DEBUGGER_MESSAGE_IMAGE_CREATED 
     1588//                      && thread->last_event->data.image_created.info.type 
     1589//                              == B_APP_IMAGE) { 
     1590//TRACE(("haiku_init_debug_create_inferior(): Got an `app image created' " 
     1591//"message\n")); 
     1592//                      break; 
     1593//              } 
     1594// 
     1595//              resume (0, stop_signal); 
     1596//      } 
     1597} 
     1598 
     1599static void 
     1600haiku_child_create_inferior (struct target_ops *ops, char *exec_file, 
     1601        char *allargs, char **env, int from_tty) 
     1602{ 
     1603        TRACE(("haiku_child_create_inferior(`%s', `%s', %p, %d)\n", exec_file, 
     1604                allargs, env, from_tty)); 
     1605 
     1606        fork_inferior (exec_file, allargs, env, wait_for_debugger, 
     1607                haiku_init_debug_create_inferior, NULL, NULL); 
     1608 
     1609 
     1610observer_notify_inferior_created (&current_target, from_tty); 
     1611proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0); 
     1612 
     1613 
     1614        // TODO: Anything more to do here? 
     1615} 
     1616 
     1617static void 
     1618haiku_child_mourn_inferior (struct target_ops *ops) 
     1619{ 
     1620        TRACE(("haiku_child_mourn_inferior()\n")); 
     1621 
     1622        haiku_cleanup_team_debug_info(); 
     1623        unpush_target (sHaikuTarget); 
     1624        generic_mourn_inferior (); 
     1625} 
     1626 
     1627static int 
     1628haiku_child_can_run (void) 
     1629{ 
     1630        return 1; 
     1631} 
     1632 
     1633static int 
     1634haiku_child_thread_alive (struct target_ops *ops, ptid_t ptid) 
     1635{ 
     1636        thread_info info; 
     1637 
     1638        TRACE(("haiku_child_thread_alive(`%s')\n", haiku_pid_to_str(ops, ptid))); 
     1639 
     1640        return (get_thread_info(ptid_get_tid(ptid), &info) == B_OK); 
     1641} 
     1642 
     1643static char * 
     1644haiku_pid_to_str (struct target_ops *ops, ptid_t ptid) 
     1645{ 
     1646        static char buffer[B_OS_NAME_LENGTH + 64 + 64]; 
     1647        team_info teamInfo; 
     1648        thread_info threadInfo; 
     1649        status_t error; 
     1650 
     1651        // get the team info for the target team 
     1652        error = get_team_info(ptid_get_pid(ptid), &teamInfo); 
     1653        if (error != B_OK) { 
     1654                sprintf(buffer, "invalid team ID %d", ptid_get_pid(ptid)); 
     1655                return buffer; 
     1656        } 
     1657 
     1658        // get the thread info for the target thread 
     1659        error = get_thread_info(ptid_get_tid(ptid), &threadInfo); 
     1660        if (error != B_OK) { 
     1661                sprintf(buffer, "team %.*s (%ld) invalid thread ID %ld", 
     1662                        (int)sizeof(teamInfo.args), teamInfo.args, teamInfo.team, 
     1663                        ptid_get_tid(ptid)); 
     1664                return buffer; 
     1665        } 
     1666 
     1667        sprintf(buffer, "team %.*s (%ld) thread %s (%ld)", 
     1668                (int)sizeof(teamInfo.args), teamInfo.args, teamInfo.team, 
     1669                threadInfo.name, threadInfo.thread); 
     1670 
     1671        return buffer; 
     1672} 
     1673 
     1674char * 
     1675haiku_child_pid_to_exec_file (int pid) 
     1676{ 
     1677        static char buffer[B_PATH_NAME_LENGTH]; 
     1678         
     1679        // The only way to get the path to the application's executable seems to 
     1680        // be to get an image_info of its image, which also contains a path. 
     1681        // Several images may belong to the team (libraries, add-ons), but only 
     1682        // the one in question should be typed B_APP_IMAGE. 
     1683        image_info info; 
     1684        int32 cookie = 0; 
     1685 
     1686        TRACE(("haiku_child_pid_to_exec_file(%ld)\n", pid)); 
     1687        while (get_next_image_info(0, &cookie, &info) == B_OK) { 
     1688                if (info.type == B_APP_IMAGE) { 
     1689                        strncpy(buffer, info.name, B_PATH_NAME_LENGTH - 1); 
     1690                        buffer[B_PATH_NAME_LENGTH - 1] = 0; 
     1691                        return buffer; 
     1692                } 
     1693        } 
     1694 
     1695        return NULL; 
     1696} 
     1697 
     1698 
     1699void 
     1700_initialize_haiku_nat (void) 
     1701{ 
     1702        // child operations 
     1703        struct target_ops *t = XZALLOC (struct target_ops); 
     1704        t->to_shortname = "child"; 
     1705        t->to_longname = "Haiku child process"; 
     1706        t->to_doc = "Haiku child process (started by the \"run\" command)."; 
     1707        t->to_open = haiku_child_open; 
     1708        t->to_close = haiku_child_close; 
     1709        t->to_attach = haiku_child_attach; 
     1710        t->to_detach = haiku_child_detach; 
     1711        t->to_resume = haiku_child_resume; 
     1712        t->to_wait = haiku_child_wait; 
     1713        t->to_fetch_registers = haiku_child_fetch_inferior_registers; 
     1714        t->to_store_registers = haiku_child_store_inferior_registers; 
     1715        t->to_prepare_to_store = haiku_child_prepare_to_store; 
     1716        t->deprecated_xfer_memory = haiku_child_deprecated_xfer_memory; 
     1717        t->to_xfer_partial = haiku_child_xfer_partial; 
     1718        t->to_files_info = haiku_child_files_info; 
     1719 
     1720        t->to_insert_breakpoint = memory_insert_breakpoint; 
     1721        t->to_remove_breakpoint = memory_remove_breakpoint; 
     1722                // TODO: We can do better. If we wanted to. 
     1723 
     1724        // TODO: The following terminal calls are not documented or not yet 
     1725        // understood by me. 
     1726        t->to_terminal_init = terminal_init_inferior; 
     1727        t->to_terminal_inferior = terminal_inferior; 
     1728        t->to_terminal_ours_for_output = terminal_ours_for_output; 
     1729        t->to_terminal_ours = terminal_ours; 
     1730        t->to_terminal_save_ours = terminal_save_ours; 
     1731        t->to_terminal_info = child_terminal_info; 
     1732 
     1733        t->to_kill = haiku_child_kill_inferior; 
     1734        t->to_stop = haiku_child_stop_inferior; 
     1735        t->to_create_inferior = haiku_child_create_inferior; 
     1736        t->to_mourn_inferior = haiku_child_mourn_inferior; 
     1737        t->to_can_run = haiku_child_can_run; 
     1738        t->to_thread_alive = haiku_child_thread_alive; 
     1739// How about to_find_new_threads? Perhaps not necessary, as we could be informed 
     1740// about thread creation/deletion. 
     1741        t->to_pid_to_str = haiku_pid_to_str; 
     1742        t->to_pid_to_exec_file = haiku_child_pid_to_exec_file; 
     1743 
     1744        t->to_stratum = process_stratum; 
     1745        t->to_has_all_memory = default_child_has_all_memory; 
     1746        t->to_has_memory = default_child_has_memory; 
     1747        t->to_has_stack = default_child_has_stack; 
     1748        t->to_has_registers = default_child_has_registers; 
     1749        t->to_has_execution = default_child_has_execution; 
     1750        t->to_magic = OPS_MAGIC; 
     1751 
     1752        sHaikuTarget = t; 
     1753 
     1754        add_target (t); 
     1755} 
  • gdb/haiku-nat.h

    diff -ruN gdb-7.2-orig/gdb/haiku-nat.h gdb-7.2/gdb/haiku-nat.h
    old new  
     1/* Haiku native-dependent definitions. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#ifndef HAIKU_NAT_H 
     23#define HAIKU_NAT_H 
     24 
     25#include <debugger.h> 
     26 
     27/* Required by haiku-nat.c, implemented in <arch>-haiku-nat.c. */ 
     28 
     29void haiku_supply_registers(int reg, const debug_cpu_state *cpuState); 
     30void haiku_collect_registers(int reg, debug_cpu_state *cpuState); 
     31 
     32 
     33struct haiku_image_info; 
     34 
     35/* Function used by solib-haiku.c to iterate through the list of images of 
     36   the inferior. 
     37   TODO: This must go, since it works only in a native debugger. We can 
     38   probably tunnel these data through the xfer_memory() function. 
     39*/ 
     40struct haiku_image_info *haiku_get_next_image_info(int lastID); 
     41 
     42#endif  /* HAIKU_NAT_H */ 
  • gdb/haiku-tdep.c

    diff -ruN gdb-7.2-orig/gdb/haiku-tdep.c gdb-7.2/gdb/haiku-tdep.c
    old new  
     1/* Haiku target-dependent common to multiple platforms. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#include "defs.h" 
  • gdb/i386-haiku-nat.c

    diff -ruN gdb-7.2-orig/gdb/i386-haiku-nat.c gdb-7.2/gdb/i386-haiku-nat.c
    old new  
     1/* Native-dependent code for Haiku i386. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#include "defs.h" 
     23#include "haiku-nat.h" 
     24#include "i386-tdep.h" 
     25#include "i387-tdep.h" 
     26#include "inferior.h" 
     27#include "regcache.h" 
     28#include "target.h" 
     29 
     30/* Offset in `struct debug_cpu_state' where MEMBER is stored.  */ 
     31#define REG_OFFSET(member) offsetof (struct x86_debug_cpu_state, member) 
     32 
     33/* At kHaikuI386RegOffset[REGNUM] you'll find the offset in `struct 
     34   debug_cpu_state' where the GDB register REGNUM is stored. */ 
     35static int kHaikuI386RegOffset[] = { 
     36        REG_OFFSET (eax), 
     37        REG_OFFSET (ecx), 
     38        REG_OFFSET (edx), 
     39        REG_OFFSET (ebx), 
     40        REG_OFFSET (user_esp), 
     41        REG_OFFSET (ebp), 
     42        REG_OFFSET (esi), 
     43        REG_OFFSET (edi), 
     44        REG_OFFSET (eip), 
     45        REG_OFFSET (eflags), 
     46        REG_OFFSET (cs), 
     47        REG_OFFSET (user_ss), 
     48        REG_OFFSET (ds), 
     49        REG_OFFSET (es), 
     50        REG_OFFSET (fs), 
     51        REG_OFFSET (gs) 
     52}; 
     53 
     54 
     55void 
     56haiku_supply_registers(int reg, const debug_cpu_state *cpuState) 
     57{ 
     58        if (reg == -1) { 
     59                int i; 
     60                for (i = 0; i < I386_SSE_NUM_REGS; i++) 
     61                        haiku_supply_registers(i, cpuState); 
     62        } else if (reg < I386_ST0_REGNUM) { 
     63                int offset = kHaikuI386RegOffset[reg]; 
     64                struct regcache *regcache = get_current_regcache (); 
     65                regcache_raw_supply (regcache, reg, (char*)cpuState + offset); 
     66        } else { 
     67                struct regcache *regcache = get_current_regcache (); 
     68                i387_supply_fxsave (regcache, -1, 
     69                        &cpuState->extended_registers); 
     70        } 
     71} 
     72 
     73 
     74void 
     75haiku_collect_registers(int reg, debug_cpu_state *cpuState) 
     76{ 
     77        if (reg == -1) { 
     78                int i; 
     79                for (i = 0; i < I386_SSE_NUM_REGS; i++) 
     80                        haiku_collect_registers(i, cpuState); 
     81        } else if (reg < I386_ST0_REGNUM) { 
     82                int offset = kHaikuI386RegOffset[reg]; 
     83                struct regcache *regcache = get_current_regcache (); 
     84                regcache_raw_collect (regcache, reg, (char*)cpuState + offset); 
     85        } else { 
     86                struct regcache *regcache = get_current_regcache (); 
     87                i387_collect_fxsave (regcache, -1, 
     88                        &cpuState->extended_registers); 
     89        } 
     90} 
     91 
  • gdb/i386-haiku-tdep.c

    diff -ruN gdb-7.2-orig/gdb/i386-haiku-tdep.c gdb-7.2/gdb/i386-haiku-tdep.c
    old new  
     1/* Target-dependent code for Haiku i386. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#include "defs.h" 
     23#include "gdbarch.h" 
     24#include "i386-tdep.h" 
     25#include "osabi.h" 
     26 
     27//#define TRACE_I386_HAIKU_NAT 
     28#ifdef TRACE_I386_HAIKU_NAT 
     29        #define TRACE(x)        printf x 
     30#else 
     31        #define TRACE(x)        while (false) {} 
     32#endif 
     33 
     34static void 
     35i386_haiku_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 
     36{ 
     37        struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
     38 
     39        // Haiku uses ELF. 
     40        i386_elf_init_abi (info, gdbarch); 
     41 
     42        // the offset of the PC in the jmp_buf structure (cf. setjmp(), longjmp()) 
     43        tdep->jb_pc_offset = 20; 
     44 
     45// TODO: Signal support. 
     46//      tdep->sigtramp_p = i386_haiku_sigtramp_p; 
     47//      tdep->sigcontext_addr = i386_haiku_sigcontext_addr; 
     48//      tdep->sc_reg_offset = i386_haiku_sc_reg_offset; 
     49//      tdep->sc_num_regs = ARRAY_SIZE (i386_haiku_sc_reg_offset); 
     50 
     51// We don't need this at the moment. The Haiku runtime loader also relocates 
     52// R_386_JMP_SLOT entries. No lazy resolving is done. 
     53//      set_gdbarch_skip_solib_resolver (gdbarch, haiku_skip_solib_resolver); 
     54} 
     55 
     56 
     57static enum gdb_osabi 
     58i386_haiku_osabi_sniffer (bfd * abfd) 
     59{  
     60        char *targetName = bfd_get_target (abfd); 
     61 
     62        if (strcmp (targetName, "elf32-i386") == 0) 
     63                return GDB_OSABI_HAIKU; 
     64 
     65        return GDB_OSABI_UNKNOWN; 
     66} 
     67 
     68 
     69void 
     70_initialize_i386_haiku_tdep (void) 
     71{ 
     72        gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, 
     73                i386_haiku_osabi_sniffer); 
     74 
     75        gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_HAIKU, 
     76                i386_haiku_init_abi); 
     77} 
  • gdb/nm.h

    diff -ruN gdb-7.2-orig/gdb/nm.h gdb-7.2/gdb/nm.h
    old new  
     1/* Native support for Haiku x86. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#ifndef NM_HAIKU_H 
     23#define NM_HAIKU_H 
     24 
     25#include "config/nm-haiku.h" 
     26 
     27#endif /* nm-haiku.h */ 
  • gdb/osabi.c

    diff -ruN gdb-7.2-orig/gdb/osabi.c gdb-7.2/gdb/osabi.c
    old new  
    7373  "DICOS", 
    7474  "Darwin", 
    7575  "Symbian", 
     76  "Haiku", 
    7677 
    7778  "<invalid>" 
    7879}; 
  • gdb/ser-tcp.c

    diff -ruN gdb-7.2-orig/gdb/ser-tcp.c gdb-7.2/gdb/ser-tcp.c
    old new  
    197197      return -1; 
    198198    } 
    199199 
    200   sockaddr.sin_family = PF_INET; 
     200  sockaddr.sin_family = AF_INET; 
    201201  sockaddr.sin_port = htons (port); 
    202202  memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr, 
    203203          sizeof (struct in_addr)); 
    … …  
    205205 retry: 
    206206 
    207207  if (use_udp) 
    208     scb->fd = socket (PF_INET, SOCK_DGRAM, 0); 
     208    scb->fd = socket (AF_INET, SOCK_DGRAM, 0); 
    209209  else 
    210     scb->fd = socket (PF_INET, SOCK_STREAM, 0); 
     210    scb->fd = socket (AF_INET, SOCK_STREAM, 0); 
    211211 
    212212  if (scb->fd == -1) 
    213213    return -1; 
    … …  
    305305  ioarg = 0; 
    306306  ioctl (scb->fd, FIONBIO, &ioarg); 
    307307 
     308#if (!defined(__BEOS__) && !defined(__HAIKU__)) 
    308309  if (use_udp == 0) 
    309310    { 
    310311      /* Disable Nagle algorithm. Needed in some cases. */ 
    … …  
    312313      setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY, 
    313314                  (char *)&tmp, sizeof (tmp)); 
    314315    } 
     316#endif 
    315317 
    316318#ifdef SIGPIPE 
    317319  /* If we don't do this, then GDB simply exits 
  • gdb/solib-haiku.c

    diff -ruN gdb-7.2-orig/gdb/solib-haiku.c gdb-7.2/gdb/solib-haiku.c
    old new  
     1/* Shared library support for Haiku. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#include <string.h> 
     23 
     24#include "defs.h" 
     25#include "haiku-nat.h"  // TODO: Needs to be removed. See there! 
     26#include "inferior.h" 
     27#include "objfiles.h" 
     28#include "solib-haiku.h" 
     29#include "solist.h" 
     30#include "symfile.h" 
     31#include "symtab.h" 
     32#include "target.h" 
     33#include "elf/common.h" 
     34#include "elf/internal.h" 
     35 
     36//#define TRACE_SOLIB_HAIKU 
     37#ifdef TRACE_SOLIB_HAIKU 
     38        #define TRACE(x)        printf x 
     39#else 
     40        #define TRACE(x)        while (false) {} 
     41#endif 
     42 
     43 
     44struct lm_info { 
     45        CORE_ADDR       text_address; 
     46        CORE_ADDR       unrelocated_text_address; 
     47        bool            unrelocated_text_address_initialized; 
     48}; 
     49 
     50 
     51static haiku_image_info * 
     52haiku_get_app_image() 
     53{ 
     54        haiku_image_info *image; 
     55        int lastID = -1; 
     56 
     57        while ((image = haiku_get_next_image_info(lastID)) != NULL) { 
     58                if (image->is_app_image) 
     59                        return image; 
     60 
     61                lastID = image->id; 
     62        } 
     63 
     64        return NULL; 
     65} 
     66 
     67 
     68static Elf_Internal_Phdr * 
     69read_phdrs(bfd *abfd, int *_count) 
     70{ 
     71        long size; 
     72        int count; 
     73        Elf_Internal_Phdr *phdrs; 
     74 
     75        // get the phdrs size 
     76        size = bfd_get_elf_phdr_upper_bound(abfd); 
     77        if (size <= 0) 
     78                return NULL; 
     79 
     80        // alloc memory 
     81        phdrs = (Elf_Internal_Phdr *)xmalloc(size); 
     82        if (!phdrs) 
     83                return NULL; 
     84 
     85        // read the phdrs 
     86        count = bfd_get_elf_phdrs(abfd, phdrs); 
     87        if (count < 0) { 
     88                xfree(phdrs); 
     89                return NULL; 
     90        } 
     91 
     92        *_count = count; 
     93        return phdrs; 
     94} 
     95 
     96 
     97static CORE_ADDR 
     98get_bfd_vma(bfd *abfd) 
     99{ 
     100        int count; 
     101        Elf_Internal_Phdr *phdrs; 
     102        int i; 
     103        CORE_ADDR result = 0; 
     104 
     105        // get the phdrs array 
     106        phdrs = read_phdrs(abfd, &count); 
     107        if (!phdrs) 
     108                return 0; 
     109 
     110        // iterate through phdrs array and find the first one to load 
     111        for (i = 0; i < count; i++) { 
     112                Elf_Internal_Phdr *phdr = phdrs + i; 
     113                if (phdr->p_type != PT_LOAD) 
     114                        continue; 
     115 
     116                // found the first segment to load 
     117                result = phdr->p_vaddr & ~(B_PAGE_SIZE - 1); 
     118TRACE(("get_bfd_vma(): found first segment: %p\n", (void*)result)); 
     119                break; 
     120        } 
     121 
     122        xfree(phdrs); 
     123 
     124        return result; 
     125} 
     126 
     127 
     128static CORE_ADDR 
     129get_unrelocated_text_address(struct so_list *so) 
     130{ 
     131        if (!so->lm_info->unrelocated_text_address_initialized) { 
     132                so->lm_info->unrelocated_text_address = get_bfd_vma(so->abfd); 
     133                so->lm_info->unrelocated_text_address_initialized = true; 
     134        } 
     135 
     136        return so->lm_info->unrelocated_text_address; 
     137} 
     138 
     139 
     140static void 
     141relocate_main_executable (void) 
     142{ 
     143        haiku_image_info *appImageInfo = haiku_get_app_image(); 
     144 
     145        TRACE(("relocate_main_executable()\n")); 
     146 
     147TRACE(("relocate_main_executable(): symfile_objfile: %p\n", 
     148symfile_objfile)); 
     149TRACE(("relocate_main_executable(): symfile_objfile->obfd: %p\n", 
     150(symfile_objfile ? symfile_objfile->obfd : NULL))); 
     151TRACE(("relocate_main_executable(): app image: %p\n", appImageInfo)); 
     152 
     153        // Relocate the executable here. 
     154        if (symfile_objfile && symfile_objfile->obfd && appImageInfo) { 
     155                CORE_ADDR unrelocatedAddress = get_bfd_vma(symfile_objfile->obfd); 
     156                CORE_ADDR displacement = (CORE_ADDR)appImageInfo->text_address 
     157                        - unrelocatedAddress; 
     158 
     159TRACE(("relocate_main_executable(): image text address: %p, " 
     160"unrelocated address: %p\n", (void*)appImageInfo->text_address, 
     161(void*)unrelocatedAddress)); 
     162 
     163                if (displacement != 0) { 
     164                        struct cleanup *old_chain; 
     165                        struct section_offsets *new_offsets; 
     166                        int i, changed; 
     167 
     168                        changed = 0; 
     169 
     170                        new_offsets = xcalloc (symfile_objfile->num_sections, 
     171                                sizeof (struct section_offsets)); 
     172                        old_chain = make_cleanup (xfree, new_offsets); 
     173 
     174                        for (i = 0; i < symfile_objfile->num_sections; i++) { 
     175                                if (displacement 
     176                                        != ANOFFSET (symfile_objfile->section_offsets, i)) { 
     177                                        changed = 1; 
     178                                } 
     179                                new_offsets->offsets[i] = displacement; 
     180                        } 
     181 
     182                        if (changed) 
     183                                objfile_relocate (symfile_objfile, new_offsets); 
     184 
     185                        do_cleanups (old_chain); 
     186                } 
     187        } 
     188} 
     189 
     190 
     191// #pragma mark - 
     192 
     193static void 
     194haiku_relocate_section_addresses (struct so_list *so, struct section_table *sec) 
     195{ 
     196        CORE_ADDR unrelocatedAddress = get_unrelocated_text_address(so); 
     197        long relocation = so->lm_info->text_address - unrelocatedAddress; 
     198 
     199//      TRACE(("haiku_relocate_section_addresses()\n")); 
     200 
     201        sec->addr += relocation; 
     202        sec->endaddr += relocation; 
     203} 
     204 
     205 
     206static void 
     207haiku_free_so (struct so_list *so) 
     208{ 
     209        xfree (so->lm_info); 
     210} 
     211 
     212 
     213static void 
     214haiku_clear_solib (void) 
     215{ 
     216} 
     217 
     218 
     219static void 
     220haiku_solib_create_inferior_hook (void) 
     221{ 
     222        relocate_main_executable(); 
     223} 
     224 
     225 
     226static void 
     227haiku_special_symbol_handling (void) 
     228{ 
     229} 
     230 
     231 
     232static struct so_list * 
     233haiku_current_sos (void) 
     234{ 
     235        int lastID = -1; 
     236        haiku_image_info *image; 
     237        struct so_list *head = 0; 
     238        struct so_list **link_ptr = &head; 
     239 
     240        TRACE(("haiku_current_sos()\n")); 
     241 
     242        while ((image = haiku_get_next_image_info(lastID)) != NULL) { 
     243                struct so_list *object 
     244                        = (struct so_list *) xmalloc (sizeof (struct so_list)); 
     245                struct cleanup *old_chain = make_cleanup (xfree, object); 
     246 
     247                lastID = image->id; 
     248 
     249                memset (object, 0, sizeof (*object)); 
     250 
     251                object->lm_info = XMALLOC(struct lm_info); 
     252                make_cleanup (xfree, object->lm_info); 
     253                object->lm_info->text_address = image->text_address; 
     254                object->lm_info->unrelocated_text_address = 0; 
     255                object->lm_info->unrelocated_text_address_initialized = false; 
     256 
     257                // Note: I don't know why, but the other solib implementations seem 
     258                // to ignore the executable's shared object. We'll just do the same 
     259                // here. 
     260                if (image->is_app_image) { 
     261                        free_so (object); 
     262 
     263                        // Others don't do that, but it helps a lot to relocate the 
     264                        // executable here. Otherwise, when attaching gdb to a running 
     265                        // process it would never be done. 
     266                        relocate_main_executable(); 
     267                } else { 
     268                        strncpy (object->so_name, image->path, SO_NAME_MAX_PATH_SIZE); 
     269                        object->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 
     270                        strncpy (object->so_original_name, image->name, 
     271                                SO_NAME_MAX_PATH_SIZE); 
     272                        object->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 
     273 
     274                        object->next = 0; 
     275                        *link_ptr = object; 
     276                        link_ptr = &object->next; 
     277                } 
     278 
     279                discard_cleanups (old_chain); 
     280        } 
     281 
     282        return head; 
     283} 
     284 
     285 
     286static int 
     287haiku_open_symbol_file_object (void *from_ttyp) 
     288{ 
     289        // Note: I have never seen this function being called. The Sun OS 
     290        // implementation is a no-op. 
     291        haiku_image_info *appImage = haiku_get_app_image(); 
     292 
     293        TRACE(("haiku_open_symbol_file_object(%p)\n", from_ttyp)); 
     294 
     295        if (!appImage) { 
     296                TRACE(("haiku_open_symbol_file_object(): No app image!\n")); 
     297                return 0; 
     298        } 
     299 
     300        symbol_file_add_main (appImage->path, *(int *)from_ttyp); 
     301 
     302        return 1; 
     303} 
     304 
     305 
     306static int 
     307haiku_in_dynsym_resolve_code (CORE_ADDR pc) 
     308{ 
     309        // No dynamic resolving implemented in Haiku yet. 
     310        return 0; 
     311} 
     312 
     313 
     314// #pragma mark - 
     315 
     316static struct target_so_ops haiku_so_ops; 
     317 
     318extern initialize_file_ftype _initialize_haiku_solib; 
     319 
     320void 
     321_initialize_haiku_solib (void) 
     322{ 
     323        haiku_so_ops.relocate_section_addresses = haiku_relocate_section_addresses; 
     324        haiku_so_ops.free_so = haiku_free_so; 
     325        haiku_so_ops.clear_solib = haiku_clear_solib; 
     326        haiku_so_ops.solib_create_inferior_hook = haiku_solib_create_inferior_hook; 
     327        haiku_so_ops.special_symbol_handling = haiku_special_symbol_handling; 
     328        haiku_so_ops.current_sos = haiku_current_sos; 
     329        haiku_so_ops.open_symbol_file_object = haiku_open_symbol_file_object; 
     330        haiku_so_ops.in_dynsym_resolve_code = haiku_in_dynsym_resolve_code; 
     331 
     332        /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */ 
     333        current_target_so_ops = &haiku_so_ops; 
     334} 
  • gdb/solib-haiku.h

    diff -ruN gdb-7.2-orig/gdb/solib-haiku.h gdb-7.2/gdb/solib-haiku.h
    old new  
     1/* Shared library support for Haiku. 
     2 
     3   Copyright 2005 Ingo Weinhold <bonefish@cs.tu-berlin.de>. 
     4 
     5   This file is part of GDB. 
     6 
     7   This program is free software; you can redistribute it and/or modify 
     8   it under the terms of the GNU General Public License as published by 
     9   the Free Software Foundation; either version 2 of the License, or 
     10   (at your option) any later version. 
     11 
     12   This program is distributed in the hope that it will be useful, 
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15   GNU General Public License for more details. 
     16 
     17   You should have received a copy of the GNU General Public License 
     18   along with this program; if not, write to the Free Software 
     19   Foundation, Inc., 59 Temple Place - Suite 330, 
     20   Boston, MA 02111-1307, USA.  */ 
     21 
     22#include "defs.h" 
     23 
     24typedef struct haiku_image_info { 
     25        int                     id; 
     26        char            name[256]; 
     27        char            path[1024]; 
     28        CORE_ADDR       text_address; 
     29        int                     text_size; 
     30        CORE_ADDR       data_address; 
     31        int                     data_size; 
     32        bool            is_app_image; 
     33} haiku_image_info; 
     34 
  • include/debug_support.h

    diff -ruN gdb-7.2-orig/include/debug_support.h gdb-7.2/include/debug_support.h
    old new  
     1/* 
     2 * Copyright 2005-2009, Ingo Weinhold, bonefish@users.sf.net. 
     3 * Distributed under the terms of the MIT License. 
     4 */ 
     5#ifndef _DEBUG_SUPPORT_H 
     6#define _DEBUG_SUPPORT_H 
     7 
     8#include <debugger.h> 
     9#include <OS.h> 
     10 
     11#ifdef __cplusplus 
     12extern "C" { 
     13#endif 
     14 
     15typedef struct debug_context { 
     16        team_id team; 
     17        port_id nub_port; 
     18        port_id reply_port; 
     19} debug_context; 
     20 
     21 
     22status_t init_debug_context(debug_context *context, team_id team, 
     23        port_id nubPort); 
     24void destroy_debug_context(debug_context *context); 
     25 
     26status_t send_debug_message(debug_context *context, int32 messageCode, 
     27                        const void *message, int32 messageSize, void *reply, 
     28                        int32 replySize); 
     29 
     30ssize_t debug_read_memory_partial(debug_context *context, const void *address, 
     31                        void *buffer, size_t size); 
     32ssize_t debug_read_memory(debug_context *context, const void *address, 
     33                        void *buffer, size_t size); 
     34ssize_t debug_read_string(debug_context *context, const void *_address, 
     35                        char *buffer, size_t size); 
     36ssize_t debug_write_memory_partial(debug_context *context, const void *address, 
     37                        void *buffer, size_t size); 
     38ssize_t debug_write_memory(debug_context *context, const void *address, 
     39                        void *buffer, size_t size); 
     40 
     41status_t debug_get_cpu_state(debug_context *context, thread_id thread, 
     42                        debug_debugger_message *messageCode, debug_cpu_state *cpuState); 
     43 
     44 
     45// stack trace support 
     46 
     47typedef struct debug_stack_frame_info { 
     48        void    *frame; 
     49        void    *parent_frame; 
     50        void    *return_address; 
     51} debug_stack_frame_info; 
     52 
     53status_t debug_get_instruction_pointer(debug_context *context, thread_id thread, 
     54                        void **ip, void **stackFrameAddress); 
     55status_t debug_get_stack_frame(debug_context *context, 
     56                        void *stackFrameAddress, debug_stack_frame_info *stackFrameInfo); 
     57 
     58 
     59// symbol lookup support 
     60 
     61typedef struct debug_symbol_lookup_context debug_symbol_lookup_context; 
     62typedef struct debug_symbol_iterator debug_symbol_iterator; 
     63 
     64status_t debug_create_symbol_lookup_context(team_id team, 
     65                        debug_symbol_lookup_context **lookupContext); 
     66void debug_delete_symbol_lookup_context( 
     67                        debug_symbol_lookup_context *lookupContext); 
     68 
     69status_t debug_get_symbol(debug_symbol_lookup_context* lookupContext, 
     70                        image_id image, const char* name, int32 symbolType, 
     71                        void** _symbolLocation, size_t* _symbolSize, int32* _symbolType); 
     72status_t debug_lookup_symbol_address(debug_symbol_lookup_context *lookupContext, 
     73                        const void *address, void **baseAddress, char *symbolName, 
     74                        int32 symbolNameSize, char *imageName, int32 imageNameSize, 
     75                        bool *exactMatch); 
     76 
     77status_t debug_create_image_symbol_iterator( 
     78                        debug_symbol_lookup_context* lookupContext, image_id imageID, 
     79                        debug_symbol_iterator** _iterator); 
     80status_t debug_create_file_symbol_iterator(const char* path, 
     81                        debug_symbol_iterator** _iterator); 
     82void debug_delete_symbol_iterator(debug_symbol_iterator* iterator); 
     83 
     84status_t debug_next_image_symbol(debug_symbol_iterator* iterator, 
     85                        char* nameBuffer, size_t nameBufferLength, int32* _symbolType, 
     86                        void** _symbolLocation, size_t* _symbolSize); 
     87status_t debug_get_symbol_iterator_image_info(debug_symbol_iterator* iterator, 
     88                        image_info* info); 
     89 
     90#ifdef __cplusplus 
     91}       // extern "C" 
     92#endif 
     93 
     94 
     95#endif  // _DEBUG_SUPPORT_H 
  • readline/histfile.c

    diff -ruN gdb-7.2-orig/readline/histfile.c gdb-7.2/readline/histfile.c
    old new  
    399399    { 
    400400      write (file, bp, chars_read - (bp - buffer)); 
    401401 
    402 #if defined (__BEOS__) 
     402#if (defined(__BEOS__) || defined(__HAIKU__)) 
    403403      /* BeOS ignores O_TRUNC. */ 
    404404      ftruncate (file, chars_read - (bp - buffer)); 
    405405#endif 
  • readline/input.c

    diff -ruN gdb-7.2-orig/readline/input.c gdb-7.2/readline/input.c
    old new  
    475475      if (result == 0) 
    476476        return (EOF); 
    477477 
    478 #if defined (__BEOS__) 
     478#if (defined(__BEOS__) || defined(__HAIKU__)) 
    479479      if (errno == EINTR) 
    480480        continue; 
    481481#endif 

Download in other formats:

  • Original Format

Trac Powered

Powered by Trac 0.13dev-r10686
By Edgewall Software.

Visit the Trac open source project at
http://trac.edgewall.org/