From a988325c2410b0ce11675fd262940bdc030f6bff Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 7 Aug 2012 13:47:19 +0000 Subject: [PATCH] * config/tc-i386.c (lex_got): Provide implementation for PE format. * gas/i386/secrel.s: Add test of @SECREL32. * gas/i386/secrel.d: Add expected disassembly. * scripttempl/pe.sc (R_TLS): Add .tls$AAA and .tls$ZZZ. * scripttempl/pep.sc (R_TLS): Add .tls$AAA and .tls$ZZZ. * archive.c (_bfd_delete_archive_data): New function. * libbfd-in.h (_bfd_delete_archive_data): Declare. * libbfd.h: Rebuild. * opncls.c (_bfd_delete_bfd): Call _bfd_delete_archive_data. --- bfd/ChangeLog | 7 +++ bfd/archive.c | 13 ++++ bfd/libbfd-in.h | 2 + bfd/libbfd.h | 2 + bfd/opncls.c | 4 ++ gas/ChangeLog | 5 ++ gas/config/tc-i386.c | 103 ++++++++++++++++++++++++++++++++ gas/testsuite/ChangeLog | 5 ++ gas/testsuite/gas/i386/secrel.d | 3 +- gas/testsuite/gas/i386/secrel.s | 2 + ld/ChangeLog | 5 ++ ld/scripttempl/pe.sc | 8 ++- ld/scripttempl/pep.sc | 8 ++- 13 files changed, 164 insertions(+), 3 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 91a09e699f4..da2a229eadc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2012-08-07 Tom Tromey + + * archive.c (_bfd_delete_archive_data): New function. + * libbfd-in.h (_bfd_delete_archive_data): Declare. + * libbfd.h: Rebuild. + * opncls.c (_bfd_delete_bfd): Call _bfd_delete_archive_data. + 2012-08-07 Nick Clifton * po/uk.po: Updated Ukranian translation. diff --git a/bfd/archive.c b/bfd/archive.c index fe57755770b..1148c115fd5 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -293,6 +293,19 @@ bfd_set_archive_head (bfd *output_archive, bfd *new_head) return TRUE; } +/* Free the archive hash table, if it exists. */ + +void +_bfd_delete_archive_data (bfd *abfd) +{ + struct artdata *ardata = bfd_ardata (abfd); + + BFD_ASSERT (abfd->format == bfd_archive); + + if (ardata && ardata->cache) + htab_delete (ardata->cache); +} + bfd * _bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos) { diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 1495825c4d6..8cdb1c65c36 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -130,6 +130,8 @@ extern void bfd_release bfd * _bfd_create_empty_archive_element_shell (bfd *obfd); +void _bfd_delete_archive_data + (bfd *abfd); bfd * _bfd_look_for_bfd_in_cache (bfd *, file_ptr); bfd_boolean _bfd_add_bfd_to_archive_cache diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c31780dab1f..a1e544f75fe 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -135,6 +135,8 @@ extern void bfd_release bfd * _bfd_create_empty_archive_element_shell (bfd *obfd); +void _bfd_delete_archive_data + (bfd *abfd); bfd * _bfd_look_for_bfd_in_cache (bfd *, file_ptr); bfd_boolean _bfd_add_bfd_to_archive_cache diff --git a/bfd/opncls.c b/bfd/opncls.c index 0c02ee4e2b1..e538981f6d8 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -130,11 +130,15 @@ _bfd_new_bfd_contained_in (bfd *obfd) static void _bfd_delete_bfd (bfd *abfd) { + if (abfd->format == bfd_archive) + _bfd_delete_archive_data (abfd); + if (abfd->memory) { bfd_hash_table_free (&abfd->section_htab); objalloc_free ((struct objalloc *) abfd->memory); } + free (abfd); } diff --git a/gas/ChangeLog b/gas/ChangeLog index 9597f5eb4b7..f3af9311543 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2012-08-07 Daniel Green + + * config/tc-i386.c (lex_got): Provide implementation for PE + format. + 2012-08-06 Maciej W. Rozycki * config/tc-mips.c (append_insn): Also handle moving delay-slot diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 5303f63da04..49eb8c10600 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6788,6 +6788,109 @@ lex_got (enum bfd_reloc_code_real *rel, } #endif +#ifdef TE_PE +#ifdef lex_got +#undef lex_got +#endif +/* Parse operands of the form + @SECREL32+ + + If we find one, set up the correct relocation in RELOC and copy the + input string, minus the `@SECREL32' into a malloc'd buffer for + parsing by the calling routine. Return this buffer, and if ADJUST + is non-null set it to the length of the string we removed from the + input line. Otherwise return NULL. + + This function is copied from the ELF version above adjusted for PE targets. */ + +static char * +lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED, + int *adjust ATTRIBUTE_UNUSED, + i386_operand_type *types ATTRIBUTE_UNUSED) +{ + static const struct + { + const char *str; + int len; + const enum bfd_reloc_code_real rel[2]; + const i386_operand_type types64; + } + gotrel[] = + { + { STRING_COMMA_LEN ("SECREL32"), { BFD_RELOC_32_SECREL, + BFD_RELOC_32_SECREL }, + OPERAND_TYPE_IMM32_32S_64_DISP32_64 }, + }; + + char *cp; + unsigned j; + + for (cp = input_line_pointer; *cp != '@'; cp++) + if (is_end_of_line[(unsigned char) *cp] || *cp == ',') + return NULL; + + for (j = 0; j < ARRAY_SIZE (gotrel); j++) + { + int len = gotrel[j].len; + + if (strncasecmp (cp + 1, gotrel[j].str, len) == 0) + { + if (gotrel[j].rel[object_64bit] != 0) + { + int first, second; + char *tmpbuf, *past_reloc; + + *rel = gotrel[j].rel[object_64bit]; + if (adjust) + *adjust = len; + + if (types) + { + if (flag_code != CODE_64BIT) + { + types->bitfield.imm32 = 1; + types->bitfield.disp32 = 1; + } + else + *types = gotrel[j].types64; + } + + /* The length of the first part of our input line. */ + first = cp - input_line_pointer; + + /* The second part goes from after the reloc token until + (and including) an end_of_line char or comma. */ + past_reloc = cp + 1 + len; + cp = past_reloc; + while (!is_end_of_line[(unsigned char) *cp] && *cp != ',') + ++cp; + second = cp + 1 - past_reloc; + + /* Allocate and copy string. The trailing NUL shouldn't + be necessary, but be safe. */ + tmpbuf = (char *) xmalloc (first + second + 2); + memcpy (tmpbuf, input_line_pointer, first); + if (second != 0 && *past_reloc != ' ') + /* Replace the relocation token with ' ', so that + errors like foo@SECLREL321 will be detected. */ + tmpbuf[first++] = ' '; + memcpy (tmpbuf + first, past_reloc, second); + tmpbuf[first + second] = '\0'; + return tmpbuf; + } + + as_bad (_("@%s reloc is not supported with %d-bit output format"), + gotrel[j].str, 1 << (5 + object_64bit)); + return NULL; + } + } + + /* Might be a symbol version string. Don't as_bad here. */ + return NULL; +} + +#endif /* TE_PE */ + void x86_cons (expressionS *exp, int size) { diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 026750e1160..b5d11cc5dd9 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-08-07 Nick Clifton + + * gas/i386/secrel.s: Add test of @SECREL32. + * gas/i386/secrel.d: Add expected disassembly. + 2012-08-06 Maciej W. Rozycki * gas/mips/mips.exp: Set has_newabi for all Linux targets. diff --git a/gas/testsuite/gas/i386/secrel.d b/gas/testsuite/gas/i386/secrel.d index 58967cb5141..ac23301f7ea 100644 --- a/gas/testsuite/gas/i386/secrel.d +++ b/gas/testsuite/gas/i386/secrel.d @@ -21,7 +21,7 @@ OFFSET[ ]+TYPE[ ]+VALUE 0+89 secrel32 ext2d 0+8e secrel32 ext36 0+93 secrel32 ext3f - +0+a2 secrel32 bar Contents of section \.text: 0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< @@ -37,6 +37,7 @@ Contents of section \.data: 0070 0000111f 00000011 3c3c3c3c 3c3c3c3c ........<<<<<<<< 0080 3e3e3e3e 00000000 11000000 00110000 >>>>............ 0090 00001100 00000011 3c3c3c3c 3c3c3c3c ........<<<<<<<< + 00a0 8d902c00 00000000 ..,..... Contents of section \.rdata: 0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< 0010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< diff --git a/gas/testsuite/gas/i386/secrel.s b/gas/testsuite/gas/i386/secrel.s index c16299016b6..2fc5a257f63 100644 --- a/gas/testsuite/gas/i386/secrel.s +++ b/gas/testsuite/gas/i386/secrel.s @@ -64,6 +64,8 @@ sam1f: .ascii "<" .byte 0x11 .ascii "<<<<<<<<" + leal bar@SECREL32+44(%eax), %edx + .section .rdata .ascii ">>>>" diff --git a/ld/ChangeLog b/ld/ChangeLog index cd2402bf195..c4bc473d26b 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2012-08-07 Daniel Green + + * scripttempl/pe.sc (R_TLS): Add .tls$AAA and .tls$ZZZ. + * scripttempl/pep.sc (R_TLS): Add .tls$AAA and .tls$ZZZ. + 2012-08-07 Nick Clifton * po/ja.po: Updated Japanese translation. diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc index 3a27952fe1b..5b9bd6147ab 100644 --- a/ld/scripttempl/pe.sc +++ b/ld/scripttempl/pe.sc @@ -39,9 +39,11 @@ if test "${RELOCATING}"; then R_CRT_XP='*(SORT(.CRT$XP*)) /* Pre-termination */' R_CRT_XT='*(SORT(.CRT$XT*)) /* Termination */' R_TLS=' + *(.tls$AAA) *(.tls) *(.tls$) - *(SORT(.tls$*))' + *(SORT(.tls$*)) + *(.tls$ZZZ)' R_RSRC='*(SORT(.rsrc$*))' else R_TEXT= @@ -179,6 +181,10 @@ SECTIONS ${RELOCATING+___crt_xt_end__ = . ;} } + /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be + at the end of section. This is important because _tls_start MUST + be at the beginning of the section to enable SECREL32 relocations with TLS + data. */ .tls ${RELOCATING+BLOCK(__section_alignment__)} : { ${RELOCATING+___tls_start__ = . ;} diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc index b2113fe227d..ff11153054b 100644 --- a/ld/scripttempl/pep.sc +++ b/ld/scripttempl/pep.sc @@ -39,9 +39,11 @@ if test "${RELOCATING}"; then R_CRT_XP='*(SORT(.CRT$XP*)) /* Pre-termination */' R_CRT_XT='*(SORT(.CRT$XT*)) /* Termination */' R_TLS=' + *(.tls$AAA) *(.tls) *(.tls$) - *(SORT(.tls$*))' + *(SORT(.tls$*)) + *(.tls$ZZZ)' R_RSRC='*(SORT(.rsrc$*))' else R_TEXT= @@ -185,6 +187,10 @@ SECTIONS ${RELOCATING+___crt_xt_end__ = . ;} } + /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be + at the end of the .tls section. This is important because _tls_start MUST + be at the beginning of the section to enable SECREL32 relocations with TLS + data. */ .tls ${RELOCATING+BLOCK(__section_alignment__)} : { ${RELOCATING+___tls_start__ = . ;} -- 2.30.2