LINK6 format bug fixes
Nick Clifton
nickc@cygnus.com
Mon Mar 6 11:49:00 GMT 2000
Hi Guys,
I am checking in the patch below to fix several bugs that have been
discovered in the LINK6 support code that I added to BFD recently.
Cheers
Nick
2000-03-06 Nick Clifton <nickc@cygnus.com>
* peicode.h (struct pe_ILF_vars): Add sym_ptr_table and
sym_ptr_ptr fields.
(SIZEOF_ILF_SYM_PTR_TABLE): Define.
(SIZEOF_ILF_STRINGS): Redefine.
(pe_ILF_make_a_symbol-reloc): New function. Creates a symbol
relative reloc, as opposed to a section relative reloc.
(pe_ILF_make_a_symbol): Set the class of local symbols to C_STAT
not C_LABEL.
Add length of symbol's prefix to string pointer.
Store a pointer to the symbol in the symbol pointer table.
(pe_ILF_build_a_bfd): Do not build .idata$2 or .idata$7.
Initialise the symbol pointer table.
Store the hint in the Hint/Name table.
Make the jump reloc be symbol realtive, not section relative.
Create an import symbol for imported code.
Index: bfd/peicode.h
===================================================================
RCS file: /cvs/src//src/bfd/peicode.h,v
retrieving revision 1.18
diff -p -w -r1.18 peicode.h
*** peicode.h 2000/03/01 20:39:07 1.18
--- peicode.h 2000/03/06 19:46:47
*************** typedef struct
*** 118,123 ****
--- 118,126 ----
combined_entry_type * native_syms;
combined_entry_type * native_ptr;
+ coff_symbol_type ** sym_ptr_table;
+ coff_symbol_type ** sym_ptr_ptr;
+
unsigned int sec_index;
char * string_table;
*************** static asection_ptr pe_ILF_make_a_
*** 135,140 ****
--- 138,144 ----
static void pe_ILF_make_a_reloc PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, asection_ptr));
static void pe_ILF_make_a_symbol PARAMS ((pe_ILF_vars *, const char *, const char *, asection_ptr, flagword));
static void pe_ILF_save_relocs PARAMS ((pe_ILF_vars *, asection_ptr));
+ static void pe_ILF_make_a_symbol_reloc PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, struct symbol_cache_entry **, unsigned int));
static boolean pe_ILF_build_a_bfd PARAMS ((bfd *, unsigned short, bfd_byte *, bfd_byte *, unsigned int, unsigned int));
static const bfd_target * pe_ILF_object_p PARAMS ((bfd *));
static const bfd_target * pe_bfd_object_p PARAMS ((bfd *));
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 431,441 ****
The value for SIZEOF_ILF_STRINGS is computed as follows:
There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters
! per symbol for their names (longest section name is .idata$2).
There will be two symbols for the imported value, one the symbol name
and one with _imp__ prefixed. Allowing for the terminating nul's this
! is strlen (symbol_name) * 2 + 8.
The strings in the string table must start STRING__SIZE_SIZE bytes into
the table in order to for the string lookup code in coffgen/coffcode to
--- 435,445 ----
The value for SIZEOF_ILF_STRINGS is computed as follows:
There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters
! per symbol for their names (longest section name is .idata$x).
There will be two symbols for the imported value, one the symbol name
and one with _imp__ prefixed. Allowing for the terminating nul's this
! is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
The strings in the string table must start STRING__SIZE_SIZE bytes into
the table in order to for the string lookup code in coffgen/coffcode to
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 447,456 ****
#define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
#define SIZEOF_ILF_SYM_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_table))
#define SIZEOF_ILF_NATIVE_SYMS (NUM_ILF_SYMS * sizeof (* vars.native_syms))
#define SIZEOF_ILF_EXT_SYMS (NUM_ILF_SYMS * sizeof (* vars.esym_table))
#define SIZEOF_ILF_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.reltab))
#define SIZEOF_ILF_INT_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
! #define SIZEOF_ILF_STRINGS (strlen (symbol_name) * 2 + 8 + NUM_ILF_SECTIONS * 9 + STRING_SIZE_SIZE)
#define SIZEOF_IDATA2 (5 * 4)
#define SIZEOF_IDATA4 (1 * 4)
#define SIZEOF_IDATA5 (1 * 4)
--- 451,464 ----
#define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
#define SIZEOF_ILF_SYM_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_table))
#define SIZEOF_ILF_NATIVE_SYMS (NUM_ILF_SYMS * sizeof (* vars.native_syms))
+ #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
#define SIZEOF_ILF_EXT_SYMS (NUM_ILF_SYMS * sizeof (* vars.esym_table))
#define SIZEOF_ILF_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.reltab))
#define SIZEOF_ILF_INT_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
! #define SIZEOF_ILF_STRINGS (strlen (symbol_name) * 2 + 8 \
! + 21 + strlen (source_dll) \
! + NUM_ILF_SECTIONS * 9 \
! + STRING_SIZE_SIZE)
#define SIZEOF_IDATA2 (5 * 4)
#define SIZEOF_IDATA4 (1 * 4)
#define SIZEOF_IDATA5 (1 * 4)
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 463,468 ****
--- 471,477 ----
+ SIZEOF_ILF_SYMS \
+ SIZEOF_ILF_SYM_TABLE \
+ SIZEOF_ILF_NATIVE_SYMS \
+ + SIZEOF_ILF_SYM_PTR_TABLE \
+ SIZEOF_ILF_EXT_SYMS \
+ SIZEOF_ILF_RELOCS \
+ SIZEOF_ILF_INT_RELOCS \
*************** pe_bfd_copy_private_bfd_data (ibfd, obfd
*** 478,487 ****
/* Create an empty relocation against the given symbol. */
static void
! pe_ILF_make_a_reloc (pe_ILF_vars * vars,
bfd_vma address,
bfd_reloc_code_real_type reloc,
! asection_ptr sec)
{
arelent * entry;
struct internal_reloc * internal;
--- 487,497 ----
/* Create an empty relocation against the given symbol. */
static void
! pe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars,
bfd_vma address,
bfd_reloc_code_real_type reloc,
! struct symbol_cache_entry ** sym,
! unsigned int sym_index)
{
arelent * entry;
struct internal_reloc * internal;
*************** pe_ILF_make_a_reloc (pe_ILF_vars *
*** 492,501 ****
entry->address = address;
entry->addend = 0;
entry->howto = bfd_reloc_type_lookup (vars->abfd, reloc);
! entry->sym_ptr_ptr = sec->symbol_ptr_ptr;
internal->r_vaddr = address;
! internal->r_symndx = coff_section_data (vars->abfd, sec)->i;
internal->r_type = entry->howto->type;
#if 0 /* These fields do not need to be initialised. */
internal->r_size = 0;
--- 502,511 ----
entry->address = address;
entry->addend = 0;
entry->howto = bfd_reloc_type_lookup (vars->abfd, reloc);
! entry->sym_ptr_ptr = sym;
internal->r_vaddr = address;
! internal->r_symndx = sym_index;
internal->r_type = entry->howto->type;
#if 0 /* These fields do not need to be initialised. */
internal->r_size = 0;
*************** pe_ILF_make_a_reloc (pe_ILF_vars *
*** 508,513 ****
--- 518,534 ----
BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
}
+ /* Create an empty relocation against the given section. */
+ static void
+ pe_ILF_make_a_reloc (pe_ILF_vars * vars,
+ bfd_vma address,
+ bfd_reloc_code_real_type reloc,
+ asection_ptr sec)
+ {
+ pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
+ coff_section_data (vars->abfd, sec)->i);
+ }
+
/* Move the queued relocs into the given section. */
static void
pe_ILF_save_relocs (pe_ILF_vars * vars,
*************** pe_ILF_make_a_symbol (pe_ILF_vars * var
*** 546,552 ****
unsigned short sclass;
if (extra_flags & BSF_LOCAL)
! sclass = C_LABEL;
else
sclass = C_EXT;
--- 567,573 ----
unsigned short sclass;
if (extra_flags & BSF_LOCAL)
! sclass = C_STAT;
else
sclass = C_EXT;
*************** pe_ILF_make_a_symbol (pe_ILF_vars * var
*** 556,562 ****
if (extra_flags & BSF_FUNCTION)
sclass = C_THUMBEXTFUNC;
else if (extra_flags & BSF_LOCAL)
! sclass = C_THUMBLABEL;
else
sclass = C_THUMBEXT;
}
--- 577,583 ----
if (extra_flags & BSF_FUNCTION)
sclass = C_THUMBEXTFUNC;
else if (extra_flags & BSF_LOCAL)
! sclass = C_THUMBSTAT;
else
sclass = C_THUMBEXT;
}
*************** pe_ILF_make_a_symbol (pe_ILF_vars * var
*** 573,579 ****
--- 594,604 ----
/* Initialise the external symbol. */
bfd_h_put_32 (vars->abfd, vars->string_ptr - vars->string_table, (bfd_byte *) esym->e.e.e_offset);
+ if (section)
bfd_h_put_16 (vars->abfd, section->target_index, (bfd_byte *) esym->e_scnum);
+ else
+ bfd_h_put_16 (vars->abfd, 0, (bfd_byte *) esym->e_scnum);
+
esym->e_sclass[0] = sclass;
/* The following initialisations are unnecessary - the memory is
*************** pe_ILF_make_a_symbol (pe_ILF_vars * var
*** 587,592 ****
--- 612,618 ----
/* Initialise the internal symbol structure. */
ent->u.syment.n_sclass = sclass;
+ if (section)
ent->u.syment.n_scnum = section->target_index;
ent->u.syment._n._n_n._n_offset = (long) sym;
*************** pe_ILF_make_a_symbol (pe_ILF_vars * var
*** 612,625 ****
#endif
* vars->table_ptr = vars->sym_index;
/* Adjust pointers for the next symbol. */
vars->sym_index ++;
vars->sym_ptr ++;
vars->table_ptr ++;
vars->native_ptr ++;
vars->esym_ptr ++;
! vars->string_ptr += strlen (symbol_name) + 1;
BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
}
--- 638,653 ----
#endif
* vars->table_ptr = vars->sym_index;
+ * vars->sym_ptr_ptr = sym;
/* Adjust pointers for the next symbol. */
vars->sym_index ++;
vars->sym_ptr ++;
+ vars->sym_ptr_ptr ++;
vars->table_ptr ++;
vars->native_ptr ++;
vars->esym_ptr ++;
! vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
}
*************** pe_ILF_make_a_section (pe_ILF_vars * var
*** 672,678 ****
/* Create a symbol to refer to this section. */
pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
! /* Cache the index to the symbol in the coff_section_data structire. */
coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
return sec;
--- 700,706 ----
/* Create a symbol to refer to this section. */
pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
! /* Cache the index to the symbol in the coff_section_data structure. */
coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
return sec;
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 761,770 ****
struct internal_filehdr internal_f;
unsigned int import_type;
unsigned int import_name_type;
! asection_ptr id2, id4, id5, id6 = NULL, id7, text;
- text = NULL;
-
/* Decode and verify the types field of the ILF structure. */
import_type = types & 0x3;
import_name_type = (types & 0x1c) >> 2;
--- 789,798 ----
struct internal_filehdr internal_f;
unsigned int import_type;
unsigned int import_name_type;
! asection_ptr id4, id5, id6 = NULL, text = NULL;
! coff_symbol_type ** imp_sym;
! unsigned int imp_index;
/* Decode and verify the types field of the ILF structure. */
import_type = types & 0x3;
import_name_type = (types & 0x1c) >> 2;
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 833,838 ****
--- 861,870 ----
vars.native_ptr = (combined_entry_type *) ptr;
ptr += SIZEOF_ILF_NATIVE_SYMS;
+ vars.sym_ptr_table = (coff_symbol_type **) ptr;
+ vars.sym_ptr_ptr = (coff_symbol_type **) ptr;
+ ptr += SIZEOF_ILF_SYM_PTR_TABLE;
+
vars.esym_table = (SYMENT *) ptr;
vars.esym_ptr = (SYMENT *) ptr;
ptr += SIZEOF_ILF_EXT_SYMS;
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 857,872 ****
vars.magic = magic;
/* Create the initial .idata$<n> sections:
! .idata$2: Import Directory Table
.idata$4: Import Lookup Table
.idata$5: Import Address Table
Note we do not create a .idata$3 section as this is
created for us by the linker script. */
- id2 = pe_ILF_make_a_section (& vars, ".idata$2", SIZEOF_IDATA2, 0);
id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
! if (id2 == NULL || id4 == NULL || id5 == NULL)
return false;
/* Fill in the contents of these sections. */
--- 889,903 ----
vars.magic = magic;
/* Create the initial .idata$<n> sections:
! [.idata$2: Import Directory Table -- not needed]
.idata$4: Import Lookup Table
.idata$5: Import Address Table
Note we do not create a .idata$3 section as this is
created for us by the linker script. */
id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
! if (id4 == NULL || id5 == NULL)
return false;
/* Fill in the contents of these sections. */
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 876,883 ****
/* XXX - treat as IMPORT_NAME ??? */
abort ();
! * (unsigned int *) id4->contents = ordinal | 0x80000000;
! * (unsigned int *) id5->contents = ordinal | 0x80000000;
}
else
{
--- 907,914 ----
/* XXX - treat as IMPORT_NAME ??? */
abort ();
! * (unsigned int *) id4->contents = ordinal | 0x80000000UL;
! * (unsigned int *) id5->contents = ordinal | 0x80000000UL;
}
else
{
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 904,925 ****
* symbol = 0;
}
-
- strcpy (id6->contents, symbol);
- }
-
- /* Create .idata$7 - the Dll Name Table. */
- id7 = pe_ILF_make_a_section (& vars, ".idata$7", SIZEOF_IDATA7, 0);
- if (id7 == NULL)
- return false;
! strcpy (id7->contents + 2, source_dll);
! /* Now generate the relocs for the sections. */
! pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_RVA, id4);
! pe_ILF_make_a_reloc (& vars, 12, BFD_RELOC_RVA, id7);
! pe_ILF_make_a_reloc (& vars, 16, BFD_RELOC_RVA, id5);
! pe_ILF_save_relocs (& vars, id2);
if (import_name_type != IMPORT_ORDINAL)
{
--- 935,946 ----
* symbol = 0;
}
! id6->contents[0] = ordinal & 0xff;
! id6->contents[1] = ordinal >> 8;
! strcpy (id6->contents + 2, symbol);
! }
if (import_name_type != IMPORT_ORDINAL)
{
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 957,973 ****
/* Copy in the jump code. */
memcpy (text->contents, jtab[i].data, jtab[i].size);
/* Create a reloc for the data in the text section. */
#ifdef MIPS_ARCH_MAGIC_WINCE
if (magic == MIPS_ARCH_MAGIC_WINCE)
{
! pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_HI16_S, id5);
pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_LO16, text);
! pe_ILF_make_a_reloc (& vars, 4, BFD_RELOC_LO16, id5);
}
else
#endif
! pe_ILF_make_a_reloc (& vars, jtab[i].offset, BFD_RELOC_32, id5);
pe_ILF_save_relocs (& vars, text);
break;
--- 978,1002 ----
/* Copy in the jump code. */
memcpy (text->contents, jtab[i].data, jtab[i].size);
+ /* Create an import symbol. */
+ pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
+ imp_sym = vars.sym_ptr_ptr - 1;
+ imp_index = vars.sym_index - 1;
+
/* Create a reloc for the data in the text section. */
#ifdef MIPS_ARCH_MAGIC_WINCE
if (magic == MIPS_ARCH_MAGIC_WINCE)
{
! pe_ILF_make_a_symbol_reloc (& vars, 0, BFD_RELOC_HI16_S,
! (asection **) imp_sym, imp_index);
pe_ILF_make_a_reloc (& vars, 0, BFD_RELOC_LO16, text);
! pe_ILF_make_a_symbol_reloc (& vars, 4, BFD_RELOC_LO16,
! (asection **) imp_sym, imp_index);
}
else
#endif
! pe_ILF_make_a_symbol_reloc (& vars, jtab[i].offset, BFD_RELOC_32,
! (asymbol **) imp_sym, imp_index);
pe_ILF_save_relocs (& vars, text);
break;
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 1013,1025 ****
/* Now create a symbol describing the imported value. */
switch (import_type)
{
case IMPORT_CODE:
pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
BSF_NOT_AT_END | BSF_FUNCTION);
break;
case IMPORT_DATA:
! /* XXX not sure if I need to do anythign here. */
break;
default:
--- 1042,1065 ----
/* Now create a symbol describing the imported value. */
switch (import_type)
{
+ bfd_byte * ptr;
+
case IMPORT_CODE:
pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
BSF_NOT_AT_END | BSF_FUNCTION);
+
+ /* Create an import symbol for the DLL, without the
+ .dll suffix. */
+ ptr = strrchr (source_dll, '.');
+ if (ptr)
+ * ptr = 0;
+ pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
+ if (ptr)
+ * ptr = '.';
break;
case IMPORT_DATA:
! /* Nothing to do here. */
break;
default:
*************** pe_ILF_build_a_bfd (bfd * abfd
*** 1027,1034 ****
abort ();
}
- pe_ILF_make_a_symbol (& vars, "_imp__", symbol_name, id5, 0);
-
/* Point the bfd at the symbol table. */
obj_symbols (abfd) = vars.sym_cache;
bfd_get_symcount (abfd) = vars.sym_index;
--- 1067,1072 ----
More information about the Binutils
mailing list