aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorIain Sandoe <iain@codesourcery.com>2012-01-12 14:03:12 +0000
committerIain Sandoe <iain@codesourcery.com>2012-01-12 14:03:12 +0000
commit50d10658eef31d1c68763d556f02954b9c7c4f00 (patch)
treedcb4c7afc7cee5e547676de8c5069101eb4ddcf1 /bfd
parent0a4734dc09362b45ad88c4092fe2531d27b8d1d1 (diff)
downloadgdb-50d10658eef31d1c68763d556f02954b9c7c4f00.zip
gdb-50d10658eef31d1c68763d556f02954b9c7c4f00.tar.gz
gdb-50d10658eef31d1c68763d556f02954b9c7c4f00.tar.bz2
add indirect_symbol to mach-o port.
bfd: * mach-o.c (bfd_mach_o_count_indirect_symbols): New. (bfd_mach_o_build_dysymtab_command): Populate indirect symbol table. * mach-o.h (bfd_mach_o_asymbol): Move declaration to start of the file. (bfd_mach_o_section): Add indirect_syms field. gas: * config/obj-macho.c (obj_mach_o_set_symbol_qualifier): Switch off lazy when the symbol is private_extern. (obj_mach_o_indirect_sym): New type. (obj_mach_o_indirect_symbol): New. (mach_o_pseudo_table): Use obj_mach_o_indirect_symbol. (obj_macho_frob_label): Adjust to avoid adding bsyms for locals. (obj_macho_frob_label): Likewise. Adjust external and comm symbol tests. (obj_mach_o_set_indirect_symbols): New. (obj_mach_o_frob_file_after_relocs): New. *config/obj-macho.h (obj_frob_file_after_relocs): Define. (obj_mach_o_frob_file_after_relocs): Declare. include/mach-o: * loader.h (BFD_MACH_O_INDIRECT_SYM_LOCAL): New. (BFD_MACH_O_INDIRECT_SYM_ABS): New gas/testsuite: * gas/mach-o/dysymtab-2.d: New. * gas/mach-o/err-syms-4.s: New. * gas/mach-o/err-syms-5.s: New. * gas/mach-o/err-syms-6.s: New. * gas/mach-o/symbols-6-64.d: New. * gas/mach-o/symbols-6-64.s: New. * gas/mach-o/symbols-6.d: New. * gas/mach-o/symbols-6.s: New.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/mach-o.c64
-rw-r--r--bfd/mach-o.h34
3 files changed, 86 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 55ccf7e..7e36b6d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2012-01-12 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_count_indirect_symbols): New.
+ (bfd_mach_o_build_dysymtab_command): Populate indirect symbol table.
+ * mach-o.h (bfd_mach_o_asymbol): Move declaration to start of the
+ file. (bfd_mach_o_section): Add indirect_syms field.
+
2012-01-11 Iain Sandoe <idsandoe@googlemail.com>
* mach-o.c (bfd_mach_o_build_seg_command): Separate computation of
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 6913b1d..c519663 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -2079,6 +2079,33 @@ bfd_mach_o_build_seg_command (const char *segment,
return TRUE;
}
+/* Count the number of indirect symbols in the image.
+ Requires that the sections are in their final order. */
+
+static unsigned int
+bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
+{
+ unsigned int i;
+ unsigned int nisyms = 0;
+
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ bfd_mach_o_section *sec = mdata->sections[i];
+
+ switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ {
+ case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_SYMBOL_STUBS:
+ nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+ break;
+ default:
+ break;
+ }
+ }
+ return nisyms;
+}
+
static bfd_boolean
bfd_mach_o_build_dysymtab_command (bfd *abfd,
bfd_mach_o_data_struct *mdata,
@@ -2135,9 +2162,11 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
dsym->nundefsym = 0;
}
+ dsym->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
if (dsym->nindirectsyms > 0)
{
unsigned i;
+ unsigned n;
mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
dsym->indirectsymoff = mdata->filelen;
@@ -2146,11 +2175,38 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
if (dsym->indirect_syms == NULL)
return FALSE;
-
- /* So fill in the indices. */
- for (i = 0; i < dsym->nindirectsyms; ++i)
+
+ n = 0;
+ for (i = 0; i < mdata->nsects; ++i)
{
- /* TODO: fill in the table. */
+ bfd_mach_o_section *sec = mdata->sections[i];
+
+ switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ {
+ case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_SYMBOL_STUBS:
+ {
+ unsigned j, num;
+ bfd_mach_o_asymbol **isyms = sec->indirect_syms;
+
+ num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+ if (isyms == NULL || num == 0)
+ break;
+ /* Record the starting index in the reserved1 field. */
+ sec->reserved1 = n;
+ for (j = 0; j < num; j++, n++)
+ {
+ if (isyms[j] == NULL)
+ dsym->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
+ else
+ dsym->indirect_syms[n] = isyms[j]->symbol.udata.i;
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
}
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
index ca810a0..7f54961 100644
--- a/bfd/mach-o.h
+++ b/bfd/mach-o.h
@@ -42,6 +42,18 @@ typedef struct bfd_mach_o_header
}
bfd_mach_o_header;
+typedef struct bfd_mach_o_asymbol
+{
+ /* The actual symbol which the rest of BFD works with. */
+ asymbol symbol;
+
+ /* Mach-O symbol fields. */
+ unsigned char n_type;
+ unsigned char n_sect;
+ unsigned short n_desc;
+}
+bfd_mach_o_asymbol;
+
#define BFD_MACH_O_SEGNAME_SIZE 16
#define BFD_MACH_O_SECTNAME_SIZE 16
@@ -64,6 +76,12 @@ typedef struct bfd_mach_o_section
/* Corresponding bfd section. */
asection *bfdsection;
+ /* An array holding the indirect symbols for this section.
+ NULL values indicate local symbols.
+ The number of symbols is determined from the section size and type. */
+
+ bfd_mach_o_asymbol **indirect_syms;
+
/* Simply linked list. */
struct bfd_mach_o_section *next;
}
@@ -105,26 +123,12 @@ typedef struct bfd_mach_o_reloc_info
}
bfd_mach_o_reloc_info;
-typedef struct bfd_mach_o_asymbol
-{
- /* The actual symbol which the rest of BFD works with. */
- asymbol symbol;
-
- /* Mach-O symbol fields. */
- unsigned char n_type;
- unsigned char n_sect;
- unsigned short n_desc;
-}
-bfd_mach_o_asymbol;
-
/* The symbol table is sorted like this:
(1) local.
(otherwise in order of generation)
(2) external defined
(sorted by name)
- (3) external undefined
- (sorted by name)
- (4) common
+ (3) external undefined / common
(sorted by name)
*/