diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c index 350cca30c0..7008109322 100644 --- a/bfd/coff-ppc.c +++ b/bfd/coff-ppc.c @@ -1132,8 +1132,17 @@ static boolean in_reloc_p(abfd, howto) { return (! howto->pc_relative) + && (howto->type != IMAGE_REL_PPC_ADDR32NB) && (howto->type != IMAGE_REL_PPC_TOCREL16) - && (howto->type != IMAGE_REL_PPC_IMGLUE); + && (howto->type != IMAGE_REL_PPC_IMGLUE) + && (howto->type != IMAGE_REL_PPC_IFGLUE) + && (howto->type != IMAGE_REL_PPC_SECREL) + && (howto->type != IMAGE_REL_PPC_SECTION) + && (howto->type != IMAGE_REL_PPC_SECREL16) + && (howto->type != IMAGE_REL_PPC_REFHI) + && (howto->type != IMAGE_REL_PPC_REFLO) + && (howto->type != IMAGE_REL_PPC_PAIR) + && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ; } /* this function is in charge of performing all the ppc PE relocations */ @@ -1519,11 +1528,12 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, bfd_vma addr = toc_section->output_section->vma + toc_section->output_offset + our_toc_offset; - fprintf(stderr, - " Toc Section reloc candidate\n"); - if (coff_data(output_bfd)->pe) addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; + + fprintf(stderr, + " Toc Section .reloc candidate addr = %x\n", addr); + fwrite (&addr, 1,4, (FILE *) info->base_file); } @@ -1722,11 +1732,14 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, + input_section->output_offset + input_section->output_section->vma; + DUMP_RELOC2(howto->name, rel); + if (coff_data(output_bfd)->pe) { + bfd_vma before_addr = addr; addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; fprintf(stderr, - " adjusted down to %d", addr); + " adjusted down from %x to %x", before_addr, addr); } fprintf(stderr, "\n"); diff --git a/bfd/coffcode.h b/bfd/coffcode.h index e0c4f1782d..b7eeea48ec 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -981,6 +981,10 @@ coff_set_alignment_hook (abfd, section, scnhdr) { section->alignment_power = 1; } + else if (strcmp (section->name, ".reloc") == 0) + { + section->alignment_power = 1; + } #endif } #undef ALIGN_SET diff --git a/bfd/peicode.h b/bfd/peicode.h index 78a2d1d2ad..ddb7d70789 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1617,6 +1617,97 @@ pe_print_pdata(abfd, vfile) free (data); } +static const char *tbl[6] = +{ +"ABSOLUTE", +"HIGH", +"LOW", +"HIGHLOW", +"HIGHADJ", +"unknown" +}; + +static boolean +pe_print_reloc(abfd, vfile) + bfd*abfd; + void *vfile; +{ + FILE *file = vfile; + bfd_byte *data = 0; + asection *section = bfd_get_section_by_name (abfd, ".reloc"); + bfd_size_type datasize = 0; + bfd_size_type i; + bfd_size_type start, stop; + int onaline = 20; + bfd_vma addr_value; + + if (section == 0) + return true; + + if (bfd_section_size (abfd, section) == 0) + return true; + + 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); + if (data == NULL && datasize != 0) + return false; + + bfd_get_section_contents (abfd, + section, + (PTR) data, 0, + bfd_section_size (abfd, section)); + + start = 0; + + stop = bfd_section_size (abfd, section); + + for (i = start; i < stop;) + { + int j; + bfd_vma virtual_address; + long number, size; + + /* The .reloc section is a sequence of blocks, with a header consisting + of two 32 bit quantities, followed by a number of 16 bit entries */ + + virtual_address = bfd_get_32(abfd, data+i); + size = bfd_get_32(abfd, data+i+4); + number = (size - 8) / 2; + + if (size == 0) + { + break; + } + + fprintf (file, + "\nVirtual Address: %08lx Chunk size %d (0x%x) " + "Number of fixups %d\n", + virtual_address, size, size, number); + + for (j = 0; j < number; ++j) + { + unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2); + int t = (e & 0xF000) >> 12; + int off = e & 0x0FFF; + + if (t > 5) + abort(); + + fprintf(file, + "\treloc %4d offset %4x [%4x] %s\n", + j, off, off+virtual_address, tbl[t]); + + } + i += size; + } + + free (data); +} + static boolean pe_print_private_bfd_data (abfd, vfile) bfd *abfd; @@ -1668,6 +1759,7 @@ pe_print_private_bfd_data (abfd, vfile) pe_print_idata(abfd, vfile); pe_print_edata(abfd, vfile); pe_print_pdata(abfd, vfile); + pe_print_reloc(abfd, vfile); return true; }