From 731093717a9c5f8ab217f2c14f02541c8bdefd4b Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Wed, 9 Nov 2005 06:05:58 +0000 Subject: [PATCH] Fix GAS section alignment, at least for ELF output. In GAS mode, the section alignment is set to the maximum alignment used anywhere in the section. svn path=/trunk/yasm/; revision=1317 --- modules/objfmts/elf/elf-objfmt.c | 10 ++++++++- modules/objfmts/elf/elf.c | 6 ++++++ modules/objfmts/elf/elf.h | 1 + modules/parsers/gas/gas-bison.y | 25 +++++++--------------- modules/parsers/gas/tests/datavis2.hex | 8 +++---- modules/parsers/gas/tests/gassectalign.asm | 1 + modules/parsers/gas/tests/gassectalign.hex | 4 ++-- 7 files changed, 31 insertions(+), 24 deletions(-) diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index 5aaec99e..05331343 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -772,6 +772,7 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, type = SHT_PROGBITS; flags = SHF_ALLOC + SHF_EXECINSTR; } else if (strcmp(sectname, ".comment") == 0) { + align = 0; type = SHT_PROGBITS; flags = 0; } else { @@ -918,13 +919,20 @@ elf_objfmt_section_align(/*@unused@*/ yasm_objfmt *objfmt, yasm_section *sect, unsigned long align, unsigned long line) { /*@dependent@*/ /*@null@*/ elf_secthead *esd; + const yasm_intnum *old_align_intn; + unsigned long old_align = 0; esd = yasm_section_get_data(sect, &elf_section_data); if (!esd) yasm_internal_error(N_("NULL elf section data in section_align")); - elf_secthead_set_align(esd, yasm_intnum_create_uint(align)); + old_align_intn = elf_secthead_get_align(esd); + if (old_align_intn) + old_align = yasm_intnum_get_uint(old_align_intn); + + if (align > old_align) + elf_secthead_set_align(esd, yasm_intnum_create_uint(align)); } static yasm_symrec * diff --git a/modules/objfmts/elf/elf.c b/modules/objfmts/elf/elf.c index 58fd6966..3e77556a 100644 --- a/modules/objfmts/elf/elf.c +++ b/modules/objfmts/elf/elf.c @@ -761,6 +761,12 @@ elf_secthead_get_index(elf_secthead *shead) return shead->index; } +const yasm_intnum * +elf_secthead_get_align(const elf_secthead *shead) +{ + return shead->align; +} + const yasm_intnum * elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align) { diff --git a/modules/objfmts/elf/elf.h b/modules/objfmts/elf/elf.h index bbd000b2..fb6129a2 100644 --- a/modules/objfmts/elf/elf.h +++ b/modules/objfmts/elf/elf.h @@ -463,6 +463,7 @@ void elf_secthead_append_reloc(yasm_section *sect, elf_secthead *shead, elf_section_type elf_secthead_get_type(elf_secthead *shead); int elf_secthead_is_empty(elf_secthead *shead); struct yasm_symrec *elf_secthead_get_sym(elf_secthead *shead); +const struct yasm_intnum *elf_secthead_get_align(const elf_secthead *shead); const struct yasm_intnum *elf_secthead_set_align(elf_secthead *shead, struct yasm_intnum *align); elf_section_index elf_secthead_get_index(elf_secthead *shead); diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y index c9298db9..8d132f48 100644 --- a/modules/parsers/gas/gas-bison.y +++ b/modules/parsers/gas/gas-bison.y @@ -811,6 +811,7 @@ gas_parser_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams, { /*@dependent@*/ yasm_valparam *bound, *fill = NULL, *maxskip = NULL; yasm_expr *boundval, *fillval = NULL, *maxskipval = NULL; + yasm_intnum *boundintn; bound = yasm_vps_first(valparams); boundval = bound->param; @@ -844,26 +845,16 @@ gas_parser_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams, /* If .align is the first bytecode in the section, it's really specifying * section alignment. */ - if (parser_gas->prev_bc - == yasm_section_bcs_first(parser_gas->cur_section)) { - yasm_intnum *boundintn = yasm_expr_get_intnum(&boundval, NULL); - unsigned long boundint; - if (!boundintn) { - yasm__error(cur_line, N_("section alignment not constnat")); - return NULL; - } - boundint = yasm_intnum_get_uint(boundintn); + boundintn = yasm_expr_get_intnum(&boundval, NULL); + if (boundintn) { + unsigned long boundint = yasm_intnum_get_uint(boundintn); /* Alignments must be a power of two. */ - if ((boundint & (boundint - 1)) != 0) { - yasm__error(cur_line, - N_("section alignment is not a power of two")); - return NULL; + if ((boundint & (boundint - 1)) == 0) { + yasm_objfmt_section_align(parser_gas->objfmt, + parser_gas->cur_section, boundint, + cur_line); } - - yasm_objfmt_section_align(parser_gas->objfmt, parser_gas->cur_section, - boundint, cur_line); - return NULL; } return yasm_bc_create_align(boundval, fillval, maxskipval, diff --git a/modules/parsers/gas/tests/datavis2.hex b/modules/parsers/gas/tests/datavis2.hex index a0a71fd7..8afb9678 100644 --- a/modules/parsers/gas/tests/datavis2.hex +++ b/modules/parsers/gas/tests/datavis2.hex @@ -93,8 +93,6 @@ 01 00 00 -00 -00 23 20 3a @@ -131,6 +129,8 @@ 00 00 00 +00 +00 2e 74 65 @@ -686,7 +686,7 @@ d8 00 00 00 -60 +5e 00 00 00 @@ -702,7 +702,7 @@ d8 00 00 00 -04 +00 00 00 00 diff --git a/modules/parsers/gas/tests/gassectalign.asm b/modules/parsers/gas/tests/gassectalign.asm index b11bffee..6539d4cc 100644 --- a/modules/parsers/gas/tests/gassectalign.asm +++ b/modules/parsers/gas/tests/gassectalign.asm @@ -1,6 +1,7 @@ .text .align 8 .data +.align 8 .align 16 .bss .align 32 diff --git a/modules/parsers/gas/tests/gassectalign.hex b/modules/parsers/gas/tests/gassectalign.hex index 2740266d..f46f2cdf 100644 --- a/modules/parsers/gas/tests/gassectalign.hex +++ b/modules/parsers/gas/tests/gassectalign.hex @@ -366,7 +366,7 @@ ff 00 00 00 -38 +40 00 00 00 @@ -382,7 +382,7 @@ ff 00 00 00 -08 +10 00 00 00 -- 2.40.0