aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/bfd-in2.h12
-rw-r--r--bfd/coff-alpha.c2
-rw-r--r--bfd/coff-arm.c12
-rw-r--r--bfd/coff-mips.c2
-rw-r--r--bfd/coff-rs6000.c2
-rw-r--r--bfd/coff-sh.c2
-rw-r--r--bfd/coff64-rs6000.c2
-rw-r--r--bfd/coffcode.h21
-rw-r--r--bfd/cofflink.c2
-rw-r--r--bfd/libbfd-in.h6
-rw-r--r--bfd/libbfd.h6
-rw-r--r--bfd/libcoff.h9
-rw-r--r--bfd/linker.c20
-rw-r--r--bfd/peXXigen.c111
-rw-r--r--bfd/version.h2
-rw-r--r--binutils/nm.c29
-rw-r--r--binutils/testsuite/binutils-all/nm-coff-1.s26
-rw-r--r--binutils/testsuite/binutils-all/nm-coff-sdef-1.s26
-rw-r--r--binutils/testsuite/binutils-all/nm.exp6
-rw-r--r--gas/config/obj-coff.c4
-rw-r--r--gdb/NEWS5
-rw-r--r--gdb/doc/gdb.texinfo5
-rw-r--r--gdb/solib-svr4.c108
-rw-r--r--gdb/solib.c27
-rw-r--r--gdb/solist.h14
-rw-r--r--gdb/testsuite/gdb.base/attach-pie-noexec.exp4
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c28
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c54
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids.exp106
-rw-r--r--gdb/testsuite/gdb.base/dlmopen.exp8
-rw-r--r--gdb/testsuite/gdb.mi/mi-dlmopen.exp6
-rw-r--r--gdbserver/regcache.cc3
-rw-r--r--gprofng/src/DwarfLib.cc24
-rw-r--r--gprofng/src/Elf.cc69
-rw-r--r--gprofng/src/Elf.h3
-rw-r--r--gprofng/src/Stabs.cc216
-rw-r--r--gprofng/src/Stabs.h6
-rw-r--r--gprofng/src/vec.h7
-rw-r--r--ld/pe-dll.c6
39 files changed, 679 insertions, 322 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 7a8318e..ec60f23 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2913,6 +2913,18 @@ const char *bfd_format_string (bfd_format format);
&& bfd_is_abs_section ((H)->u.def.section) \
&& !(H)->rel_from_abs)
+bool _bfd_generic_link_add_one_symbol
+ (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bool copy,
+ bool collect,
+ struct bfd_link_hash_entry **hashp);
+
bool bfd_link_align_section (asection *, unsigned int);
bool bfd_link_split_section (bfd *abfd, asection *sec);
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
index 2798efd..e2f1a4d 100644
--- a/bfd/coff-alpha.c
+++ b/bfd/coff-alpha.c
@@ -2359,7 +2359,7 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL
+ NULL, NULL, NULL,
},
/* Supported architecture. */
bfd_arch_alpha,
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index ab5f7b0..ee57451 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -1876,8 +1876,8 @@ record_arm_to_thumb_glue (struct bfd_link_info * info,
it. */
bh = NULL;
val = globals->arm_glue_size + 1;
- bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_GLOBAL, s, val, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, val, NULL, true, false, &bh);
free (tmp_name);
@@ -1929,8 +1929,8 @@ record_thumb_to_arm_glue (struct bfd_link_info * info,
bh = NULL;
val = globals->thumb_glue_size + 1;
- bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_GLOBAL, s, val, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, val, NULL, true, false, &bh);
/* If we mark it 'thumb', the disassembler will do a better job. */
myh = (struct coff_link_hash_entry *) bh;
@@ -1952,8 +1952,8 @@ record_thumb_to_arm_glue (struct bfd_link_info * info,
bh = NULL;
val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
- bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_LOCAL, s, val, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_LOCAL, s, val, NULL, true, false, &bh);
free (tmp_name);
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
index e2c632c..8c4d4f7 100644
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -1316,7 +1316,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
_bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL
+ NULL, NULL,
},
/* Supported architecture. */
bfd_arch_mips,
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 7a20dba..ae9a0f6 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -4584,7 +4584,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
xcoff_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
@@ -4774,7 +4773,6 @@ static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
xcoff_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c
index 275c4f5..c3e0e42 100644
--- a/bfd/coff-sh.c
+++ b/bfd/coff-sh.c
@@ -3108,7 +3108,7 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata
};
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 5a4bcbf..ec7ed08 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -2495,7 +2495,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
xcoff64_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
@@ -2768,7 +2767,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
xcoff64_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 325a8ab..bd0374f 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1516,11 +1516,6 @@ CODE_FRAGMENT
. (bfd *, struct bfd_link_info *, bfd *, asection *,
. struct internal_reloc *, bool *);
.
-. bool (*_bfd_coff_link_add_one_symbol)
-. (struct bfd_link_info *, bfd *, const char *, flagword,
-. asection *, bfd_vma, const char *, bool, bool,
-. struct bfd_link_hash_entry **);
-.
. bool (*_bfd_coff_link_output_has_begun)
. (bfd *, struct coff_final_link_info *);
.
@@ -1659,10 +1654,6 @@ INTERNAL
.#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
. ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
. (obfd, info, ibfd, sec, rel, adjustedp))
-.#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
-. value, string, cp, coll, hashp)\
-. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
-. (info, abfd, name, flags, section, value, string, cp, coll, hashp))
.
.#define bfd_coff_link_output_has_begun(a,p) \
. ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p))
@@ -5513,10 +5504,6 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED,
#define coff_adjust_symndx NULL
#endif
-#ifndef coff_link_add_one_symbol
-#define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol
-#endif
-
#ifndef coff_link_output_has_begun
static bool
@@ -5615,7 +5602,7 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata
};
@@ -5656,7 +5643,7 @@ static const bfd_coff_backend_data ticoff0_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata
};
@@ -5698,7 +5685,7 @@ static const bfd_coff_backend_data ticoff1_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata /* huh */
};
@@ -5941,7 +5928,7 @@ static const bfd_coff_backend_data bigobj_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata /* huh */
};
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 876aed7..501731b 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -445,7 +445,7 @@ coff_link_add_symbols (bfd *abfd,
if (addit)
{
- if (! (bfd_coff_link_add_one_symbol
+ if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value,
(const char *) NULL, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index b2f70fb..ae6d303 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -645,12 +645,6 @@ extern bool _bfd_generic_link_add_archive_symbols
/* Forward declaration to avoid prototype errors. */
typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
-/* Generic routine to add a single symbol. */
-extern bool _bfd_generic_link_add_one_symbol
- (struct bfd_link_info *, bfd *, const char *name, flagword,
- asection *, bfd_vma, const char *, bool copy,
- bool constructor, struct bfd_link_hash_entry **) ATTRIBUTE_HIDDEN;
-
/* Generic routine to mark section as supplying symbols only. */
extern void _bfd_generic_link_just_syms
(asection *, struct bfd_link_info *) ATTRIBUTE_HIDDEN;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 4f6f5ea..d367fea 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -651,12 +651,6 @@ extern bool _bfd_generic_link_add_archive_symbols
/* Forward declaration to avoid prototype errors. */
typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
-/* Generic routine to add a single symbol. */
-extern bool _bfd_generic_link_add_one_symbol
- (struct bfd_link_info *, bfd *, const char *name, flagword,
- asection *, bfd_vma, const char *, bool copy,
- bool constructor, struct bfd_link_hash_entry **) ATTRIBUTE_HIDDEN;
-
/* Generic routine to mark section as supplying symbols only. */
extern void _bfd_generic_link_just_syms
(asection *, struct bfd_link_info *) ATTRIBUTE_HIDDEN;
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index d0cfd09..05ebe35 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -864,11 +864,6 @@ typedef struct
(bfd *, struct bfd_link_info *, bfd *, asection *,
struct internal_reloc *, bool *);
- bool (*_bfd_coff_link_add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword,
- asection *, bfd_vma, const char *, bool, bool,
- struct bfd_link_hash_entry **);
-
bool (*_bfd_coff_link_output_has_begun)
(bfd *, struct coff_final_link_info *);
@@ -1005,10 +1000,6 @@ typedef struct
#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
(obfd, info, ibfd, sec, rel, adjustedp))
-#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
- value, string, cp, coll, hashp)\
- ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
- (info, abfd, name, flags, section, value, string, cp, coll, hashp))
#define bfd_coff_link_output_has_begun(a,p) \
((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p))
diff --git a/bfd/linker.c b/bfd/linker.c
index 2a4b8f0..a9a23e5 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1378,7 +1378,25 @@ hash_entry_bfd (struct bfd_link_hash_entry *h)
/*NOTREACHED*/
}
-/* Add a symbol to the global hash table.
+/*
+FUNCTION
+ _bfd_generic_link_add_one_symbol
+
+SYNOPSIS
+ bool _bfd_generic_link_add_one_symbol
+ (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bool copy,
+ bool collect,
+ struct bfd_link_hash_entry **hashp);
+
+DESCRIPTION
+ Add a symbol to the global hash table.
ABFD is the BFD the symbol comes from.
NAME is the name of the symbol.
FLAGS is the BSF_* bits associated with the symbol.
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 2901268..9938108 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -593,7 +593,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
bfd_vma sa, fa, ib;
- IMAGE_DATA_DIRECTORY idata2, idata5, tls;
+ IMAGE_DATA_DIRECTORY idata2, idata5, tls, loadcfg;
sa = extra->SectionAlignment;
fa = extra->FileAlignment;
@@ -602,6 +602,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
+ loadcfg = pe->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE];
if (aouthdr_in->tsize)
{
@@ -651,6 +652,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
extra->DataDirectory[PE_IMPORT_TABLE] = idata2;
extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
extra->DataDirectory[PE_TLS_TABLE] = tls;
+ extra->DataDirectory[PE_LOAD_CONFIG_TABLE] = loadcfg;
if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0)
/* Until other .idata fixes are made (pending patch), the entry for
@@ -4403,6 +4405,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
struct coff_link_hash_entry *h1;
struct bfd_link_info *info = pfinfo->info;
bool result = true;
+ char name[20];
/* There are a few fields that need to be filled in now while we
have symbol table access.
@@ -4430,8 +4433,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_TABLE, ".idata$2");
result = false;
}
@@ -4450,8 +4453,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_TABLE, ".idata$4");
result = false;
}
@@ -4471,8 +4474,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_ADDRESS_TABLE, ".idata$5");
result = false;
}
@@ -4491,8 +4494,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_ADDRESS_TABLE, ".idata$6");
result = false;
}
}
@@ -4533,17 +4536,16 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
- " because .idata$6 is missing"), abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+ abfd, PE_IMPORT_ADDRESS_TABLE, "__IAT_end__");
result = false;
}
}
}
- h1 = coff_link_hash_lookup (coff_hash_table (info),
- (bfd_get_symbol_leading_char (abfd) != 0
- ? "__tls_used" : "_tls_used"),
- false, false, true);
+ name[0] = bfd_get_symbol_leading_char (abfd);
+ strcpy (name + !!name[0], "_tls_used");
+ h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true);
if (h1 != NULL)
{
if ((h1->root.type == bfd_link_hash_defined
@@ -4558,8 +4560,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+ abfd, PE_TLS_TABLE, name);
result = false;
}
/* According to PECOFF sepcifications by Microsoft version 8.2
@@ -4573,6 +4575,81 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
#endif
}
+ name[0] = bfd_get_symbol_leading_char (abfd);
+ strcpy (name + !!name[0], "_load_config_used");
+ h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true);
+ if (h1 != NULL)
+ {
+ char data[4];
+ if ((h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ {
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset
+ - pe_data (abfd)->pe_opthdr.ImageBase);
+
+ if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].VirtualAddress
+ & (bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd)
+ - 1))
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not properly aligned"),
+ abfd, PE_LOAD_CONFIG_TABLE, name);
+ result = false;
+ }
+
+ /* The size is stored as the first 4 bytes at _load_config_used. */
+ if (bfd_get_section_contents (abfd,
+ h1->root.u.def.section->output_section, data,
+ h1->root.u.def.section->output_offset + h1->root.u.def.value,
+ 4))
+ {
+ uint32_t size = bfd_get_32 (abfd, data);
+ /* The Microsoft PE format documentation says for compatibility
+ with Windows XP and earlier, the size must be 64 for x86
+ images. */
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].Size
+ = (bfd_get_arch (abfd) == bfd_arch_i386
+ && ((bfd_get_mach (abfd) & ~bfd_mach_i386_intel_syntax)
+ == bfd_mach_i386_i386)
+ && ((pe_data (abfd)->pe_opthdr.Subsystem
+ == IMAGE_SUBSYSTEM_WINDOWS_GUI)
+ || (pe_data (abfd)->pe_opthdr.Subsystem
+ == IMAGE_SUBSYSTEM_WINDOWS_CUI))
+ && (pe_data (abfd)->pe_opthdr.MajorSubsystemVersion * 256
+ + pe_data (abfd)->pe_opthdr.MinorSubsystemVersion
+ <= 0x0501))
+ ? 64 : size;
+
+ if (size > h1->root.u.def.section->size - h1->root.u.def.value)
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: size too large for the containing section"),
+ abfd, PE_LOAD_CONFIG_TABLE);
+ result = false;
+ }
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: size can't be read from %s"),
+ abfd, PE_LOAD_CONFIG_TABLE, name);
+ result = false;
+ }
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+ abfd, PE_LOAD_CONFIG_TABLE, name);
+ result = false;
+ }
+ }
+
/* If there is a .pdata section and we have linked pdata finally, we
need to sort the entries ascending. */
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64))
diff --git a/bfd/version.h b/bfd/version.h
index ec40174..09a913a 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -16,7 +16,7 @@
In releases, the date is not included in either version strings or
sonames. */
-#define BFD_VERSION_DATE 20250404
+#define BFD_VERSION_DATE 20250407
#define BFD_VERSION @bfd_version@
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
#define REPORT_BUGS_TO @report_bugs_to@
diff --git a/binutils/nm.c b/binutils/nm.c
index 4e86057..7ef5d61 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -79,7 +79,15 @@ struct extended_symbol_info
#define SYM_STAB_DESC(sym) (sym->sinfo->stab_desc)
#define SYM_STAB_OTHER(sym) (sym->sinfo->stab_other)
#define SYM_SIZE(sym) \
- (sym->elfinfo ? sym->elfinfo->internal_elf_sym.st_size: sym->ssize)
+ (sym->elfinfo \
+ && sym->elfinfo->internal_elf_sym.st_size \
+ ? sym->elfinfo->internal_elf_sym.st_size \
+ : sym->coffinfo \
+ && ISFCN (sym->coffinfo->native->u.syment.n_type) \
+ && sym->coffinfo->native->u.syment.n_numaux \
+ && sym->coffinfo->native[1].u.auxent.x_sym.x_misc.x_fsize \
+ ? sym->coffinfo->native[1].u.auxent.x_sym.x_misc.x_fsize \
+ : sym->ssize)
/* The output formatting functions. */
static void print_object_filename_bsd (const char *);
@@ -1036,9 +1044,9 @@ size_forward2 (const void *P_x, const void *P_y)
return sorters[0][reverse_sort] (x->minisym, y->minisym);
}
-/* Sort the symbols by size. ELF provides a size but for other formats
- we have to make a guess by assuming that the difference between the
- address of a symbol and the address of the next higher symbol is the
+/* Sort the symbols by size. ELF and COFF may provide a size but for other
+ formats we have to make a guess by assuming that the difference between
+ the address of a symbol and the address of the next higher symbol is the
size. */
static long
@@ -1081,6 +1089,8 @@ sort_symbols_by_size (bfd *abfd, bool is_dynamic, void *minisyms,
asection *sec;
bfd_vma sz;
asymbol *temp;
+ const elf_symbol_type *elfsym;
+ const coff_symbol_type *coffsym;
if (from + size < fromend)
{
@@ -1100,8 +1110,15 @@ sort_symbols_by_size (bfd *abfd, bool is_dynamic, void *minisyms,
we can't rely on that information for the symbol size. Ditto for
bfd/section.c:global_syms like *ABS*. */
if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
- && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- sz = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ && (elfsym = elf_symbol_from (sym)) != NULL
+ && elfsym->internal_elf_sym.st_size != 0)
+ sz = elfsym->internal_elf_sym.st_size;
+ else if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
+ && (coffsym = coff_symbol_from (sym)) != NULL
+ && ISFCN (coffsym->native->u.syment.n_type)
+ && coffsym->native->u.syment.n_numaux != 0
+ && coffsym->native[1].u.auxent.x_sym.x_misc.x_fsize != 0)
+ sz = coffsym->native[1].u.auxent.x_sym.x_misc.x_fsize;
else if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
&& bfd_is_com_section (sec))
sz = sym->value;
diff --git a/binutils/testsuite/binutils-all/nm-coff-1.s b/binutils/testsuite/binutils-all/nm-coff-1.s
new file mode 100644
index 0000000..3efc10e
--- /dev/null
+++ b/binutils/testsuite/binutils-all/nm-coff-1.s
@@ -0,0 +1,26 @@
+ .globl text_symbol1
+ .globl text_symbol2
+ .globl text_symbol3
+ .macro ENDFN name:req
+ .def \name
+ .type 0x20 /* DT_FUNC */
+ .scl 2 /* C_EXT */
+ .endef
+ .def \name
+ .scl 0xff /* C_EFCN */
+ .val .
+ .endef
+ .endm
+ .text
+text_symbol1:
+ .long 0
+ .long 0
+ .long 0
+ ENDFN text_symbol1
+text_symbol2:
+ .long 0
+ .long 0
+ ENDFN text_symbol2
+text_symbol3:
+ .long 0
+ ENDFN text_symbol3
diff --git a/binutils/testsuite/binutils-all/nm-coff-sdef-1.s b/binutils/testsuite/binutils-all/nm-coff-sdef-1.s
new file mode 100644
index 0000000..f1a10bb
--- /dev/null
+++ b/binutils/testsuite/binutils-all/nm-coff-sdef-1.s
@@ -0,0 +1,26 @@
+ .globl text_symbol1
+ .globl text_symbol2
+ .globl text_symbol3
+ .macro ENDFN name:req
+ .sdef \name
+ .type 0x20 /* DT_FUNC */
+ .scl 2 /* C_EXT */
+ .endef
+ .sdef \name
+ .scl 0xff /* C_EFCN */
+ .val .
+ .endef
+ .endm
+ .text
+text_symbol1:
+ .byte 0,0,0,0
+ .byte 0,0,0,0
+ .byte 0,0,0,0
+ ENDFN text_symbol1
+text_symbol2:
+ .byte 0,0,0,0
+ .byte 0,0,0,0
+ ENDFN text_symbol2
+text_symbol3:
+ .byte 0,0,0,0
+ ENDFN text_symbol3
diff --git a/binutils/testsuite/binutils-all/nm.exp b/binutils/testsuite/binutils-all/nm.exp
index e1b2d16..b81126b 100644
--- a/binutils/testsuite/binutils-all/nm.exp
+++ b/binutils/testsuite/binutils-all/nm.exp
@@ -163,6 +163,12 @@ if { [is_elf_format]
|| [istarget wasm32-*-*]
|| [istarget bpf-*-*]} {
set nm_1_src "nm-elf-1.s"
+} elseif {[is_coff_format] && ![istarget arm*-*-*]} {
+ if {[istarget *c4x-*-*] || [istarget *c54x-*-*]} {
+ set nm_1_src "nm-coff-sdef-1.s"
+ } else {
+ set nm_1_src "nm-coff-1.s"
+ }
} else {
set nm_1_src "nm-1.s"
}
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
index 19759cd..eb5784e 100644
--- a/gas/config/obj-coff.c
+++ b/gas/config/obj-coff.c
@@ -1887,8 +1887,8 @@ static const pseudo_typeS coff_pseudo_table[] =
{"loc", obj_coff_loc, 0},
{"optim", s_ignore, 0}, /* For sun386i cc (?) */
{"weak", obj_coff_weak, 0},
-#if defined TC_TIC4X
- /* The tic4x uses sdef instead of def. */
+#if defined (TC_TIC4X) || defined (TC_TIC54X)
+ /* The tic4x and tic54x use sdef instead of def. */
{"sdef", obj_coff_def, 0},
#endif
#if defined(SEH_CMDS)
diff --git a/gdb/NEWS b/gdb/NEWS
index 6a557bb..99ec392 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -35,6 +35,11 @@
a -h or --help option, which prints each options and a brief
description.
+* On systems that support linkage namespaces, the output of the command
+ "info sharedlibraries" may add one more column, NS, which identifies the
+ namespace into which the library was loaded, if more than one namespace
+ is active.
+
* New commands
maintenance check psymtabs
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e034ac5..4e4509a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22172,6 +22172,11 @@ be determined then the address range for the @code{.text} section from
the library will be listed. If the @code{.text} section cannot be
found then no addresses will be listed.
+On systems that support linkage namespaces, the output includes an
+additional column @code{NS} if the inferior has more than one active
+namespace when the command is used. This column the linkage namespace
+that the shared library was loaded into.
+
@kindex info dll
@item info dll @var{regex}
This is an alias of @code{info sharedlibrary}.
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 398123f..2f839bd 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -405,11 +405,54 @@ struct svr4_info
The special entry zero is reserved for a linear list to support
gdbstubs that do not support namespaces. */
std::map<CORE_ADDR, std::vector<svr4_so>> solib_lists;
+
+ /* Mapping between r_debug[_ext] addresses and a user-friendly
+ identifier for the namespace. A vector is used to make it
+ easy to assign new internal IDs to namespaces.
+
+ For gdbservers that don't support namespaces, the first (and only)
+ entry of the vector will be 0.
+
+ A note on consistency. We can't make the IDs be consistent before
+ and after the initial relocation of the inferior (when the global
+ _r_debug is relocated, as mentioned in the previous comment). It is
+ likely that this is a non-issue, since the inferior can't have called
+ dlmopen yet, but I think it is worth noting.
+
+ The only issue I am aware at this point is that, if when parsing an
+ XML file, we read an LMID that given by an XML file (and read in
+ library_list_start_library) is the identifier obtained with dlinfo
+ instead of the address of r_debug[_ext], and after attaching the
+ inferior adds another SO to that namespace, we might double-count it
+ since we won't have access to the LMID later on. However, this is
+ already a problem with the existing solib_lists code. */
+ std::vector<CORE_ADDR> namespace_id;
+
+ /* This identifies which namespaces are active. A namespace is considered
+ active when there is at least one shared object loaded into it. */
+ std::set<size_t> active_namespaces;
};
/* Per-program-space data key. */
static const registry<program_space>::key<svr4_info> solib_svr4_pspace_data;
+/* Check if the lmid address is already assigned an ID in the svr4_info,
+ and if not, assign it one and add it to the list of known namespaces. */
+static void
+svr4_maybe_add_namespace (svr4_info *info, CORE_ADDR lmid)
+{
+ int i;
+ for (i = 0; i < info->namespace_id.size (); i++)
+ {
+ if (info->namespace_id[i] == lmid)
+ break;
+ }
+ if (i == info->namespace_id.size ())
+ info->namespace_id.push_back (lmid);
+
+ info->active_namespaces.insert (i);
+}
+
/* Return whether DEBUG_BASE is the default namespace of INFO. */
static bool
@@ -1041,14 +1084,18 @@ library_list_start_library (struct gdb_xml_parser *parser,
/* Older versions did not supply lmid. Put the element into the flat
list of the special namespace zero in that case. */
gdb_xml_value *at_lmid = xml_find_attribute (attributes, "lmid");
+ svr4_info *info = get_svr4_info (current_program_space);
if (at_lmid == nullptr)
- solist = list->cur_list;
+ {
+ solist = list->cur_list;
+ svr4_maybe_add_namespace (info, 0);
+ }
else
{
ULONGEST lmid = *(ULONGEST *) at_lmid->value.get ();
solist = &list->solib_lists[lmid];
+ svr4_maybe_add_namespace (info, lmid);
}
-
solist->emplace_back (name, std::move (li));
}
@@ -1286,6 +1333,8 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Remove any old libraries. We're going to read them back in again. */
info->solib_lists.clear ();
+ info->active_namespaces.clear ();
+
/* Fall back to manual examination of the target if the packet is not
supported or gdbserver failed to find DT_DEBUG. gdb.server/solib-list.exp
tests a case where gdbserver cannot find the shared libraries list while
@@ -1333,7 +1382,10 @@ svr4_current_sos_direct (struct svr4_info *info)
ignore_first = true;
auto cleanup = make_scope_exit ([info] ()
- { info->solib_lists.clear (); });
+ {
+ info->solib_lists.clear ();
+ info->active_namespaces.clear ();
+ });
/* Collect the sos in each namespace. */
CORE_ADDR debug_base = info->debug_base;
@@ -1343,8 +1395,11 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Walk the inferior's link map list, and build our so_list list. */
lm = solib_svr4_r_map (debug_base);
if (lm != 0)
- svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base],
- ignore_first);
+ {
+ svr4_maybe_add_namespace (info, debug_base);
+ svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base],
+ ignore_first);
+ }
}
/* On Solaris, the dynamic linker is not in the normal list of
@@ -1361,8 +1416,11 @@ svr4_current_sos_direct (struct svr4_info *info)
{
/* Add the dynamic linker's namespace unless we already did. */
if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
- svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base],
- 0);
+ {
+ svr4_maybe_add_namespace (info, debug_base);
+ svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base],
+ 0);
+ }
}
cleanup.release ();
@@ -1778,6 +1836,10 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
return 0;
prev_lm = 0;
+
+ /* If the list is empty, we are seeing a new namespace for the
+ first time, so assign it an internal ID. */
+ svr4_maybe_add_namespace (info, debug_base);
}
else
prev_lm = solist.back ().lm_info->lm_addr;
@@ -1845,6 +1907,8 @@ disable_probes_interface (svr4_info *info)
free_probes_table (info);
info->solib_lists.clear ();
+ info->namespace_id.clear ();
+ info->active_namespaces.clear ();
}
/* Update the solib list as appropriate when using the
@@ -3042,6 +3106,8 @@ svr4_solib_create_inferior_hook (int from_tty)
/* Clear the probes-based interface's state. */
free_probes_table (info);
info->solib_lists.clear ();
+ info->namespace_id.clear ();
+ info->active_namespaces.clear ();
/* Relocate the main executable if necessary. */
svr4_relocate_main_executable ();
@@ -3460,6 +3526,32 @@ svr4_find_solib_addr (solib &so)
return li->l_addr_inferior;
}
+/* See solib_ops::find_solib_ns in solist.h. */
+
+static int
+svr4_find_solib_ns (const solib &so)
+{
+ CORE_ADDR debug_base = find_debug_base_for_solib (&so);
+ svr4_info *info = get_svr4_info (current_program_space);
+ for (int i = 0; i < info->namespace_id.size (); i++)
+ {
+ if (info->namespace_id[i] == debug_base)
+ {
+ gdb_assert (info->active_namespaces.count (i) == 1);
+ return i;
+ }
+ }
+ error (_("No namespace found"));
+}
+
+/* see solib_ops::num_active_namespaces in solist.h. */
+static int
+svr4_num_active_namespaces ()
+{
+ svr4_info *info = get_svr4_info (current_program_space);
+ return info->active_namespaces.size ();
+}
+
const struct solib_ops svr4_so_ops =
{
svr4_relocate_section_addresses,
@@ -3475,6 +3567,8 @@ const struct solib_ops svr4_so_ops =
svr4_update_solib_event_breakpoints,
svr4_handle_solib_event,
svr4_find_solib_addr,
+ svr4_find_solib_ns,
+ svr4_num_active_namespaces,
};
void _initialize_svr4_solib ();
diff --git a/gdb/solib.c b/gdb/solib.c
index 1d26970..3ddd4f9 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1051,12 +1051,24 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
}
}
+ /* How many columns the table should have. If the inferior has
+ more than one namespace active, we need a column to show that. */
+ int num_cols = 4;
+ const solib_ops *ops = gdbarch_so_ops (gdbarch);
+ if (ops->num_active_namespaces != nullptr
+ && ops->num_active_namespaces () > 1)
+ num_cols++;
+
{
- ui_out_emit_table table_emitter (uiout, 4, nr_libs, "SharedLibraryTable");
+ ui_out_emit_table table_emitter (uiout, num_cols, nr_libs,
+ "SharedLibraryTable");
/* The "- 1" is because ui_out adds one space between columns. */
uiout->table_header (addr_width - 1, ui_left, "from", "From");
uiout->table_header (addr_width - 1, ui_left, "to", "To");
+ if (ops->num_active_namespaces != nullptr
+ && ops->num_active_namespaces () > 1)
+ uiout->table_header (5, ui_left, "namespace", "NS");
uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read");
uiout->table_header (0, ui_noalign, "name", "Shared Object Library");
@@ -1083,6 +1095,19 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
uiout->field_skip ("to");
}
+ if (ops->num_active_namespaces != nullptr
+ && ops->num_active_namespaces ()> 1)
+ {
+ try
+ {
+ uiout->field_fmt ("namespace", "[[%d]]", ops->find_solib_ns (so));
+ }
+ catch (const gdb_exception_error &er)
+ {
+ uiout->field_skip ("namespace");
+ }
+ }
+
if (!top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()
&& so.symbols_loaded && !objfile_has_symbols (so.objfile))
{
diff --git a/gdb/solist.h b/gdb/solist.h
index 9a157a4..03d2392 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -180,6 +180,20 @@ struct solib_ops
name). */
std::optional<CORE_ADDR> (*find_solib_addr) (solib &so);
+
+ /* Return which linker namespace contains the current so.
+ If the linker or libc does not support linkage namespaces at all
+ (which is basically all of them but solib-svr4), this function should
+ be set to nullptr, so that "info shared" won't add an unnecessary
+ column.
+
+ If the namespace can not be determined (such as when we're stepping
+ though the dynamic linker), this function should throw a
+ gdb_exception_error. */
+ int (*find_solib_ns) (const solib &so);
+
+ /* Returns the number of active namespaces in the inferior. */
+ int (*num_active_namespaces) ();
};
/* A unique pointer to a so_list. */
diff --git a/gdb/testsuite/gdb.base/attach-pie-noexec.exp b/gdb/testsuite/gdb.base/attach-pie-noexec.exp
index 4e6ede1..20c93b5 100644
--- a/gdb/testsuite/gdb.base/attach-pie-noexec.exp
+++ b/gdb/testsuite/gdb.base/attach-pie-noexec.exp
@@ -35,7 +35,7 @@ if ![runto_main] {
}
set test "sanity check info shared"
gdb_test_multiple "info shared" $test {
- -re "From\[ \t\]+To\[ \t\]+Syms Read\[ \t\]+Shared Object Library\r\n0x.*\r\n$gdb_prompt $" {
+ -re "From\[ \t\]+To(\\s+NS)?\[ \t\]+Syms Read\[ \t\]+Shared Object Library\r\n0x.*\r\n$gdb_prompt $" {
pass $test
}
-re "No shared libraries loaded at this time\\.\r\n$gdb_prompt $" {
@@ -62,6 +62,6 @@ if { ![gdb_attach $testpid] } {
return
}
gdb_test "set architecture $arch" "The target architecture is set to \"$arch\"\\."
-gdb_test "info shared" "From\[ \t\]+To\[ \t\]+Syms Read\[ \t\]+Shared Object Library\r\n0x.*"
+gdb_test "info shared" "From\[ \t\]+To(\\s+NS)?\[ \t\]+Syms Read\[ \t\]+Shared Object Library\r\n0x.*"
kill_wait_spawned_process $test_spawn_id
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c
new file mode 100644
index 0000000..86cbb0f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-lib.c
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+int gdb_dlmopen_glob = 0;
+
+__attribute__((visibility ("default")))
+int
+inc (int n)
+{
+ int amount = gdb_dlmopen_glob;
+ return n + amount; /* bp.inc. */
+}
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
new file mode 100644
index 0000000..3bcd819
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids-main.c
@@ -0,0 +1,54 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stddef.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+ void *handle[4];
+ int (*fun) (int);
+ Lmid_t lmid;
+ int dl;
+
+ handle[0] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
+ assert (handle[0] != NULL);
+
+ handle[1] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
+ assert (handle[1] != NULL);
+
+ handle[2] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
+ assert (handle[2] != NULL);
+
+ dlclose (handle[0]); /* TAG: first dlclose */
+ dlclose (handle[1]); /* TAG: second dlclose */
+ dlclose (handle[2]); /* TAG: third dlclose */
+
+ handle[3] = dlmopen (LM_ID_NEWLM, DSO_NAME, RTLD_LAZY | RTLD_LOCAL);
+ dlinfo (handle[3], RTLD_DI_LMID, &lmid);
+
+ dlclose (handle[3]); /* TAG: fourth dlclose */
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
new file mode 100644
index 0000000..03b7a52
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -0,0 +1,106 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+#
+#
+# Test several things related to handling linker namespaces:
+# * That the user-facing namespace ID is consistent;
+
+require allow_dlmopen_tests
+
+standard_testfile -main.c -lib.c
+
+set srcfile_lib $srcfile2
+set binfile_lib [standard_output_file dlmopen-lib.so]
+
+if { [build_executable "build shlib" $binfile_lib $srcfile_lib \
+ [list debug shlib]] == -1 } {
+ return
+}
+
+if { [build_executable "failed to build" $testfile $srcfile \
+ [list additional_flags=-DDSO_NAME=\"$binfile_lib\" \
+ shlib_load debug]] } {
+ return
+}
+
+# Run the command "info sharedlibrary" and get the first namespace
+# for the so
+proc get_first_so_ns {} {
+ set ns -1
+ gdb_test_multiple "info sharedlibrary" "get SO namespace" -lbl {
+ -re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" {
+ exp_continue
+ }
+ -re "^$::hex\\s+$::hex\\s+\\\[\\\[($::decimal)\\\]\\\]\\s+\[^\r\n]+$::binfile_lib.*" {
+ set ns $expect_out(1,string)
+ }
+ -re "^$::gdb_prompt $" {
+ }
+ -re "^\[^\r\n\]+\r\n" {
+ exp_continue
+ }
+ }
+ return $ns
+}
+
+# Run the tests relating to the command "info sharedlibrary", to
+# verify that the namespace ID is consistent.
+proc test_info_shared {} {
+ clean_restart $::binfile
+
+ if { ![runto_main] } {
+ return
+ }
+
+ # First test that we don't print a namespace column at the start.
+ gdb_test "info sharedlibrary" \
+ "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library.*" \
+ "before loading anything"
+
+ gdb_breakpoint [gdb_get_line_number "TAG: first dlclose"]
+ gdb_continue_to_breakpoint "TAG: first dlclose"
+
+ # Next, test that we *do* print a namespace column after loading SOs.
+ gdb_test "info sharedlibrary" \
+ "From\\s+To\\s+NS\\s+Syms\\s+Read\\s+Shared Object Library.*" \
+ "after loading everything"
+
+ gdb_assert {[get_first_so_ns] == 1} "before closing any library"
+
+ gdb_test "next" ".*second dlclose.*" "close first library"
+ gdb_assert {[get_first_so_ns] == 2} "after closing one library"
+
+ gdb_test "next" ".*third dlclose.*" "close second library"
+ gdb_assert {[get_first_so_ns] == 3} "before closing two libraries"
+
+ gdb_breakpoint [gdb_get_line_number "TAG: fourth dlclose"]
+ gdb_continue_to_breakpoint "TAG: fourth dlclose"
+ # As of writing this test, glibc's LMID is just an index on an array of
+ # namespaces. After closing a namespace, requesting a new one will
+ # return the index of the lowest-closed namespace, so this will likely
+ # be namespace 1, and because of glibc's reuse of the r_debug object,
+ # GDB should be able to assign the same number.
+ gdb_assert {[get_first_so_ns] == [get_integer_valueof "lmid" "-1"]} \
+ "reopen a namespace"
+
+ gdb_test "next" ".*return 0.*" "final namespace inactive"
+ gdb_test "info sharedlibrary" \
+ "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library.*" \
+ "after unloading everything"
+}
+
+test_info_shared
diff --git a/gdb/testsuite/gdb.base/dlmopen.exp b/gdb/testsuite/gdb.base/dlmopen.exp
index a8e3b08..084c5bc 100644
--- a/gdb/testsuite/gdb.base/dlmopen.exp
+++ b/gdb/testsuite/gdb.base/dlmopen.exp
@@ -106,7 +106,7 @@ proc check_dso_count { dso num } {
set count 0
gdb_test_multiple "info shared" "info shared" {
- -re "$hex $hex Yes \[^\r\n\]*$dso\r\n" {
+ -re "$hex $hex \(\[\[$::decimal\]\]\\s+\)\?Yes \[^\r\n\]*$dso\r\n" {
# use longer form so debug remote does not interfere
set count [expr $count + 1]
exp_continue
@@ -233,12 +233,12 @@ proc get_dyld_info {} {
set dyld_count 0
set dyld_start_addr ""
gdb_test_multiple "info sharedlibrary" "" {
- -re "From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library\r\n" {
+ -re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" {
exp_continue
}
- -re "^($::hex)\\s+$::hex\\s+\[^/\]+(/\[^\r\n\]+)\r\n" {
+ -re "^($::hex)\\s+$::hex\\s+\(\#$::decimal\\s+\)?\[^/\]+(/\[^\r\n\]+)\r\n" {
set addr $expect_out(1,string)
- set lib $expect_out(2,string)
+ set lib $expect_out(3,string)
if { [is_dyln $lib] } {
# This looks like it might be the dynamic linker.
diff --git a/gdb/testsuite/gdb.mi/mi-dlmopen.exp b/gdb/testsuite/gdb.mi/mi-dlmopen.exp
index a5743f8..c0208eb 100644
--- a/gdb/testsuite/gdb.mi/mi-dlmopen.exp
+++ b/gdb/testsuite/gdb.mi/mi-dlmopen.exp
@@ -81,12 +81,12 @@ proc get_dyld_info {} {
set dyld_count 0
set dyld_start_addr ""
gdb_test_multiple "info sharedlibrary" "" {
- -re "~\"From\\s+To\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" {
+ -re "~\"From\\s+To(\\s+NS)?\\s+Syms\\s+Read\\s+Shared Object Library\\\\n\"\r\n" {
exp_continue
}
- -re "^~\"($::hex)\\s+$::hex\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" {
+ -re "^~\"($::hex)\\s+${::hex}(\\s+$::decimal)?\\s+\[^/\]+(/\[^\r\n\]+)\\\\n\"\r\n" {
set addr $expect_out(1,string)
- set lib $expect_out(2,string)
+ set lib $expect_out(3,string)
if { [is_dyln $lib] } {
# This looks like it might be the dynamic linker.
diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc
index c08c9ae..96855f0 100644
--- a/gdbserver/regcache.cc
+++ b/gdbserver/regcache.cc
@@ -353,8 +353,7 @@ supply_register_by_name_zeroed (struct regcache *regcache,
#endif
/* Supply the whole register set whose contents are stored in BUF, to
- REGCACHE. If BUF is NULL, all the registers' values are recorded
- as unavailable. */
+ REGCACHE. */
void
supply_regblock (struct regcache *regcache, const void *buf)
diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc
index 9b40401..d399c33 100644
--- a/gprofng/src/DwarfLib.cc
+++ b/gprofng/src/DwarfLib.cc
@@ -204,12 +204,6 @@ ElfReloc::dump_rela_debug_sec (int sec)
if (ScnSize == 0 || EntSize == 0)
return;
- Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
- if (shdr_sym == NULL)
- return;
- Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);
- Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
- char *Strtab = data_str ? (char*) data_str->d_buf : NULL;
Elf_Internal_Rela rela;
int n, cnt = (int) (ScnSize / EntSize);
@@ -233,7 +227,8 @@ ElfReloc::dump_rela_debug_sec (int sec)
int ndx = (int) GELF_R_SYM (rela.r_info);
Elf_Internal_Shdr *secHdr;
Elf_Internal_Sym sym;
- elf->elf_getsym (data_sym, ndx, &sym);
+ asymbol *asym;
+ asym = elf->elf_getsym (ndx, &sym, false);
Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
n, (int) rela.r_addend,
(long long) rela.r_offset, (long long) rela.r_info,
@@ -243,12 +238,9 @@ ElfReloc::dump_rela_debug_sec (int sec)
case STT_FUNC:
case STT_OBJECT:
case STT_NOTYPE:
- secHdr = elf->get_shdr (sym.st_shndx);
- if (secHdr)
- Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
- (long long) (sym.st_value + secHdr->sh_offset));
- if (Strtab && sym.st_name)
- Dprintf (DUMP_RELA_SEC, NTXT (" %s"), Strtab + sym.st_name);
+ Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
+ (long long) (bfd_asymbol_value (asym)));
+ Dprintf (DUMP_RELA_SEC, NTXT (" %s"), bfd_asymbol_name (asym));
break;
case STT_SECTION:
secHdr = elf->get_shdr (sym.st_shndx);
@@ -311,10 +303,6 @@ ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
return rlc;
int cnt = (int) (data->d_size / shdr->sh_entsize);
- Elf_Internal_Shdr *shdr_sym = elfp->get_shdr (shdr->sh_link);
- if (shdr_sym == NULL)
- return rlc;
- Elf_Data *data_sym = elfp->elf_getdata (shdr->sh_link);
Vector<Sreloc *> *vp = NULL;
for (int n = 0; n < cnt; n++)
@@ -331,7 +319,7 @@ ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
}
int ndx = (int) GELF_R_SYM (rela.r_info);
Elf_Internal_Sym sym;
- elfp->elf_getsym (data_sym, ndx, &sym);
+ elfp->elf_getsym (ndx, &sym, false);
srlc = new Sreloc;
srlc->offset = rela.r_offset;
diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc
index b9da240..f0fd121 100644
--- a/gprofng/src/Elf.cc
+++ b/gprofng/src/Elf.cc
@@ -533,42 +533,43 @@ Elf::elf_strptr (unsigned int sec, uint64_t off)
return NULL;
}
-Elf_Internal_Sym *
-Elf::elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst)
+long
+Elf::elf_getSymCount (bool is_dynamic)
{
- if (dst == NULL || edta == NULL)
- return NULL;
- if (elf_getclass () == ELFCLASS32)
- {
- if (edta->d_size <= ndx * sizeof (Elf32_Sym))
- return NULL;
- Elf32_Sym *hdr = (Elf32_Sym*) bind (edta->d_off + ndx * sizeof (Elf32_Sym), sizeof (Elf32_Sym));
- if (hdr == NULL)
- return NULL;
- dst->st_name = decode (hdr->st_name);
- dst->st_value = decode (hdr->st_value);
- dst->st_size = decode (hdr->st_size);
- dst->st_info = ELF64_ST_INFO (ELF32_ST_BIND (decode (hdr->st_info)),
- ELF32_ST_TYPE (decode (hdr->st_info)));
- dst->st_other = decode (hdr->st_other);
- dst->st_shndx = decode (hdr->st_shndx);
- }
+ if (bfd_dynsym == NULL && bfd_sym == NULL)
+ get_bfd_symbols ();
+ if (is_dynamic)
+ return bfd_dynsymcnt;
+ return bfd_symcnt;
+}
+
+/* Returns an ASYMBOL on index NDX if it exists. If DST is defined,
+ the internal elf symbol at intex NDX is copied into it. IS_DYNAMIC
+ selects the type of the symbol. */
+
+asymbol *
+Elf::elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic)
+{
+ asymbol *asym;
+
+ if (bfd_dynsym == NULL && bfd_sym == NULL)
+ get_bfd_symbols ();
+
+ if (is_dynamic)
+ if (ndx < bfd_dynsymcnt)
+ asym = bfd_dynsym[ndx];
+ else
+ return NULL;
else
- {
- if (edta->d_size <= ndx * sizeof (Elf64_Sym))
- return NULL;
- Elf64_Sym *hdr = (Elf64_Sym*) bind (edta->d_off + ndx * sizeof (Elf64_Sym),
- sizeof (Elf64_Sym));
- if (hdr == NULL)
- return NULL;
- dst->st_name = decode (hdr->st_name);
- dst->st_value = decode (hdr->st_value);
- dst->st_size = decode (hdr->st_size);
- dst->st_info = decode (hdr->st_info);
- dst->st_other = decode (hdr->st_other);
- dst->st_shndx = decode (hdr->st_shndx);
- }
- return dst;
+ if (ndx < bfd_symcnt)
+ asym = bfd_sym[ndx];
+ else
+ return NULL;
+
+ if (dst != NULL)
+ *dst = ((elf_symbol_type *) asym)->internal_elf_sym;
+
+ return asym;
}
Elf_Internal_Rela *
diff --git a/gprofng/src/Elf.h b/gprofng/src/Elf.h
index 7c32dfe..b324c39 100644
--- a/gprofng/src/Elf.h
+++ b/gprofng/src/Elf.h
@@ -92,7 +92,8 @@ public:
int64_t elf_checksum ();
uint64_t get_baseAddr();
char *elf_strptr (unsigned int sec, uint64_t off);
- Elf_Internal_Sym *elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst);
+ long elf_getSymCount (bool is_dynamic);
+ asymbol *elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic);
Elf_Internal_Rela *elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
Elf_Internal_Rela *elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
Elf64_Ancillary *elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst);
diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc
index 2120319..b98ac28 100644
--- a/gprofng/src/Stabs.cc
+++ b/gprofng/src/Stabs.cc
@@ -241,6 +241,40 @@ RelValueCmp (const void *a, const void *b)
(item1->value == item2->value) ? 0 : -1;
}
+/* Remove all duplicate symbols which can be in SymLst. The
+ duplication is due to processing of both static and dynamic
+ symbols. This function is called before computing symbol
+ aliases. */
+
+void
+Stabs::removeDupSyms ()
+{
+ long ind, i, last;
+ Symbol *symA, *symB;
+ SymLst->sort (SymImgOffsetCmp);
+ dump ();
+
+ last = 0;
+ ind = SymLst->size ();
+ for (i = 0; i < ind; i++)
+ {
+ symA = SymLst->fetch (i);
+ if (symA->img_offset == 0) // Ignore this bad symbol
+ continue;
+
+ SymLst->put (last++, symA);
+ for (long k = i + 1; k < ind; k++, i++)
+ {
+ symB = SymLst->fetch (k);
+ if (symA->img_offset != symB->img_offset)
+ break;
+ if (strcmp (symA->name, symB->name) != 0)
+ break;
+ }
+ }
+ SymLst->truncate (last);
+}
+
Stabs *
Stabs::NewStabs (char *_path, char *lo_name)
{
@@ -272,7 +306,7 @@ Stabs::Stabs (char *_path, char *_lo_name)
stabsModules = NULL;
textsz = 0;
wsize = Wnone;
- st_check_symtab = st_check_relocs = false;
+ st_check_symtab = false;
status = DBGD_ERR_NONE;
if (openElf (false) == NULL)
@@ -412,7 +446,6 @@ Stabs::read_symbols (Vector<Function*> *functions)
if (openElf (true) == NULL)
return false;
check_Symtab ();
- check_Relocs ();
if (functions)
{
Function *fp;
@@ -1703,43 +1736,31 @@ Stabs::check_Symtab ()
pltSym->flags |= SYM_PLT;
}
}
- if (elf->symtab)
- readSymSec (elf->symtab, elf);
- else
- {
- readSymSec (elf->SUNW_ldynsym, elf);
- readSymSec (elf->dynsym, elf);
- }
+
+ // Read first static symbols
+ readSymSec (elf, false);
+
+ // Read dynamic symbols
+ readSymSec (elf, true);
}
void
-Stabs::readSymSec (unsigned int sec, Elf *elf)
+Stabs::readSymSec (Elf *elf, bool is_dynamic)
{
Symbol *sitem;
Sp_lang_code local_lcode;
- if (sec == 0)
- return;
- // Get ELF data
- Elf_Data *data = elf->elf_getdata (sec);
- if (data == NULL)
- return;
- uint64_t SymtabSize = data->d_size;
- Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
-
- if ((SymtabSize == 0) || (shdr->sh_entsize == 0))
- return;
- Elf_Data *data_str = elf->elf_getdata (shdr->sh_link);
- if (data_str == NULL)
- return;
- char *Strtab = (char *) data_str->d_buf;
+ unsigned int tot = elf->elf_getSymCount (is_dynamic);
// read func symbolic table
- for (unsigned int n = 0, tot = SymtabSize / shdr->sh_entsize; n < tot; n++)
+ for (unsigned int n = 0; n < tot; n++)
{
Elf_Internal_Sym Sym;
- elf->elf_getsym (data, n, &Sym);
- const char *st_name = Sym.st_name < data_str->d_size ?
- (Strtab + Sym.st_name) : NTXT ("no_name");
+ asymbol *asym;
+ asym = elf->elf_getsym (n, &Sym, is_dynamic);
+ // TBD: convert this check to an assert
+ if (asym == NULL)
+ break;
+ const char *st_name = bfd_asymbol_name (asym);
switch (GELF_ST_TYPE (Sym.st_info))
{
case STT_FUNC:
@@ -1814,6 +1835,7 @@ Stabs::readSymSec (unsigned int sec, Elf *elf)
}
}
}
+ removeDupSyms ();
fixSymtabAlias ();
SymLst->sort (SymValueCmp);
get_save_addr (elf->need_swap_endian);
@@ -1821,142 +1843,6 @@ Stabs::readSymSec (unsigned int sec, Elf *elf)
}//check_Symtab
void
-Stabs::check_Relocs ()
-{
- // We may have many relocation tables to process: .rela.text%foo,
- // rela.text%bar, etc. On Intel, compilers generate .rel.text sections
- // which have to be processed as well. A lot of rework is needed here.
- Symbol *sptr = NULL;
- if (st_check_relocs)
- return;
- st_check_relocs = true;
-
- Elf *elf = openElf (false);
- if (elf == NULL)
- return;
- for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++)
- {
- bool use_rela, use_PLT;
- char *name = elf->get_sec_name (sec);
- if (name == NULL)
- continue;
- if (strncmp (name, NTXT (".rela.text"), 10) == 0)
- {
- use_rela = true;
- use_PLT = false;
- }
- else if (streq (name, NTXT (".rela.plt")))
- {
- use_rela = true;
- use_PLT = true;
- }
- else if (strncmp (name, NTXT (".rel.text"), 9) == 0)
- {
- use_rela = false;
- use_PLT = false;
- }
- else if (streq (name, NTXT (".rel.plt")))
- {
- use_rela = false;
- use_PLT = true;
- }
- else
- continue;
-
- Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
- if (shdr == NULL)
- continue;
-
- // Get ELF data
- Elf_Data *data = elf->elf_getdata (sec);
- if (data == NULL)
- continue;
- uint64_t ScnSize = data->d_size;
- uint64_t EntSize = shdr->sh_entsize;
- if ((ScnSize == 0) || (EntSize == 0))
- continue;
- int tot = (int) (ScnSize / EntSize);
-
- // Get corresponding text section
- Elf_Internal_Shdr *shdr_txt = elf->get_shdr (shdr->sh_info);
- if (shdr_txt == NULL)
- continue;
- if (!(shdr_txt->sh_flags & SHF_EXECINSTR))
- continue;
-
- // Get corresponding symbol table section
- Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link);
- if (shdr_sym == NULL)
- continue;
- Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link);
-
- // Get corresponding string table section
- Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link);
- if (data_str == NULL)
- continue;
- char *Strtab = (char*) data_str->d_buf;
- for (int n = 0; n < tot; n++)
- {
- Elf_Internal_Sym sym;
- Elf_Internal_Rela rela;
- char *symName;
- if (use_rela)
- elf->elf_getrela (data, n, &rela);
- else
- {
- // GElf_Rela is extended GElf_Rel
- elf->elf_getrel (data, n, &rela);
- rela.r_addend = 0;
- }
-
- int ndx = (int) GELF_R_SYM (rela.r_info);
- elf->elf_getsym (data_sym, ndx, &sym);
- switch (GELF_ST_TYPE (sym.st_info))
- {
- case STT_FUNC:
- case STT_OBJECT:
- case STT_NOTYPE:
- if (sym.st_name == 0 || sym.st_name >= data_str->d_size)
- continue;
- symName = Strtab + sym.st_name;
- break;
- case STT_SECTION:
- {
- Elf_Internal_Shdr *secHdr = elf->get_shdr (sym.st_shndx);
- if (secHdr == NULL)
- continue;
- if (sptr == NULL)
- sptr = new Symbol;
- sptr->value = secHdr->sh_offset + rela.r_addend;
- long index = SymLst->bisearch (0, -1, &sptr, SymFindCmp);
- if (index == -1)
- continue;
- Symbol *sp = SymLst->fetch (index);
- if (sptr->value != sp->value)
- continue;
- symName = sp->name;
- break;
- }
- default:
- continue;
- }
- Reloc *reloc = new Reloc;
- reloc->name = dbe_strdup (symName);
- reloc->type = GELF_R_TYPE (rela.r_info);
- reloc->value = use_PLT ? rela.r_offset
- : rela.r_offset + shdr_txt->sh_offset;
- reloc->addend = rela.r_addend;
- if (use_PLT)
- RelPLTLst->append (reloc);
- else
- RelLst->append (reloc);
- }
- }
- delete sptr;
- RelLst->sort (RelValueCmp);
-} //check_Relocs
-
-void
Stabs::get_save_addr (bool need_swap_endian)
{
if (elfDis->is_Intel ())
diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h
index 42aa6fb..d34741f 100644
--- a/gprofng/src/Stabs.h
+++ b/gprofng/src/Stabs.h
@@ -129,8 +129,7 @@ class Stabs {
// Interface with Elf Symbol Table
void check_Symtab();
- void readSymSec(unsigned int sec, Elf *elf);
- void check_Relocs();
+ void readSymSec (Elf *elf, bool is_dynamic);
void get_save_addr(bool need_swap_endian);
Symbol *map_PC_to_sym(uint64_t pc);
Symbol *pltSym;
@@ -146,9 +145,10 @@ class Stabs {
Map<const char*, Symbol*> *get_elf_symbols();
Dwarf *dwarf;
- bool st_check_symtab, st_check_relocs;
+ bool st_check_symtab;
Function *createFunction(LoadObject *lo, Module *module, Symbol *sym);
void fixSymtabAlias();
+ void removeDupSyms ();
// Interface with dwarf
Dwarf *openDwarf();
diff --git a/gprofng/src/vec.h b/gprofng/src/vec.h
index 04cce4e..a768a02 100644
--- a/gprofng/src/vec.h
+++ b/gprofng/src/vec.h
@@ -112,6 +112,13 @@ public:
return data[index];
}
+ void
+ truncate (long ncount)
+ {
+ if (count > ncount && ncount >= 0)
+ count = ncount;
+ }
+
// Return the first index in "this" that equals "item".
// Return -1 if "item" is not found.
long find (const ITEM item);
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index de1cfaf..4a2ea03 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -2639,9 +2639,9 @@ make_import_fixup_mark (arelent *rel, char *name)
memcpy (fixup_name, buf, prefix_len);
bh = NULL;
- bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL,
- current_sec, /* sym->section, */
- rel->address, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL,
+ current_sec, /* sym->section, */
+ rel->address, NULL, true, false, &bh);
return bh->root.string;
}