aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2012-08-07 13:47:19 +0000
committerNick Clifton <nickc@redhat.com>2012-08-07 13:47:19 +0000
commita988325c2410b0ce11675fd262940bdc030f6bff (patch)
tree93df8e694479ee61dc37cace2f924872a6762dea /gas/config/tc-i386.c
parent4f69f4c267a21e787685116945fb40729a7297a5 (diff)
downloadgdb-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.c103
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)
{