From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9871 invoked by alias); 1 Sep 2014 07:29:17 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 9859 invoked by uid 89); 1 Sep 2014 07:29:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 01 Sep 2014 07:29:14 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1XOM34-00022s-1e from Taimoor_Mirza@mentor.com for gdb-patches@sourceware.org; Mon, 01 Sep 2014 00:29:10 -0700 Received: from [137.202.156.220] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server (TLS) id 14.2.247.3; Mon, 1 Sep 2014 08:29:08 +0100 Message-ID: <54042041.1030805@codesourcery.com> Date: Mon, 01 Sep 2014 07:29:00 -0000 From: Taimoor User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: Subject: Re: [PING][PATCH 2/2] Testsuite for varobj updation after symbol removal References: <1403864035-30650-1-git-send-email-tmirza@codesourcery.com> <1403864035-30650-3-git-send-email-tmirza@codesourcery.com> <53E0B97C.6040606@codesourcery.com> In-Reply-To: <53E0B97C.6040606@codesourcery.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2014-09/txt/msg00009.txt.bz2 Ping Regards, Taimoor On 08/05/2014 04:01 PM, Taimoor wrote: > Ping. > > On 06/27/2014 03:13 PM, Taimoor Mirza wrote: >> This patch provides testcases for variable object updation after removing >> symbols. Test programs are same as used for testing remove-symbol-file >> command in gdb.base. sym-file-main.c is modified to just add a global >> variable for which varible object is created in testsuite. >> >> Testing: >> ======= >> This is tested for x86 target and also on ppc-linux-gnu and >> mips-gnu-linux >> using both simulator and real boards. >> >> 2014-06-27 Taimoor Mirza >> >> * gdb.mi/mi-var-invalidate.exp: Add tests to check global >> variable object change list is correct when its value is >> updated before removing symbols. >> * gdb.mi/sym-file-loader.c: New file. >> * gdb.mi/sym-file-loader.h: New file. >> * gdb.mi/sym-file-main.c: New file. >> * gdb.mi/sym-file-lib.c: New file. >> >> --- >> gdb/testsuite/gdb.mi/mi-var-invalidate.exp | 67 ++++++ >> gdb/testsuite/gdb.mi/sym-file-lib.c | 26 ++ >> gdb/testsuite/gdb.mi/sym-file-loader.c | 353 >> ++++++++++++++++++++++++++++ >> gdb/testsuite/gdb.mi/sym-file-loader.h | 99 ++++++++ >> gdb/testsuite/gdb.mi/sym-file-main.c | 84 +++++++ >> 5 files changed, 629 insertions(+) >> create mode 100644 gdb/testsuite/gdb.mi/sym-file-lib.c >> create mode 100644 gdb/testsuite/gdb.mi/sym-file-loader.c >> create mode 100644 gdb/testsuite/gdb.mi/sym-file-loader.h >> create mode 100644 gdb/testsuite/gdb.mi/sym-file-main.c >> >> diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp >> b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp >> index e6ba392..e3bf953 100644 >> --- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp >> +++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp >> @@ -121,5 +121,72 @@ mi_gdb_test "-var-info-type global_simple" \ >> "\\^done,type=\"\"" \ >> "no type for invalid variable global_simple" >> >> +# Test varobj updation after removing symbols. >> + >> +if {[skip_shlib_tests]} { >> + return 0 >> +} >> + >> +set target_size TARGET_UNKNOWN >> +if {[is_lp64_target]} { >> + set target_size TARGET_LP64 >> +} elseif {[is_ilp32_target]} { >> + set target_size TARGET_ILP32 >> +} else { >> + return 0 >> +} >> + >> +set main_basename sym-file-main >> +set loader_basename sym-file-loader >> +set lib_basename sym-file-lib >> + >> +standard_testfile $main_basename.c $loader_basename.c $lib_basename.c >> + >> +set libsrc "${srcdir}/${subdir}/${srcfile3}" >> +set test_bin_name "sym-test-file" >> +set test_bin [standard_output_file ${test_bin_name}] >> +set shlib_name [standard_output_file ${lib_basename}.so] >> +set exec_opts [list debug "additional_flags= -I$srcdir/../../include/ \ >> +-D$target_size -DSHLIB_NAME\\=\"$shlib_name\""] >> + >> +if [get_compiler_info] { >> + return -1 >> +} >> + >> +if {[gdb_compile_shlib $libsrc $shlib_name {debug}] != ""} { >> + untested ${testfile} >> + return -1 >> +} >> + >> +if {[build_executable $testfile $test_bin "$srcfile $srcfile2" >> $exec_opts]} { >> + return -1 >> +} >> + >> +mi_delete_breakpoints >> +mi_gdb_load ${test_bin} >> + >> +# Create varobj for count variable. >> +mi_create_varobj var_count count "Create global varobj for count" >> + >> +# Run to GDB_ADD_SYMBOl_FILE in $srcfile for adding >> +# $shlib_name. >> +mi_runto gdb_add_symbol_file >> + >> +# Add $shlib_name using 'add-symbol-file'. >> +mi_gdb_test "-interpreter-exec console \"add-symbol-file >> ${shlib_name} addr\"" \ >> + "~\"add symbol table from file .*so.*at.*= $hex.*\\^done" \ >> + "add-symbol-file ${shlib_name}" >> + >> +# Continue to gdb_remove_symbol_file in $srcfile. >> +mi_runto gdb_remove_symbol_file >> + >> +# Remove $shlib_name using 'remove-symbol-file'. >> +mi_gdb_test "-interpreter-exec console \"remove-symbol-file -a addr\"" \ >> + ".*\\^done"\ >> + "remove-symbol-file test" >> + >> +# Check var_count varobj changelist is not empty. >> +mi_varobj_update var_count {var_count} "Update var_count" >> + >> mi_gdb_exit >> return 0 >> diff --git a/gdb/testsuite/gdb.mi/sym-file-lib.c >> b/gdb/testsuite/gdb.mi/sym-file-lib.c >> new file mode 100644 >> index 0000000..dae5188 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.mi/sym-file-lib.c >> @@ -0,0 +1,26 @@ >> +/* Copyright 2013-2014 Free Software Foundation, Inc. >> + This program is free software; you can redistribute it and/or modify >> + it under the terms of the GNU General Public License as published by >> + the Free Software Foundation; either version 3 of the License, or >> + (at your option) any later version. >> + >> + This program is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + GNU General Public License for more details. >> + >> + You should have received a copy of the GNU General Public License >> + along with this program. If not, see . >> +*/ >> + >> +extern int >> +bar () >> +{ >> + return 1; /* gdb break at bar. */ >> +} >> + >> +extern int >> +foo (int a) >> +{ >> + return a; /* gdb break at foo. */ >> +} >> diff --git a/gdb/testsuite/gdb.mi/sym-file-loader.c >> b/gdb/testsuite/gdb.mi/sym-file-loader.c >> new file mode 100644 >> index 0000000..c72a1d1 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.mi/sym-file-loader.c >> @@ -0,0 +1,353 @@ >> +/* Copyright 2013-2014 Free Software Foundation, Inc. >> + This program is free software; you can redistribute it and/or modify >> + it under the terms of the GNU General Public License as published by >> + the Free Software Foundation; either version 3 of the License, or >> + (at your option) any later version. >> + >> + This program is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + GNU General Public License for more details. >> + >> + You should have received a copy of the GNU General Public License >> + along with this program. If not, see . >> +*/ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "sym-file-loader.h" >> + >> +#ifdef TARGET_LP64 >> + >> +uint8_t >> +elf_st_type (uint8_t st_info) >> +{ >> + return ELF64_ST_TYPE (st_info); >> +} >> + >> +#elif defined TARGET_ILP32 >> + >> +uint8_t >> +elf_st_type (uint8_t st_info) >> +{ >> + return ELF32_ST_TYPE (st_info); >> +} >> + >> +#endif >> + >> +/* Load a program segment. */ >> + >> +static struct segment * >> +load (uint8_t *addr, Elf_External_Phdr *phdr, struct segment *tail_seg) >> +{ >> + struct segment *seg = NULL; >> + uint8_t *mapped_addr = NULL; >> + void *from = NULL; >> + void *to = NULL; >> + >> + /* For the sake of simplicity all operations are permitted. */ >> + unsigned perm = PROT_READ | PROT_WRITE | PROT_EXEC; >> + >> + mapped_addr = (uint8_t *) mmap ((void *) GETADDR (phdr, p_vaddr), >> + GET (phdr, p_memsz), perm, >> + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); >> + >> + from = (void *) (addr + GET (phdr, p_offset)); >> + to = (void *) mapped_addr; >> + >> + memcpy (to, from, GET (phdr, p_filesz)); >> + >> + seg = (struct segment *) malloc (sizeof (struct segment)); >> + >> + if (seg == 0) >> + return 0; >> + >> + seg->mapped_addr = mapped_addr; >> + seg->phdr = phdr; >> + seg->next = 0; >> + >> + if (tail_seg != 0) >> + tail_seg->next = seg; >> + >> + return seg; >> +} >> + >> +/* Mini shared library loader. No reallocation >> + is performed for the sake of simplicity. */ >> + >> +int >> +load_shlib (const char *file, Elf_External_Ehdr **ehdr_out, >> + struct segment **seg_out) >> +{ >> + uint64_t i; >> + int fd; >> + off_t fsize; >> + uint8_t *addr; >> + Elf_External_Ehdr *ehdr; >> + Elf_External_Phdr *phdr; >> + struct segment *head_seg = NULL; >> + struct segment *tail_seg = NULL; >> + >> + /* Map the lib in memory for reading. */ >> + fd = open (file, O_RDONLY); >> + if (fd < 0) >> + { >> + perror ("fopen failed."); >> + return -1; >> + } >> + >> + fsize = lseek (fd, 0, SEEK_END); >> + >> + if (fsize < 0) >> + { >> + perror ("lseek failed."); >> + return -1; >> + } >> + >> + addr = (uint8_t *) mmap (NULL, fsize, PROT_READ, MAP_PRIVATE, fd, 0); >> + if (addr == (uint8_t *) -1) >> + { >> + perror ("mmap failed."); >> + return -1; >> + } >> + >> + /* Check if the lib is an ELF file. */ >> + ehdr = (Elf_External_Ehdr *) addr; >> + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 >> + || ehdr->e_ident[EI_MAG1] != ELFMAG1 >> + || ehdr->e_ident[EI_MAG2] != ELFMAG2 >> + || ehdr->e_ident[EI_MAG3] != ELFMAG3) >> + { >> + printf ("Not an ELF file: %x\n", ehdr->e_ident[EI_MAG0]); >> + return -1; >> + } >> + >> + if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) >> + { >> + if (sizeof (void *) != 4) >> + { >> + printf ("Architecture mismatch."); >> + return -1; >> + } >> + } >> + else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) >> + { >> + if (sizeof (void *) != 8) >> + { >> + printf ("Architecture mismatch."); >> + return -1; >> + } >> + } >> + >> + /* Load the program segments. For the sake of simplicity >> + assume that no reallocation is needed. */ >> + phdr = (Elf_External_Phdr *) (addr + GET (ehdr, e_phoff)); >> + for (i = 0; i < GET (ehdr, e_phnum); i++, phdr++) >> + { >> + if (GET (phdr, p_type) == PT_LOAD) >> + { >> + struct segment *next_seg = load (addr, phdr, tail_seg); >> + if (next_seg == 0) >> + continue; >> + tail_seg = next_seg; >> + if (head_seg == 0) >> + head_seg = next_seg; >> + } >> + } >> + *ehdr_out = ehdr; >> + *seg_out = head_seg; >> + return 0; >> +} >> + >> +/* Return the section-header table. */ >> + >> +Elf_External_Shdr * >> +find_shdrtab (Elf_External_Ehdr *ehdr) >> +{ >> + return (Elf_External_Shdr *) (((uint8_t *) ehdr) + GET (ehdr, >> e_shoff)); >> +} >> + >> +/* Return the string table of the section headers. */ >> + >> +const char * >> +find_shstrtab (Elf_External_Ehdr *ehdr, uint64_t *size) >> +{ >> + const Elf_External_Shdr *shdr; >> + const Elf_External_Shdr *shstr; >> + >> + if (GET (ehdr, e_shnum) <= GET (ehdr, e_shstrndx)) >> + { >> + printf ("The index of the string table is corrupt."); >> + return NULL; >> + } >> + >> + shdr = find_shdrtab (ehdr); >> + >> + shstr = &shdr[GET (ehdr, e_shstrndx)]; >> + *size = GET (shstr, sh_size); >> + return ((const char *) ehdr) + GET (shstr, sh_offset); >> +} >> + >> +/* Return the string table named SECTION. */ >> + >> +const char * >> +find_strtab (Elf_External_Ehdr *ehdr, >> + const char *section, uint64_t *strtab_size) >> +{ >> + uint64_t shstrtab_size = 0; >> + const char *shstrtab; >> + uint64_t i; >> + const Elf_External_Shdr *shdr = find_shdrtab (ehdr); >> + >> + /* Get the string table of the section headers. */ >> + shstrtab = find_shstrtab (ehdr, &shstrtab_size); >> + if (shstrtab == NULL) >> + return NULL; >> + >> + for (i = 0; i < GET (ehdr, e_shnum); i++) >> + { >> + uint64_t name = GET (shdr + i, sh_name); >> + if (GET (shdr + i, sh_type) == SHT_STRTAB && name <= shstrtab_size >> + && strcmp ((const char *) &shstrtab[name], section) == 0) >> + { >> + *strtab_size = GET (shdr + i, sh_size); >> + return ((const char *) ehdr) + GET (shdr + i, sh_offset); >> + } >> + >> + } >> + return NULL; >> +} >> + >> +/* Return the section header named SECTION. */ >> + >> +Elf_External_Shdr * >> +find_shdr (Elf_External_Ehdr *ehdr, const char *section) >> +{ >> + uint64_t shstrtab_size = 0; >> + const char *shstrtab; >> + uint64_t i; >> + >> + /* Get the string table of the section headers. */ >> + shstrtab = find_shstrtab (ehdr, &shstrtab_size); >> + if (shstrtab == NULL) >> + return NULL; >> + >> + Elf_External_Shdr *shdr = find_shdrtab (ehdr); >> + for (i = 0; i < GET (ehdr, e_shnum); i++) >> + { >> + uint64_t name = GET (shdr + i, sh_name); >> + if (name <= shstrtab_size) >> + { >> + if (strcmp ((const char *) &shstrtab[name], section) == 0) >> + return &shdr[i]; >> + } >> + >> + } >> + return NULL; >> +} >> + >> +/* Return the symbol table. */ >> + >> +Elf_External_Sym * >> +find_symtab (Elf_External_Ehdr *ehdr, uint64_t *symtab_size) >> +{ >> + uint64_t i; >> + const Elf_External_Shdr *shdr = find_shdrtab (ehdr); >> + >> + for (i = 0; i < GET (ehdr, e_shnum); i++) >> + { >> + if (GET (shdr + i, sh_type) == SHT_SYMTAB) >> + { >> + *symtab_size = GET (shdr + i, sh_size) / sizeof >> (Elf_External_Sym); >> + return (Elf_External_Sym *) (((const char *) ehdr) + >> + GET (shdr + i, sh_offset)); >> + } >> + } >> + return NULL; >> +} >> + >> +/* Translate a file offset to an address in a loaded segment. */ >> + >> +int >> +translate_offset (uint64_t file_offset, struct segment *seg, void >> **addr) >> +{ >> + while (seg) >> + { >> + uint64_t p_from, p_to; >> + >> + Elf_External_Phdr *phdr = seg->phdr; >> + >> + if (phdr == NULL) >> + { >> + seg = seg->next; >> + continue; >> + } >> + >> + p_from = GET (phdr, p_offset); >> + p_to = p_from + GET (phdr, p_filesz); >> + >> + if (p_from <= file_offset && file_offset < p_to) >> + { >> + *addr = (void *) (seg->mapped_addr + (file_offset - p_from)); >> + return 0; >> + } >> + seg = seg->next; >> + } >> + >> + return -1; >> +} >> + >> +/* Lookup the address of FUNC. */ >> + >> +int >> +lookup_function (const char *func, >> + Elf_External_Ehdr *ehdr, struct segment *seg, void **addr) >> +{ >> + const char *strtab; >> + uint64_t strtab_size = 0; >> + Elf_External_Sym *symtab; >> + uint64_t symtab_size = 0; >> + uint64_t i; >> + >> + /* Get the string table for the symbols. */ >> + strtab = find_strtab (ehdr, ".strtab", &strtab_size); >> + if (strtab == NULL) >> + { >> + printf (".strtab not found."); >> + return -1; >> + } >> + >> + /* Get the symbol table. */ >> + symtab = find_symtab (ehdr, &symtab_size); >> + if (symtab == NULL) >> + { >> + printf ("symbol table not found."); >> + return -1; >> + } >> + >> + for (i = 0; i < symtab_size; i++) >> + { >> + Elf_External_Sym *sym = &symtab[i]; >> + >> + if (elf_st_type (GET (sym, st_info)) != STT_FUNC) >> + continue; >> + >> + if (GET (sym, st_name) < strtab_size) >> + { >> + const char *name = &strtab[GET (sym, st_name)]; >> + if (strcmp (name, func) == 0) >> + { >> + >> + uint64_t offset = GET (sym, st_value); >> + return translate_offset (offset, seg, addr); >> + } >> + } >> + } >> + >> + return -1; >> +} >> diff --git a/gdb/testsuite/gdb.mi/sym-file-loader.h >> b/gdb/testsuite/gdb.mi/sym-file-loader.h >> new file mode 100644 >> index 0000000..03dc7e1 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.mi/sym-file-loader.h >> @@ -0,0 +1,99 @@ >> +/* Copyright 2013-2014 Free Software Foundation, Inc. >> + This program is free software; you can redistribute it and/or modify >> + it under the terms of the GNU General Public License as published by >> + the Free Software Foundation; either version 3 of the License, or >> + (at your option) any later version. >> + >> + This program is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + GNU General Public License for more details. >> + >> + You should have received a copy of the GNU General Public License >> + along with this program. If not, see . >> +*/ >> + >> +#ifndef __SYM_FILE_LOADER__ >> +#define __SYM_FILE_LOADER__ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#ifdef TARGET_LP64 >> + >> +typedef Elf64_External_Phdr Elf_External_Phdr; >> +typedef Elf64_External_Ehdr Elf_External_Ehdr; >> +typedef Elf64_External_Shdr Elf_External_Shdr; >> +typedef Elf64_External_Sym Elf_External_Sym; >> +typedef uint64_t Elf_Addr; >> + >> +#elif defined TARGET_ILP32 >> + >> +typedef Elf32_External_Phdr Elf_External_Phdr; >> +typedef Elf32_External_Ehdr Elf_External_Ehdr; >> +typedef Elf32_External_Shdr Elf_External_Shdr; >> +typedef Elf32_External_Sym Elf_External_Sym; >> +typedef uint32_t Elf_Addr; >> + >> +#endif >> + >> +#define GET(hdr, field) (\ >> +sizeof ((hdr)->field) == 1 ? (uint64_t) (hdr)->field[0] : \ >> +sizeof ((hdr)->field) == 2 ? (uint64_t) *(uint16_t *) (hdr)->field : \ >> +sizeof ((hdr)->field) == 4 ? (uint64_t) *(uint32_t *) (hdr)->field : \ >> +sizeof ((hdr)->field) == 8 ? *(uint64_t *) (hdr)->field : \ >> +*(uint64_t *) NULL) >> + >> +#define GETADDR(hdr, field) (\ >> +sizeof ((hdr)->field) == sizeof (Elf_Addr) ? *(Elf_Addr *) >> (hdr)->field : \ >> +*(Elf_Addr *) NULL) >> + >> +struct segment >> +{ >> + uint8_t *mapped_addr; >> + Elf_External_Phdr *phdr; >> + struct segment *next; >> +}; >> + >> +/* Mini shared library loader. No reallocation is performed >> + for the sake of simplicity. */ >> + >> +int >> +load_shlib (const char *file, Elf_External_Ehdr **ehdr_out, >> + struct segment **seg_out); >> + >> +/* Return the section-header table. */ >> + >> +Elf_External_Shdr *find_shdrtab (Elf_External_Ehdr *ehdr); >> + >> +/* Return the string table of the section headers. */ >> + >> +const char *find_shstrtab (Elf_External_Ehdr *ehdr, uint64_t *size); >> + >> +/* Return the string table named SECTION. */ >> + >> +const char *find_strtab (Elf_External_Ehdr *ehdr, >> + const char *section, uint64_t *strtab_size); >> + >> +/* Return the section header named SECTION. */ >> + >> +Elf_External_Shdr *find_shdr (Elf_External_Ehdr *ehdr, const char >> *section); >> + >> +/* Return the symbol table. */ >> + >> +Elf_External_Sym *find_symtab (Elf_External_Ehdr *ehdr, >> + uint64_t *symtab_size); >> + >> +/* Translate a file offset to an address in a loaded segment. */ >> + >> +int translate_offset (uint64_t file_offset, struct segment *seg, void >> **addr); >> + >> +/* Lookup the address of FUNC. */ >> + >> +int >> +lookup_function (const char *func, Elf_External_Ehdr* ehdr, >> + struct segment *seg, void **addr); >> + >> +#endif >> diff --git a/gdb/testsuite/gdb.mi/sym-file-main.c >> b/gdb/testsuite/gdb.mi/sym-file-main.c >> new file mode 100644 >> index 0000000..8260824 >> --- /dev/null >> +++ b/gdb/testsuite/gdb.mi/sym-file-main.c >> @@ -0,0 +1,84 @@ >> +/* Copyright 2013-2014 Free Software Foundation, Inc. >> + This program is free software; you can redistribute it and/or modify >> + it under the terms of the GNU General Public License as published by >> + the Free Software Foundation; either version 3 of the License, or >> + (at your option) any later version. >> + >> + This program is distributed in the hope that it will be useful, >> + but WITHOUT ANY WARRANTY; without even the implied warranty of >> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + GNU General Public License for more details. >> + >> + You should have received a copy of the GNU General Public License >> + along with this program. If not, see . >> +*/ >> + >> +#include >> +#include >> + >> +#include "sym-file-loader.h" >> + >> +// Global variable >> +int count = 0; >> + >> +void >> +gdb_add_symbol_file (void *addr, const char *file) >> +{ >> + return; >> +} >> + >> +void >> +gdb_remove_symbol_file (void *addr) >> +{ >> + return; >> +} >> + >> +/* Load a shared library without relying on the standard >> + loader to test GDB's commands for adding and removing >> + symbol files at runtime. */ >> + >> +int >> +main (int argc, const char *argv[]) >> +{ >> + const char *file = SHLIB_NAME; >> + Elf_External_Ehdr *ehdr = NULL; >> + struct segment *head_seg = NULL; >> + Elf_External_Shdr *text; >> + char *text_addr = NULL; >> + int (*pbar) () = NULL; >> + int (*pfoo) (int) = NULL; >> + >> + if (load_shlib (file, &ehdr, &head_seg) != 0) >> + return -1; >> + >> + /* Get the text section. */ >> + text = find_shdr (ehdr, ".text"); >> + if (text == NULL) >> + return -1; >> + >> + /* Notify GDB to add the symbol file. */ >> + if (translate_offset (GET (text, sh_offset), head_seg, (void **) >> &text_addr) >> + != 0) >> + return -1; >> + >> + gdb_add_symbol_file (text_addr, file); >> + >> + /* Call bar from SHLIB_NAME. */ >> + if (lookup_function ("bar", ehdr, head_seg, (void *) &pbar) != 0) >> + return -1; >> + >> + (*pbar) (); >> + >> + /* Call foo from SHLIB_NAME. */ >> + if (lookup_function ("foo", ehdr, head_seg, (void *) &pfoo) != 0) >> + return -1; >> + >> + (*pfoo) (2); >> + >> + count++; >> + >> + /* Notify GDB to remove the symbol file. */ >> + gdb_remove_symbol_file (text_addr); >> + >> + return 0; >> +} >>