diff options
Diffstat (limited to 'ld/ld_script.h')
-rw-r--r-- | ld/ld_script.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/ld/ld_script.h b/ld/ld_script.h new file mode 100644 index 000000000000..ea862521c883 --- /dev/null +++ b/ld/ld_script.h @@ -0,0 +1,285 @@ +/*- + * Copyright (c) 2011-2013 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: ld_script.h 2881 2013-01-09 22:46:54Z kaiwang27 $ + */ + +enum ld_script_cmd_type { + LSC_ASSERT, + LSC_ASSIGN, + LSC_AS_NEEDED, + LSC_ENTRY, + LSC_EXTERN, + LSC_FCA, + LSC_HIDDEN_ASSIGN, + LSC_ICA, + LSC_INPUT, + LSC_MEMORY, + LSC_NOCROSSREFS, + LSC_OUTPUT, + LSC_OUTPUT_ARCH, + LSC_OUTPUT_FORMAT, + LSC_PHDRS, + LSC_PROVIDE_ASSIGN, + LSC_REGION_ALIAS, + LSC_SEARCH_DIR, + LSC_SECTIONS, + LSC_SECTIONS_OUTPUT, + LSC_SECTIONS_OUTPUT_DATA, + LSC_SECTIONS_OUTPUT_INPUT, + LSC_SECTIONS_OUTPUT_KEYWORD, + LSC_SECTIONS_OVERLAY, + LSC_STARTUP, + LSC_TARGET, + LSC_VERSION, +}; + +struct ld_script_cmd { + enum ld_script_cmd_type ldc_type; /* ldscript cmd type */ + void *ldc_cmd; /* ldscript cmd */ + STAILQ_ENTRY(ld_script_cmd) ldc_next; /* next cmd */ +}; + +STAILQ_HEAD(ld_script_cmd_head, ld_script_cmd); + +struct ld_script_list { + void *ldl_entry; /* list entry */ + struct ld_script_list *ldl_next; /* next entry */ +}; + +struct ld_script_assert { + struct ld_exp *lda_exp; /* expression to assert */ + char *lda_msg; /* assertion message */ +}; + +enum ld_script_assign_op { + LSAOP_ADD_E, + LSAOP_AND_E, + LSAOP_DIV_E, + LSAOP_E, + LSAOP_LSHIFT_E, + LSAOP_MUL_E, + LSAOP_OR_E, + LSAOP_RSHIFT_E, + LSAOP_SUB_E, +}; + +struct ld_script_assign { + struct ld_exp *lda_var; /* symbol */ + struct ld_exp *lda_val; /* value */ + enum ld_script_assign_op lda_op; /* assign op */ + unsigned lda_provide; /* provide assign */ + int64_t lda_res; /* assign result */ +}; + +struct ld_script_input_file { + unsigned ldif_as_needed; /* as_needed list */ + union { + char *ldif_name; /* input file name */ + struct ld_script_list *ldif_ldl; /* input file list */ + } ldif_u; +}; + +struct ld_script_nocrossref { + struct ld_script_list *ldn_l; /* nocrossref sections */ + STAILQ_ENTRY(ld_script_nocrossref) ldn_next; /* next nocrossref */ +}; + +struct ld_script_region { + char *ldsr_name; /* memory region name */ + char *ldsr_attr; /* memory region attribute */ + struct ld_exp *ldsr_origin; /* memroy region start address */ + struct ld_exp *ldsr_len; /* memroy region length */ + STAILQ_ENTRY(ld_script_region) ldsr_next; /* next memory region */ +}; + +struct ld_script_region_alias { + char *ldra_alias; /* memory region alias name */ + char *ldra_region; /* memory region */ + STAILQ_ENTRY(ld_script_region_alias) ldra_next; /* next region alias */ +}; + +struct ld_script_phdr { + char *ldsp_name; /* phdr name */ + char *ldsp_type; /* phdr type */ + unsigned ldsp_filehdr; /* FILEHDR keyword */ + unsigned ldsp_phdrs; /* PHDRS keyword */ + struct ld_exp *ldsp_addr; /* segment address */ + unsigned ldsp_flags; /* segment flags */ + STAILQ_ENTRY(ld_script_phdr) ldsp_next; /* next phdr */ +}; + +enum ld_script_sections_output_data_type { + LSODT_BYTE, + LSODT_SHORT, + LSODT_LONG, + LSODT_QUAD, + LSODT_SQUAD, + LSODT_FILL, +}; + +struct ld_script_sections_output_data { + enum ld_script_sections_output_data_type ldod_type; /* data type */ + struct ld_exp *ldod_exp; /* data expression */ +}; + +struct ld_script_sections_output_input { + struct ld_wildcard *ldoi_ar; /* archive name */ + struct ld_wildcard *ldoi_file; /* file/member name */ + struct ld_script_list *ldoi_exclude; /* exclude file list */ + struct ld_script_list *ldoi_sec; /* section name list */ + unsigned ldoi_flags; /* input section flags */ + unsigned ldoi_keep; /* keep input section */ +}; + +enum ld_script_sections_output_keywords { + LSOK_CONSTRUCTORS, + LSOK_CONSTRUCTORS_SORT_BY_NAME, + LSOK_CREATE_OBJECT_SYMBOLS, +}; + +struct ld_script_sections_output { + char *ldso_name; /* output section name */ + char *ldso_type; /* output section type */ + struct ld_exp *ldso_vma; /* output section vma */ + struct ld_exp *ldso_lma; /* output section lma */ + struct ld_exp *ldso_align; /* output section align */ + struct ld_exp *ldso_subalign; /* output sectino subalign */ + char *ldso_constraint; /* output section constraint */ + char *ldso_region; /* output section region */ + char *ldso_lma_region; /* output section lma region */ + struct ld_script_list *ldso_phdr; /* output section segment list */ + struct ld_exp *ldso_fill; /* output section fill exp */ + struct ld_script_cmd_head ldso_c; /* output section cmd list */ +}; + +struct ld_script_sections_overlay_section { + char *ldos_name; /* overlay section name */ + struct ld_script_list *ldos_phdr; /* overlay section segment */ + struct ld_exp *ldos_fill; /* overlay section fill exp */ + struct ld_script_cmd_head ldos_c; /* output section cmd list */ +}; + +struct ld_script_sections_overlay { + struct ld_exp *ldso_vma; /* overlay vma */ + struct ld_exp *ldso_lma; /* overlay lma */ + unsigned ldso_nocrossref; /* no corss-ref between sections */ + char *ldso_region; /* overlay region */ + struct ld_script_list *ldso_phdr; /* overlay segment */ + struct ld_exp *ldso_fill; /* overlay fill exp */ + struct ld_script_list *ldso_s; /* overlay section list */ +}; + +struct ld_script_sections { + struct ld_script_cmd_head ldss_c; /* section cmd list */ +}; + +struct ld_script_variable { + char *ldv_name; /* variable name */ + struct ld_symbol *ldv_symbol; /* assoicated symbol */ + int64_t ldv_val; /* variable value */ + UT_hash_handle hh; /* hash handle */ +}; + +enum ld_script_version_lang { + VL_C = 0, + VL_CPP, + VL_JAVA +}; + +struct ld_script_version_entry_head; + +struct ld_script_version_entry { + enum ld_script_version_lang ldve_lang; /* version entry lanauage */ + char *ldve_sym; /* symbol wildcard */ + unsigned char ldve_local; /* symbol scope */ + unsigned char ldve_glob; /* ldve_sym contains glob chars. */ + STAILQ_ENTRY(ld_script_version_entry) ldve_next; + + /* Following fields are only used during script parsing. */ + struct ld_script_version_entry_head *ldve_list; /* extern block */ + unsigned char ldve_lang_set; /* lang is set */ +}; + +STAILQ_HEAD(ld_script_version_entry_head, ld_script_version_entry); + +struct ld_script_version_node { + char *ldvn_name; /* version name */ + char *ldvn_dep; /* version dependency */ + struct ld_script_version_entry_head *ldvn_e; /* version entries */ + STAILQ_ENTRY(ld_script_version_node) ldvn_next; +}; + +struct ld_script { + char *lds_entry_point; /* entry point symbol */ + STAILQ_HEAD(, ld_script_phdr) lds_p; /* phdr table */ + STAILQ_HEAD(, ld_script_region_alias) lds_a; /* region aliases list */ + STAILQ_HEAD(, ld_script_region) lds_r; /* memory region list */ + STAILQ_HEAD(, ld_script_nocrossref) lds_n; /* nocrossref list */ + STAILQ_HEAD(, ld_script_version_node) lds_vn; /* version node list */ + unsigned char lds_vn_name_omitted; /* version node w/o name exists */ + struct ld_script_cmd_head lds_c; /* other ldscript cmd list */ + struct ld_script_variable *lds_v; /* variable table */ +}; + +struct ld_script_cmd *ld_script_assert(struct ld *, struct ld_exp *, char *); +struct ld_script_assign *ld_script_assign(struct ld *, struct ld_exp *, + enum ld_script_assign_op, struct ld_exp *, unsigned, unsigned); +void ld_script_assign_dump(struct ld *, struct ld_script_assign *); +void ld_script_assign_free(struct ld_script_assign *); +void ld_script_cleanup(struct ld *); +struct ld_script_cmd *ld_script_cmd(struct ld *, enum ld_script_cmd_type, + void *); +void ld_script_cmd_free(struct ld_script_cmd *); +void ld_script_cmd_insert(struct ld_script_cmd_head *, + struct ld_script_cmd *); +void ld_script_extern(struct ld *, struct ld_script_list *); +void ld_script_group(struct ld *, struct ld_script_list *); +void ld_script_init(struct ld *); +void ld_script_input(struct ld *, struct ld_script_list *); +struct ld_script_input_file *ld_script_input_file(struct ld *, unsigned, + void *); +struct ld_script_list *ld_script_list(struct ld *, struct ld_script_list *, + void *); +void ld_script_list_free(struct ld_script_list *, void (*)(void *)); +struct ld_script_list *ld_script_list_reverse(struct ld_script_list *); +void ld_script_nocrossrefs(struct ld *, struct ld_script_list *); +struct ld_script_phdr *ld_script_phdr(struct ld *, char *, char *, unsigned, + unsigned, struct ld_exp *, unsigned); +void ld_script_parse(const char *); +void ld_script_parse_internal(void); +struct ld_script_region *ld_script_region(struct ld *, char *, char *, + struct ld_exp *, struct ld_exp *); +void ld_script_process_assign(struct ld *, struct ld_script_assign *); +void ld_script_process_entry(struct ld *, char *); +void ld_script_region_alias(struct ld *, char *, char *); +int64_t ld_script_variable_value(struct ld *, char *); +void ld_script_version_add_node(struct ld *, char *, void *, char *); +struct ld_script_version_entry *ld_script_version_alloc_entry(struct ld *, + char *, void *); +void *ld_script_version_link_entry(struct ld *, + struct ld_script_version_entry_head *, struct ld_script_version_entry *); +void ld_script_version_set_lang(struct ld *, + struct ld_script_version_entry_head *, char *); |