diff options
author | Bernd Schmidt <bernds@codesourcery.com> | 2011-03-31 08:58:28 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds@codesourcery.com> | 2011-03-31 08:58:28 +0000 |
commit | ac14530735340ebde54e9d536e3a0fd3e82f36db (patch) | |
tree | 3b0c55c7d997536e48c444d999138e9bc449df3f /gas/config/tc-tic6x.c | |
parent | 53dd76d35f32095e432e4822dbe06f017f7d7069 (diff) | |
download | gdb-ac14530735340ebde54e9d536e3a0fd3e82f36db.zip gdb-ac14530735340ebde54e9d536e3a0fd3e82f36db.tar.gz gdb-ac14530735340ebde54e9d536e3a0fd3e82f36db.tar.bz2 |
include/elf/
* tic6x.h (R_C6000_JUMP_SPLOT, R_C6000_EHTYPE,
R_C6000_PCR_H16, R_C6000_PCR_L16): New relocs.
(SHN_TIC6X_SCOMMON): Define.
bfd/
* elf32-tic6x.h (struct elf32_tic6x_params): New.
(elf32_tic6x_setup): Declare.
* elf32-tic6x.c: Include <limits.h>.
(ELF_DYNAMIC_LINKER, DEFAULT_STACK_SIZE, PLT_ENTRY_SIZE): Define.
(struct elf32_tic6x_link_hash_table, struct elf32_link_hash_entry):
New structures.
(elf32_tic6x_link_hash_table, is_tic6x_elf): New macros.
(tic6x_elf_scom_section, tic6x_elf_scom_symbol,
tic6x_elf_scom_symbol_ptr): New static variables.
(elf32_tic6x_howto_table, elf32_tic6x_howto_table_rel,
elf32_tic6x_reloc_map): Add R_C6000_JUMP_SLOT, R_C6000_EHTYPE,
R_C6000_PCR_H16 and R_C6000_PCR_L16.
(elf32_tic6x_link_hash_newfunc, elf32_tic6x_link_hash_table_create,
elf32_tic6x_link_hash_table_free, elf32_tic6x_setup,
elf32_tic6x_using_dsbt, elf32_tic6x_install_rela,
elf32_tic6x_create_dynamic_sections, elf32_tic6x_make_got_dynreloc,
elf32_tic6x_finish_dynamic_symbol, elf32_tic6x_gc_sweep_hook,
elf32_tic6x_adjust_dynamic_symbol): New static functions.
(elf32_tic6x_relocate_section): For R_C6000_PCR_S21, convert branches
to weak symbols as required by the ABI.
Handle GOT and DSBT_INDEX relocs, and copy relocs to the output file
as needed when generating DSBT output.
(elf32_tic6x_check_relocs, elf32_tic6x_add_symbol_hook,
elf32_tic6x_symbol_processing, elf32_tic6x_section_from_bfd_section,
elf32_tic6x_allocate_dynrelocs, elf32_tic6x_size_dynamic_sections,
elf32_tic6x_always_size_sections, elf32_tic6x_modify_program_headers,
elf32_tic6x_finish_dynamic_sections, elf32_tic6x_plt_sym_val,
elf32_tic6x_copy_private_data, elf32_tic6x_link_omit_section_dynsym):
New static functions.
(ELF_MAXPAGESIZE): Define to 0x1000.
(bfd_elf32_bfd_copy_private_bfd_data,
bfd_elf32_bfd_link_hash_table_create,
bfd_elf32_bfd_link_hash_table_free, elf_backend_can_refcount,
elf_backend_want_got_plt, elf_backend_want_dynbss,
elf_backend_plt_readonly, elf_backend_got_header_size,
elf_backend_gc_sweep_hook, elf_backend_modify_program_headers,
elf_backend_create_dynamic_sections, elf_backend_adjust_dynamic_symbol,
elf_backend_check_relocs, elf_backend_add_symbol_hook,
elf_backend_symbol_processing, elf_backend_link_output_symbol_hook,
elf_backend_section_from_bfd_section,
elf_backend_finish_dynamic_symbol, elf_backend_always_size_sections,
elf32_tic6x_size_dynamic_sections, elf_backend_finish_dynamic_sections,
elf_backend_omit_section_dynsym, elf_backend_plt_sym_val): Define.
* bfd/reloc.c (BFD_RELOC_C6000_JUMP_SLOT, BFD_RELOC_C6000_EHTYPE,
BFD_RELOC_C6000_PCR_H16, BFD_RELOC_C6000_PCR_S16): Add.
* bfd/bfd-in2.h: Regenerate.
* bfd/libbfd.h: Regenerate.
* config.bfd: Accept tic6x-*-* instead of tic6x-*-elf.
gas/
* config/tc-tic6x.c (sbss_section, scom_section, scom_symbol): New
static variables.
(md_begin): Initialize them.
(s_tic6x_scomm): New static function.
(md_pseudo_table): Add "scomm".
(tc_gen_reloc): Really undo all adjustments made by
bfd_install_relocation.
* doc/c-tic6x.texi: Document the .scomm directive.
gas/testsuite/
* gas/tic6x/scomm-directive-1.s: New test.
* gas/tic6x/scomm-directive-1.d: New test.
* gas/tic6x/scomm-directive-2.s: New test.
* gas/tic6x/scomm-directive-2.d: New test.
* gas/tic6x/scomm-directive-3.s: New test.
* gas/tic6x/scomm-directive-3.d: New test.
* gas/tic6x/scomm-directive-4.s: New test.
* gas/tic6x/scomm-directive-4.d: New test.
* gas/tic6x/scomm-directive-5.s: New test.
* gas/tic6x/scomm-directive-5.d: New test.
* gas/tic6x/scomm-directive-6.s: New test.
* gas/tic6x/scomm-directive-6.d: New test.
* gas/tic6x/scomm-directive-7.s: New test.
* gas/tic6x/scomm-directive-7.d: New test.
* gas/tic6x/scomm-directive-8.s: New test.
* gas/tic6x/scomm-directive-8.d: New test.
ld/
* emulparams/elf32_tic6x_le.sh (BIG_OUTPUT_FORMAT, EXTRA_EM_FILE,
GENERATE_SHLIB_SCRIPT): New defines.
(TEXT_START_ADDR): Define differently depending on target.
(.got): Redefine to include "*(.dsbt)".
(SDATA_START_SYMBOLS): Remove, replace with
(OTHER_GOT_SYMBOLS): New.
(OTHER_BSS_SECTIONS): Define only for ELF targets.
* emultempl/tic6xdsbt.em: New file.
* gen-doc.texi: Set C6X.
* ld.texinfo: Likewise.
(Options specific to C6X uClinux targets): New section.
binutils/
* readelf.c (get_symbol_index_type): Handle SCOM for TIC6X.
(dump_relocations): Likewise.
binutils/testsuite/
* lib/binutils-common.exp (is_elf_format): Accept tic6x*-*-uclinux*.
ld/testsuite/
* ld-scripts/crossref.exp: Add CFLAGS for tic6x*-*-*.
* ld-elf/sec-to-seg.exp: Remove tic6x from list of targets defining
pagesize to 1.
* ld-tic6x/tic6x.exp: Add support for DSBT shared library/executable
linking tests.
* ld-tic6x/dsbt.ld: New linker script.
* ld-tic6x/dsbt-be.ld: New linker script.
* ld-tic6x/dsbt-overflow.ld: New linker script.
* ld-tic6x/dsbt-inrange.ld: New linker script.
* ld-tic6x/shlib-1.s: New test.
* ld-tic6x/shlib-2.s: New test.
* ld-tic6x/shlib-app-1r.s: New test.
* ld-tic6x/shlib-app-1.s: New test.
* ld-tic6x/shlib-1.sd: New test.
* ld-tic6x/shlib-1.dd: New test.
* ld-tic6x/shlib-app-1.rd: New test.
* ld-tic6x/shlib-app-1rb.rd: New test.
* ld-tic6x/shlib-app-1.sd: New test.
* ld-tic6x/static-app-1rb.od: New test.
* ld-tic6x/shlib-app-1.dd: New test.
* ld-tic6x/shlib-app-1rb.sd: New test.
* ld-tic6x/static-app-1b.od: New test.
* ld-tic6x/static-app-1r.od: New test.
* ld-tic6x/shlib-1rb.rd: New test.
* ld-tic6x/shlib-app-1rb.dd: New test.
* ld-tic6x/shlib-1rb.sd: New test.
* ld-tic6x/shlib-1rb.dd: New test.
* ld-tic6x/shlib-app-1b.od: New test.
* ld-tic6x/tic6x.exp: New test.
* ld-tic6x/static-app-1rb.rd: New test.
* ld-tic6x/shlib-app-1r.od: New test.
* ld-tic6x/static-app-1.od: New test.
* ld-tic6x/static-app-1b.rd: New test.
* ld-tic6x/static-app-1r.rd: New test.
* ld-tic6x/static-app-1rb.sd: New test.
* ld-tic6x/static-app-1b.sd: New test.
* ld-tic6x/static-app-1rb.dd: New test.
* ld-tic6x/static-app-1r.sd: New test.
* ld-tic6x/static-app-1b.dd: New test.
* ld-tic6x/shlib-1b.rd: New test.
* ld-tic6x/static-app-1r.dd: New test.
* ld-tic6x/shlib-app-1b.rd: New test.
* ld-tic6x/shlib-1r.rd: New test.
* ld-tic6x/shlib-app-1r.rd: New test.
* ld-tic6x/shlib-1b.sd: New test.
* ld-tic6x/static-app-1.rd: New test.
* ld-tic6x/shlib-app-1b.sd: New test.
* ld-tic6x/shlib-1r.sd: New test.
* ld-tic6x/shlib-1b.dd: New test.
* ld-tic6x/shlib-app-1r.sd: New test.
* ld-tic6x/shlib-app-1b.dd: New test.
* ld-tic6x/shlib-1r.dd: New test.
* ld-tic6x/static-app-1.sd: New test.
* ld-tic6x/shlib-app-1r.dd: New test.
* ld-tic6x/static-app-1.dd: New test.
* ld-tic6x/shlib-noindex.rd: New test.
* ld-tic6x/shlib-noindex.dd: New test.
* ld-tic6x/shlib-noindex.sd: New test.
* ld-tic6x/got-reloc-local-1.s: New test.
* ld-tic6x/got-reloc-local-2.s: New test.
* ld-tic6x/got-reloc-local-r.d: New test.
* ld-tic6x/got-reloc-global.s: New test.
* ld-tic6x/got-reloc-global-addend-1.d: New test.
* ld-tic6x/got-reloc-global-addend-1.s: New test.
* ld-tic6x/got-reloc-global-addend-2.d: New test.
* ld-tic6x/got-reloc-inrange.d: New test.
* ld-tic6x/got-reloc-overflow.d: New test.
* ld-tic6x/got-reloc-global-addend-2.s: New test.
* ld-tic6x/dsbt-index-error.d: New test.
* ld-tic6x/dsbt-index.d: New test.
* ld-tic6x/dsbt-index.s: New test.
* ld-tic6x/shlib-app-1.od: New test.
* ld-tic6x/shlib-app-1rb.od: New test.
* ld-tic6x/shlib-1.rd: New test.
* ld-tic6x/weak.d: New test.
* ld-tic6x/weak-be.d: New test.
* ld-tic6x/weak.s: New test.
* ld-tic6x/weak-data.d: New test.
* ld-tic6x/common.d: New test.
* ld-tic6x/common.ld: New test.
* ld-tic6x/common.s: New test.
Diffstat (limited to 'gas/config/tc-tic6x.c')
-rw-r--r-- | gas/config/tc-tic6x.c | 177 |
1 files changed, 175 insertions, 2 deletions
diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index c937ba5..6ff8006 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -34,6 +34,11 @@ #define TRUNC(X) ((valueT) (X) & 0xffffffffU) #define SEXT(X) ((TRUNC (X) ^ 0x80000000U) - 0x80000000U) +/* Stuff for .scomm symbols. */ +static segT sbss_section; +static asection scom_section; +static asymbol scom_symbol; + const char comment_chars[] = ";"; const char line_comment_chars[] = "#*;"; const char line_separator_chars[] = "@"; @@ -349,6 +354,138 @@ s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +/* .scomm pseudo-op handler. + + This is a new pseudo-op to handle putting objects in .scommon. + By doing this the linker won't need to do any work, + and more importantly it removes the implicit -G arg necessary to + correctly link the object file. */ + +static void +s_tic6x_scomm (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char c; + char *p; + offsetT size; + symbolS *symbolP; + offsetT align; + int align2; + + name = input_line_pointer; + c = get_symbol_end (); + + /* Just after name is now '\0'. */ + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + as_bad (_("expected comma after symbol name")); + ignore_rest_of_line (); + return; + } + + /* Skip ','. */ + input_line_pointer++; + if ((size = get_absolute_expression ()) < 0) + { + /* xgettext:c-format */ + as_warn (_("invalid length for .scomm directive")); + ignore_rest_of_line (); + return; + } + + /* The third argument to .scomm is the alignment. */ + if (*input_line_pointer != ',') + align = 8; + else + { + ++input_line_pointer; + align = get_absolute_expression (); + if (align <= 0) + { + as_warn (_("alignment is not a positive number")); + align = 8; + } + } + + /* Convert to a power of 2 alignment. */ + if (align) + { + for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2) + continue; + if (align != 1) + { + as_bad (_("alignment is not a power of 2")); + ignore_rest_of_line (); + return; + } + } + else + align2 = 0; + + *p = 0; + symbolP = symbol_find_or_make (name); + *p = c; + + if (S_IS_DEFINED (symbolP)) + { + /* xgettext:c-format */ + as_bad (_("attempt to re-define symbol `%s'"), + S_GET_NAME (symbolP)); + ignore_rest_of_line (); + return; + } + + if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size) + { + /* xgettext:c-format */ + as_bad (_("attempt to redefine `%s' with a different length"), + S_GET_NAME (symbolP)); + + ignore_rest_of_line (); + return; + } + + if (symbol_get_obj (symbolP)->local) + { + segT old_sec = now_seg; + int old_subsec = now_subseg; + char *pfrag; + + record_alignment (sbss_section, align2); + subseg_set (sbss_section, 0); + + if (align2) + frag_align (align2, 0, 0); + + if (S_GET_SEGMENT (symbolP) == sbss_section) + symbol_get_frag (symbolP)->fr_symbol = 0; + + symbol_set_frag (symbolP, frag_now); + + pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size, + (char *) 0); + *pfrag = 0; + S_SET_SIZE (symbolP, size); + S_SET_SEGMENT (symbolP, sbss_section); + S_CLEAR_EXTERNAL (symbolP); + subseg_set (old_sec, old_subsec); + } + else + { + S_SET_VALUE (symbolP, (valueT) size); + S_SET_ALIGN (symbolP, 1 << align2); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, &scom_section); + } + + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; + + demand_empty_rest_of_line (); +} + /* Track for each attribute whether it has been set explicitly (and so should not have a default value set by the assembler). */ static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES]; @@ -396,6 +533,7 @@ const pseudo_typeS md_pseudo_table[] = { "arch", s_tic6x_arch, 0 }, { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 }, { "nocmp", s_tic6x_nocmp, 0 }, + { "scomm", s_tic6x_scomm, 0 }, { "word", cons, 4 }, { 0, 0, 0 } }; @@ -411,6 +549,9 @@ void md_begin (void) { tic6x_opcode_id id; + flagword applicable; + segT seg; + subsegT subseg; bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0); @@ -427,6 +568,32 @@ md_begin (void) != NULL) as_fatal ("%s", _(errmsg)); } + + /* Save the current subseg so we can restore it [it's the default one and + we don't want the initial section to be .sbss]. */ + seg = now_seg; + subseg = now_subseg; + + /* The sbss section is for local .scomm symbols. */ + sbss_section = subseg_new (".bss", 0); + seg_info (sbss_section)->bss = 1; + + /* This is copied from perform_an_assembly_pass. */ + applicable = bfd_applicable_section_flags (stdoutput); + bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC); + + subseg_set (seg, subseg); + + /* We must construct a fake section similar to bfd_com_section + but with the name .scommon. */ + scom_section = bfd_com_section; + scom_section.name = ".scommon"; + scom_section.output_section = & scom_section; + scom_section.symbol = & scom_symbol; + scom_section.symbol_ptr_ptr = & scom_section.symbol; + scom_symbol = * bfd_com_section.symbol; + scom_symbol.name = ".scommon"; + scom_symbol.section = & scom_section; } /* Whether the current line being parsed had the "||" parallel bars. */ @@ -4029,11 +4196,13 @@ arelent * tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; + asymbol *symbol; bfd_reloc_code_real_type r_type; reloc = xmalloc (sizeof (arelent)); reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); - *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + symbol = symbol_get_bfdsym (fixp->fx_addsy); + *reloc->sym_ptr_ptr = symbol; reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->addend = (tic6x_generate_rela ? fixp->fx_offset : 0); r_type = fixp->fx_r_type; @@ -4049,7 +4218,11 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) /* Correct for adjustments bfd_install_relocation will make. */ if (reloc->howto->pcrel_offset && reloc->howto->partial_inplace) - reloc->addend += reloc->address; + { + reloc->addend += reloc->address; + if (!bfd_is_com_section (symbol)) + reloc->addend -= symbol->value; + } return reloc; } |