diff options
-rw-r--r-- | bfd/coff-arm.c | 132 | ||||
-rw-r--r-- | bfd/coffcode.h | 21 | ||||
-rw-r--r-- | bfd/coffswap.h | 52 |
3 files changed, 91 insertions, 114 deletions
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 3136a8d..31a3994 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -45,6 +45,8 @@ aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, static bfd_reloc_status_type coff_arm_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + +/* Used by the assembler. */ static bfd_reloc_status_type coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) @@ -57,7 +59,6 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, char **error_message; { symvalue diff; - if (output_bfd == (bfd *) NULL) return bfd_reloc_continue; @@ -183,7 +184,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = complain_overflow_signed, aoutarm_fix_pcrel_26 , "ARM26", - true, + false, 0x00ffffff, 0x00ffffff, PCRELOFFSET), @@ -282,10 +283,34 @@ static reloc_howto_type aoutarm_std_reloc_howto[] = }; - #define RTYPE2HOWTO(cache_ptr, dst) \ (cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type; +#define coff_rtype_to_howto coff_arm_rtype_to_howto +static reloc_howto_type * +coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp) + bfd *abfd; + asection *sec; + struct internal_reloc *rel; + struct coff_link_hash_entry *h; + struct internal_syment *sym; + bfd_vma *addendp; +{ + reloc_howto_type *howto; + + howto = aoutarm_std_reloc_howto + rel->r_type; + + if (rel->r_type == 11) + { + /* Gross, where can I get this from ?? */ + struct bfd_link_info *link_info = coff_data(sec->output_section->owner)->link_info; + *addendp -= link_info->pe_info->image_base.value; + } + return howto; + +} +/* Used by the assembler. */ + static bfd_reloc_status_type aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) @@ -301,6 +326,8 @@ aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_ok; } +/* Used by the assembler. */ + static bfd_reloc_status_type aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) @@ -356,10 +383,11 @@ aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, /* Now the ARM magic... Change the reloc type so that it is marked as done. Strictly this is only necessary if we are doing a partial relocation. */ reloc_entry->howto = &aoutarm_std_reloc_howto[7]; - + return flag; } + static CONST struct reloc_howto_struct * arm_reloc_type_lookup(abfd,code) bfd *abfd; @@ -395,100 +423,6 @@ arm_reloc_type_lookup(abfd,code) /* The page size is a guess based on ELF. */ #define COFF_PAGE_SIZE 0x1000 -/* For some reason when using arm COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. Ian Taylor, Cygnus Support. */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -aacoff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for arm - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - - - /* Turn a howto into a reloc nunmber */ @@ -512,8 +446,6 @@ aacoff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, /* We use the special COFF backend linker. */ #define coff_relocate_section _bfd_coff_generic_relocate_section - - #include "coffcode.h" static const bfd_target * diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 76d8fd4..1995d6e 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1507,7 +1507,7 @@ coff_compute_section_file_positions (abfd) asection *current; asection *previous = (asection *) NULL; file_ptr sofar = FILHSZ; - int page_size; + #ifndef I960 file_ptr old_sofar; #endif @@ -1515,6 +1515,7 @@ coff_compute_section_file_positions (abfd) #ifdef COFF_IMAGE_WITH_PE + int page_size; if (coff_data (abfd)->link_info) { page_size = pe_value (&(coff_data (abfd)->link_info->pe_info->file_alignment), @@ -1522,9 +1523,10 @@ coff_compute_section_file_positions (abfd) } else page_size = PE_DEF_FILE_ALIGNMENT; -#else - page_size = COFF_PAGE_SIZE; +#elif defined (COFF_PAGE_SIZE) + int page_size = COFF_PAGE_SIZE; #endif + if (bfd_get_start_address (abfd)) { /* A start address may have been added to the original file. In this @@ -1577,9 +1579,11 @@ coff_compute_section_file_positions (abfd) /* In demand paged files the low order bits of the file offset must match the low order bits of the virtual address. */ +#ifdef COFF_PAGE_SIZE if ((abfd->flags & D_PAGED) != 0 && (current->flags & SEC_ALLOC) != 0) sofar += (current->vma - sofar) % page_size; +#endif current->filepos = sofar; @@ -1748,11 +1752,11 @@ fill_pe_header_info (abfd, internal_f, internal_a) internal_a->entry -= ib; - sa = internal_a->pe->SectionAlignment = pe_value (&pe_info->section_alignment, - NT_SECTION_ALIGNMENT); + sa = internal_a->pe->SectionAlignment = pe_value (&pe_info->section_alignment, + NT_SECTION_ALIGNMENT); - fa = internal_a->pe->FileAlignment = pe_value (&pe_info->file_alignment, - NT_FILE_ALIGNMENT); + fa = internal_a->pe->FileAlignment = pe_value (&pe_info->file_alignment, + NT_FILE_ALIGNMENT); #define FA(x) (((x) + fa -1 ) & (- fa)) #define SA(x) (((x) + sa -1 ) & (- sa)) @@ -1841,8 +1845,6 @@ fill_pe_header_info (abfd, internal_f, internal_a) structure are in order and that I have successfully saved the last section's address and size. */ - - /* The headers go up to where the first section starts. */ internal_a->pe->SizeOfHeaders = abfd->sections->filepos; @@ -1874,7 +1876,6 @@ fill_pe_header_info (abfd, internal_f, internal_a) bfd_vma dsize= 0; bfd_vma isize = SA(abfd->sections->filepos); bfd_vma tsize= 0; - bfd_vma dstart = 0; for (sec = abfd->sections; sec; sec = sec->next) { int rounded = FA(sec->_raw_size); diff --git a/bfd/coffswap.h b/bfd/coffswap.h index 4b35942..4ab7340 100644 --- a/bfd/coffswap.h +++ b/bfd/coffswap.h @@ -715,6 +715,51 @@ coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask); aouthdr_int->fprmask = bfd_h_get_32(abfd, aouthdr_ext->fprmask); #endif + +#ifdef COFF_IMAGE_WITH_PE + + { + struct internal_extra_pe_aouthdr *a; + PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext); + a = aouthdr_int->pe = bfd_alloc (abfd, sizeof (*a)); + + a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase); + a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment); + a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment); + a->MajorOperatingSystemVersion = + bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion); + a->MinorOperatingSystemVersion = + bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion); + a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion); + a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion); + a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion); + a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion); + a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1); + a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage); + a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders); + a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum); + a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem); + a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics); + a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve); + a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit); + a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve); + a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit); + a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags); + a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes); + + { + int idx; + for (idx=0; idx < 16; idx++) + { + a->DataDirectory[idx].VirtualAddress = + bfd_h_get_32 (abfd, src->DataDirectory[idx][0]); + a->DataDirectory[idx].Size = + bfd_h_get_32 (abfd, src->DataDirectory[idx][1]); + } + } + } +#endif + } static unsigned int @@ -736,7 +781,7 @@ coff_swap_aouthdr_out (abfd, in, out) (bfd_byte *) aouthdr_out->text_start); PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, (bfd_byte *) aouthdr_out->data_start); -#ifdef COFF_WITH_PE +#ifdef COFF_IMAGE_WITH_PE { PEAOUTHDR *peaouthdr_out = (PEAOUTHDR *)aouthdr_out; bfd_h_put_32 (abfd, aouthdr_in->pe->ImageBase, @@ -855,13 +900,12 @@ coff_swap_scnhdr_in (abfd, ext, in) #ifdef I960 scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align); #endif - +#ifdef COFF_IMAGE_WITH_PE #ifdef NT_EXE_IMAGE_BASE -/* if (scnhdr_int->s_vaddr != 0) { scnhdr_int->s_vaddr += NT_EXE_IMAGE_BASE; } -*/ +#endif #endif } |