anybody wants to revive the code, you will have to figure out how
to handle those issues. */
-boolean in_reloc_p PARAMS((bfd *, reloc_howto_type *));
+static void add_data_entry
+ PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));
+static boolean pe_print_pdata PARAMS ((bfd *, PTR));
+static boolean pe_print_reloc PARAMS ((bfd *, PTR));
/**********************************************************************/
}
-static void add_data_entry (abfd, aout, idx, name, base)
+/* A support function for below. */
+
+static void
+add_data_entry (abfd, aout, idx, name, base)
bfd *abfd;
struct internal_extra_pe_aouthdr *aout;
int idx;
/* first null out all data directory entries .. */
memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
- add_data_entry (abfd, extra, 0, ".edata", ib);
- add_data_entry (abfd, extra, 1, ".idata", ib);
- add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
+ add_data_entry (abfd, extra, 0, ".edata", 0);
-#ifdef POWERPC_LE_PE
- /* FIXME: do other PE platforms use this? */
- add_data_entry (abfd, extra, 3, ".pdata" ,ib);
-#endif
+ /* Don't call add_data_entry for .idata$2 or .idata$5. It's done in
+ bfd_coff_final_link where all the required information is
+ available. */
- add_data_entry (abfd, extra, 5, ".reloc", ib);
+ /* However, until other .idata fixes are made (pending patch), the
+ entry for .idata is needed for backwards compatability. FIXME. */
+ add_data_entry (abfd, extra, 1, ".idata" ,0);
-#ifdef POWERPC_LE_PE
- /* On the PPC NT system, this field is set up as follows. It is not
- an "officially" reserved field, so it currently has no title.
- first_thunk_address is idata$5, and the thunk_size is the size of
- the idata$5 chunk of the idata section. */
- extra->DataDirectory[12].VirtualAddress = first_thunk_address;
- extra->DataDirectory[12].Size = thunk_size;
-
- /* On the PPC NT system, the size of the directory entry is not the
- size of the entire section. It's actually offset to the end of
- the idata$3 component of the idata section. This is the size of
- the entire import table. (also known as the start of idata$4). */
- extra->DataDirectory[1].Size = import_table_size;
-#endif
+ add_data_entry (abfd, extra, 2, ".rsrc" ,0);
+
+ add_data_entry (abfd, extra, 3, ".pdata", 0);
+
+ /* For some reason, the virtual size (which is what's set by
+ add_data_entry) for .reloc is not the same as the size recorded
+ in this slot by MSVC; it doesn't seem to cause problems (so far),
+ but since it's the best we've got, use it. It does do the right
+ thing for .pdata. */
+ if (pe_data (abfd)->has_reloc_section)
+ add_data_entry (abfd, extra, 5, ".reloc", 0);
{
asection *sec;
dsize += rounded;
if (sec->flags & SEC_CODE)
tsize += rounded;
- isize += SA(rounded);
+ /* The image size is the total VIRTUAL size (which is what is
+ in the virt_size field). Files have been seen (from MSVC
+ 5.0 link.exe) where the file size of the .data segment is
+ quite small compared to the virtual size. Without this
+ fix, strip munges the file. */
+ isize += SA (FA (pei_section_data (abfd, sec)->virt_size));
}
aouthdr_in->dsize = dsize;
extra->SizeOfHeaders = abfd->sections->filepos;
bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
-#ifdef POWERPC_LE_PE
- /* this little piece of magic sets the "linker version" field to 2.60 */
- bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
-#else
- /* this little piece of magic sets the "linker version" field to 2.55 */
- bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
-#endif
+#define LINKER_VERSION 256 /* That is, 2.56 */
+
+ /* This piece of magic sets the "linker version" field to
+ LINKER_VERSION. */
+ bfd_h_put_16 (abfd,
+ LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256,
+ (bfd_byte *) aouthdr_out->standard.vstamp);
PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
& 0xffffffff),
(bfd_byte *) scnhdr_ext->s_vaddr);
- /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
- value except for the BSS section, its s_size should be 0 */
+ /* NT wants the size data to be rounded up to the next
+ NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
+ sometimes). */
-
- if (strcmp (scnhdr_int->s_name, _BSS) == 0)
+ if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
{
ps = scnhdr_int->s_size;
ss = 0;
(bfd_byte *) scnhdr_ext->s_size);
+ /* s_paddr in PE is really the virtual size. */
PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
/* FIXME: even worse, I don't see how to get the original alignment field*/
/* back... */
- /* FIXME: Basing this on section names is bogus. Also, this should
- be in sec_to_styp_flags. */
-
{
int flags = scnhdr_int->s_flags;
- if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
- strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
- strcmp (scnhdr_int->s_name, ".bss") == 0)
- flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
- else if (strcmp (scnhdr_int->s_name, ".text") == 0)
- flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
- else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
- flags = (SEC_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
- | IMAGE_SCN_MEM_SHARED);
- else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
- flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
- else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
- || strcmp (scnhdr_int->s_name, ".edata") == 0)
- flags = IMAGE_SCN_MEM_READ | SEC_DATA;
- else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
- flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
- IMAGE_SCN_MEM_READ ;
- /* Remember this field is a max of 8 chars, so the null is _not_ there
- for an 8 character name like ".reldata". (yep. Stupid bug) */
- else if (strncmp (scnhdr_int->s_name, ".reldata", 8) == 0)
- flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
- IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
- else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
- flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
- IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
- else if (strncmp (scnhdr_int->s_name, ".drectve", 8) == 0)
- flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
- else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0)
- flags |= (IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE
- | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ);
- else if (strcmp (scnhdr_int->s_name, ".rsrc") == 0)
- flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED;
- else
- {
- flags |= IMAGE_SCN_MEM_READ;
- if (! (flags & SEC_READONLY))
- flags |= IMAGE_SCN_MEM_WRITE;
- if (flags & SEC_SHARED)
- flags |= IMAGE_SCN_MEM_SHARED;
- }
-
bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
}
- if (scnhdr_int->s_nlnno <= 0xffff)
- bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
- else
+ if (coff_data (abfd)->link_info
+ && ! coff_data (abfd)->link_info->relocateable
+ && ! coff_data (abfd)->link_info->shared
+ && strcmp (scnhdr_int->s_name, ".text") == 0)
{
- (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
- bfd_get_filename (abfd),
- scnhdr_int->s_nlnno);
- bfd_set_error (bfd_error_file_truncated);
- bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
- ret = 0;
+ /* By inference from looking at MS output, the 32 bit field
+ which is the combintion of the number_of_relocs and
+ number_of_linenos is used for the line number count in
+ executables. A 16-bit field won't do for cc1. The MS
+ document says that the number of relocs is zero for
+ executables, but the 17-th bit has been observed to be there.
+ Overflow is not an issue: a 4G-line program will overflow a
+ bunch of other fields long before this! */
+ bfd_h_put_16 (abfd, scnhdr_int->s_nlnno & 0xffff,
+ (bfd_byte *) scnhdr_ext->s_nlnno);
+ bfd_h_put_16 (abfd, scnhdr_int->s_nlnno >> 16,
+ (bfd_byte *) scnhdr_ext->s_nreloc);
}
- if (scnhdr_int->s_nreloc <= 0xffff)
- bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
else
{
- (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
- bfd_get_filename (abfd),
- scnhdr_int->s_nreloc);
- bfd_set_error (bfd_error_file_truncated);
- bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
- ret = 0;
+ if (scnhdr_int->s_nlnno <= 0xffff)
+ bfd_h_put_16 (abfd, scnhdr_int->s_nlnno,
+ (bfd_byte *) scnhdr_ext->s_nlnno);
+ else
+ {
+ (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nlnno);
+ bfd_set_error (bfd_error_file_truncated);
+ bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+ ret = 0;
+ }
+ if (scnhdr_int->s_nreloc <= 0xffff)
+ bfd_h_put_16 (abfd, scnhdr_int->s_nreloc,
+ (bfd_byte *) scnhdr_ext->s_nreloc);
+ else
+ {
+ (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nreloc);
+ bfd_set_error (bfd_error_file_truncated);
+ bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+ ret = 0;
+ }
}
return ret;
}
/**********************************************************************/
static boolean
-pe_print_idata(abfd, vfile)
+pe_print_idata (abfd, vfile)
bfd *abfd;
PTR vfile;
{
bfd_size_type dataoff;
bfd_size_type secsize;
bfd_size_type i;
- bfd_size_type start, stop;
int onaline = 20;
pe_data_type *pe = pe_data (abfd);
if (datasize == 0)
return true;
+
+ fprintf (file, _("\nThe import table is the .idata section\n"));
}
else
{
+ /* idata buried in some other section: e.g. KERNEL32.DLL. */
bfd_vma addr, size;
addr = extra->DataDirectory[1].VirtualAddress;
for (section = abfd->sections; section != NULL; section = section->next)
{
- if (section->vma - extra->ImageBase <= addr
- && ((section->vma - extra->ImageBase
- + bfd_section_size (abfd, section))
- >= addr + size))
- break;
+ if (addr >= section->vma
+ && addr < section->vma + bfd_section_size(abfd,section))
+ break;
}
if (section == NULL)
- return true;
+ {
+ fprintf (file,
+ _("\nThere is an import table, but the section containing it could not be found\n"));
+ return true;
+ }
- /* For some reason the import table size is not reliable. The
- import data will extend past the indicated size, and before
- the indicated address. */
- dataoff = addr - (section->vma - extra->ImageBase);
+ fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
+ section->name, (unsigned long)addr);
+
+ dataoff = addr - section->vma;
datasize = size;
}
if (! bfd_get_section_contents (abfd, section, (PTR) data, 0, secsize))
return false;
- adj = (extra->ImageBase - section->vma) & 0xffffffff;
+ adj = - section->vma;
- start = dataoff;
- stop = dataoff + datasize;
- for (i = start; i < stop; i += onaline)
+ for (i = 0; i < datasize; i += onaline)
{
bfd_vma hint_addr;
bfd_vma time_stamp;
" %08lx\t",
(unsigned long int) (i + section->vma + dataoff));
- if (i+20 > stop)
+ if (i + 20 > datasize)
{
/* check stuff */
;
}
-
- hint_addr = bfd_get_32(abfd, data+i);
- time_stamp = bfd_get_32(abfd, data+i+4);
- forward_chain = bfd_get_32(abfd, data+i+8);
- dll_name = bfd_get_32(abfd, data+i+12);
- first_thunk = bfd_get_32(abfd, data+i+16);
-
- fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
- hint_addr,
- time_stamp,
- forward_chain,
- dll_name,
- first_thunk);
+
+ hint_addr = bfd_get_32 (abfd, data + i + dataoff);
+ time_stamp = bfd_get_32 (abfd, data + i + 4 + dataoff);
+ forward_chain = bfd_get_32 (abfd, data + i + 8 + dataoff);
+ dll_name = bfd_get_32 (abfd, data + i + 12 + dataoff);
+ first_thunk = bfd_get_32 (abfd, data + i + 16 + dataoff);
+
+ fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
+ hint_addr,
+ time_stamp,
+ forward_chain,
+ dll_name,
+ first_thunk);
if (hint_addr == 0 && first_thunk == 0)
break;
- /* the image base is present in the section->vma */
- dll = (char *) data + dll_name + adj;
+ dll = (char *) data + dll_name - section->vma + dataoff;
fprintf(file, _("\n\tDLL Name: %s\n"), dll);
if (hint_addr != 0)
idx = hint_addr + adj;
- for (j = 0; j < stop; j += 4)
+ for (j = 0; j < datasize; j += 4)
{
unsigned long member = bfd_get_32 (abfd, data + idx + j);
idx2 = first_thunk + adj;
- for (j=0;j<stop;j+=4)
+ for (j = 0; j < datasize; j += 4)
{
int ordinal;
char *member_name;
{
datasize = bfd_section_size (abfd, section);
dataoff = 0;
+ fprintf (file, _("\nThe export table is the .edata section\n"));
}
else
{
+ /* edata is buried in some other section: e.g. NTDLL.DLL. */
bfd_vma addr, size;
addr = extra->DataDirectory[0].VirtualAddress;
for (section = abfd->sections; section != NULL; section = section->next)
{
- if (section->vma - extra->ImageBase <= addr
- && ((section->vma - extra->ImageBase
- + bfd_section_size (abfd, section))
- >= addr + size))
- break;
+ if (addr >= section->vma
+ && addr < section->vma + bfd_section_size (abfd, section))
+ break;
}
if (section == NULL)
- return true;
+ {
+ fprintf (file,
+ _("\nThere is an export table, but the section containing it could not be found\n"));
+ return true;
+ }
+
+ fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
+ section->name, (unsigned long) addr);
datasize = size;
- dataoff = addr - (section->vma - extra->ImageBase);
+ dataoff = addr - section->vma;
}
data = (bfd_byte *) bfd_malloc (datasize);
edt.npt_addr = bfd_get_32(abfd, data+32);
edt.ot_addr = bfd_get_32(abfd, data+36);
- adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff;
+ adj = - (section->vma + dataoff);
/* Dump the EDT first first */
fprintf(file,
fprintf (file, "\n");
- /* The next table to find si the Export Address Table. It's basically
+ /* The next table to find is the Export Address Table. It's basically
a list of pointers that either locate a function in this dll, or
forward the call to another dll. Something like:
typedef union
{
bfd_vma eat_member = bfd_get_32 (abfd,
data + edt.eat_addr + (i * 4) + adj);
- bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff;
- bfd_vma edata_start = bfd_get_section_vma (abfd,section) + dataoff;
+ bfd_vma eat_actual = eat_member;
+ bfd_vma edata_start = bfd_get_section_vma (abfd, section);
bfd_vma edata_end = edata_start + datasize;
if (eat_member == 0)
{
/* this rva is to a name (forwarding function) in our section */
/* Should locate a function descriptor */
- fprintf(file,
- "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
- (long) i, (long) (i + edt.base), eat_member,
- "Forwarder RVA", data + eat_member + adj);
+ fprintf (file,
+ "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
+ (long) i, (long) (i + edt.base), eat_member,
+ _("Forwarder RVA"), data + eat_member + adj);
}
else
{
/* Should locate a function descriptor in the reldata section */
- fprintf(file,
- "\t[%4ld] +base[%4ld] %04lx %s\n",
- (long) i, (long) (i + edt.base), eat_member, "Export RVA");
+ fprintf (file,
+ "\t[%4ld] +base[%4ld] %04lx %s\n",
+ (long) i, (long) (i + edt.base), eat_member,
+ _("Export RVA"));
}
}
bfd_size_type start, stop;
int onaline = 20;
- if (section == 0)
- return true;
+ if (section == NULL
+ || coff_section_data (abfd, section) == NULL
+ || pei_section_data (abfd, section) == NULL)
+ return true;
- stop = bfd_section_size (abfd, section);
+ stop = pei_section_data (abfd, section)->virt_size;
if ((stop % onaline) != 0)
fprintf (file, _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
(long)stop, onaline);
- fprintf(file,
- _("\nThe Function Table (interpreted .pdata section contents)\n"));
- fprintf(file,
- _(" vma:\t\tBegin End EH EH PrologEnd\n"));
- fprintf(file,
- _(" \t\tAddress Address Handler Data Address\n"));
+ fprintf (file,
+ _("\nThe Function Table (interpreted .pdata section contents)\n"));
+ fprintf (file,
+ _(" vma:\t\tBegin End EH EH PrologEnd Exception\n"));
+ fprintf (file,
+ _(" \t\tAddress Address Handler Data Address Mask\n"));
if (bfd_section_size (abfd, section) == 0)
return true;
bfd_vma eh_handler;
bfd_vma eh_data;
bfd_vma prolog_end_addr;
+ int em_data;
- if (i+20 > stop)
+ if (i + 20 > stop)
break;
-
+
begin_addr = bfd_get_32(abfd, data+i);
end_addr = bfd_get_32(abfd, data+i+4);
eh_handler = bfd_get_32(abfd, data+i+8);
" %08lx\t",
(unsigned long int) (i + section->vma));
- fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
- begin_addr,
- end_addr,
- eh_handler,
- eh_data,
- prolog_end_addr);
+ em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
+ eh_handler &= 0xfffffffc;
+ prolog_end_addr &= 0xfffffffc;
+
+ fprintf (file, "%08lx %08lx %08lx %08lx %08lx %x",
+ begin_addr,
+ end_addr,
+ eh_handler,
+ eh_data,
+ prolog_end_addr,
+ em_data);
#ifdef POWERPC_LE_PE
if (eh_handler == 0 && eh_data != 0)
return true;
}
-static const char *tbl[6] =
+#define IMAGE_REL_BASED_HIGHADJ 4
+static const char * const tbl[] =
{
"ABSOLUTE",
"HIGH",
"LOW",
"HIGHLOW",
"HIGHADJ",
-"MIPS_JMPADDR"
+"MIPS_JMPADDR",
+"UNKNOWN", /* MUST be last */
};
static boolean
bfd_size_type i;
bfd_size_type start, stop;
- if (section == 0)
+ if (section == NULL)
return true;
if (bfd_section_size (abfd, section) == 0)
return true;
- fprintf(file,
- _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
+ fprintf (file,
+ _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
datasize = bfd_section_size (abfd, section);
for (j = 0; j < number; ++j)
{
- unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
- int t = (e & 0xF000) >> 12;
+ unsigned short e = bfd_get_16 (abfd, data + i + 8 + j * 2);
+ unsigned int t = (e & 0xF000) >> 12;
int off = e & 0x0FFF;
- if (t > 5)
- abort();
+ if (t >= sizeof (tbl) / sizeof (tbl[0]))
+ t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
- fprintf(file,
- _("\treloc %4d offset %4x [%4lx] %s\n"),
- j, off, (long) (off + virtual_address), tbl[t]);
+ fprintf (file,
+ _("\treloc %4d offset %4x [%4lx] %s"),
+ j, off, (long) (off + virtual_address), tbl[t]);
+ /* HIGHADJ takes an argument, - the next record *is* the
+ low 16 bits of addend. */
+ if (t == IMAGE_REL_BASED_HIGHADJ)
+ {
+ fprintf (file, " (%4x)",
+ ((unsigned int)
+ bfd_get_16 (abfd, data + i + 8 + j * 2 + 2)));
+ j++;
+ }
+
+ fprintf (file, "\n");
}
i += size;
}
PF (0x8000, "big endian");
#undef PF
+ /* ctime implies '\n'. */
+ fprintf (file, "\nTime/Date\t\t%s", ctime (&pe->coff.timestamp));
fprintf (file,"\nImageBase\t\t");
fprintf_vma (file, i->ImageBase);
fprintf (file,"\nSectionAlignment\t");
pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
pe_data (obfd)->dll = pe_data (ibfd)->dll;
+ /* for strip: if we removed .reloc, we'll make a real mess of things
+ if we don't remove this entry as well. */
+ if (! pe_data (obfd)->has_reloc_section)
+ {
+ pe_data(obfd)->pe_opthdr.DataDirectory[5].VirtualAddress = 0;
+ pe_data(obfd)->pe_opthdr.DataDirectory[5].Size = 0;
+ }
return true;
}
}
pei_section_data (obfd, osec)->virt_size =
pei_section_data (ibfd, isec)->virt_size;
+ pei_section_data (obfd, osec)->pe_flags =
+ pei_section_data (ibfd, isec)->pe_flags;
}
return true;
&& ! bfd_is_abs_section (symbol->section))
ret->value += pe_data (abfd)->pe_opthdr.ImageBase;
}
+
+/* Handle the .idata section and other things that need symbol table
+ access. */
+
+boolean
+_bfd_pei_final_link_postscript (abfd, pfinfo)
+ bfd *abfd;
+ struct coff_final_link_info *pfinfo;
+{
+ struct coff_link_hash_entry *h1;
+ struct bfd_link_info *info = pfinfo->info;
+
+ /* There are a few fields that need to be filled in now while we
+ have symbol table access.
+
+ The .idata subsections aren't directly available as sections, but
+ they are in the symbol table, so get them from there. */
+
+ /* The import directory. This is the address of .idata$2, with size
+ of .idata$2 + .idata$3. */
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$2", false, false, true);
+ if (h1 != NULL)
+ {
+ pe_data(abfd)->pe_opthdr.DataDirectory[1].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$4", false, false, true);
+ pe_data (abfd)->pe_opthdr.DataDirectory[1].Size =
+ ((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.DataDirectory[1].VirtualAddress);
+
+ /* The import address table. This is the size/address of
+ .idata$5. */
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$5", false, false, true);
+ pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$6", false, false, true);
+ pe_data (abfd)->pe_opthdr.DataDirectory[12].Size =
+ ((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.DataDirectory[12].VirtualAddress);
+ }
+
+ /* If we couldn't find idata$2, we either have an excessively
+ trivial program or are in DEEP trouble; we have to assume trivial
+ program.... */
+ return true;
+}