diff options
author | Nick Clifton <nickc@redhat.com> | 2012-08-07 13:47:19 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2012-08-07 13:47:19 +0000 |
commit | a988325c2410b0ce11675fd262940bdc030f6bff (patch) | |
tree | 93df8e694479ee61dc37cace2f924872a6762dea /gas/config/tc-i386.c | |
parent | 4f69f4c267a21e787685116945fb40729a7297a5 (diff) | |
download | gdb-a988325c2410b0ce11675fd262940bdc030f6bff.zip gdb-a988325c2410b0ce11675fd262940bdc030f6bff.tar.gz gdb-a988325c2410b0ce11675fd262940bdc030f6bff.tar.bz2 |
* config/tc-i386.c (lex_got): Provide implementation for PE
format.
* gas/i386/secrel.s: Add test of <symbol>@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.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 5303f63d..49eb8c1 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 + <symbol>@SECREL32+<nnn> + + 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) { |