145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ELF object format 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2003-2007 Michael Urman 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met: 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer. 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer in the 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * documentation and/or other materials provided with the distribution. 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE. 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h> 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Notes 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * elf-objfmt uses the "linking" view of an ELF file: 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ELF header, an optional program header table, several sections, 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and a section header table 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The ELF header tells us some overall program information, 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * where to find the PHT (if it exists) with phnum and phentsize, 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and where to find the SHT with shnum and shentsize 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The PHT doesn't seem to be generated by NASM for elftest.asm 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The SHT 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Each Section is spatially disjoint, and has exactly one SHT entry. 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h> 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "elf.h" 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "elf-machine.h" 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct yasm_objfmt_elf { 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_base objfmt; /* base structure */ 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_head* elf_symtab; /* symbol table of indexed syms */ 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_head* shstrtab; /* section name strtab */ 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_head* strtab; /* strtab entries */ 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_entry *file_strtab_entry;/* .file symbol associated string */ 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *dotdotsym; /* ..sym symbol */ 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_objfmt_elf; 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct { 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf; 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns; 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org FILE *f; 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead *shead; 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *sect; 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object *object; 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long sindex; 70a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org yasm_symrec *GOT_sym; 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} elf_objfmt_output_info; 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct { 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object *object; 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf; 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns; 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int local_names; 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} build_symtab_info; 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_elf_LTX_objfmt; 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_elf32_LTX_objfmt; 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_elf64_LTX_objfmt; 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic elf_symtab_entry * 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_section_index sectidx, elf_symbol_binding bind, 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symbol_type type, elf_symbol_vis vis, 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *size, elf_address *value, 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object *object) 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data); 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!entry) { 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ char *symname = yasm_symrec_get_global_name(sym, object); 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_entry *name = 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_append_str(objfmt_elf->strtab, symname); 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(symname); 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = elf_symtab_entry_create(name, sym); 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_add_data(sym, &elf_symrec_data, entry); 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Only append to table if not already appended */ 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!elf_sym_in_table(entry)) 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_set_nonzero(entry, NULL, sectidx, bind, type, size, value); 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_sym_set_visibility(entry, vis); 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return entry; 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic elf_symtab_entry * 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbuild_extern(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object) 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams = 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_objext_valparams(sym); 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objext_valparams) { 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp = yasm_vps_first(objext_valparams); 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (; vp; vp = yasm_vps_next(vp)) { 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_vp_string(vp)) 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TYPE, 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("unrecognized symbol type `%s'"), 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_vp_string(vp)); 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL, 0, 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STV_DEFAULT, NULL, NULL, object); 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct elf_build_global_data { 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *size; 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long type; /* elf_symbol_type */ 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symbol_vis vis; 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int vis_overrides; 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_global_helper_valparam(void *obj, yasm_valparam *vp, unsigned long line, 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *d) 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct elf_build_global_data *data = (struct elf_build_global_data *)d; 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s; 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!vp->val && (s = yasm_vp_id(vp))) { 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TYPE, N_("unrecognized symbol type `%s'"), 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s); 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!vp->val && vp->type == YASM_PARAM_EXPR && !data->size) { 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->size = yasm_expr_copy(vp->param.e); 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return yasm_dir_helper_valparam_warn(obj, vp, line, d); 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_global_helper_vis(void *obj, yasm_valparam *vp, unsigned long line, 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *d, uintptr_t vis) 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct elf_build_global_data *data = (struct elf_build_global_data *)d; 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->vis = vis; 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->vis_overrides++; 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic elf_symtab_entry * 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbuild_global(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object) 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams = 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_objext_valparams(sym); 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct elf_build_global_data data; 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org static const yasm_dir_help help[] = { 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "function", 0, yasm_dir_helper_flag_set, 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_build_global_data, type), STT_FUNC }, 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "data", 0, yasm_dir_helper_flag_set, 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_build_global_data, type), STT_OBJECT }, 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "object", 0, yasm_dir_helper_flag_set, 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_build_global_data, type), STT_OBJECT }, 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "internal", 0, elf_global_helper_vis, 0, STV_INTERNAL }, 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "hidden", 0, elf_global_helper_vis, 0, STV_HIDDEN }, 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "protected", 0, elf_global_helper_vis, 0, STV_PROTECTED }, 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org }; 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.size = NULL; 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = 0; 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.vis = STV_DEFAULT; 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.vis_overrides = 0; 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objext_valparams) 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dir_helper(sym, yasm_vps_first(objext_valparams), 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_decl_line(sym), help, NELEMS(help), 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &data, elf_global_helper_valparam); 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.vis_overrides > 1) { 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("More than one symbol visibility provided; using last")); 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_GLOBAL, 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type, data.vis, data.size, NULL, 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org object); 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@null@*/ elf_symtab_entry * 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbuild_common(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, yasm_object *object) 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr **size = yasm_symrec_get_common_size(sym); 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams = 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_objext_valparams(sym); 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long addralign = 0; 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objext_valparams) { 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp = yasm_vps_first(objext_valparams); 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (; vp; vp = yasm_vps_next(vp)) { 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!vp->val) { 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr *align_expr; 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ const yasm_intnum *align_intn; 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(align_expr = yasm_vp_expr(vp, object->symtab, 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_def_line(sym))) 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || !(align_intn = yasm_expr_get_intnum(&align_expr, 0))) { 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("alignment constraint is not an integer")); 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (align_expr) 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(align_expr); 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org addralign = yasm_intnum_get_uint(align_intn); 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(align_expr); 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Alignments must be a power of two. */ 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!is_exp2(addralign)) { 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("alignment constraint is not a power of two")); 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("Unrecognized qualifier `%s'"), vp->val); 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return elf_objfmt_symtab_append(objfmt_elf, sym, SHN_COMMON, STB_GLOBAL, 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0, STV_DEFAULT, *size, &addralign, object); 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d) 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org build_symtab_info *info = (build_symtab_info *)d; 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_sym_vis vis = yasm_symrec_get_visibility(sym); 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_sym_status status = yasm_symrec_get_status(sym); 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data); 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_address value=0; 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *sect=NULL; 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *precbc=NULL; 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vis & YASM_SYM_EXTERN) { 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = build_extern(info->objfmt_elf, sym, info->object); 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_decl_line(sym)); 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vis & YASM_SYM_COMMON) { 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = build_common(info->objfmt_elf, sym, info->object); 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_decl_line(sym)); 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If the COMMON variable was actually defined, fall through. */ 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(status & YASM_SYM_DEFINED)) 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Ignore any undefined at this point. */ 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(status & YASM_SYM_DEFINED)) 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm_symrec_get_label(sym, &precbc)) { 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm_symrec_get_equ(sym) && !yasm_symrec_is_abs(sym)) 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org precbc = NULL; 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (precbc) 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sect = yasm_bc_get_section(precbc); 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (entry && elf_sym_in_table(entry)) 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ; 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (vis & YASM_SYM_GLOBAL) { 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = build_global(info->objfmt_elf, sym, info->object); 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int is_sect = 0; 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Locals (except when debugging) do not need to be 30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * in the symbol table, unless they're a section. 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (sect && 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0) 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org is_sect = 1; 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#if 0 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME: to enable this we must have handling in place for special 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * symbols. 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!info->local_names && !is_sect) 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_symrec_get_equ(sym) && !yasm_symrec_is_abs(sym)) 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = yasm_symrec_get_data(sym, &elf_symrec_data); 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!entry) { 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ char *symname = 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_global_name(sym, info->object); 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_entry *name = !info->local_names || is_sect ? NULL : 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_append_str(info->objfmt_elf->strtab, symname); 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(symname); 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = elf_symtab_entry_create(name, sym); 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_add_data(sym, &elf_symrec_data, entry); 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!elf_sym_in_table(entry)) 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, entry); 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL, 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org is_sect ? STT_SECTION : 0, NULL, 0); 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (is_sect) 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (precbc) 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value = yasm_bc_next_offset(precbc); 34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_set_nonzero(entry, sect, 0, 0, 0, NULL, &value); 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_objfmt * 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_create_common(yasm_object *object, yasm_objfmt_module *module, 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int bits_pref, 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const elf_machine_handler **elf_march_out) 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = yasm_xmalloc(sizeof(yasm_objfmt_elf)); 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *filesym; 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_entry *entry; 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const elf_machine_handler *elf_march; 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->objfmt.module = module; 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_march = elf_set_arch(object->arch, object->symtab, bits_pref); 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!elf_march) { 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(objfmt_elf); 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (elf_march_out) 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *elf_march_out = elf_march; 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->shstrtab = elf_strtab_create(); 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->strtab = elf_strtab_create(); 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->elf_symtab = elf_symtab_create(); 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME: misuse of NULL bytecode here; it works, but only barely. */ 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org filesym = yasm_symtab_define_label(object->symtab, ".file", NULL, 0, 0); 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Put in current input filename; we'll replace it in output() */ 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->file_strtab_entry = 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_append_str(objfmt_elf->strtab, object->src_filename); 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = elf_symtab_entry_create(objfmt_elf->file_strtab_entry, filesym); 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_add_data(filesym, &elf_symrec_data, entry); 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_set_nonzero(entry, NULL, SHN_ABS, STB_LOCAL, STT_FILE, NULL, 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL); 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* FIXME: misuse of NULL bytecode */ 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->dotdotsym = 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_define_label(object->symtab, "..sym", NULL, 0, 0); 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (yasm_objfmt *)objfmt_elf; 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_objfmt * 38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_create(yasm_object *object) 39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const elf_machine_handler *elf_march; 39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt *objfmt; 39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf; 39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt = elf_objfmt_create_common(object, &yasm_elf_LTX_objfmt, 0, 39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &elf_march); 39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt) { 39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf = (yasm_objfmt_elf *)objfmt; 39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Figure out which bitness of object format to use */ 40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (elf_march->bits == 32) 40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->objfmt.module = &yasm_elf32_LTX_objfmt; 40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (elf_march->bits == 64) 40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_elf->objfmt.module = &yasm_elf64_LTX_objfmt; 40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return objfmt; 40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_objfmt * 40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf32_objfmt_create(yasm_object *object) 41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return elf_objfmt_create_common(object, &yasm_elf32_LTX_objfmt, 32, NULL); 41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_objfmt * 41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf64_objfmt_create(yasm_object *object) 41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return elf_objfmt_create_common(object, &yasm_elf64_LTX_objfmt, 64, NULL); 41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic long 42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output_align(FILE *f, unsigned int align) 42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long pos; 42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long delta; 42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!is_exp2(align)) 42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("requested alignment not a power of two"); 42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pos = ftell(f); 42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pos == -1) { 43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_IO, 43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("could not get file position on output file")); 43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org delta = align - (pos & (align-1)); 43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (delta != align) { 43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pos += delta; 43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fseek(f, pos, SEEK_SET) < 0) { 43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_IO, 43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("could not set file position on output file")); 44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return pos; 44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc, 44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *buf, unsigned int destsize, 44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int valsize, int warn, void *d) 45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_reloc_entry *reloc; 45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output_info *info = d; 45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *zero; 45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int retval; 45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc = elf_reloc_entry_create(sym, NULL, 457a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org yasm_intnum_create_uint(bc->offset), 0, valsize, 0); 45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (reloc == NULL) { 45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TYPE, N_("elf: invalid relocation size")); 46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* allocate .rel[a] sections on a need-basis */ 46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_append_reloc(info->sect, info->shead, reloc); 46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org zero = yasm_intnum_create_uint(0); 466a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_handle_reloc_addend(zero, reloc, 0); 46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_arch_intnum_tobytes(info->object->arch, zero, buf, destsize, 46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org valsize, 0, bc, warn); 46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(zero); 47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output_value(yasm_value *value, unsigned char *buf, 47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int destsize, unsigned long offset, 47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *bc, int warn, /*@null@*/ void *d) 47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d; 47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ yasm_intnum *intn; 48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long intn_val; 48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ elf_reloc_entry *reloc = NULL; 48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int retval; 48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int valsize = value->size; 48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info == NULL) 48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("null info struct"); 48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->abs) 48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->abs = yasm_expr_simplify(value->abs, 1); 49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Try to output constant and PC-relative section-local first. 49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note this does NOT output any value with a SEG, WRT, external, 49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * cross-section, or non-PC-relative reference (those are handled below). 49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (yasm_value_output_basic(value, buf, destsize, bc, warn, 49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->object->arch)) { 49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case -1: 49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 0: 50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Handle other expressions, with relocation if necessary */ 50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->seg_of || value->section_rel || value->rshift > 0) { 50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("elf: relocation too complex")); 50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn_val = 0; 51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->rel) { 51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_sym_vis vis = yasm_symrec_get_visibility(value->rel); 51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel; 51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ yasm_symrec *wrt = value->wrt; 51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (wrt == info->objfmt_elf->dotdotsym) 51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org wrt = NULL; 52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (wrt && elf_is_wrt_sym_relative(wrt)) 52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ; 52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (wrt && elf_is_wrt_pos_adjusted(wrt)) 52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn_val = offset + bc->offset; 52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (vis == YASM_SYM_LOCAL) { 52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *sym_precbc; 52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Local symbols need relocation to their section's start, and 52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * add in the offset of the bytecode (within the target section) 52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * into the abs portion. 52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * This is only done if the symbol is relocated against the 53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * section instead of the symbol itself. 53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_symrec_get_label(sym, &sym_precbc)) { 53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Relocate to section start */ 53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *sym_sect = yasm_bc_get_section(sym_precbc); 53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ elf_secthead *sym_shead; 53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym_shead = yasm_section_get_data(sym_sect, &elf_section_data); 53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(sym_shead != NULL); 53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym = elf_secthead_get_sym(sym_shead); 54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn_val = yasm_bc_next_offset(sym_precbc); 54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* For PC-relative, need to add offset of expression within bc. */ 54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->curpos_rel) 54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn_val += offset; 54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 549a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org /* Check for _GLOBAL_OFFSET_TABLE_ symbol reference */ 55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org reloc = elf_reloc_entry_create(sym, wrt, 55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_create_uint(bc->offset + offset), value->curpos_rel, 552a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org valsize, sym == info->GOT_sym); 55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (reloc == NULL) { 55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TYPE, 55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("elf: invalid relocation (WRT or size)")); 55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* allocate .rel[a] sections on a need-basis */ 55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_append_reloc(info->sect, info->shead, reloc); 56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org intn = yasm_intnum_create_uint(intn_val); 56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->abs) { 56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, 0); 56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!intn2) { 56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("elf: relocation too complex")); 56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2); 57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (reloc) 576a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_handle_reloc_addend(intn, reloc, offset); 57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_arch_intnum_tobytes(info->object->arch, intn, buf, destsize, 57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org valsize, 0, bc, warn); 57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(intn); 58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d) 58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d; 58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char buf[256]; 58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@only@*/ unsigned char *bigbuf; 58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long size = 256; 59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int gap; 59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info == NULL) 59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("null info struct"); 59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bigbuf = yasm_bc_tobytes(bc, buf, &size, &gap, info, 59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output_value, elf_objfmt_output_reloc); 59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Don't bother doing anything else if size ended up being 0. */ 59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (size == 0) { 60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bigbuf) 60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bigbuf); 60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *bcsize = yasm_intnum_create_uint(size); 60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_add_size(info->shead, bcsize); 60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(bcsize); 60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Warn that gaps are converted to 0 and write out the 0's. */ 61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (gap) { 61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long left; 61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_UNINIT_CONTENTS, 61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("uninitialized space declared in code/data section: zeroing")); 61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Write out in chunks */ 61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memset(buf, 0, 256); 61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org left = size; 61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (left > 256) { 61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(buf, 256, 1, info->f); 62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org left -= 256; 62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(buf, left, 1, info->f); 62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Output buf (or bigbuf if non-NULL) to file */ 62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(bigbuf ? bigbuf : buf, (size_t)size, 1, info->f); 62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If bigbuf was allocated, free it */ 62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bigbuf) 63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bigbuf); 63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d) 63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d; 63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ elf_secthead *shead; 64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long pos; 64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *relname; 64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *sectname; 64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info == NULL) 64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("null info struct"); 64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org shead = yasm_section_get_data(sect, &elf_section_data); 64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (shead == NULL) 64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("no associated data"); 64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (elf_secthead_get_align(shead) == 0) 65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_align(shead, yasm_section_get_align(sect)); 65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* don't output header-only sections */ 65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((elf_secthead_get_type(shead) & SHT_NOBITS) == SHT_NOBITS) 65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { 65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *last = yasm_section_bcs_last(sect); 65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (last) { 65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *sectsize; 65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sectsize = yasm_intnum_create_uint(yasm_bc_next_offset(last)); 66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_add_size(shead, sectsize); 66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(sectsize); 66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_index(shead, ++info->sindex); 66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((pos = ftell(info->f)) == -1) { 66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_IO, 66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("couldn't read position on output stream")); 67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 0); 67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pos = elf_secthead_set_file_offset(shead, pos); 67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fseek(info->f, pos, SEEK_SET) < 0) { 67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_IO, N_("couldn't seek on output stream")); 67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 0); 67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->sect = sect; 67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->shead = shead; 68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_traverse(sect, info->errwarns, info, 68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output_bytecode); 68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_index(shead, ++info->sindex); 68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* No relocations to output? Go on to next section */ 68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (elf_secthead_write_relocs_to_file(info->f, sect, shead, 68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->errwarns) == 0) 68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_rel_index(shead, ++info->sindex); 69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* name the relocation section .rel[a].foo */ 69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sectname = yasm_section_get_name(sect); 69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org relname = elf_secthead_name_reloc_section(sectname); 69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_rel_name(shead, 69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_append_str(info->objfmt_elf->shstrtab, relname)); 69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(relname); 69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d) 70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d; 70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ elf_secthead *shead; 70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info == NULL) 70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("null info struct"); 70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org shead = yasm_section_get_data(sect, &elf_section_data); 71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (shead == NULL) 71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error("no section header attached to section"); 71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if(elf_secthead_write_to_file(info->f, shead, info->sindex+1)) 71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->sindex++; 71545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 71645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output strtab headers here? */ 71745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 71845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* relocation entries for .foo are stored in section .rel[a].foo */ 71945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if(elf_secthead_write_rel_to_file(info->f, 3, sect, shead, 72045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->sindex+1)) 72145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->sindex++; 72245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 72345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 72445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 72545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 72645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 72745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_output(yasm_object *object, FILE *f, int all_syms, 72845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns) 72945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 73045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; 73145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output_info info; 73245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org build_symtab_info buildsym_info; 73345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org long pos; 73445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long elf_shead_addr; 73545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead *esdn; 73645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long elf_strtab_offset, elf_shstrtab_offset, elf_symtab_offset; 73745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long elf_strtab_size, elf_shstrtab_size, elf_symtab_size; 73845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_entry *elf_strtab_name, *elf_shstrtab_name, *elf_symtab_name; 73945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long elf_symtab_nlocal; 74045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 74145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.object = object; 74245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.objfmt_elf = objfmt_elf; 74345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.errwarns = errwarns; 74445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.f = f; 745a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org info.GOT_sym = yasm_symtab_get(object->symtab, "_GLOBAL_OFFSET_TABLE_"); 74645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 74745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Update filename strtab */ 74845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_entry_set_str(objfmt_elf->file_strtab_entry, 74945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org object->src_filename); 75045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 75145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Allocate space for Ehdr by seeking forward */ 75245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fseek(f, (long)(elf_proghead_get_size()), SEEK_SET) < 0) { 75345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file")); 75445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 75545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 75645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 75745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 75845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* add all (local) syms to symtab because relocation needs a symtab index 75945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * if all_syms, register them by name. if not, use strtab entry 0 */ 76045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buildsym_info.object = object; 76145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buildsym_info.objfmt_elf = objfmt_elf; 76245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buildsym_info.errwarns = errwarns; 76345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buildsym_info.local_names = all_syms; 76445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_traverse(object->symtab, &buildsym_info, 76545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_build_symtab); 76645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_nlocal = elf_symtab_assign_indices(objfmt_elf->elf_symtab); 76745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 76845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output known sections - includes reloc sections which aren't in yasm's 76945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * list. Assign indices as we go. */ 77045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.sindex = 3; 77145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_object_sections_traverse(object, &info, 77245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output_section)) 77345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 77445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 77545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* add final sections to the shstrtab */ 77645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".strtab"); 77745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".symtab"); 77845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_shstrtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, 77945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ".shstrtab"); 78045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 78145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output .shstrtab */ 78245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((pos = elf_objfmt_output_align(f, 4)) == -1) { 78345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 78445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 78545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 78645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_shstrtab_offset = (unsigned long) pos; 78745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_shstrtab_size = elf_strtab_output_to_file(f, objfmt_elf->shstrtab); 78845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 78945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output .strtab */ 79045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((pos = elf_objfmt_output_align(f, 4)) == -1) { 79145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 79245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 79345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 79445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_offset = (unsigned long) pos; 79545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_size = elf_strtab_output_to_file(f, objfmt_elf->strtab); 79645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 79745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output .symtab - last section so all others have indexes */ 79845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((pos = elf_objfmt_output_align(f, 4)) == -1) { 79945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 80045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 80145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 80245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_offset = (unsigned long) pos; 80345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab, 80445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org errwarns); 80545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 80645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output section header table */ 80745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((pos = elf_objfmt_output_align(f, 16)) == -1) { 80845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 80945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 81045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 81145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_shead_addr = (unsigned long) pos; 81245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 81345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* stabs debugging support */ 81445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (strcmp(yasm_dbgfmt_keyword(object->dbgfmt), "stabs")==0) { 81545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *stabsect = yasm_object_find_general(object, ".stab"); 81645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *stabstrsect = 81745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object_find_general(object, ".stabstr"); 81845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (stabsect && stabstrsect) { 81945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead *stab = 82045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_data(stabsect, &elf_section_data); 82145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead *stabstr = 82245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_data(stabstrsect, &elf_section_data); 82345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (stab && stabstr) { 82445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_link(stab, elf_secthead_get_index(stabstr)); 82545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 82645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 82745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_internal_error(N_("missing .stab or .stabstr section/data")); 82845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 82945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 83045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 83145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output dummy section header - 0 */ 83245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.sindex = 0; 83345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 83445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org esdn = elf_secthead_create(NULL, SHT_NULL, 0, 0, 0); 83545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_index(esdn, 0); 83645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_write_to_file(f, esdn, 0); 83745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_destroy(esdn); 83845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 83945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org esdn = elf_secthead_create(elf_shstrtab_name, SHT_STRTAB, 0, 84045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_shstrtab_offset, elf_shstrtab_size); 84145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_index(esdn, 1); 84245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_write_to_file(f, esdn, 1); 84345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_destroy(esdn); 84445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 84545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org esdn = elf_secthead_create(elf_strtab_name, SHT_STRTAB, 0, 84645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_offset, elf_strtab_size); 84745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_index(esdn, 2); 84845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_write_to_file(f, esdn, 2); 84945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_destroy(esdn); 85045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 85145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org esdn = elf_secthead_create(elf_symtab_name, SHT_SYMTAB, 0, 85245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_offset, elf_symtab_size); 85345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_index(esdn, 3); 85445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_info(esdn, elf_symtab_nlocal); 85545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_link(esdn, 2); /* for .strtab, which is index 2 */ 85645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_write_to_file(f, esdn, 3); 85745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_destroy(esdn); 85845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 85945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.sindex = 3; 86045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output remaining section headers */ 86145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object_sections_traverse(object, &info, elf_objfmt_output_secthead); 86245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 86345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* output Ehdr */ 86445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fseek(f, 0, SEEK_SET) < 0) { 86545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_IO, N_("could not seek on output file")); 86645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 86745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 86845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 86945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 87045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_proghead_write_to_file(f, elf_shead_addr, info.sindex+1, 1); 87145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 87245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 87345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 87445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_destroy(yasm_objfmt *objfmt) 87545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 87645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; 87745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_destroy(objfmt_elf->elf_symtab); 87845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_destroy(objfmt_elf->shstrtab); 87945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_destroy(objfmt_elf->strtab); 88045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(objfmt); 88145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 88245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 883a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgstatic void 884a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgelf_objfmt_init_new_section(yasm_section *sect, unsigned long line) 88545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 886a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org yasm_object *object = yasm_section_get_object(sect); 887a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org const char *sectname = yasm_section_get_name(sect); 88845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; 88945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead *esd; 89045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym; 89145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab, 89245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sectname); 89345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 894a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_section_type type=SHT_PROGBITS; 895a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_size entsize=0; 896a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 897a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (yasm__strcasecmp(sectname, ".stab")==0) { 898a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org entsize = 12; 899a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } else if (yasm__strcasecmp(sectname, ".stabstr")==0) { 900a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org type = SHT_STRTAB; 901a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 902a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 903a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org esd = elf_secthead_create(name, type, 0, 0, 0); 904a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_secthead_set_entsize(esd, entsize); 90545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_add_data(sect, &elf_section_data, esd); 90645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym = yasm_symtab_define_label(object->symtab, sectname, 90745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_first(sect), 1, line); 90845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 90945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_sym(esd, sym); 91045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 91145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 91245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_section * 91345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_add_default_section(yasm_object *object) 91445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 91545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *retval; 91645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int isnew; 91745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 91845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_object_get_general(object, ".text", 16, 1, 0, &isnew, 0); 919a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (isnew) 920a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { 921a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_secthead *esd = yasm_section_get_data(retval, &elf_section_data); 922a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_secthead_set_typeflags(esd, SHT_PROGBITS, 923a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org SHF_ALLOC + SHF_EXECINSTR); 924a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org yasm_section_set_default(retval, 1); 925a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 92645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 92745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 92845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 92945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct elf_section_switch_data { 93045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_intnum *align_intn; 93145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long flags; 93245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long type; 93345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int gasflags; 93445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int stdsect; 93545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 93645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 93745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* GAS-style flags */ 93845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 93945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_helper_gasflags(void *obj, yasm_valparam *vp, unsigned long line, void *d, 94045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ uintptr_t arg) 94145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 94245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct elf_section_switch_data *data = (struct elf_section_switch_data *)d; 94345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s = yasm_vp_string(vp); 94445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t i; 94545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 94645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 94745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 94845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("non-string section attribute")); 94945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 95045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 95145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 95245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data->stdsect && strlen(s) == 0) { 95345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->gasflags = 1; 95445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 95545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 95645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 95745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags = 0; 95845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<strlen(s); i++) { 95945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (s[i]) { 96045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'a': 96145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_ALLOC; 96245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 96345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'w': 96445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_WRITE; 96545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 96645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'x': 96745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_EXECINSTR; 96845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 96945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'M': 97045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_MERGE; 97145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 97245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'S': 97345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_STRINGS; 97445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 97545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'G': 97645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_GROUP; 97745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 97845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'T': 97945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->flags |= SHF_TLS; 98045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 98145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 98245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 98345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("unrecognized section attribute: `%c'"), 98445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s[i]); 98545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 98645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 98745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 98845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->gasflags = 1; 98945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 99045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 99145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 99245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@observer@*/ /*@null@*/ yasm_section * 99345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, 99445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_valparamhead *objext_valparams, 99545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long line) 99645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 99745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp; 99845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *retval; 99945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int isnew; 100045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long align = 4; 100145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int flags_override = 0; 100245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *sectname; 100345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int resonly = 0; 100445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 100545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct elf_section_switch_data data; 100645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 100745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org static const yasm_dir_help help[] = { 100845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "alloc", 0, yasm_dir_helper_flag_or, 100945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_ALLOC }, 101045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "exec", 0, yasm_dir_helper_flag_or, 101145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_EXECINSTR }, 101245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "write", 0, yasm_dir_helper_flag_or, 101345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_WRITE }, 101445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "tls", 0, yasm_dir_helper_flag_or, 101545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_TLS }, 101645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "progbits", 0, yasm_dir_helper_flag_set, 101745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, type), SHT_PROGBITS }, 101845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "noalloc", 0, yasm_dir_helper_flag_and, 101945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_ALLOC }, 102045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "noexec", 0, yasm_dir_helper_flag_and, 102145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_EXECINSTR }, 102245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "nowrite", 0, yasm_dir_helper_flag_and, 102345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_WRITE }, 102445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "notls", 0, yasm_dir_helper_flag_and, 102545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, flags), SHF_TLS }, 102645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "noprogbits", 0, yasm_dir_helper_flag_set, 102745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, type), SHT_NOBITS }, 102845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "nobits", 0, yasm_dir_helper_flag_set, 102945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, type), SHT_NOBITS }, 103045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "gasflags", 1, elf_helper_gasflags, 0, 0 }, 103145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "align", 1, yasm_dir_helper_intn, 103245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct elf_section_switch_data, align_intn), 0 } 103345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org }; 103445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr *merge_expr = NULL; 103545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ const yasm_intnum *merge_intn = NULL; 103645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead *esd; 103745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 103845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.align_intn = NULL; 103945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = SHF_ALLOC; 104045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_PROGBITS; 104145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.gasflags = 0; 104245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.stdsect = 1; 104345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 104445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_first(valparams); 104545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sectname = yasm_vp_string(vp); 104645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!sectname) 104745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 104845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_next(vp); 104945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 105045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (strcmp(sectname, ".bss") == 0) { 105145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_NOBITS; 105245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = SHF_ALLOC + SHF_WRITE; 105345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org resonly = 1; 105445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (strcmp(sectname, ".data") == 0) { 105545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_PROGBITS; 105645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = SHF_ALLOC + SHF_WRITE; 105745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (strcmp(sectname, ".tdata") == 0) { 105845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_PROGBITS; 105945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = SHF_ALLOC + SHF_WRITE + SHF_TLS; 106045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (strcmp(sectname, ".rodata") == 0) { 106145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_PROGBITS; 106245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = SHF_ALLOC; 106345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (strcmp(sectname, ".text") == 0) { 106445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org align = 16; 106545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_PROGBITS; 106645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = SHF_ALLOC + SHF_EXECINSTR; 106745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (strcmp(sectname, ".comment") == 0) { 106845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org align = 0; 106945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.type = SHT_PROGBITS; 107045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = 0; 107145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 107245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Default to code */ 107345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org align = 1; 107445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.stdsect = 0; 107545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 107645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 107745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org flags_override = yasm_dir_helper(object, vp, line, help, NELEMS(help), 107845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &data, yasm_dir_helper_valparam_warn); 107945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (flags_override < 0) 108045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; /* error occurred */ 108145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 108245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.align_intn) { 108345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org align = yasm_intnum_get_uint(data.align_intn); 108445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(data.align_intn); 108545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 108645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Alignments must be a power of two. */ 108745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!is_exp2(align)) { 108845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 108945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("argument to `%s' is not a power of two"), 109045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "align"); 109145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 109245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 109345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 109445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 109545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Handle merge entity size */ 109645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.flags & SHF_MERGE) { 109745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objext_valparams && (vp = yasm_vps_first(objext_valparams)) 109845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && !vp->val) { 109945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!(merge_expr = yasm_vp_expr(vp, object->symtab, line)) || 110045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org !(merge_intn = yasm_expr_get_intnum(&merge_expr, 0))) 110145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 110245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("invalid merge entity size")); 110345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 110445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 110545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("entity size for SHF_MERGE not specified")); 110645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags &= ~SHF_MERGE; 110745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 110845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 110945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 111045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_object_get_general(object, sectname, align, 111145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (data.flags & SHF_EXECINSTR) != 0, 111245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org resonly, &isnew, line); 111345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1114a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org esd = yasm_section_get_data(retval, &elf_section_data); 111545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 111645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (isnew || yasm_section_is_default(retval)) { 111745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_set_default(retval, 0); 111845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_typeflags(esd, data.type, data.flags); 111945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (merge_intn) 112045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_secthead_set_entsize(esd, yasm_intnum_get_uint(merge_intn)); 112145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_set_align(retval, align, line); 112245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (flags_override && !data.gasflags) 112345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 112445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section flags ignored on section redeclaration")); 112545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (merge_expr) 112645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(merge_expr); 112745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 112845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 112945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 113045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@observer@*/ /*@null@*/ yasm_symrec * 113145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelf_objfmt_get_special_sym(yasm_object *object, const char *name, 113245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *parser) 113345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 113445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm__strcasecmp(name, "sym") == 0) { 113545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; 113645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return objfmt_elf->dotdotsym; 113745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 113845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return elf_get_special_sym(name, parser); 113945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 114045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 114145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 114245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdir_type(yasm_object *object, yasm_valparamhead *valparams, 114345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, unsigned long line) 114445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 114545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; 114645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp = yasm_vps_first(valparams); 114745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *symname = yasm_vp_id(vp); 114845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Get symbol elf data */ 114945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym = yasm_symtab_use(object->symtab, symname, line); 115045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data); 115145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ const char *type; 115245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 115345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create entry if necessary */ 115445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!entry) { 115545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = elf_symtab_entry_create( 115645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_append_str(objfmt_elf->strtab, symname), sym); 115745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_add_data(sym, &elf_symrec_data, entry); 115845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 115945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 116045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Pull new type from param */ 116145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_next(vp); 116245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vp && !vp->val && (type = yasm_vp_id(vp))) { 116345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm__strcasecmp(type, "function") == 0) 116445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_sym_set_type(entry, STT_FUNC); 116545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (yasm__strcasecmp(type, "object") == 0) 116645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_sym_set_type(entry, STT_OBJECT); 116745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (yasm__strcasecmp(type, "tls_object") == 0) 116845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_sym_set_type(entry, STT_TLS); 116945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (yasm__strcasecmp(type, "notype") == 0) 117045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_sym_set_type(entry, STT_NOTYPE); 117145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 117245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 117345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("unrecognized symbol type `%s'"), type); 117445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 117545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_SYNTAX, N_("no type specified")); 117645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 117745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 117845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 117945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdir_size(yasm_object *object, yasm_valparamhead *valparams, 118045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, unsigned long line) 118145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 118245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; 118345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp = yasm_vps_first(valparams); 118445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *symname = yasm_vp_id(vp); 118545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Get symbol elf data */ 118645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym = yasm_symtab_use(object->symtab, symname, line); 118745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data); 118845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr *size; 118945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 119045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create entry if necessary */ 119145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!entry) { 119245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org entry = elf_symtab_entry_create( 119345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_strtab_append_str(objfmt_elf->strtab, symname), sym); 119445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_add_data(sym, &elf_symrec_data, entry); 119545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 119645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 119745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Pull new size from param */ 119845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_next(vp); 119945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vp && !vp->val && (size = yasm_vp_expr(vp, object->symtab, line))) 120045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_sym_set_size(entry, size); 120145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 120245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_SYNTAX, N_("no size specified")); 120345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 120445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 120545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 120645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdir_weak(yasm_object *object, yasm_valparamhead *valparams, 120745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, unsigned long line) 120845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 120945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; 121045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp = yasm_vps_first(valparams); 121145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *symname = yasm_vp_id(vp); 121245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym = yasm_symtab_declare(object->symtab, symname, 121345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_SYM_GLOBAL, line); 121445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_symtab_append(objfmt_elf, sym, SHN_UNDEF, STB_WEAK, 0, 121545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STV_DEFAULT, NULL, NULL, object); 121645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 121745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 121845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 121945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdir_ident(yasm_object *object, yasm_valparamhead *valparams, 122045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, unsigned long line) 122145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 122245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead sect_vps; 122345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_datavalhead dvs; 122445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *comment; 122545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp; 122645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp2; 122745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 122845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Accept, but do nothing with empty ident */ 122945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!valparams) 123045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 123145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_first(valparams); 123245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!vp) 123345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 123445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 123545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Put ident data into .comment section */ 123645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_vps_initialize(§_vps); 123745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp2 = yasm_vp_create_string(NULL, yasm__xstrdup(".comment")); 123845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_vps_append(§_vps, vp2); 123945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org comment = elf_objfmt_section_switch(object, §_vps, NULL, line); 124045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_vps_delete(§_vps); 124145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 124245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* To match GAS output, if the comment section is empty, put an 124345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * initial 0 byte in the section. 124445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 124545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_section_bcs_first(comment) == yasm_section_bcs_last(comment)) { 124645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_initialize(&dvs); 124745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_append(&dvs, yasm_dv_create_expr( 124845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_create_ident( 124945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_int(yasm_intnum_create_uint(0)), line))); 125045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_append(comment, 125145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bc_create_data(&dvs, 1, 0, object->arch, line)); 125245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 125345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 125445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_initialize(&dvs); 125545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org do { 125645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s = yasm_vp_string(vp); 125745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 125845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 125945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_(".comment requires string parameters")); 126045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_delete(&dvs); 126145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 126245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 126345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dvs_append(&dvs, 126445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_dv_create_string(yasm__xstrdup(s), strlen(s))); 126545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } while ((vp = yasm_vps_next(vp))); 126645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 126745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_append(comment, 126845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bc_create_data(&dvs, 1, 1, object->arch, line)); 126945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 127045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 127145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define valid debug formats to use with this object format */ 127245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *elf_objfmt_dbgfmt_keywords[] = { 127345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 127445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "stabs", 127545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "dwarf2", 127645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL 127745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 127845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 127945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_directive elf_objfmt_directives[] = { 128045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { ".type", "gas", dir_type, YASM_DIR_ID_REQUIRED }, 128145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { ".size", "gas", dir_size, YASM_DIR_ID_REQUIRED }, 128245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { ".weak", "gas", dir_weak, YASM_DIR_ID_REQUIRED }, 128345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { ".ident", "gas", dir_ident, YASM_DIR_ANY }, 128445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "type", "nasm", dir_type, YASM_DIR_ID_REQUIRED }, 128545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "size", "nasm", dir_size, YASM_DIR_ID_REQUIRED }, 128645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "weak", "nasm", dir_weak, YASM_DIR_ID_REQUIRED }, 128745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "ident", "nasm", dir_ident, YASM_DIR_ANY }, 128845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { NULL, NULL, NULL, 0 } 128945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 129045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 129145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *elf_nasm_stdmac[] = { 129245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro type 1+.nolist", 129345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "[type %1]", 129445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endmacro", 129545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro size 1+.nolist", 129645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "[size %1]", 129745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endmacro", 129845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro weak 1+.nolist", 129945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "[weak %1]", 130045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endmacro", 130145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL 130245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 130345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 130445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_stdmac elf_objfmt_stdmacs[] = { 130545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "nasm", "nasm", elf_nasm_stdmac }, 130645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { NULL, NULL, NULL } 130745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 130845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 130945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define objfmt structure -- see objfmt.h for details */ 131045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_elf_LTX_objfmt = { 131145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "ELF", 131245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "elf", 131345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "o", 131445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 32, 131545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0, 131645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_dbgfmt_keywords, 131745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 131845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_directives, 131945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_stdmacs, 132045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_create, 132145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output, 132245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_destroy, 132345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_add_default_section, 1324a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_objfmt_init_new_section, 132545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_section_switch, 132645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_get_special_sym 132745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 132845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 132945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_elf32_LTX_objfmt = { 133045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "ELF (32-bit)", 133145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "elf32", 133245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "o", 133345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 32, 133445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0, 133545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_dbgfmt_keywords, 133645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 133745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_directives, 133845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_stdmacs, 133945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf32_objfmt_create, 134045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output, 134145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_destroy, 134245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_add_default_section, 1343a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_objfmt_init_new_section, 134445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_section_switch, 134545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_get_special_sym 134645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 134745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 134845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_elf64_LTX_objfmt = { 134945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "ELF (64-bit)", 135045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "elf64", 135145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "o", 135245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 64, 135345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0, 135445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_dbgfmt_keywords, 135545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 135645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_directives, 135745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_stdmacs, 135845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf64_objfmt_create, 135945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_output, 136045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_destroy, 136145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_add_default_section, 1362a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org elf_objfmt_init_new_section, 136345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_section_switch, 136445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org elf_objfmt_get_special_sym 136545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 1366