Initial import.
[libobjid.git] / gdb-6.3.patch
1 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=207644
2
3
4 diff -u -rup -x testsuite gdb-6.3-orig/gdb/corelow.c gdb-6.3/gdb/corelow.c
5 --- gdb-6.3-orig/gdb/corelow.c  2004-10-08 22:29:46.000000000 +0200
6 +++ gdb-6.3/gdb/corelow.c       2006-12-29 18:51:19.000000000 +0100
7 @@ -30,6 +30,8 @@
8  #ifdef HAVE_SYS_FILE_H
9  #include <sys/file.h>          /* needed for F_OK and friends */
10  #endif
11 +#include <dirent.h>
12 +#include <asm/page.h>          /* FIXME: `PAGE_SIZE'!  */
13  #include "frame.h"             /* required by inferior.h */
14  #include "inferior.h"
15  #include "symtab.h"
16 @@ -45,6 +47,13 @@
17  #include "readline/readline.h"
18  #include "observer.h"
19  #include "gdb_assert.h"
20 +#include "gdbcmd.h"
21 +#include "completer.h"
22 +#include "elf-bfd.h"
23 +#include "libbfd.h"
24 +#include "solist.h"
25 +
26 +#include <objid.h>
27  
28  #ifndef O_BINARY
29  #define O_BINARY 0
30 @@ -272,6 +281,369 @@ add_to_thread_list (bfd *abfd, asection 
31      inferior_ptid = pid_to_ptid (thread_id);   /* Yes, make it current */
32  }
33  
34 +static char *object_path;
35 +
36 +static void
37 +show_objectdirectories (char *ignore, int from_tty)
38 +{
39 +  puts_filtered ("Object directories searched: ");
40 +  puts_filtered (object_path);
41 +  puts_filtered ("\n");
42 +}
43 +
44 +static void
45 +init_object_path (void)
46 +{
47 +  object_path = xstrdup ("");
48 +}
49 +
50 +/* Add zero or more directories to the front of the object path.  */
51 +
52 +void
53 +objectdirectory_command (char *dirname, int from_tty)
54 +{
55 +  dont_repeat ();
56 +  /* FIXME, this goes to "delete dir"... */
57 +  if (dirname == 0)
58 +    {
59 +      if (from_tty && query ("Reinitialize object path to empty? "))
60 +       {
61 +         xfree (object_path);
62 +         init_object_path ();
63 +       }
64 +    }
65 +  else
66 +    {
67 +      mod_path (dirname, &object_path);
68 +    }
69 +  if (from_tty)
70 +    show_objectdirectories ((char *) 0, from_tty);
71 +}
72 +
73 +struct objid_cache
74 +  {
75 +    struct objid_cache *next;
76 +    char *filename;
77 +    ElfW(Word) sum;
78 +  };
79 +static struct objid_cache *objid_cache;
80 +
81 +static const char *
82 +objid_cache_find (ElfW(Word) sum)
83 +{
84 +  struct objid_cache *item;
85 +
86 +  for (item = objid_cache; item != NULL; item = item->next)
87 +    if (item->sum == sum)
88 +      return item->filename;
89 +
90 +  return NULL;
91 +}
92 +
93 +static void
94 +objid_cache_add (const char *filename, ElfW(Word) sum)
95 +{
96 +  const char *filename_old;
97 +  struct objid_cache *objid_cache_new;
98 +
99 +  filename_old = objid_cache_find (sum);
100 +  if (filename_old != NULL && strcmp (filename, filename_old) != 0)
101 +    warning ("Duplicite checksum of `%s' vs. `%s'", filename_old, filename);
102 +  if (filename_old != NULL)
103 +    return;
104 +
105 +  objid_cache_new = xmalloc (sizeof (*objid_cache_new));
106 +  objid_cache_new->next = objid_cache;
107 +  objid_cache_new->filename = xstrdup (filename);
108 +  objid_cache_new->sum = sum;
109 +  objid_cache = objid_cache_new;
110 +}
111 +
112 +static void
113 +objid_cache_clear (void)
114 +{
115 +  while (objid_cache)
116 +    {
117 +      struct objid_cache *freeing;
118 +
119 +      freeing = objid_cache;
120 +      objid_cache = freeing->next;
121 +      xfree (freeing->filename);
122 +      xfree (freeing);
123 +    }
124 +}
125 +
126 +static void
127 +objid_locate_file_bfd (bfd *abfd)
128 +{
129 +  unsigned phi;
130 +  FILE *f;
131 +  Elf_Internal_Ehdr *ehdr;
132 +  ElfW(Word) sum = 0;
133 +
134 +  if (bfd_check_format (abfd, bfd_object) == FALSE)
135 +    {
136 +      if (bfd_get_error () != bfd_error_file_not_recognized)
137 +       warning ("Error checking binary `%s' (%s)", bfd_get_filename (abfd),
138 +                bfd_errmsg (bfd_get_error ()));
139 +      return;
140 +    }
141 +  /* Non-executable files?  Such as the `.o' files.  */
142 +  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) == 0)
143 +    return;
144 +
145 +  /* `bfd_target_elf_flavour' is required for elf_tdata().  */
146 +  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
147 +    return;
148 +
149 +  ehdr = elf_tdata (abfd)->elf_header;
150 +
151 +  for (phi = 0; phi < ehdr->e_phnum; phi++)
152 +    {
153 +      Elf_Internal_Phdr *phdr = &elf_tdata (abfd)->phdr[phi];
154 +      bfd_size_type remains;
155 +
156 +      /* Match the same conditions as in libobjid `phdr_callback'!  */
157 +      /* FIXME: Unify the code.  */
158 +      if (phdr->p_type != PT_LOAD)
159 +       continue;
160 +      if (!(phdr->p_flags & PF_R))
161 +       continue;
162 +      /* Present?  We probably could not checksum such one. */
163 +      if (phdr->p_flags & PF_W)
164 +       continue;
165 +
166 +      if (bfd_seek (abfd, phdr->p_offset, SEEK_SET) != 0)
167 +        {
168 +         warning ("Error seeking binary `%s' to program header #%u (%s)",
169 +                  bfd_get_filename (abfd), phi, bfd_errmsg (bfd_get_error ()));
170 +         return;
171 +       }
172 +      remains = phdr->p_filesz;
173 +      while (remains > 0)
174 +        {
175 +         unsigned char buf[0x10000];
176 +         bfd_size_type count;
177 +         unsigned char *ptr;
178 +
179 +         count = min (remains, sizeof (buf));
180 +         if (bfd_bread (buf, count, abfd) != count)
181 +           {
182 +             warning ("Error reading binary `%s' of program header #%u (%s)",
183 +                      bfd_get_filename (abfd), phi,
184 +                      bfd_errmsg (bfd_get_error ()));
185 +             return;
186 +           }
187 +
188 +         for (ptr = buf; ptr < buf + count; ptr++)
189 +           sum = sum * 31 + *ptr;
190 +
191 +         remains -= count;
192 +       }
193 +    }
194 +
195 +  objid_cache_add (bfd_get_filename (abfd), sum);
196 +}
197 +
198 +static void
199 +objid_locate_file (const char *filename)
200 +{
201 +  bfd *abfd;
202 +
203 +  /* FIXME: Persistent storage - `core_bfd'!  */
204 +  abfd = bfd_openr (filename, bfd_get_target (core_bfd));
205 +  if (abfd == NULL)
206 +    {
207 +      warning ("Error opening binary `%s' (%s)", filename,
208 +              bfd_errmsg (bfd_get_error ()));
209 +      return;
210 +    }
211 +
212 +  objid_locate_file_bfd (abfd);
213 +
214 +  if (!bfd_close (abfd))
215 +    {
216 +      warning ("Error closing binary `%s' (%s)", filename,
217 +              bfd_errmsg (bfd_get_error ()));
218 +      return;
219 +    }
220 +}
221 +
222 +static void
223 +objid_locate_dir (const char *dirname)
224 +{
225 +  DIR *dir;
226 +  struct dirent *dirent;
227 +
228 +  dir = opendir (dirname);
229 +  if (dir == NULL)
230 +    {
231 +      warning ("Error scanning object directory `%s' (%s)", dirname,
232 +              safe_strerror (errno));
233 +      return;
234 +    }
235 +  while (errno = 0, dirent = readdir (dir))
236 +    {
237 +      char *targetname;
238 +
239 +      if (strcmp (dirent->d_name, ".") == 0)
240 +        continue;
241 +      if (strcmp (dirent->d_name, "..") == 0)
242 +        continue;
243 +      targetname = xstrprintf ("%s/%s", dirname, dirent->d_name);
244 +      if (dirent->d_type == DT_DIR)
245 +       objid_locate_dir (targetname);
246 +      if (dirent->d_type == DT_REG)
247 +        objid_locate_file (targetname);
248 +      xfree (targetname);
249 +    }
250 +  if (errno != 0)
251 +    warning ("Error reading object directory `%s' (%s)", dirname,
252 +            safe_strerror (errno));
253 +  if (closedir (dir))
254 +    {
255 +      warning ("Error closing object directory `%s' (%s)", dirname,
256 +              safe_strerror (errno));
257 +      return;
258 +    }
259 +}
260 +
261 +static void
262 +objid_cache_reload (void)
263 +{
264 +  char *p, *p1;
265 +
266 +  objid_cache_clear ();
267 +
268 +  if (strcmp (object_path, "") == 0)
269 +    return;
270 +
271 +  for (p = object_path; p; p = p1 ? p1 + 1 : 0)
272 +    {
273 +      char *dirname;
274 +      DIR *dir;
275 +
276 +      p1 = strchr (p, DIRNAME_SEPARATOR);
277 +      if (p1 == NULL)
278 +        dirname = xstrdup (p);
279 +      else
280 +       {
281 +         dirname = xmalloc (p1 + 1 - p);
282 +         memcpy (dirname, p, p1 - p);
283 +         dirname[p1 - p] = 0;
284 +       }
285 +      objid_locate_dir (dirname);
286 +      xfree (dirname);
287 +    }
288 +}
289 +
290 +/* HEADER_POINTER is at the place of user data OBJ.  */
291 +/* Return TRUE of allocated header has been read to `*header_pointer'.  */
292 +static bfd_boolean
293 +objid_locate_scan (bfd *abfd, asection *sect,
294 +                   ElfW(LibobjidHdr) **header_pointer)
295 +{
296 +  file_ptr offset;
297 +  bfd_size_type size = bfd_section_size (abfd, sect);
298 +  ElfW(LibobjidHdr) header_local, *header;
299 +
300 +  if (size < sizeof (header_local))
301 +    return FALSE;
302 +
303 +  /* FIXME: `PAGE_SIZE' should be from `auxv'.  */
304 +  for (offset = 0; offset <= size - sizeof (header_local); offset += PAGE_SIZE)
305 +    {
306 +      if (bfd_get_section_contents (abfd, sect, &header_local, offset,
307 +                                   sizeof (header_local)) == FALSE)
308 +       continue;
309 +      if (header_local.magic != ElfW(Magic))
310 +       continue;
311 +      if (header_local.self != bfd_section_vma (abfd, sect) + offset)
312 +       continue;
313 +      if (header_local.self_not != ~header_local.self)
314 +       continue;
315 +      /* Sanity check to avoid loading xmalloc() crashes.  */
316 +      if (header_local.size > 0x10000)
317 +       continue;
318 +      if (header_local.size < sizeof (*header)
319 +                              + header_local.obj_count * sizeof (*header->obj))
320 +       continue;
321 +
322 +      header = xmalloc (header_local.size);
323 +      if (bfd_get_section_contents (abfd, sect, header, offset,
324 +                                   header_local.size) == TRUE)
325 +       {
326 +         *header_pointer = header;
327 +         return TRUE;
328 +       }
329 +      xfree (header);
330 +    }
331 +  return FALSE;
332 +}
333 +
334 +static void
335 +objid_exec_load (char *exec_file, int from_tty)
336 +{
337 +  if (exec_bfd == NULL
338 +      || query (_("Load the matching executable/symbols \"%s\"? "),
339 +              exec_file))
340 +    {
341 +      if (catch_command_errors (exec_file_attach,
342 +                              exec_file, from_tty, RETURN_MASK_ALL))
343 +       catch_command_errors (symbol_file_add_main_userloaded,
344 +                            exec_file, from_tty, RETURN_MASK_ALL);
345 +    }
346 +}
347 +
348 +static void
349 +objid_locate (bfd *core_bfd, int from_tty)
350 +{
351 +  asection *sect;
352 +  ElfW(LibobjidHdr) *header;
353 +  unsigned obji;
354 +
355 +  if (bfd_sections_find_if (core_bfd,
356 +        (bfd_boolean (*) (bfd *abfd, asection *sect, void *obj))
357 +        objid_locate_scan, &header) == NULL)
358 +    return;
359 +
360 +  /* FIXME: Keep the cache more persistent.  */
361 +  objid_cache_reload ();
362 +
363 +  for (obji = 0; obji < header->obj_count; obji++)
364 +    {
365 +      ElfW(LibobjidObj) *obj = &header->obj[obji];
366 +      CORE_ADDR filename_addr = obj->filename;
367 +      char *filename;
368 +      int filename_errno;
369 +
370 +      /* Return value 0 is OK - empty strings.  */
371 +      if (target_read_string (filename_addr, &filename, FILENAME_MAX,
372 +                             &filename_errno) <= 0 || filename_errno != 0)
373 +       warning ("Error reading objid object #%u filename (%s)", obji,
374 +                safe_strerror (filename_errno));
375 +      else
376 +       {
377 +         const char *filename_found;
378 +         
379 +         filename_found = objid_cache_find (obj->checksum);
380 +         if (filename_found != NULL)
381 +           {
382 +             /* Main executable?  It is the first entry with empty name.  */
383 +             if (obji == 0 && strcmp (filename, "") == 0)
384 +               objid_exec_load ((char *) filename_found, from_tty);
385 +             else if (strcmp (filename, "") != 0)
386 +               solib_open_map (filename, filename_found);
387 +             else
388 +               warning ("Ignoring invalid objid mapping `%s' -> `%s'",
389 +                        filename, filename_found);
390 +           }
391 +       }
392 +      xfree (filename);
393 +    }
394 +  xfree (header);
395 +}
396 +
397  /* This routine opens and sets up the core file bfd.  */
398  
399  static void
400 @@ -393,6 +765,9 @@ core_open (char *filename, int from_tty)
401        /* Fetch all registers from core file.  */
402        target_fetch_registers (-1);
403  
404 +      /* Locate objid section, if present.  */
405 +      objid_locate (core_bfd, from_tty);
406 +
407        /* Add symbols and section mappings for any shared libraries.  */
408  #ifdef SOLIB_ADD
409        catch_errors (solib_add_stub, &from_tty, (char *) 0,
410 @@ -679,8 +1054,26 @@ int coreops_suppress_target;
411  void
412  _initialize_corelow (void)
413  {
414 +  struct cmd_list_element *c;
415 +
416    init_core_ops ();
417  
418    if (!coreops_suppress_target)
419      add_target (&core_ops);
420 +
421 +  init_object_path ();
422 +
423 +  c = add_cmd ("objectdirectory", class_files, objectdirectory_command,
424 +              "Add directory DIR to beginning of libobjid based search path\n\
425 +for binary files.\n\
426 +DIR can also be $cwd for the current working directory.\n\
427 +With no argument, reset the search path to be empty, the default.",
428 +              &cmdlist);
429 +
430 +  set_cmd_completer (c, filename_completer);
431 +
432 +  add_cmd ("objectdirectories", no_class, show_objectdirectories,
433 +          "Current search path for libobjid based finding binary files.\n\
434 +$cwd in the path means the current working directory.",
435 +          &showlist);
436  }
437 diff -u -rup -x testsuite gdb-6.3-orig/gdb/defs.h gdb-6.3/gdb/defs.h
438 --- gdb-6.3-orig/gdb/defs.h     2006-12-28 17:29:07.000000000 +0100
439 +++ gdb-6.3/gdb/defs.h  2006-12-28 18:23:59.000000000 +0100
440 @@ -614,6 +614,11 @@ extern void init_source_path (void);
441  
442  extern void init_last_source_visited (void);
443  
444 +/* From corelow.c */
445 +/* FIXME: init.c based.  */
446 +
447 +extern void objectdirectory_command (char *dirname, int from_tty);
448 +
449  /* From exec.c */
450  
451  extern void exec_set_section_offsets (bfd_signed_vma text_off,
452 diff -u -rup -x testsuite gdb-6.3-orig/gdb/main.c gdb-6.3/gdb/main.c
453 --- gdb-6.3-orig/gdb/main.c     2006-12-28 17:29:10.000000000 +0100
454 +++ gdb-6.3/gdb/main.c  2006-12-28 20:23:46.000000000 +0100
455 @@ -134,6 +134,13 @@ captured_main (void *data)
456    /* Number of elements of cmdarg used.  */
457    int ncmd;
458  
459 +  /* Indices of all arguments of --objectdirectory option.  */
460 +  char **objectdirarg;
461 +  /* Allocated size.  */
462 +  int objectdirsize;
463 +  /* Number of elements used.  */
464 +  int nobjectdir;
465 +
466    /* Indices of all arguments of --directory option.  */
467    char **dirarg;
468    /* Allocated size.  */
469 @@ -173,6 +180,9 @@ captured_main (void *data)
470    dirsize = 1;
471    dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
472    ndir = 0;
473 +  objectdirsize = 1;
474 +  objectdirarg = (char **) xmalloc (objectdirsize * sizeof (*objectdirarg));
475 +  nobjectdir = 0;
476  
477    quit_flag = 0;
478    line = (char *) xmalloc (linesize);
479 @@ -240,7 +250,8 @@ captured_main (void *data)
480        OPT_STATISTICS,
481        OPT_TUI,
482        OPT_NOWINDOWS,
483 -      OPT_WINDOWS
484 +      OPT_WINDOWS,
485 +      OPT_OBJECTDIRECTORY
486      };
487      static struct option long_options[] =
488      {
489 @@ -289,6 +300,7 @@ captured_main (void *data)
490        {"interpreter", required_argument, 0, 'i'},
491        {"i", required_argument, 0, 'i'},
492        {"directory", required_argument, 0, 'd'},
493 +      {"objectdirectory", required_argument, 0, OPT_OBJECTDIRECTORY},
494        {"d", required_argument, 0, 'd'},
495        {"cd", required_argument, 0, OPT_CD},
496        {"tty", required_argument, 0, 't'},
497 @@ -457,6 +469,16 @@ extern int gdbtk_test (char *);
498                 remote_timeout = i;
499             }
500             break;
501 +         case OPT_OBJECTDIRECTORY:
502 +           objectdirarg[nobjectdir++] = optarg;
503 +           if (nobjectdir >= objectdirsize)
504 +             {
505 +               objectdirsize *= 2;
506 +               objectdirarg = (char **) xrealloc ((char *) objectdirarg,
507 +                                                  objectdirsize
508 +                                                  * sizeof (*objectdirarg));
509 +             }
510 +           break;
511  
512           case '?':
513             fprintf_unfiltered (gdb_stderr,
514 @@ -636,6 +658,11 @@ extern int gdbtk_test (char *);
515      catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL);
516    xfree (dirarg);
517  
518 +  for (i = 0; i < nobjectdir; i++)
519 +    catch_command_errors (objectdirectory_command, objectdirarg[i], 0,
520 +                         RETURN_MASK_ALL);
521 +  xfree (objectdirarg);
522 +
523    if (execarg != NULL
524        && symarg != NULL
525        && strcmp (execarg, symarg) == 0)
526 @@ -845,6 +872,7 @@ Options:\n\n\
527    fputs_unfiltered (_("\
528    --dbx              DBX compatibility mode.\n\
529    --directory=DIR    Search for source files in DIR.\n\
530 +  --objectdirectory=DIR Search for binary files by libobjid in DIR.\n\
531    --epoch            Output information used by epoch emacs-GDB interface.\n\
532    --exec=EXECFILE    Use EXECFILE as the executable.\n\
533    --fullname         Output information used by emacs-GDB interface.\n\
534 diff -u -rup -x testsuite gdb-6.3-orig/gdb/objid.h gdb-6.3/gdb/objid.h
535 --- gdb-6.3-orig/gdb/objid.h    2006-12-29 11:34:47.000000000 +0100
536 +++ gdb-6.3/gdb/objid.h 2006-12-28 21:27:51.000000000 +0100
537 @@ -0,0 +1,29 @@
538 +#ifndef OBJID_H
539 +#define OBJID_H 1
540 +
541 +
542 +#include <link.h>
543 +
544 +
545 +#define Elf32_Magic 0x0B11D032
546 +#define Elf64_Magic 0x0B11D064
547 +
548 +typedef struct
549 +  {
550 +    ElfW(Addr) filename;
551 +    ElfW(Word) checksum;
552 +  } ElfW(LibobjidObj);
553 +
554 +typedef struct
555 +  {
556 +    ElfW(Word) magic;
557 +    ElfW(Addr) self;
558 +    ElfW(Addr) self_not;       /* == ~self */
559 +    /* Total size of all OBJs including this header.  */
560 +    ElfW(Word) size;
561 +    ElfW(Word) obj_count;
562 +    ElfW(LibobjidObj) obj[0];
563 +  } ElfW(LibobjidHdr);
564 +
565 +
566 +#endif /* !OBJID_H */
567 diff -u -rup -x testsuite gdb-6.3-orig/gdb/solib.c gdb-6.3/gdb/solib.c
568 --- gdb-6.3-orig/gdb/solib.c    2006-12-28 17:29:11.000000000 +0100
569 +++ gdb-6.3/gdb/solib.c 2006-12-29 01:37:08.000000000 +0100
570 @@ -73,6 +73,60 @@ static char *solib_search_path = NULL;
571  
572  void add_to_target_sections (int, struct target_ops *, struct so_list *);
573  
574 +struct solib_open_map
575 +  {
576 +    struct solib_open_map *next;
577 +    char *from;
578 +    char *to;
579 +  };
580 +static struct solib_open_map *solib_open_map_list;
581 +
582 +static const char *
583 +solib_open_map_find (const char *from)
584 +{
585 +  struct solib_open_map *item;
586 +
587 +  for (item = solib_open_map_list; item != NULL; item = item->next)
588 +    if (strcmp (item->from, from) == 0)
589 +      return item->to;
590 +
591 +  return NULL;
592 +}
593 +
594 +void
595 +solib_open_map (const char *from, const char *to)
596 +{
597 +  const char *to_old;
598 +  struct solib_open_map *item_new;
599 +
600 +  to_old = solib_open_map_find (from);
601 +  if (to_old != NULL && strcmp (to_old, to) != 0)
602 +    warning ("Duplicite mapping of `%s' -> `%s' vs. `%s'", from, to_old, to);
603 +  if (to_old != NULL)
604 +    return;
605 +
606 +  item_new = xmalloc (sizeof (*item_new));
607 +  item_new->from = xstrdup (from);
608 +  item_new->to = xstrdup (to);
609 +  item_new->next = solib_open_map_list;
610 +  solib_open_map_list = item_new;
611 +}
612 +
613 +static void
614 +solib_open_map_reset (void)
615 +{
616 +  while (solib_open_map_list != NULL)
617 +    {
618 +      struct solib_open_map *freeing;
619 +      
620 +      freeing = solib_open_map_list;
621 +      xfree (freeing->from);
622 +      xfree (freeing->to);
623 +      solib_open_map_list = freeing->next;
624 +      xfree (freeing);
625 +    }
626 +}
627 +
628  /*
629  
630     GLOBAL FUNCTION
631 @@ -117,6 +171,11 @@ solib_open (char *in_pathname, char **fo
632    char *temp_pathname = NULL;
633    char *p = in_pathname;
634    int solib_absolute_prefix_is_empty;
635 +  const char *in_pathname_mapped;
636 +
637 +  in_pathname_mapped = solib_open_map_find (in_pathname);
638 +  if (in_pathname_mapped != NULL)
639 +    in_pathname = (char *) in_pathname_mapped;
640  
641    solib_absolute_prefix_is_empty = (solib_absolute_prefix == NULL
642                                      || *solib_absolute_prefix == 0);
643 @@ -821,6 +880,8 @@ clear_solib (void)
644      }
645  
646    TARGET_SO_CLEAR_SOLIB ();
647 +
648 +  solib_open_map_reset ();
649  }
650  
651  static void
652 diff -u -rup -x testsuite gdb-6.3-orig/gdb/solist.h gdb-6.3/gdb/solist.h
653 --- gdb-6.3-orig/gdb/solist.h   2006-12-28 17:29:07.000000000 +0100
654 +++ gdb-6.3/gdb/solist.h        2006-12-29 00:10:49.000000000 +0100
655 @@ -121,6 +121,8 @@ struct so_list *master_so_list (void);
656  /* Find solib binary file and open it.  */
657  extern int solib_open (char *in_pathname, char **found_pathname);
658  
659 +extern void solib_open_map (const char *from, const char *to);
660 +
661  /* Add the list of sections in so_list to the target to_sections.  */
662  extern void add_to_target_sections (int, struct target_ops *, struct so_list *);
663  
664 diff -u -rup -x testsuite gdb-6.3-orig/gdb/symfile.c gdb-6.3/gdb/symfile.c
665 --- gdb-6.3-orig/gdb/symfile.c  2006-12-28 17:29:10.000000000 +0100
666 +++ gdb-6.3/gdb/symfile.c       2006-12-28 21:59:10.000000000 +0100
667 @@ -973,6 +973,12 @@ symbol_file_add_main (char *args, int fr
668    symbol_file_add_main_1 (args, from_tty, 0);
669  }
670  
671 +void
672 +symbol_file_add_main_userloaded (char *args, int from_tty)
673 +{
674 +  symbol_file_add_main_1 (args, from_tty, OBJF_USERLOADED);
675 +}
676 +
677  static void
678  symbol_file_add_main_1 (char *args, int from_tty, int flags)
679  {
680 diff -u -rup -x testsuite gdb-6.3-orig/gdb/symfile.h gdb-6.3/gdb/symfile.h
681 --- gdb-6.3-orig/gdb/symfile.h  2004-09-08 23:58:19.000000000 +0200
682 +++ gdb-6.3/gdb/symfile.h       2006-12-28 21:59:11.000000000 +0100
683 @@ -310,6 +310,7 @@ extern CORE_ADDR symbol_overlayed_addres
684  
685  /* Load symbols from a file.  */
686  extern void symbol_file_add_main (char *args, int from_tty);
687 +extern void symbol_file_add_main_userloaded (char *args, int from_tty);
688  
689  /* Clear GDB symbol tables.  */
690  extern void symbol_file_clear (int from_tty);