diff options
author | Mark Harmstone <mark@harmstone.com> | 2022-04-07 14:47:17 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2022-04-07 14:47:17 +0100 |
commit | 145667f8d991932165a70d7c1551620be44e4b4f (patch) | |
tree | 1166831bf54cbafa71f078c8a567a4fd2b36ee21 /gas | |
parent | 591cc9fbbfd6d51131c0f1d4a92e7893edcc7a28 (diff) | |
download | gdb-145667f8d991932165a70d7c1551620be44e4b4f.zip gdb-145667f8d991932165a70d7c1551620be44e4b4f.tar.gz gdb-145667f8d991932165a70d7c1551620be44e4b4f.tar.bz2 |
Add support for COFF secidx relocations
bfd * coff-i386.c (in_reloc_p): Add R_SECTION.
(howto_table): Add R_SECTION.
(coff_pe_i386_relocation_section): Add support for R_SECTION.
(coff_i386_reloc_type_lookup): Add support for
BFD_RELOC_16_SECCIDX.
* coff-x86_64.c (in_reloc_p): Add R_SECTION.
(howto_table): Add R_SECTION.
(coff_pe_amd64_relocation_section): Add support for R_SECTION.
(coff_amd64_reloc_type_lookup): Add support for
BFD_RELOC_16_SECCIDX.
* reloc.c: Add BFD_RELOC_16_SECIDX.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
gas * config/tc-i386.c (pe_directive_secidx): New function.
(md_pseudo_table): Add support for secidx.
(x86_cons_fix_new): Likewise.
(tc_gen_reloc): Likewise.
* expr.c (op_rank): Add O_secidx.
* expr.h (operatorT): Likewise.
* symbols.c (resolve_symbol_value): Add support for O_secidx.
* testsuite/gas/i386/secidx.s: New test source file.
* testsuite/gas/i386/secidx.d: New test driver file.
* testsuite/gas/i386/i386.exp: Run new test.
include * coff/i386.h: Define R_SECTION.
* coff/x86_64.h: Likewise.
ld * testsuite/ld-pe/secidx1.s: New test source file.
* testsuite/ld-pe/secidx2.s: New test source file.
* testsuite/ld-pe/secidx.d: New test driver file.
* testsuite/ld-pe/secidx_64.d: New test driver file.
* testsuite/ld-pe/pe.exp: Add new tests.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 31 | ||||
-rw-r--r-- | gas/expr.c | 1 | ||||
-rw-r--r-- | gas/expr.h | 40 | ||||
-rw-r--r-- | gas/symbols.c | 8 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/i386.exp | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/secidx.d | 40 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/secidx.s | 79 |
8 files changed, 192 insertions, 23 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 54abdfb..63fcc53 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2022-04-07 Mark Harmstone <mark@harmstone.com> + + * config/tc-i386.c (pe_directive_secidx): New function. + (md_pseudo_table): Add support for secidx. + (x86_cons_fix_new): Likewise. + (tc_gen_reloc): Likewise. + * expr.c (op_rank): Add O_secidx. + * expr.h (operatorT): Likewise. + * symbols.c (resolve_symbol_value): Add support for O_secidx. + * testsuite/gas/i386/secidx.s: New test source file. + * testsuite/gas/i386/secidx.d: New test driver file. + * testsuite/gas/i386/i386.exp: Run new test. + 2022-04-07 Andreas Krebbel <krebbel@linux.ibm.com> * config/tc-s390.c (s390_parse_cpu): Add z16 as alternate CPU diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 7617792..c2678ea 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -152,6 +152,7 @@ static void set_check (int); static void set_cpu_arch (int); #ifdef TE_PE static void pe_directive_secrel (int); +static void pe_directive_secidx (int); #endif static void signed_cons (int); static char *output_invalid (int c); @@ -1385,6 +1386,7 @@ const pseudo_typeS md_pseudo_table[] = #endif #ifdef TE_PE {"secrel32", pe_directive_secrel, 0}, + {"secidx", pe_directive_secidx, 0}, #endif {0, 0, 0} }; @@ -10267,6 +10269,8 @@ x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, exp->X_op = O_symbol; r = BFD_RELOC_32_SECREL; } + else if (exp->X_op == O_secidx) + r = BFD_RELOC_16_SECIDX; #endif fix_new_exp (frag, off, len, exp, 0, r); @@ -10306,13 +10310,16 @@ lex_got (enum bfd_reloc_code_real *rel, we don't yet know the operand size (this will be set by insn matching). Hence we record the word32 relocation here, and adjust the reloc according to the real size in reloc(). */ - static const struct { + static const struct + { const char *str; int len; const enum bfd_reloc_code_real rel[2]; const i386_operand_type types64; bool need_GOT_symbol; - } gotrel[] = { + } + gotrel[] = + { #ifndef TE_PE #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) { STRING_COMMA_LEN ("SIZE"), { BFD_RELOC_SIZE32, @@ -10557,6 +10564,25 @@ pe_directive_secrel (int dummy ATTRIBUTE_UNUSED) input_line_pointer--; demand_empty_rest_of_line (); } + +static void +pe_directive_secidx (int dummy ATTRIBUTE_UNUSED) +{ + expressionS exp; + + do + { + expression (&exp); + if (exp.X_op == O_symbol) + exp.X_op = O_secidx; + + emit_expr (&exp, 2); + } + while (*input_line_pointer++ == ','); + + input_line_pointer--; + demand_empty_rest_of_line (); +} #endif /* Handle Vector operations. */ @@ -14359,6 +14385,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) case BFD_RELOC_VTABLE_INHERIT: #ifdef TE_PE case BFD_RELOC_32_SECREL: + case BFD_RELOC_16_SECIDX: #endif code = fixp->fx_r_type; break; @@ -1522,6 +1522,7 @@ static operator_rankT op_rank[O_max] = { 0, /* O_constant */ 0, /* O_symbol */ 0, /* O_symbol_rva */ + 0, /* O_secidx */ 0, /* O_register */ 0, /* O_big */ 9, /* O_uminus */ @@ -18,28 +18,27 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -/* - * By popular demand, we define a struct to represent an expression. - * This will no doubt mutate as expressions become baroque. - * - * Currently, we support expressions like "foo OP bar + 42". In other - * words we permit a (possibly undefined) symbol, a (possibly - * undefined) symbol and the operation used to combine the symbols, - * and an (absolute) augend. RMS says this is so we can have 1-pass - * assembly for any compiler emissions, and a 'case' statement might - * emit 'undefined1 - undefined2'. - * - * The type of an expression used to be stored as a segment. That got - * confusing because it overloaded the concept of a segment. I added - * an operator field, instead. - */ +/* By popular demand, we define a struct to represent an expression. + This will no doubt mutate as expressions become baroque. + + Currently, we support expressions like "foo OP bar + 42". In other + words we permit a (possibly undefined) symbol, a (possibly + undefined) symbol and the operation used to combine the symbols, + and an (absolute) augend. RMS says this is so we can have 1-pass + assembly for any compiler emissions, and a 'case' statement might + emit 'undefined1 - undefined2'. + + The type of an expression used to be stored as a segment. That got + confusing because it overloaded the concept of a segment. I added + an operator field, instead. */ /* This is the type of an expression. The operator types are also used while parsing an expression. NOTE: This enumeration must match the op_rank array in expr.c. */ -typedef enum { +typedef enum +{ /* An illegal expression. */ O_illegal, /* A nonexistent expression. */ @@ -50,6 +49,8 @@ typedef enum { O_symbol, /* X_add_symbol + X_add_number - the base address of the image. */ O_symbol_rva, + /* The section index of X_add_symbol. */ + O_secidx, /* A register (X_add_number is register number). */ O_register, /* A big value. If X_add_number is negative or 0, the value is in @@ -112,7 +113,8 @@ typedef enum { O_max } operatorT; -typedef struct expressionS { +typedef struct expressionS +{ /* The main symbol. */ symbolS *X_add_symbol; /* The second symbol, if needed. */ @@ -182,12 +184,10 @@ extern unsigned int get_single_number (void); extern symbolS *make_expr_symbol (expressionS * expressionP); extern int expr_symbol_where (symbolS *, const char **, unsigned int *); extern void current_location (expressionS *); - extern symbolS *expr_build_uconstant (offsetT); extern symbolS *expr_build_dot (void); extern uint32_t generic_bignum_to_int32 (void); extern uint64_t generic_bignum_to_int64 (void); - -int resolve_expression (expressionS *); +extern int resolve_expression (expressionS *); extern bool literal_prefix_dollar_hex; diff --git a/gas/symbols.c b/gas/symbols.c index b35c6d2..fb480be 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -1364,6 +1364,7 @@ resolve_symbol_value (symbolS *symp) case O_symbol: case O_symbol_rva: + case O_secidx: left = resolve_symbol_value (add_symbol); seg_left = S_GET_SEGMENT (add_symbol); if (finalize_syms) @@ -1444,6 +1445,13 @@ resolve_symbol_value (symbolS *symp) final_val += symp->frag->fr_address + left; resolved = symbol_resolved_p (add_symbol); symp->flags.resolving = 0; + + if (op == O_secidx && seg_left != undefined_section) + { + final_val = 0; + break; + } + goto exit_dont_set_value; } else diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 96356d3..2c84ccc 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -703,11 +703,12 @@ if [gas_32_check] then { } } - # This is a PE specific test. + # These are PE specific tests. if { [istarget "*-*-cygwin*"] || [istarget "*-*-pe"] || [istarget "*-*-mingw*"] } then { run_dump_test "secrel" + run_dump_test "secidx" } # Miscellaneous tests. diff --git a/gas/testsuite/gas/i386/secidx.d b/gas/testsuite/gas/i386/secidx.d new file mode 100644 index 0000000..baf299f --- /dev/null +++ b/gas/testsuite/gas/i386/secidx.d @@ -0,0 +1,40 @@ +#objdump: -rs +#name: i386 secidx reloc + +.*: +file format pe-i386 + +RELOCATION RECORDS FOR \[\.data\]: +OFFSET[ ]+TYPE[ ]+VALUE +0+24 secidx \.text +0+27 secidx \.text +0+2a secidx \.text +0+2d secidx \.text +0+3c secidx \.data +0+3f secidx \.data +0+42 secidx \.data +0+45 secidx \.data +0+54 secidx \.rdata +0+57 secidx \.rdata +0+5a secidx \.rdata +0+5d secidx \.rdata +0+6c secidx ext24 +0+6f secidx ext2d +0+72 secidx ext36 +0+75 secidx ext3f + +Contents of section \.text: + 0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< + 0010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< +Contents of section \.data: + 0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< + 0010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< + 0020 3e3e3e3e 00001100 00110000 11000011 >>>>............ + 0030 3c3c3c3c 3c3c3c3c 3e3e3e3e 00001100 <<<<<<<<>>>>.... + 0040 00110000 11000011 3c3c3c3c 3c3c3c3c ........<<<<<<<< + 0050 3e3e3e3e 00001100 00110000 11000011 >>>>............ + 0060 3c3c3c3c 3c3c3c3c 3e3e3e3e 00001100 <<<<<<<<>>>>.... + 0070 00110000 11000011 3c3c3c3c 3c3c3c3c ........<<<<<<<< +Contents of section \.rdata: + 0000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< + 0010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< + 0020 3e3e3e3e 00000000 00000000 00000000 >>>>............ diff --git a/gas/testsuite/gas/i386/secidx.s b/gas/testsuite/gas/i386/secidx.s new file mode 100644 index 0000000..7ac1d2c --- /dev/null +++ b/gas/testsuite/gas/i386/secidx.s @@ -0,0 +1,79 @@ +.text + + .ascii ">>>>" +pre04: .ascii "<<<<" + .ascii ">>>>>" +pre0d: .ascii "<<<" + .ascii ">>>>>>" +pre16: .ascii "<<" + .ascii ">>>>>>>" +pre1f: .ascii "<" + +.data + + .ascii ">>>>" +sam04: .ascii "<<<<" + .ascii ">>>>>" +sam0d: .ascii "<<<" + .ascii ">>>>>>" +sam16: .ascii "<<" + .ascii ">>>>>>>" +sam1f: .ascii "<" + + .ascii ">>>>" + .secidx pre04 + .byte 0x11 + .secidx pre0d + .byte 0x11 + .secidx pre16 + .byte 0x11 + .secidx pre1f + .byte 0x11 + .ascii "<<<<<<<<" + + .ascii ">>>>" + .secidx sam04 + .byte 0x11 + .secidx sam0d + .byte 0x11 + .secidx sam16 + .byte 0x11 + .secidx sam1f + .byte 0x11 + .ascii "<<<<<<<<" + + .ascii ">>>>" + .secidx nex04 + .byte 0x11 + .secidx nex0d + .byte 0x11 + .secidx nex16 + .byte 0x11 + .secidx nex1f + .byte 0x11 + .ascii "<<<<<<<<" + + .ascii ">>>>" + .secidx ext24 + .byte 0x11 + .secidx ext2d + .byte 0x11 + .secidx ext36 + .byte 0x11 + .secidx ext3f + .byte 0x11 + .ascii "<<<<<<<<" + +.section .rdata + + .ascii ">>>>" +nex04: .ascii "<<<<" + .ascii ">>>>>" +nex0d: .ascii "<<<" + .ascii ">>>>>>" +nex16: .ascii "<<" + .ascii ">>>>>>>" +nex1f: .ascii "<" + .ascii ">>>>" + + .p2align 4,0 |